Compare commits

..
52 Commits
Author SHA1 Message Date
Joachim Wiberg 68c7352108 Update ChangeLog and bump version for 4.1-rc2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 16:16:00 +02:00
Joachim Wiberg 0d40e43c4b Update ChangeLog with fixes for containers
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 13:33:35 +02:00
Joachim Wiberg 9867fd82df Check correct struct member to determine if / has 'ro' flag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 12:50:48 +02:00
Joachim Wiberg 1c941fdfbb plugins: add support for disabling RTC and urandom plugins
Some systems may want to handle RTC and /dev/urandom by themselves, or
not at all as in the case of containers where the host does all this.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 11:43:58 +02:00
Joachim Wiberg 0ba67a72f8 plugins: add missing x11-common plugin to static libplug.la
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-06-01 11:43:26 +02:00
Joachim Wiberg 09b9e26b2d fs_init(): skip mounting proc/dev/sys if already mounted
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 17:35:07 +02:00
Joachim Wiberg d25c1d5564 logit: avoid modifying argv[] strings
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 17:03:10 +02:00
Joachim Wiberg d4358ed3f7 Drop nasty hide_args() hack, should not be needed anymore
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 16:51:08 +02:00
Joachim Wiberg cc6ffa35fc Drop parsing of /proc/cmdline by default, instead use argc + argv[]
For most use-cases the kernel will give Finit its arguments as proper
command line args in argc + argv[], like any other program.  However,
for some users, most notably Alpine Linux, there is a slightly broken
initramfs that cannot forward more than one argument using init_args,
for such systems you can re-enable the old behavior with a configure
switch --enable-kernel-cmdline -- it's not ideal but what can you do.

The main reason for removing this feature by default is to support
use-cases where Finit runs as the init for container apps that can read
/proc -- we do not want them to use the init args from the host.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 16:51:08 +02:00
Joachim Wiberg 55e9cb2f58 Update with info on dropped multiple consoles
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 13:59:21 +02:00
Joachim Wiberg 2641256254 plugins: sys: no need to compose path, name is already absolute path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 13:58:30 +02:00
Joachim Wiberg 473116f603 Drop experimental multiple console output support
It has barely worked and only caused more problems than solved annoying
issues.  We have one console for output, /dev/console, which the kernel
sets up for us.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 10:48:37 +02:00
Joachim Wiberg e18d63df4a Always make sure to not acquire controlling TTY for output redirect
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 10:48:04 +02:00
Joachim Wiberg 4b1b3f6913 Update ChangeLog with latest changes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 09:35:20 +02:00
Joachim Wiberg f6da5e4136 Revert "Travis-CI: disable clang temporarily for Coverity Scan run"
This reverts commit 754358113f.
2021-05-31 07:48:49 +02:00
Joachim Wiberg d1d5d39144 Fix possible NULL ptr deref, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:43:29 +02:00
Joachim Wiberg 754358113f Travis-CI: disable clang temporarily for Coverity Scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:27:12 +02:00
Joachim Wiberg c24207516d keventd: properly zero terminate buffer, found by Coverity Scan
Also, fix default: case in error handling, must always continue back to
poll() on any recv() error.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:22:50 +02:00
Joachim Wiberg 2a23bce78d Hide progress output also on stop/shutdown for services w/o -- descr
Progress at startup has been hidden for services w/o -- description, but
for some reason this check was not added to service_stop().  This patch
rectifies the situation, finally.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 07:17:48 +02:00
Joachim Wiberg a19b82ea5f Allow tty's to always respawn, no max restart count
This patch adds a `respawn` flag for services and ttys, always set for
ttys, that allows bypassing the crash/restart counter and immediately
restart a 'crashing' service.

For tty type services this is the expected behavior, but for regular
services it is not.  That is why `respawn` flags is not advertised in
the docs.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 06:29:11 +02:00
Joachim Wiberg ed9590aef1 Fix tty default :ID => tty:S0 instead of tty:ttyS0
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-31 06:27:59 +02:00
Joachim Wiberg 25683221cc Set default envs like sysvinit and busybox does; TERM, LOGNAME, USER
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 13:22:50 +02:00
Joachim Wiberg 9cc9e3ddbb getty: if we cannot execute /bin/login, try sulogin before /bin/sh
Basic security measure, don't bail to shell if we cannot find/exec
login, instead try sulogin before falling back to plain shell.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 12:42:48 +02:00
Joachim Wiberg 654f8aeb19 getty: handle variable number of arguments, only tty required
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:55:21 +02:00
Joachim Wiberg e349abb897 stty: allow utf8 input characters
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 3027a6755f Adjust logic in finding system consoles for progress/debug output
By default, Linux gives us /dev/console for output.  This is a pseudo
device that uses the same actual device as the last console=foo listed
in /proc/cmdline.  The last one listed is the main console, which is
also the *first* one listed in /sys/class/tty/console/active, so we skip
that when we check for system consoles to avoid duplicating output.

The getty code in tty.c currently has its own handling of @console,
which we keep for now.  Ideally, however, the code should be merged.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 5404aa6037 Refactor run_getty() and run_getty2() into one
By moving the built-in getty to a stand-alone bundled getty we can now
refactor the old run_getty() functions into a single one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg a319e32438 Clean up prepare_tty()
When TTYs became first class citizens in Finit 4.0 much of the
boilerplate setup is now down by service_start().  Also, the calls to
TIOCSCTTY, VINTR, and SIGINT ignore is not necessary to do here, it
should be done by the getty used, if any.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 2eaf57fc67 stty: simplify and ignore BREAK/SIGINT
It is up to /bin/login, sulogin, or plain shells to unblock SIGINT.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 88ec4a55cb Call setsid() before redirecting stdio or unblocking signals
We must detach from the controlling TTY before enabling signals and
setting up new stdio.  TTYs have their own handling of stdio.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 0acbc60ec1 initctl: drop confusing 'errno 0' from "Timed out" message
errno is not set when we timeout waiting for a reply from Finit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 4362971c6a run(): Drop extra sig_unblock()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 94c0d1b833 Refactor built-in getty into a standalone getty in /libexec
This patch moves the built-in getty out of Finit into /libexec/finit/,
reducing the size of the Finit binary and simplifying the code.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 11:26:41 +02:00
Joachim Wiberg 1e795d4e16 Fix #175: Ensure finit does not acquire 'dev' as controlling TTY
When starting a getty Finit checks first that the configured TTY device
actually exists and is a TTY.  This patch, by Tobias Waldekranz, ensures
Finit (PID 1) doesn't acquire the TTY device as a controlling TTY.  If
that happens PID 1 will get all signals sent to the process actually
started with the device as its controlling TTY.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-30 00:33:31 +02:00
Joachim Wiberg 93a027ca23 plugins: netlink: fix gcc signed vs unsigned comparsion warning
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 5f3958fab4 getty: max username is 32 chars, according to useradd(1)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 1351b708fe Fix parse error for detecting external getty
When an external getty is used, and an absolute path is not given, the
parser tried to use access() to determine built-in vs external getty.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg e867e039bb Follow-up, document SIGINT/SIGPWR in comment, add missing include
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-27 11:18:06 +02:00
Joachim Wiberg 1d1087a3b3 Merge pull request #174 from troglobit/fix-kmsg-log-level
logging: Disregard logging facility when comparing log levels
2021-05-20 19:00:08 +02:00
Jacques de Laval e91f1ea1b2 logging: Disregard logging facility when comparing log levels
If we don't extract the level (disregarding facility), statements such as
"logit(LOG_CONSOLE | LOG_NOTICE, ...)" would never reach the kernel log.

Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
2021-05-20 17:19:53 +02:00
Joachim Wiberg 55d16edadc contrib: update /etc/finit.conf examples
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-18 09:02:58 +02:00
Joachim Wiberg b79245ddb3 Add support for sys/pwr/fail and sys/key/ctrlaltdel conditions
This patch drops the default signal handlers for SIGPWR and SIGINT with
optional tasks in /etc/finit.conf, triggered by two new conditions:
sys/pwr/fail and sys/key/ctrlaltdel, respectively.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-18 08:58:11 +02:00
Joachim Wiberg e706300b6d keventd: rename fgetln() -> fgetline()
Apparently fgetln() is available in musl libc, but not glibc.  This is a
funciton that first appeared in 4.4BSD.  We take a risk that fgetline()
is free in all libc's, getline() is not.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:44:39 +02:00
Joachim Wiberg d08cbd77aa keventd: use poll.h, not sys/poll.h, fix warning on musl libc
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:41:35 +02:00
Joachim Wiberg b070ae73a4 Revert "Travis-CI: disable clang temporarily for Coverity Scan run"
This reverts commit f52c141062.
2021-05-17 00:33:30 +02:00
Joachim Wiberg 2c30eef9a1 Update changelog for v4.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:43 +02:00
Joachim Wiberg 31cdc113fc doc: update build instructions and examples
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:21 +02:00
Joachim Wiberg f6f813498b doc: add some info about keventd, what it does
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:32:11 +02:00
Joachim Wiberg 4c8baaf7c0 Make kevent a configure option, disbled by default
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-17 00:26:57 +02:00
Joachim Wiberg 57ca937f27 New function to create onshot conds without updating
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:37:41 +02:00
Joachim Wiberg d13e39e345 keventd ftbfs: add missing include path to libite
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:35:39 +02:00
Joachim Wiberg f52c141062 Travis-CI: disable clang temporarily for Coverity Scan run
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2021-05-16 23:21:31 +02:00
42 changed files with 510 additions and 334 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ script:
- ./configure --prefix= --enable-static
- make clean
- make V=1 -j5
- ./configure --prefix= --enable-x11-common-plugin --with-watchdog
- ./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
- cat config.log
- make clean
- make V=1 -j5
+57 -2
View File
@@ -7,7 +7,9 @@ All relevant changes are documented in this file.
[4.1][UNRELEASED]
-----------------
Bug fix release.
Bug fix release. Also disables handlers for `SIGINT` and `SIGPWR`, a
new set of `sys` conditions are instead generated which can be used to
trigger external programs.
### Changes
* Change behavior on SIGUSR1 to be compatible with sysvinit and systemd.
@@ -16,17 +18,62 @@ Bug fix release.
sysvinit (upgrading/reinstalling causes scripts to `kill -USR1 1`)
* Change how `contrib/debian/install.sh` sets up a Grub boot entry for
finit. We now modify the $SUPPORTED_INITS variable in `10_linux`
* Disable default kernel ctrl-alt-delete handler and let Finit instead
catch `SIGINT` from kernel to be able to perform a proper reboot.
There is no default command for this, you need to set up a task that
triggers on `<sys/key/ctrlaltdel>` to issue `initctl reboot`
* Added keventd to provide `<sys/pwr/ac>` condition to Finit. keventd
is currently only responsible for monitoring `/sys/class/power_supply`
for changes to active AC mains power online status. Enable keventd
with `configure --with-keventd`
* For handling power fail events (from UPS and similar) a process may
send `SIGPWR` to PID 1. Finit no longer redirects this to `SIGUSR1`
(poweroff). There is no default command for this, you need to set up
a task that triggers on `<sys/pwr/fail>` to issue `initctl poweroff`
* Built-in Finit getty is now a standalone program
* Default termios for TTYs now enable `IUTF8` on input
* If `/bin/login` is not found, Finit now tries `sulogin` before it
falls back to an unauthenticated `/bin/sh`
* Dropped (broken) support for multiple consoles. Finit now follows
the default console selected by the kernel, `/dev/console`
* Finit no longer parses `/proc/cmdline` for its options. Instead all
options are by default now read from `argv[]`, like a normal program,
this is also what the kernel does by default. Please note, this may
not work if your systems boots with an initramfs (ymmv), for such
cases, see `configure --enable-kernel-cmdline`
* The following plugins are now possible to disable (for containers):
`rtc.so`, `urandom.so`, you may also want to disable `hotplug.so`.
They are all enabled by default, as in Finit 4.0, but may be moved
to external tools or entries in `finit.conf` in Finit 5.0
### Fixes
* Stricter interface name validation in netlink plugin, modeled after
the kernel. Suggested by Coverity Scan
* Fix problem of re-registering a service as a task. Previously, if a
fundamental change, like type, was made to an active service/run/task
it did not take. Only possible workaround was to remove from config
* initctl: drop warning when removing a non-existing usr condition
* initctl: drop confusing `errno 0` when timing out waiting for reply
* Ensure services in plugins and from Finit main belong to a cgroup
* Ensure init top-level cgroup remains a leaf group
* Fix tty parse error for detecting use of external getty
* Fix default `name:` and `:ID` for tty's, e.g. `ttyS0` now gives
`tty:S0` as expected. This was default for built-in getty already
* Fix max username (32 chars) in bundled Finit getty
* The `contrib/*/install.sh` scripts failed to run from tarball
* Finit no longer forcibly mounts; `/dev`, `/proc`, or `/sys`, instead
it checks first if they are already mounted (devtmpfs or container)
* Fix `/etc/fstab` parser to properly check for 'ro' to not remount the
root filesystem at boot. The wrong field was read, so a root mounted
by an initramfs, or by lxc for a container, had their root remounted
* Fix #170: detect loss of default route when interfaces go down. This
emulates the missing kernel netlink message to remove the condition
net/default/route to allow stopping dependent services
* Fix #171: restore automatic mount of `/dev/shm`, `/dev/pts`, `/run`
and `/tmp`, unless mounted already by `/etc/fstab`. This is what most
desktop systems expect PID 1 to do
desktop systems expect PID 1 to do. Here we also make sure to mount
`/run/lock` as a tmpfs as well, with write perms for regular users,
this prevents regular users from filling up `/run` and causing DoS.
* Fix #173: netlink plugin runs out of socket buffer space;
finit[1]: nl_callback():recv(): No buffer space available
@@ -38,6 +85,13 @@ Bug fix release.
finit[1]: nl_callback():busy system, resynchronizing with kernel.
* Fix #174: loss of log messages using combo of prio and facility, e.g.,
`logit(LOG_CONSOLE | LOG_NOTICE, ...)`, by Jacques de Laval, Westermo
* Fix #175: ensure Finit does not acquire a controlling TTY when checking
if a device is a TTY before starting a getty. This fixes an old bug
where Ctrl-C after logout from a shell could cause PID 1 to get SIGINT,
which in turn could lead to a system reboot
[4.0][] - 2021-04-26
--------------------
@@ -911,6 +965,7 @@ Major bug fix release.
* Initial release
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.0...HEAD
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
+17 -1
View File
@@ -1,4 +1,4 @@
AC_INIT(Finit, 4.1-rc1, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
AC_INIT(Finit, 4.1-rc2, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes])
@@ -52,6 +52,10 @@ AC_ARG_ENABLE(auto_reload,
AS_HELP_STRING([--enable-auto-reload], [Automatic reload on any .conf change]),,[
enable_auto_reload=no])
AC_ARG_ENABLE(kernel_cmdline,
AS_HELP_STRING([--enable-kernel-cmdline], [Parse init args from /proc/cmdline (don't use!)]),,[
enable_kernel_cmdline=no])
AC_ARG_ENABLE(redirect,
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
enable_redirect=yes])
@@ -77,6 +81,8 @@ AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
# Check for extra arguments or packages
AC_ARG_WITH(heading,
@@ -111,6 +117,9 @@ AC_ARG_WITH(random-seed,
AS_HELP_STRING([--with-random-seed=FILE], [Save a random seed for /dev/urandom across reboots, default /var/lib/misc/random-seed]),
[random_seed=$withval], [random_seed=yes])
AC_ARG_WITH(keventd,
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
AC_ARG_WITH(watchdog,
AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]),
[watchdog=$withval], [with_watchdog=no watchdog=])
@@ -121,6 +130,9 @@ AC_ARG_WITH(watchdog,
AS_IF([test "x$enable_auto_reload" = "xyes"], [
AC_DEFINE(AUTO_RELOAD, 1, [Finit automatically does `initctl reload` on any .conf change])])
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
AS_IF([test "x$enable_redirect" = "xyes"], [
AC_DEFINE(REDIRECT_OUTPUT, 1, [Enable redirection of service output to /dev/null])])
@@ -179,6 +191,8 @@ AS_IF([test "x$with_random_seed" != "xno"], [
AC_EXPAND_DIR(random_path, "$random_seed")
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
AS_IF([test "x$with_watchdog" != "xno"], [
AS_IF([test "x$watchdog" = "xyes"], [
watchdog=/dev/watchdog])
@@ -188,6 +202,7 @@ AS_IF([test "x$with_watchdog" != "xno"], [
# Control build with automake flags
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
AM_CONDITIONAL(WATCHDOGD, [test "x$with_watchdog" != "xno"])
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
@@ -234,6 +249,7 @@ Behavior:
Optional features:
Install doc/..........: $enable_doc
Install contrib/......: $enable_contrib
Built-in keventd......: $with_keventd
Built-in watchdogd....: $with_watchdog $watchdog
Built-in logrotate....: $enable_logrotate
Redirect output.......: $enable_redirect
+1 -1
View File
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-watchdog \
--with-heading="Alpine Linux 3.13"
--with-heading="Alpine Linux" --with-keventd
echo
echo "*** Building ..."
+17 -1
View File
@@ -5,6 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+1 -1
View File
@@ -25,7 +25,7 @@ echo
--prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin \
--enable-alsa-utils-plugin --with-keventd \
--with-random-seed=/var/lib/urandom/random-seed \
--with-heading="Debian GNU/Linux"
+17 -1
View File
@@ -5,6 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+8
View File
@@ -35,6 +35,14 @@ tty /dev/tty1
tty /dev/tty2
tty /dev/tty3
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
# Alternative method instead of runparts
#task [S] /etc/init.d/keyboard-setup start -- Setting up preliminary keymap
#task [S] /etc/init.d/acpid start -- Starting ACPI Daemon
+1 -1
View File
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
--sysconfdir=/etc --localstatedir=/var \
--enable-dbus-plugin --enable-x11-common-plugin \
--enable-alsa-utils-plugin --with-watchdog \
--with-heading="Void Linux"
--with-heading="Void Linux" --with-keventd
echo
echo "*** Building ..."
+17
View File
@@ -5,5 +5,22 @@
# Default is 2
#runlevel 2
# Top-level cgroups and their default settings. All groups mandatory
# but more can be added, max 8 groups in total currently. The cgroup
# 'root' is also available, reserved for RT processes. Settings are
# as-is, only one shorthand 'mem.' exists, other than that it's the
# cgroup v2 controller default names.
#cgroup init cpu.weight:100
#cgroup user cpu.weight:100
#cgroup system cpu.weight:9700
# Task to run if ctrl-alt-del is pressed. This condition is asserted by
# Finit upon receiving SIGINT (from the kernel).
#task <sys/key/ctrlaltdel> [12345789] initctl reboot -- Rebooting system
# Task to run if the kernel gets a power fail condition is pressed.
# Asserted by Finit upon receiving SIGPWR (from the kernel).
#task <sys/pwr/fail> [12345789] initctl poweroff -- Shutting down system
## Bootstrap services and tasks
# Can be listed here or in /etc/finit.d/*.conf
+13 -8
View File
@@ -53,6 +53,10 @@ Below are a few of the main switches to configure:
built-ins (.o files) and all external libraries, except the C library
will be linked statically.
* `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from
`/proc/cmdline`, this is not recommended since Finit may be running as the
init for container apps that can see the host's `/proc` filesystem
* `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
* `--enable-dbus-plugin`: Enable the optional D-Bus `dbus.so` plugin.
@@ -70,16 +74,17 @@ Example
First, unpack the archive:
```shell
$ tar xf finit-3.0.tar.xz
$ cd finit-3.0/
$ tar xf finit-4.1.tar.gz
$ cd finit-4.1/
```
Then configure, build and install:
```shell
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-heading="Alpine Linux 3.13" --with-hostname=alpine
$ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \
--with-keventd --with-watchdog \
--with-heading="Alpine Linux" --with-hostname=alpine
$ make
.
.
@@ -87,13 +92,13 @@ $ make
$ DESTDIR=/tmp/finit make install
```
In this example the [finit-3.0.tar.xz][1] archive is unpacked to the
In this example the [finit-4.1.tar.gz][1] archive is unpacked to the
user's home directory, configured, built and installed to a temporary
staging directory. The environment variable `DESTDIR` controls the
destination directory when installing, very useful for building binary
standalone packages.
Finit 3.0 and later can detect if it runs on an embedded system, or a
Finit 4.1 and later can detect if it runs on an embedded system, or a
system that use BusyBox tools instead of udev & C:o. On such systems
`mdev` instead of `udev` is used. However, remember to also change the
Linux config to:
@@ -171,6 +176,6 @@ it only for debugging start up issues when Finit crashes.
systems since they can potentially give a user root access.
[1]: ftp://troglobit.com/finit/finit-3.0.tar.xz
[1]: ftp://troglobit.com/finit/finit-4.1.tar.gz
[libuEv]: https://github.com/troglobit/libuev
[libite]: https://github.com/troglobit/libite
+2
View File
@@ -6,6 +6,8 @@ passed on the Linux kernel command line. Not limited to Finit.
The `bool` setting is one of `on, off, true false, 1, 0`.
> **NOTE:** remember to use `--` to separate kernel parameters from
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
* `debug`: Enable kernel debug. Debug messages are printed to the
console until Finit starts up.
+13 -6
View File
@@ -87,12 +87,15 @@ Static (one-shot) conditions, like `usr/`, never enter the `flux` state.
Built-in Conditions
-------------------
Finit comes with a `pidfile` and `netlink` plugin. When enabled, the
`pidfile` plugin watches `/var/run/` (recursively) for PID files created
by the monitored services, and sets a corresponding condition in the
`pid/` namespace. Similarily, the `netlink` plugin provides basic
conditions for when an interface is brought up/down and when a default
route (gateway) is set, in the `net/` namespace.
Finit comes with a set of plugins for conditions: `pidfile`, `netlink`,
`sys`, and `usr`. The `pidfile` plugin (recursively) watches `/run/`
(recursively) for PID files created by the monitored services, and sets
a corresponding condition in the `pid/` namespace. Similarily, the
`netlink` plugin provides basic conditions for when an interface is
brought up/down and when a default route (gateway) is set, in the `net/`
namespace. The `sys` and `usr` plugins monitor are passive condition
monitors where the action is provided by `keventd`, signal handlers,
and in the case of `usr`, the end-user via the `initctl` tool
With the example listed above, finit does not start the `/sbin/netd`
daemon until `setupd` and `zebra` has started *and* created their PID
@@ -111,6 +114,10 @@ Built-in conditions:
- `net/<IFNAME>/exist`
- `net/<IFNAME>/up`
- `net/<IFNAME>/running`
- `sys/pwr/ac`
- `sys/pwr/fail`
- `sys/key/ctrlaltdel`
- `usr/foo`
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
+17
View File
@@ -26,6 +26,7 @@ Configuration
* [/etc/finit.conf](#etcfinitconf)
* [/etc/finit.d](#etcfinitd)
* [Watchdog](#watchdog)
* [keventd](#keventd)
Introduction
@@ -704,3 +705,19 @@ the only option is to remove `/libexec/finit/watchdogd` or build without
it at configure time.
[bootstrap]: bootstrap.md
keventd
-------
The kernel event daemon bundled with Finit is a simple uevent monitor
for `/sys/class/power_supply`. It provides the `sys/pwr/ac` condition,
which can be useful to prevent power hungry services like anacron to run
when a laptop is only running on battery, for instance.
Since keventd is not an integral part of Finit yet it is not enabled by
default. Enable it using `./configuure --with-keventd`. The bundled
contrib build scripts for Debian, Alpine, and Void have this enabled.
This daemon is planned to be extended with monitoring of other uevents,
patches and ideas are welcome in the issue tracker.
+22 -2
View File
@@ -7,7 +7,7 @@ AM_CPPFLAGS += $(lite_CFLAGS)
if STATIC
noinst_LTLIBRARIES = libplug.la
libplug_la_SOURCES = bootmisc.c modprobe.c rtc.c pidfile.c procps.c sys.c tty.c urandom.c usr.c
libplug_la_SOURCES = bootmisc.c modprobe.c pidfile.c procps.c sys.c tty.c usr.c
if BUILD_ALSA_UTILS_PLUGIN
libplug_la_SOURCES += alsa-utils.c
@@ -33,8 +33,20 @@ if BUILD_RESOLVCONF_PLUGIN
libplug_la_SOURCES += resolvconf.c
endif
if BUILD_RTC_PLUGIN
libplug_la_SOURCES += rtc.c
endif
if BUILD_URANDOM_PLUGIN
libplug_la_SOURCES += urandom.c
endif
if BUILD_X11_COMMON_PLUGIN
libplug_la_SOURCES += x11-common.c
endif
else
pkglib_LTLIBRARIES = bootmisc.la modprobe.la rtc.la pidfile.la procps.la sys.la tty.la urandom.la usr.la
pkglib_LTLIBRARIES = bootmisc.la modprobe.la pidfile.la procps.la sys.la tty.la usr.la
if BUILD_ALSA_UTILS_PLUGIN
pkglib_LTLIBRARIES += alsa-utils.la
@@ -60,6 +72,14 @@ if BUILD_RESOLVCONF_PLUGIN
pkglib_LTLIBRARIES += resolvconf.la
endif
if BUILD_RTC_PLUGIN
pkglib_LTLIBRARIES += rtc.la
endif
if BUILD_URANDOM_PLUGIN
pkglib_LTLIBRARIES += urandom.la
endif
if BUILD_X11_COMMON_PLUGIN
pkglib_LTLIBRARIES += x11-common.la
endif
+3 -2
View File
@@ -231,6 +231,7 @@ static int nl_parse(int sd)
while (1) {
struct nlmsghdr *nh;
ssize_t len;
size_t l;
while ((len = recv(sd, nl_buf, NL_BUFSZ, 0)) < 0) {
switch (errno) {
@@ -252,8 +253,8 @@ static int nl_parse(int sd)
}
_d("recv %lld bytes", len);
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
l = (size_t)len;
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) {
struct nlmsgerr *nle;
switch (nh->nlmsg_type) {
+1 -3
View File
@@ -43,11 +43,9 @@ static int sys_add_path(struct iwatch *iw, char *path)
static void sys_update_conds(char *dir, char *name, uint32_t mask)
{
char fn[PATH_MAX];
char *cond;
paste(fn, sizeof(fn), dir, name);
cond = strstr(fn, COND_BASE);
cond = strstr(name, COND_BASE);
if (!cond)
return;
+1 -1
View File
@@ -1,4 +1,4 @@
/* Setup random seed
/* Setup and save random seed at boot/shutdown
*
* Copyright (c) 2012-2021 Joachim Wiberg <troglobit@gmail.com>
*
+1
View File
@@ -1,5 +1,6 @@
.deps/*
finit
getty
initctl
keventd
logit
+11 -2
View File
@@ -8,7 +8,10 @@ AM_LDFLAGS = -export-dynamic
endif
sbin_PROGRAMS = finit initctl
pkglibexec_PROGRAMS = keventd logit sulogin
pkglibexec_PROGRAMS = getty logit sulogin
if KEVENTD
pkglibexec_PROGRAMS += keventd
endif
if WATCHDOGD
pkglibexec_PROGRAMS += watchdogd
endif
@@ -16,8 +19,14 @@ endif
finit_pkglibdir = $(pkglibdir)
finit_pkglib_SCRIPTS = rescue.conf sample.conf
getty_SOURCES = finit.h getty.c helpers.h logrotate.c stty.c utmp-api.c utmp-api.h
getty_CFLAGS = -W -Wall -Wextra -std=gnu99
getty_CFLAGS += $(lite_CFLAGS)
getty_LDADD = $(lite_LIBS)
keventd_SOURCES = keventd.c iwatch.c iwatch.h util.c util.h
keventd_CFLAGS = -W -Wall -Wextra -std=gnu99
keventd_CFLAGS += $(lite_CFLAGS)
keventd_LDADD = $(lite_LIBS)
sulogin_SOURCES = sulogin.c
@@ -33,7 +42,7 @@ finit_SOURCES = api.c cgroup.c cgroup.h \
cond.c cond-w.c cond.h \
conf.c conf.h \
exec.c finit.c finit.h \
getty.c stty.c \
stty.c \
helpers.c helpers.h \
iwatch.c iwatch.h \
log.c log.h \
+6 -2
View File
@@ -67,6 +67,7 @@ int client_send(struct init_request *rq, ssize_t len)
{
struct pollfd pfd = { 0 };
int sd, result = 255;
int rc;
sd = client_connect();
if (-1 == sd)
@@ -86,8 +87,11 @@ int client_send(struct init_request *rq, ssize_t len)
pfd.fd = sd;
pfd.events = POLLIN;
if (poll(&pfd, 1, 2000) <= 0) {
warn("Timed out waiting for reply from Finit, errno %d", errno);
if ((rc = poll(&pfd, 1, 2000)) <= 0) {
if (rc)
warn("poll(), errno %d", errno);
else
warnx("Timed out waiting for reply from Finit.");
goto exit;
}
+16 -4
View File
@@ -199,21 +199,33 @@ void cond_set(const char *name)
cond_update(name);
}
void cond_set_oneshot(const char *name)
int cond_set_oneshot_noupdate(const char *name)
{
const char *path;
if (string_compare(name, "nop"))
return;
return 1;
path = cond_path(name);
_d("%s => %s", name, path);
if (cond_checkpath(path))
return 1;
if (symlink(_PATH_RECONF, path) && errno != EEXIST) {
_pe("Failed creating onshot cond %s", name);
return 1;
}
return 0;
}
void cond_set_oneshot(const char *name)
{
_d("%s", name);
if (cond_set_oneshot_noupdate(name))
return;
if (symlink(_PATH_RECONF, path) && errno != EEXIST)
_pe("Failed creating onshot cond %s", name);
cond_update(name);
}
+1
View File
@@ -38,6 +38,7 @@ void cond_clear (const char *name);
void cond_reload (void);
int cond_set_noupdate (const char *name);
int cond_set_oneshot_noupdate(const char *name);
int cond_clear_noupdate(const char *name);
void cond_reassert (const char *pat);
+29 -27
View File
@@ -66,22 +66,6 @@ static TAILQ_HEAD(head, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(c
static int parse_conf(char *file, int is_rcsd);
static void drop_changes(void);
static void hide_args(int argc, char *argv[])
{
/*
* Hide command line arguments from ps (in particular for
* forked children that don't execv()). This is an ugly
* hack that only works on Linux.
* https://web.archive.org/web/20110227041321/http://netsplit.com/2007/01/10/hiding-arguments-from-ps/
*/
if (argc > 1) {
char *arg_end;
arg_end = argv[argc-1] + strlen (argv[argc-1]);
*arg_end = ' ';
}
}
int get_bool(char *arg, int default_value)
{
if (!arg)
@@ -145,24 +129,27 @@ static void parse_arg(char *arg)
single = 1;
}
void conf_parse_cmdline(int argc, char *argv[])
#ifdef KERNEL_CMDLINE
/*
* Parse /proc/cmdline to find args for init. Don't use this!
*
* Instead, rely on the kernel to give Finit its arguments as
* regular argc + argv[]. Only use this if the system you run
* on has a broken initramfs system that cannot forward args
* to Finit properly.
*/
static void parse_kernel_cmdline(void)
{
int dbg = 0;
FILE *fp;
char line[LINE_SIZE], *cmdline, *tok;
for (int i = 1; i < argc; i++)
parse_arg(argv[i]);
hide_args(argc, argv);
FILE *fp;
fp = fopen("/proc/cmdline", "r");
if (!fp)
goto done;
return;
if (!fgets(line, sizeof(line), fp)) {
fclose(fp);
goto done;
return;
}
cmdline = chomp(line);
@@ -173,8 +160,23 @@ void conf_parse_cmdline(int argc, char *argv[])
parse_arg(tok);
}
fclose(fp);
}
#else
#define parse_kernel_cmdline()
#endif
/*
* Kernel gives us all non-kernel options on our cmdline
*/
void conf_parse_cmdline(int argc, char *argv[])
{
int dbg = 0;
for (int i = 1; i < argc; i++)
parse_arg(argv[i]);
parse_kernel_cmdline();
done:
log_init(dbg);
}
+37 -57
View File
@@ -26,6 +26,7 @@
#include <ctype.h> /* isdigit() */
#include <dirent.h>
#include <err.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
@@ -33,6 +34,7 @@
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
#include <termios.h>
#include <lite/lite.h>
#include <linux/vt.h>
#include "finit.h"
#include "cgroup.h"
@@ -106,8 +108,6 @@ int run(char *cmd)
if (0 == pid) {
FILE *fp;
/* Reset signal handlers that were set by the parent process */
sig_unblock();
setsid();
/* Always redirect stdio for run() */
@@ -240,10 +240,8 @@ int exec_runtask(char *cmd, char *args[])
static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit rlimit[])
{
struct sigaction sa;
struct termios term;
char name[80];
int fd;
int fd, dummy;
fd = open(tty, O_RDWR);
if (fd < 0) {
@@ -254,44 +252,18 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
/*
* Become session leader and set controlling TTY
* to enable Ctrl-C and job control in shell.
*/
setsid();
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0)
logit(LOG_WARNING, "Failed TIOCSCTTY on %s: %s", tty, strerror(errno));
/* Set default TERM, run_getty() below allows override */
if (ioctl(fd, VT_OPENQRY, &dummy) == -1)
setenv("TERM", "vt102", 1); /* likely a serial line */
else
setenv("TERM", "linux", 1);
/*
* Reset to sane defaults in case of messup from prev. session
*/
stty(STDIN_FILENO, speed);
/*
* Disable ISIG (INTR, QUIT, SUSP) before handing over to getty.
* It is up to the getty process to allow them again.
*/
if (!tcgetattr(STDIN_FILENO, &term)) {
term.c_lflag &= ~ISIG;
term.c_cc[VEOF] = _POSIX_VDISABLE;
term.c_cc[VINTR] = _POSIX_VDISABLE;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term);
}
/* Reset signal handlers that were set by the parent process */
sig_unblock();
/*
* Ignore a few signals, needed to prevent Ctrl-C at login:
* prompt and to prevent QUIT from dumping core.
*/
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
stty(fd, speed);
close(fd);
/* Set configured limits */
for (int i = 0; i < RLIMIT_NLIMITS; i++) {
@@ -380,25 +352,7 @@ static int activate_console(int noclear, int nowait)
* since /bin/login usually only disables ECHO until a password line has
* been entered. Upon starting the user's $SHELL the ISIG flag is reset
*/
pid_t run_getty(char *tty, char *baud, char *term, int noclear, int nowait, struct rlimit rlimit[])
{
speed_t speed;
int rc = 1;
speed = stty_parse_speed(baud);
prepare_tty(tty, speed, "tty", rlimit);
if (activate_console(noclear, nowait)) {
logit(LOG_INFO, "Starting built-in getty on %s, speed %u", tty, speed);
rc = getty(tty, speed, term, NULL);
}
return rc;
}
/*
* Start external getty as defined by user in .conf file
*/
pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[])
pid_t run_getty(char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[])
{
int rc = 1;
@@ -414,6 +368,32 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait, st
return rc;
}
int sh(char *tty)
{
char *args[2] = {
NULL,
NULL
};
char *arg0;
size_t len;
/* The getty process is usually responsible for the UTMP login record */
utmp_set_login(tty, NULL);
/* Start /bin/sh as a login shell, i.e. with a prefix '-' */
len = strlen(_PATH_BSHELL) + 2;
arg0 = malloc(len);
if (!arg0)
err(1, "Failed allocating memory");
snprintf(arg0, len, "-%s", _PATH_BSHELL);
args[0] = arg0;
/* Unblock signals inherited from parent */
sig_unblock();
return execv(_PATH_BSHELL, args);
}
pid_t run_sh(char *tty, int noclear, int nowait, struct rlimit rlimit[])
{
int rc = 1;
+31 -2
View File
@@ -149,6 +149,25 @@ static int fsck_all(void)
}
#ifndef SYSROOT
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
static int fs_readonly_root(struct fstab *fs)
{
char *tok, *str;
if (!fs)
return 1;
str = fs->fs_mntops;
while ((tok = strtok(str, ","))) {
if (!strcmp(tok, "ro"))
return 1;
str = NULL;
}
return 0;
}
static void fs_remount_root(int fsckerr)
{
struct fstab *fs;
@@ -161,8 +180,7 @@ static void fs_remount_root(int fsckerr)
break;
}
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
if (!fs || !strcmp(fs->fs_type, "ro"))
if (fs_readonly_root(fs))
goto out;
if (fsckerr)
@@ -295,6 +313,15 @@ static void fs_init(void)
for (i = 0; i < NELEMS(fs); i++) {
int rc;
/*
* Check if already mounted, we may be running in a
* container, or an initramfs ran before us. The
* function fismnt() reliles on /proc/mounts being
* unique for each chroot/container.
*/
if (fismnt(fs[i].file))
continue;
rc = mount(fs[i].spec, fs[i].file, fs[i].type, 0, NULL);
if (rc && errno != EBUSY)
_pe("Failed mounting %s on %s", fs[i].spec, fs[i].file);
@@ -525,6 +552,8 @@ int main(int argc, char *argv[])
*/
setenv("PATH", _PATH_STDPATH, 1);
setenv("SHELL", _PATH_BSHELL, 1);
setenv("LOGNAME", "root", 1);
setenv("USER", "root", 1);
if (chdir("/"))
_pe("Failed cd /");
+2
View File
@@ -50,8 +50,10 @@
#define FINIT_CGPATH "/sys/fs/cgroup"
#endif
/* To use these, include config.h, or define FINIT_LIBPATH_ */
#define _PATH_LOGIT FINIT_LIBPATH_ "/logit"
#define _PATH_SULOGIN FINIT_LIBPATH_ "/sulogin"
#define _PATH_GETTY FINIT_LIBPATH_ "/getty"
#define CMD_SIZE 256
#define LINE_SIZE 1024
+58 -65
View File
@@ -21,20 +21,21 @@
* THE SOFTWARE.
*/
#include "config.h"
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
#include <termios.h>
#include "finit.h"
#include "cgroup.h"
#include "helpers.h"
#include "sig.h"
#include "utmp-api.h"
#ifndef _PATH_LOGIN
@@ -44,19 +45,14 @@
/*
* Read one character from stdin.
*/
static int readch(char *tty)
static int readch(void)
{
int st;
char ch1;
int st;
st = read(STDIN_FILENO, &ch1, 1);
if (st == 0) {
dprint(STDOUT_FILENO, "\n", 0);
_exit(0);
}
if (st < 0)
errx(1, "getty: %s: read error", tty);
if (st <= 0)
return -1;
return ch1 & 0xFF;
}
@@ -141,10 +137,10 @@ static void do_issue(char *tty)
/*
* Handle the process of a GETTY.
*/
static void do_getty(char *tty, char *name, size_t len)
static int get_logname(char *tty, char *name, size_t len)
{
int ch;
char *np;
int ch;
/*
* Display prompt.
@@ -155,14 +151,9 @@ static void do_getty(char *tty, char *name, size_t len)
do_issue(tty);
np = name;
while ((ch = readch(tty)) != '\n') {
if (ch == CTRL('U')) {
while (np > name) {
dprint(STDOUT_FILENO, "\b \b", 3);
np--;
}
continue;
}
while ((ch = readch()) != '\n') {
if (ch < 0)
return 1;
if (np < name + len)
*np++ = ch;
@@ -174,6 +165,7 @@ static void do_getty(char *tty, char *name, size_t len)
}
name[len - 1] = 0;
return 0;
}
/*
@@ -185,26 +177,27 @@ static int do_login(char *name)
{
struct stat st;
cgroup_user(name, 0);
execl(_PATH_LOGIN, _PATH_LOGIN, name, NULL);
/*
* Failed to exec login, should not happen on normal systems.
* Try a starting a rescue shell instead.
*
* Note: Add /etc/securetty handling.
*/
warnx("Failed exec %s, attempting fallback to %s ...", _PATH_LOGIN, _PATH_BSHELL);
if (fstat(0, &st) == 0 && S_ISCHR(st.st_mode))
if (fstat(0, &st) == 0 && S_ISCHR(st.st_mode)) {
warnx("Failed exec %s, attempting fallback to %s ...", _PATH_LOGIN, _PATH_SULOGIN);
execl(_PATH_SULOGIN, _PATH_SULOGIN, NULL);
warnx("Failed exec %s, attempting fallback to %s ...", _PATH_SULOGIN, _PATH_BSHELL);
execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
}
return 1; /* We shouldn't get here ... */
}
int getty(char *tty, speed_t speed, char *term, char *user)
static int getty(char *tty, speed_t speed, char *term, char *user)
{
const char cln[] = "\r\e[2K\n";
char name[30];
char name[33]; /* useradd(1) limit at 32 chars */
/*
* Clean up tty name.
@@ -212,15 +205,20 @@ int getty(char *tty, speed_t speed, char *term, char *user)
if (!strncmp(tty, _PATH_DEV, strlen(_PATH_DEV)))
tty += 5;
/* Set up TTY, re-enabling ISIG et al. */
stty(STDIN_FILENO, speed);
dprint(STDERR_FILENO, cln, strlen(cln));
/* The getty process is responsible for the UTMP login record */
utmp_set_login(tty, NULL);
if (!user)
do_getty(tty, name, sizeof(name));
else
/* Replace "Please press enter ..." with login: */
dprint(STDERR_FILENO, cln, strlen(cln));
restart:
stty(STDIN_FILENO, speed);
if (!user) {
if (get_logname(tty, name, sizeof(name))) {
sleep(5);
goto restart;
}
} else
strlcpy(name, user, sizeof(name));
if (term && term[0])
@@ -229,42 +227,37 @@ int getty(char *tty, speed_t speed, char *term, char *user)
return do_login(name);
}
int sh(char *tty)
static int usage(int rc)
{
struct termios term;
char *args[2] = {
NULL,
NULL
};
char *arg0;
size_t len;
warnx("usage: getty [-h?] tty [speed [term]]");
return rc;
}
/* The getty process is usually responsible for the UTMP login record */
utmp_set_login(tty, NULL);
int main(int argc, char *argv[])
{
char *tty, *speed = "0", *term = NULL;
int c;
/* Set up TTY, re-enabling ISIG et al. */
stty(STDIN_FILENO, B0);
/* Start /bin/sh as a login shell, i.e. with a prefix '-' */
len = strlen(_PATH_BSHELL) + 2;
arg0 = malloc(len);
if (!arg0)
err(1, "Failed allocating memory");
snprintf(arg0, len, "-%s", _PATH_BSHELL);
args[0] = arg0;
/* Reenable Ctrl-D and Ctrl-C, and ... */
if (!tcgetattr(STDIN_FILENO, &term)) {
term.c_lflag |= ISIG;
term.c_cc[VEOF] = CEOF;
term.c_cc[VINTR] = CINTR;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term);
while ((c = getopt(argc, argv, "h?")) != EOF) {
switch(c) {
case 'h':
case '?':
return usage(0);
default:
return usage(1);
}
}
/* ... unblock signals in general */
sig_unblock();
if (optind >= argc)
return usage(1);
return execv(_PATH_BSHELL, args);
tty = argv[optind++];
if (optind < argc)
speed = argv[optind++];
if (optind < argc)
term = argv[optind++];
return getty(tty, atoi(speed), term, NULL);
}
/**
+2 -83
View File
@@ -68,92 +68,13 @@ static const char *status2[] = STATUS_CLASS;
#define CHOOSE(x,y,z) z
static const char *color[] = STATUS_CLASS;
/*
* System consoles, can be given multiple times on the kernel cmdline.
* We support only three currently. If none are given on the cmdline
* we probe /sys/class/tty/console/active and use the first (default).
*/
#define MAX_CONS 3
static char *consoles[MAX_CONS];
static int fds[MAX_CONS];
static int num_cons = 0;
/*
* System default console is always the first
*/
char *console(void)
{
return consoles[0];
}
static void add_console(char *cons)
{
char path[80];
char *ptr;
int i;
if (num_cons == NELEMS(fds)) {
_e("too many consoles, max %d supported", NELEMS(fds));
return;
}
/* drop any options */
ptr = strchr(cons, ',');
if (ptr)
*ptr = 0;
if (!strncmp(cons, "/dev/", 5))
cons += 5;
snprintf(path, sizeof(path), "/dev/%s", cons);
/* check for and skip duplicates */
for (i = 0; i < num_cons; i++) {
if (string_compare(path, consoles[i]))
return;
}
/* this requires we have /dev mounted && a device there */
fds[num_cons] = open(path, O_WRONLY);
if (fds[num_cons] < 0) {
_pe("Failed opening console %s", path);
return;
}
consoles[num_cons] = strdup(path);
num_cons++;
}
static void find_active_consoles(void)
{
char *cons, *ptr, *tok;
char buf[512];
FILE *fp;
fp = fopen("/sys/class/tty/console/active", "r");
if (!fp) {
fallback:
_d("Using fallback /dev/console");
add_console("console");
return;
}
ptr = fgets(buf, sizeof(buf), fp);
fclose(fp);
if (!ptr)
goto fallback;
cons = chomp(ptr);
_d("Using these system consoles: %s", cons);
while ((tok = strtok(cons, " \t"))) {
cons = NULL;
add_console(tok);
}
return _PATH_CONSOLE;
}
void console_init(void)
{
find_active_consoles();
ttinit();
}
@@ -163,14 +84,12 @@ ssize_t cprintf(const char *fmt, ...)
char buf[len < 256 ? 256 : len];
size_t size;
va_list ap;
int i;
va_start(ap, fmt);
size = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
for (i = 0; i < num_cons; i++)
dprint(fds[i], buf, size);
dprint(STDERR_FILENO, buf, size);
return size;
}
+2 -6
View File
@@ -68,11 +68,8 @@ char *strip_line (char *line);
void enable_progress (int onoff);
void show_progress (pstyle_t style);
int getty (char *tty, speed_t speed, char *term, char *user);
int sh (char *tty);
void stty (int fd, speed_t speed);
speed_t stty_parse_speed(char *baud);
void stty (int fd, speed_t speed);
void print_banner (const char *heading);
void printv (const char *fmt, va_list ap);
@@ -95,8 +92,7 @@ int complete (char *cmd, int pid);
int run (char *cmd);
int run_interactive (char *cmd, char *fmt, ...);
int exec_runtask (char *cmd, char *args[]);
pid_t run_getty (char *tty, char *baud, char *term, int noclear, int nowait, struct rlimit rlimit[]);
pid_t run_getty2 (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]);
pid_t run_getty (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]);
pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]);
int run_parts (char *dir, char *cmd);
+1
View File
@@ -41,6 +41,7 @@
#include "service.h"
#include "cgutil.h"
#include "util.h"
#include "utmp-api.h"
struct cmd {
char *cmd;
+6 -5
View File
@@ -23,6 +23,7 @@
#include <errno.h>
#include <dirent.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -30,7 +31,6 @@
#include <syslog.h>
#include <unistd.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -80,7 +80,7 @@ static void sys_cond(char *cond, int set)
}
}
static int fgetln(char *path, char *buf, size_t len)
static int fgetline(char *path, char *buf, size_t len)
{
FILE *fp;
@@ -155,11 +155,11 @@ static void init(void)
char buf[10];
snprintf(path, sizeof(path), "%s/%s/type", _PATH_SYSFS_PWR, nm);
if (!fgetln(path, buf, sizeof(buf)) && is_ac(buf)) {
if (!fgetline(path, buf, sizeof(buf)) && is_ac(buf)) {
num_ac++;
snprintf(path, sizeof(path), "%s/%s/online", _PATH_SYSFS_PWR, nm);
if (!fgetln(path, buf, sizeof(buf))) {
if (!fgetline(path, buf, sizeof(buf))) {
if (check_online(buf))
num_ac_online++;
}
@@ -227,9 +227,10 @@ int main(int argc, char *argv[])
continue;
default:
panic("unhandled");
break;
continue;
}
}
buf[len] = 0;
/* skip libusb events, focus on kernel events/changes */
if (strncmp(buf, "change@", 7))
+1 -1
View File
@@ -104,7 +104,7 @@ void logit(int prio, const char *fmt, ...)
goto done;
}
if (prio > loglevel)
if (LOG_PRI(prio) > loglevel)
goto done;
fp = fopen("/dev/kmsg", "w");
+14 -5
View File
@@ -98,29 +98,38 @@ static int logit(int level, char *buf, size_t len)
static int parse_prio(char *arg, int *f, int *l)
{
char *ptr;
char *duparg = strdup(arg);
char *ptr, *prio;
ptr = strchr(arg, '.');
if (!duparg)
prio = arg;
else
prio = duparg;
ptr = strchr(prio, '.');
if (ptr) {
*ptr++ = 0;
for (int i = 0; facilitynames[i].c_name; i++) {
if (!strcmp(facilitynames[i].c_name, arg)) {
if (!strcmp(facilitynames[i].c_name, prio)) {
*f = facilitynames[i].c_val;
break;
}
}
arg = ptr;
prio = ptr;
}
for (int i = 0; prioritynames[i].c_name; i++) {
if (!strcmp(prioritynames[i].c_name, arg)) {
if (!strcmp(prioritynames[i].c_name, prio)) {
*l = prioritynames[i].c_val;
break;
}
}
if (duparg != arg)
free(duparg);
return 0;
}
+33 -15
View File
@@ -138,7 +138,7 @@ static int fredirect(const char *file)
{
int fd;
fd = open(file, O_WRONLY | O_APPEND);
fd = open(file, O_WRONLY | O_APPEND | O_NOCTTY);
if (-1 != fd) {
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
@@ -564,10 +564,6 @@ static int service_start(svc_t *svc)
}
args[i] = NULL;
if (!svc_is_tty(svc))
redirect(svc);
sig_unblock();
/*
* The setsid() call takes care to detach the process
* from its controlling terminal, preventing daemons
@@ -579,7 +575,13 @@ static int service_start(svc_t *svc)
* to the console at boot, for debugging or similar,
* have a look at redirect() and log.console instead.
*/
setsid();
pid = setsid();
if (pid < 1)
logit(LOG_ERR, "failed setsid(), pid %d: %s", pid, strerror(errno));
if (!svc_is_tty(svc))
redirect(svc);
sig_unblock();
if (svc_is_runtask(svc))
status = exec_runtask(args[0], &args[1]);
@@ -700,6 +702,7 @@ static void service_cleanup(svc_t *svc)
*/
static int service_stop(svc_t *svc)
{
int do_progress = 1;
int rc = 0;
if (!svc)
@@ -724,7 +727,10 @@ static int service_stop(svc_t *svc)
svc_set_state(svc, SVC_STOPPING_STATE);
if (runlevel != 1)
if (!svc->desc[0])
do_progress = 0;
if (runlevel != 1 && do_progress)
print_desc("Stopping ", svc->desc);
if (!svc_is_sysv(svc)) {
@@ -744,6 +750,7 @@ static int service_stop(svc_t *svc)
pid = fork();
switch (pid) {
case 0:
setsid();
redirect(svc);
exec_runtask(svc->cmd, args);
_exit(0);
@@ -1120,6 +1127,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *pre_script = NULL, *post_script = NULL;
struct tty tty = { 0 };
char *dev = NULL;
int respawn = 0;
int levels = 0;
int manual = 0;
char *line;
@@ -1179,6 +1187,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
name = cmd;
else if (!strncasecmp(cmd, "manual:yes", 10))
manual = 1;
else if (!strncasecmp(cmd, "respawn", 7))
respawn = 1;
else if (!strncasecmp(cmd, "halt:", 5))
halt = &cmd[5];
else if (!strncasecmp(cmd, "kill:", 5))
@@ -1221,7 +1231,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
len += strlen(tty.cmd);
else
len += 3;
len += tty.num + 1;
for (i = 0; i < tty.num; i++)
len += strlen(tty.args[i]) + 1;
@@ -1230,7 +1239,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
if (!line)
return errno;
snprintf(line, len, "%s", tty.cmd ?: "tty");
snprintf(line, len, "%s", tty.cmd ? tty.cmd : "tty");
for (i = 0; i < tty.num; i++) {
strlcat(line, " ", len);
strlcat(line, tty.args[i], len);
@@ -1244,6 +1253,9 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
dev = tty_atcon();
else
dev = tty.dev;
/* tty's always respawn, never incr. restart_cnt */
respawn = 1;
next:
svc = svc_find_by_tty(dev);
} else
@@ -1311,12 +1323,12 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
/* Create name:id tuple for identiy, e.g., tty:S0 */
ptr = strrchr(svc->dev, '/');
if (ptr) {
if (ptr)
ptr++;
if (!strncmp(ptr, "tty", 3))
ptr += 3;
} else
else
ptr = svc->dev;
if (!strncmp(ptr, "tty", 3))
ptr += 3;
if (!id || id[0] == 0)
id = ptr;
strlcpy(svc->name, "tty", sizeof(svc->name));
@@ -1350,6 +1362,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
parse_env(svc, env);
if (file)
strlcpy(svc->file, file, sizeof(svc->file));
if (respawn)
svc->respawn = 1;
/* Set configured limits */
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
@@ -1570,11 +1584,15 @@ static void service_retry(svc_t *svc)
char *restart_cnt = (char *)&svc->restart_cnt;
service_timeout_cancel(svc);
if (svc->respawn) {
_d("%s crashed, respawning ...", svc->cmd);
svc_unblock(svc);
service_step(svc);
return;
}
if (svc->state != SVC_HALTED_STATE ||
svc->block != SVC_BLOCK_RESTARTING) {
if (!svc_is_tty(svc))
_d("%s not crashing anymore", svc->cmd);
*restart_cnt = 0;
return;
}
+24 -6
View File
@@ -55,7 +55,7 @@
* SIGINT
* Sent from kernel when the CTRL-ALT-DEL key combo is pressed.
* SysV init and systemd default to reboot with `shutdown -r`.
* Finit currently forwards this to SIGTERM.
* Finit defaults to nothing but sets sys/key/ctrlaltdel condition.
*
* SIGWINCH
* Sent from kernel when the KeyboardSignal key is pressed. Some
@@ -66,7 +66,7 @@
* Sent from a power daemon, like powstatd(8), on changes to the
* UPS status. Traditionally SysV init read /etc/powerstatus and
* acted on "OK", "FAIL", or "LOW" and then removed the file.
* Finit currently forwards this to SIGUSR2.
* Finit defaults to nothing but sets sys/pwr/fail condition.
*/
#include <dirent.h>
@@ -76,6 +76,7 @@
#include <lite/lite.h>
#include "finit.h"
#include "cond.h"
#include "conf.h"
#include "config.h"
#include "helpers.h"
@@ -311,7 +312,9 @@ static void sighup_cb(uev_t *w, void *arg, int events)
}
/*
* SIGINT: Should generate <sys/key/ctrlaltdel> condition, for now reboot
* SIGINT: generates <sys/key/ctrlaltdel> condition, which the sys.so
* plugin picks up and tells Finit to start any service(s) or
* task(s) associated with the condition.
*/
static void sigint_cb(uev_t *w, void *arg, int events)
{
@@ -321,8 +324,23 @@ static void sigint_cb(uev_t *w, void *arg, int events)
return;
}
halt = SHUT_REBOOT;
service_runlevel(6);
cond_set_oneshot_noupdate("sys/key/ctrlaltdel");
}
/*
* SIGPWR: generates <sys/pwr/fail> condition, which the sys.so plugin
* picks up and tells Finit to start any service(s) or task(s)
* associated with the condition.
*/
static void sigpwr_cb(uev_t *w, void *arg, int events)
{
_d("...");
if (UEV_ERROR == events) {
_e("Unrecoverable error in signal watcher");
return;
}
cond_set_oneshot_noupdate("sys/pwr/fail");
}
/*
@@ -531,7 +549,7 @@ void sig_setup(uev_ctx_t *ctx)
/* BusyBox/SysV init style signals for halt, power-off and reboot. */
uev_signal_init(ctx, &sigusr1_watcher, sigusr1_cb, NULL, SIGUSR1);
uev_signal_init(ctx, &sigusr2_watcher, sigusr2_cb, NULL, SIGUSR2);
uev_signal_init(ctx, &sigpwr_watcher, sigusr2_cb, NULL, SIGPWR);
uev_signal_init(ctx, &sigpwr_watcher, sigpwr_cb, NULL, SIGPWR);
uev_signal_init(ctx, &sigterm_watcher, sigterm_cb, NULL, SIGTERM);
/* Some C APIs may need SIGALRM for implementing timers. */
+7 -5
View File
@@ -27,7 +27,8 @@
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
#include <termios.h>
#include <helpers.h>
#include "helpers.h"
#include "sig.h"
/* B0 means; keep kernel default */
speed_t stty_parse_speed(char *baud)
@@ -90,6 +91,10 @@ speed_t stty_parse_speed(char *baud)
void stty(int fd, speed_t speed)
{
struct termios term;
struct sigaction sa;
/* Ignore SIGINT during login phase, /bin/login resets */
IGNSIG(sa, SIGINT, SA_RESTART);
tcdrain(fd);
if (tcgetattr(fd, &term))
@@ -98,22 +103,19 @@ void stty(int fd, speed_t speed)
if (speed != B0) {
cfsetispeed(&term, speed);
cfsetospeed(&term, speed);
tcsetattr(fd, TCSAFLUSH, &term);
}
/* Modem specific control flags */
term.c_cflag &= ~(PARENB|PARODD|CSTOPB|CRTSCTS);
term.c_cflag |= CS8|HUPCL|CREAD|CLOCAL;
term.c_line = 0;
tcsetattr(fd, TCSAFLUSH, &term);
/* Timeouts, minimum chars and default flags */
term.c_cc[VTIME] = 0;
term.c_cc[VMIN] = 1;
term.c_iflag = ICRNL|IXON|IXOFF;
term.c_iflag = ICRNL|IXON|IXOFF|IUTF8;
term.c_oflag = OPOST|ONLCR;
term.c_lflag |= ICANON|ISIG|ECHO|ECHOE|ECHOK|ECHOKE;
tcsetattr(fd, TCSAFLUSH, &term);
/* Reset special characters to defaults */
term.c_cc[VINTR] = CINTR;
+1
View File
@@ -127,6 +127,7 @@ typedef struct svc {
/* Counters */
char once; /* run/task, (at least) once per runlevel */
char respawn; /* ttys, or services with `respawn`, never increment restart_cnt */
const char restart_cnt; /* Incremented for each restart by service monitor. */
union {
+8 -7
View File
@@ -161,7 +161,7 @@ int tty_parse_args(char *cmd, struct tty *tty)
tty->notty = 1; /* for board bringup */
else if (!strcmp(cmd, "rescue"))
tty->rescue = 1; /* for rescue shells */
else if (!access(cmd, X_OK))
else if (whichp(cmd)) /* in $PATH? */
tty->cmd = cmd;
else
tty->args[tty->num++] = cmd;
@@ -221,6 +221,10 @@ int tty_parse_args(char *cmd, struct tty *tty)
_d("Registering %s getty on TTY %s at %s baud with term %s", tty->cmd ? "external" : "built-in",
tty->dev, tty->baud ?: "0", tty->term ?: "N/A");
/* Built-in getty now comes as standalone program */
if (!tty->cmd)
tty->cmd = _PATH_GETTY;
return 0;
}
@@ -229,7 +233,7 @@ int tty_exists(char *dev)
struct termios c;
int fd, rc;
fd = open(dev, O_RDWR);
fd = open(dev, O_RDWR | O_NOCTTY);
if (-1 == fd)
return 0;
@@ -285,10 +289,7 @@ int tty_exec(svc_t *svc)
return run_sh(dev, svc->noclear, svc->nowait, svc->rlimit);
}
_d("%s: Starting %sgetty ...", dev, !svc->cmd ? "built-in " : "");
if (!strcmp(svc->cmd, "tty"))
return run_getty(dev, svc->baud, svc->term, svc->noclear, svc->nowait, svc->rlimit);
_d("%s: Starting %s ...", dev, svc->cmd);
for (i = 1, j = 0; i < MAX_NUM_SVC_ARGS; i++) {
if (!svc->args[i][0])
break;
@@ -297,7 +298,7 @@ int tty_exec(svc_t *svc)
}
args[j++] = NULL;
return run_getty2(dev, svc->cmd, args, svc->noclear, svc->nowait, svc->rlimit);
return run_getty(dev, svc->cmd, args, svc->noclear, svc->nowait, svc->rlimit);
}
/**
-10
View File
@@ -229,16 +229,6 @@ int fngetint(char *path, int *val)
return 0;
}
/*
* musl libc default to /dev/null/utmp and /dev/null/wtmp, respectively.
* See https://www.openwall.com/lists/musl/2012/03/04/4 for reasoning.
* Also, there's no __MUSL__, so we cannot make a libc-specific #ifdef
*/
int has_utmp(void)
{
return strncmp(_PATH_UTMP, "/dev/null", 9);
}
int strtobytes(char *arg)
{
int mod = 0, bytes;
-1
View File
@@ -54,7 +54,6 @@ int fnread (char *buf, size_t len, char *fmt, ...);
int fnwrite (char *value, char *fmt, ...);
int fngetint (char *path, int *val);
int has_utmp (void);
int strtobytes (char *arg);
char *sig2str (int sig);
char *code2str (int code);
+10
View File
@@ -42,6 +42,16 @@ int utmp_show (char *file);
void runlevel_set (int pre, int now);
/*
* musl libc default to /dev/null/utmp and /dev/null/wtmp, respectively.
* See https://www.openwall.com/lists/musl/2012/03/04/4 for reasoning.
* Also, there's no __MUSL__, so we cannot make a libc-specific #ifdef
*/
static inline int has_utmp(void)
{
return strncmp(_PATH_UTMP, "/dev/null", 9);
}
#endif /* FINIT_UTMP_API_H_ */
/**