Compare commits

...

147 Commits

Author SHA1 Message Date
db5559bb50 cgroups: add configurable cgroups_name 2024-04-30 19:20:30 +02:00
John Einar Reitan
3d30b6fdda Add xterm-kitty to color capable term list 2024-04-05 00:02:33 -05:00
William Hubbs
4574b5d8e4 clarify news update about split-usr option 2024-04-01 14:22:37 -05:00
William Hubbs
6b42019697 version 0.54 2024-04-01 12:06:53 -05:00
William Hubbs
42408e7488 update news 2024-04-01 12:05:18 -05:00
Oskari Pirhonen
957140cb78 Touch up docs/comments
Remove the mention of linking with libtermcap from einfo(3), and fix
some comments in libeinfo.c to more accurately reflect the new
situation.
2024-03-31 23:13:02 -05:00
Oskari Pirhonen
536794dfad Trivial curses/termcap removal
Remove the curses code and make the HAVE_TERMCAP-gated "fallbacks"
always present. This makes an ANSI terminal required for colors.

X-Gentoo-Bug: https://bugs.gentoo.org/904277
Closes: https://github.com/OpenRC/openrc/issues/619
2024-03-31 23:13:02 -05:00
William Hubbs
7ac2080e31 ci: update FreeBSD releases we test against 2024-03-31 18:31:19 -05:00
Sam James
12e1e88475 meson: drop broken split-usr handling
Two issues here:

* The 'split-usr' meson option wasn't doing anything, it tried to check
  if /bin was a symlink, but nothing acted on this information.

* The actual rootprefix default was decided based on whether /bin was a symlink
  which is flaky if e.g. building on a merged-usr system for use on a non-merged-usr
  system.

People can set -Drootprefix=/usr if they wish.

There's no real advantage to installing to /usr over / as the compat. symlinks
are really here to stay. If someone really does care about this, they can bring
it back and do it properly, but it doesn't seem worth it to me at all.

Bug: https://bugs.gentoo.org/927776
Fixes: cc0037e9ca
Fixes: f2362cc277
Fixes: #696
2024-03-25 14:10:13 -05:00
William Hubbs
c45fe9fba5 version 0.53 2024-01-12 11:29:03 -06:00
William Hubbs
961c479e1d update news 2024-01-12 11:24:48 -06:00
Forza-tng
f9c92d7822 enable confd cgroups mount options
This fixes #684.
2024-01-12 11:17:14 -06:00
Natanael Copa
97689d6c44 sh/rc-cgroup.sh: add openrc. prefix the cgroupv2 path
Some services, like docker, creates and manages /sys/fs/cgroup/<service>
themselves. Avoid conflict with the openrc created cgroup path by adding
a `openrc.` prefix.

Fixes: https://github.com/OpenRC/openrc/issues/680
2024-01-09 10:09:59 -06:00
Alexey Vazhnov
439cce426d supervise-daemon-guide.md: adjust markdown formatting. No logic/text changes were made. 2023-12-16 09:10:18 -05:00
Zhao Yongming
bfdafe4463 change info words "remove" to "delete" in delete sub-command
This close #664
2023-12-04 10:53:23 -05:00
Zhao Yongming
179ff285ca update start-stop-daemon manual to include --quiet 2023-12-04 10:52:07 -05:00
William Hubbs
f9bbbfbf4b update news 2023-11-16 23:29:09 -06:00
William Hubbs
59a175541d remove warning for runscript deprecation 2023-11-15 10:04:46 -06:00
William Hubbs
65b13eb86f drop the deprecated "rc" binary
This binary is a copy of the openrc binary. Referring to it as rc was
deprecated in 2016, so we should be able to drop it at this point.
2023-11-15 10:01:45 -06:00
Alexander Maltsev
fda9dcd1f2 Skip already processed files in rc_service_daemon_set
Fixes the problem described in https://bugs.gentoo.org/916947 -
start-stop-daemon hangs in infinite loop when stopping some daemons on
linux 6.6+

It appears linux 6.6 reworked tmpfs, and since then it triggers this
problem in openrc: when iterating over files via readdir, running rename
on a file could result in reading the same file again with next readdir
call.

The Open Group manual for readdir explicitly states "If a file is
removed from or added to the directory after the most recent call to
opendir() or rewinddir(), whether a subsequent call to readdir() returns
an entry for that file is unspecified.". Linux man page don't seem to
mention that, but don't seem to say anything to contradict that either.
So I presume we can't rely on some specific behaviour here.

Bug: https://bugs.gentoo.org/916947
2023-11-14 14:35:23 -06:00
Sam James
6f180e9424 init.d/cgroups.in: fix inconsistency between mount_cgroups and mount_cgroups
965de92b37 changed the default cgroup mode which
exposes an issue in init.d/cgroups.in.

While mount_cgroups defaults to 'unified' if rc_cgroup_mode is unset, cgroup2_controllers
has no default and therefore has a mismatch with the logic in mount_cgroups. The
two should be consistent so the flow makes sense, as mount_cgroups expects a certain
path to be taken in cgroup2_controllers.

Make cgroup2_controllers default to 'unified' if rc_cgroup_mode is unset, just
like mount_cgroups.

Bug: https://bugs.gentoo.org/916964
Thanks-to: acab@digitalfuture.it
2023-11-14 14:31:22 -06:00
William Hubbs
88e5d98d05 drop the deprecated runscript binary 2023-11-14 14:19:35 -06:00
Haelwenn (lanodan) Monnier
1433552435 sh/supervise-daemon.sh: Proper casing for --no-new-privs 2023-11-02 13:35:37 -04:00
William Hubbs
554ccab718 version 0.51 2023-10-10 14:16:44 -05:00
William Hubbs
228b3c6c99 update news 2023-10-10 14:15:15 -05:00
William Hubbs
965de92b37 change default RC_CGROUP_MODE to unified
This improves resource management by assigning services to individual
cgroups.

X-Gentoo-Bug: https://bugs.gentoo.org/914972
2023-10-10 12:50:09 -05:00
Adam Duskett
b85d771e1f Force symlinking of openrc-init to init
When building on embedded SDKs such as Buildroot or Yocto, if OpenRC has a
previous installation, the package will fail the installation step as the
openrc-init is already a symlink to "${DESTDIR}/${sbindir}"/init. Force
symlinking to prevent errors when reinstalling the package.
2023-10-10 08:55:33 -04:00
Lexxy Fox
cf9286d2d8 Relocate pipes.c and pipes.h file to shared directory.
With the addition of logger process redirect in supervise-daemon,
pipes.c and pipes.h are now included in both s-s-d and supervise-daemon.
Thus it makes sense to move the source files to the src/shared dir.
2023-10-03 16:43:39 -05:00
Lexxy Fox
9934e9f96e supervise-daemon: implement output_logger and error_logger.
Allows redirecting process stdin and stdout to another process,
just like is already possible with start-stop-daemon.

Also added --stdout-logger and --stderr-logger to the man page.
2023-10-03 16:43:39 -05:00
William Hubbs
f1e5510ccf version 0.50 2023-09-19 16:02:03 -05:00
William Hubbs
1b72c3a7ab update news 2023-09-19 15:59:31 -05:00
Natanael Copa
c4785f1b99 misc: add syscall fallback for close_range for musl libc
Add fallback for the close_range syscall wrapper. This is needed for
musl libc, which currently does not have a close_range wrapper.

Also set errno on errors.
2023-09-12 22:53:12 -05:00
Natanael Copa
e447562aaa start-stop-daemon: set fds to CLOEXEC instead of closing
Set file descriptors to CLOEXEC instead of closing them before exec,
similar to what we do in supervise-daemon.

Use the share cloexec_fds_from() helper for this.

closefrom() is no longer used so remove the test.
2023-09-12 22:53:12 -05:00
Natanael Copa
c199c5cf6e misc: add cloexec_fds_from() helper function
Move logic to set file descriptors to a cloexec_fds_from() function in
misc.c so it can be shared by both supervisor-daemon and
start-stop-daemon, and hide the details behind.
2023-09-12 22:53:12 -05:00
Natanael Copa
5bfb592d75 supervise-daemon: rename HAVE_CLOSE_RANGE_EXEC to HAVE_CLOSE_RANGE
Use HAVE_CLOSE_RANGE to tell if system provides a close_range(2)
wrapper, which better explains the purpose.

Add a compat inline which returns -1 if close_range is unavailable.
2023-09-12 22:53:12 -05:00
Timothy Kenno Handojo
b2c4eb97b5 remove /lib/rc/tmp creation from meson script
It is apparently for a piece of code that no longer exist.
There don't seem to be any part of the code referring to this directory (anymore, if there was).
2023-09-01 11:54:30 -05:00
William Hubbs
e740913fcb version 0.49 2023-08-31 14:13:19 -05:00
William Hubbs
1bc34a39cd update news 2023-08-31 14:12:26 -05:00
Sam James
c1cd3c9830 Don't re-define strlcpy/strlcat with >=glibc-2.38
`>=glibc-2.38` implements strlcpy, strlcat, etc so check for those functions
with Meson and don't provide conflicting prototypes.

Technically, it doesn't need _GNU_SOURCE, but it's easier because it's not
clear right now what glibc wants to guard it with. Note that these are in
POSIX next anyway.

Fixes: https://github.com/OpenRC/openrc/issues/643
Signed-off-by: Sam James <sam@gentoo.org>
2023-08-29 23:31:18 -04:00
Sven Wegener
86efc43d0e rc: fix automatic restart with runlevel-specific conf.d files
Commit fc4f15d6cd broke the automatic restart of
services having runlevel-specific conf.d files.

The double dirname() was not a mistake, but the way of getting from the
service script in init.d to the upper directory containing the conf.d
directory. dirname() modifies the argument in-place, so the second call
operated on a modified value. To make it more obvious what is going on,
have the second call operate on the returned value from the first call.

Fixes: fc4f15d ("openrc: fix double-assignment to dir")
Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
2023-07-26 22:41:42 -05:00
Jernej Jakob
cd53239701 bash-completion/rc-service: don't set or unset extglob
It breaks bash-completion.
It's not necessary to set extglob as patterns in '[[' after '=='
are always matched as if extglob were set.

Closes: #636
Signed-off-by: Jernej Jakob <jernej.jakob@gmail.com>
2023-07-26 22:41:19 -05:00
William Hubbs
92662ddc44 version 0.48 2023-07-05 16:28:44 -05:00
William Hubbs
1b6a35488d update news for 0.48 release 2023-07-05 16:25:28 -05:00
Petr Vaněk
1eccb7f5e6 man: Remove Duplicate Description of -2/--stderr Flag
This commit removes the secondary mention of the -2/--stderr flag in the
start-stop-daemon man page. The flag's functionality was already
sufficiently described in an earlier section of the text.

Signed-off-by: Petr Vaněk <arkamar@atlas.cz>
2023-05-21 10:57:53 -04:00
Oskari Pirhonen
fe37fc9322 einfo: fix vewend applet args
Fix typo preventing the args for the vewend applet from being handled.
2023-05-14 00:50:03 -04:00
Sam James
edf5f830e3 librc: allow overriding rc_interactive on kernel command line
This was originally introduced in 14625346c0 with
an example list (just one for rc_parallel) of options. Let's add in rc_interactive
as it's a pretty obvious thing one might want to override.

See https://forums.gentoo.org/viewtopic-p-8694588.html.
2023-05-10 21:39:25 -04:00
Dominique Martinet
863e1a5c87 openrc-run: fix rc_parallel race in svc_exec
svc_exec waits until SIGCHLD comes in to close its input, but in
rc_parallel case the SIGCHLD might be unrelated.

Checking the proper pid is found in signal handler and only signaling
signal_pipe the status code directly avoids this problem.
2023-04-24 22:06:53 -05:00
Dominique Martinet
0b9c3c0803 openrc-run: silence lock failures with --no-deps
work around scary warnings described in previous commit
2023-04-24 22:06:41 -05:00
Dominique Martinet
a3c721b682 openrc-run: remove kludge in restart --no-deps
restarting a service with --no-deps ran into a "hairy workaround", which
had a few problems discussed in [1]:
 - it ignores --dry-run, really restarting the requested service
 - if the service was stopped, the program is started but the service
status stays stopped. This makes long-lived services impossible to
(re)start again (pid already exists and running), and the service also
won't stop on shutdown.

The kludge had a long comment describing the following situation:
 - openvpn needs net and dns
 - net restarts dns
 - dns needs net

If the restart in net handled deps, openrc would deadlock waiting for
net in dns' restart, as net won't be started until that is done.

Restarting with --nodeps works around the deadlock, but can display
errors without the kludge (note that the services did start properly
anyway, the problem is that the default service path tries to lock dns
twice from openvn's dep's start and net's start's restart):
---
alpine:~# rc-service openvn start
openvn                   | * Caching service dependencies ...                                                                                                      [ ok ]
net                      |net starting
net                      |dns                       | * Call to flock failed: Resource temporarily unavailable
net                      |dns                       | * ERROR: dns stopped by something else
net                      |net started
dns                      |dns started
openvn                   |openvn started
alpine:~# rc-status | grep s[1-3]
 net                                                               [  started  ]
 dns                                                               [  started  ]
 openvn                                                            [  started  ]
---

Locking again in restart --nodep can fail in two patterns:
 - openvpn's need dependency start was first, and the restart in net
failed (case above): we can just silence locking failures and exit quietly
with restart --no-deps, which is not worse than trying to restart while
another process hold the lock.
 - the restart in net's start was first, and openvpn's need dependency
start failed: not much can be done here short of adding a new status
that a no-deps restart is in progress as in the comment, but this case
can actually just be solved by adjusting dependencies -- and it actually
has already been fixed: the current openvpn init script in alpine only
'use dns', so it will not try to start it, and that will start just
fine with openvpn -> net -> dns only each starting each other once
sequentially.

Another failure pattern is just starting dns directly: that will start
net, which will try to restart dns while we are starting it.
Silencing messages on restart also solves this.

Link: https://github.com/OpenRC/openrc/issues/224 [1]
2023-04-24 22:06:41 -05:00
NRK
3f82d5b1a3 rc: use LIST_FOREACH_SAFE in cleanup()
according to the linux manpage, the "safe" variant may not be available
on all platform. however we bundle our own `queue.h` so this should not
be an issue.
2023-04-24 19:20:19 -05:00
NRK
0b4732520f rc: block SIGCHLD during pid list operations
the pid list will be accessed inside the SIGCHLD signal handler. so we
must ensure SIGCHLD handler doesn't get invoked while the list is at an
inconsistent state making it unsafe to interact with.

Co-authored-by: Dominique MARTINET <dominique.martinet@atmark-techno.com>
Bug: https://github.com/OpenRC/openrc/issues/589#issuecomment-1406588576
2023-04-24 19:20:19 -05:00
NRK
bbd3acfc67 rc: avoid calling free inside SIGCHLD handler
`free` is not async-signal-safe and calling it inside a signal handler
can have bad effects, as reported in the musl ML:
https://www.openwall.com/lists/musl/2023/01/23/1

the solution:

- keep track of weather remove_pid() is being called from inside a
  signal handler or not.
- if it's inside a signal handler then DO NOT call free - instead put
  that pointer into a "to be freed later" list.
- if it's not inside a signal handler then take the "to be freed later"
  list and free anything in it.

Bug: https://github.com/OpenRC/openrc/issues/589
Reported-by: Dominique MARTINET <dominique.martinet@atmark-techno.com>
2023-04-24 19:20:19 -05:00
NRK
910e3e2a0e fstabinfo: deal with EINTR in waitpid call 2023-04-24 19:18:18 -05:00
NRK
5f04dcc951 fstabinfo: replace vfork with posix_spawnp
problem:
* vfork has been removed from POSIX [0].
* clang-tidy flags the `strerror` and `eerror` call inside the vfork-ed
  child as undefined behavior.

solution: use posix_spawnp, which is serves similar purpose and is
specified in posix. and as an added bonus, it's also easier to use and
less lines of code.

[0]: https://www.man7.org/linux/man-pages/man2/vfork.2.html#CONFORMING_TO
2023-04-24 19:18:18 -05:00
Oskari Pirhonen
8f52c64c37 einfo.h: fix EINFO_RESTRICT macro usage
Make function declarations use the EINFO_RESTRICT macro instead of
__EINFO_RESTRICT which gets treated as the name of the argument.
2023-04-23 16:11:15 -04:00
Sam James
09d405fb3e shared: fix pointer type in UNCONST
Thanks to vapier for noticing.
2023-04-20 07:50:49 -04:00
Sam James
36e4e04ba9 meson.build: add -Werror=... for modern C issues
Clang 16 makes these warnings fatal and GCC 14 is likely to as well.
2023-04-19 16:44:51 -04:00
Sam James
eb8831a141 Rename attribute macros to namespaced RC_*
This conflicts with linux-headers which uses __unused for some padding members
on ppc64le at least.

Closes: https://github.com/OpenRC/openrc/issues/622
2023-04-19 16:44:51 -04:00
William Hubbs
0b5cb3abcb version 0.47 2023-04-18 00:14:28 -05:00
William Hubbs
f6ed2c660c update news 2023-04-18 00:13:16 -05:00
Doug Freed
002bcf0b67 rc.conf: note SSD_* vars need exporting 2023-04-17 23:53:18 -05:00
William Hubbs
b9241988a7 init.d/rc.conf: make unicode default to yes 2023-03-07 00:48:43 -06:00
psykose
5ae4d4edb5 rc.conf: default to unicode console
it's the high year of 2023, after all.

closes #607
2023-03-06 22:41:36 -05:00
NRK
95b2948e6e seedrng: fix copyright year
this was mistakenly changed to 2023 instead of 2022-2023 in 63a5ee3d
2023-02-16 07:54:17 -05:00
anon
b73d326387 rc-status: comment consistecy 2023-02-15 22:51:40 -05:00
anon
476272be0c rc-status: all flags respect '-f' 2023-02-15 22:51:40 -05:00
NRK
63a5ee3d8c seedrng: fix memory leak reported by clang-tidy
`seed_dir` gets allocated via xstrdup but never gets freed - which
clang-tidy flags as a memory leak.

instead of free-ing the allocation, just don't allocate to begin with
since there's no need for it.

also bump the copyright year.
2023-02-05 00:38:20 -05:00
NRK
36cc40a9d6 bash-completions/rc-service: don't use grep
Co-authored-by: Mike Frysinger <vapier@gentoo.org>
Closes: https://github.com/OpenRC/openrc/issues/344
2023-02-02 19:37:09 -05:00
NRK
ae5e38dce5 start-stop-daemon: avoid malloc inside sig-handler
same rational as 459783bb

Bug: https://github.com/OpenRC/openrc/issues/589
2023-01-30 22:54:20 -05:00
NRK
5858f980c8 openrc-run: avoid malloc inside sig-handler
same rational as 459783bb

Bug: https://github.com/OpenRC/openrc/issues/589
2023-01-30 22:54:20 -05:00
Sam James
db96295e00 value: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
f5ed484920 swclock: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
00f90f2b0e supervise-daemon: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
b405681926 start-stop-daemon: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
d5700d036a shell_var: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
616f756ca8 shared: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
17cfb41d81 service: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
1bc87b7a7c seedrng: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
f3be11a00d rc-update: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
406ab2a4ca rc-status: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
7878a53542 rc-service: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
084e6b5e20 rc-depend: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
a7bd13145b rc-abort: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
28ecb38515 openrc-shutdown: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
91737be1ab openrc-run: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
fb6ffc5713 openrc: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
01acbe3c27 openrc-init: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
aa5c3ccd0b mountinfo: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
d795ea183f mark_service: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
5af3944440 librc: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
01bcdb43b6 libeinfo: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
bcd1975fe7 kill_all: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
57e194df4f is_older_than: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
dacd0ab189 is_newer_than: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
7cfe93d032 fstabinfo: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
893df75e30 einfo: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
c80d6bb2ed checkpath: missing includes from IWYU 2023-01-29 11:32:22 -06:00
Sam James
bfe38c98a8 src: shared: schedules: add missing includes to header
Needed for clang-tidy prep work, as it requires headers to work standalone
(which is useful anyway).
2023-01-28 22:14:30 -06:00
Sam James
e8a76ad6e6 src: shared: plugin: add missing includes to header
Needed for clang-tidy prep work, as it requires headers to work standalone
(which is useful anyway).
2023-01-28 22:14:30 -06:00
Sam James
7d63049adb src: shared: misc: add missing includes to header
Needed for clang-tidy prep work, as it requires headers to work standalone
(which is useful anyway).
2023-01-28 22:14:30 -06:00
Sam James
dc0b3157a9 src: shared: helpers: add missing includes to header
Needed for clang-tidy prep work, as it requires headers to work standalone
(which is useful anyway).
2023-01-28 22:14:30 -06:00
Sam James
2f6b5b7ef4 openrc: rc-logger: add missing includes to header
Needed for clang-tidy prep work, as it requires headers to work standalone
(which is useful anyway).
2023-01-28 22:14:30 -06:00
NRK
eb3635dd1f swclock: fix codeql warning and upgrade to futimens
this was reported by codeql's scan as a TOCTOU bug. while that's true in
theory, i don't believe it would've had any practical effect.

a better justification for this change might be the fact that it
upgrades from `utime` (which is depreciated by POSIX [0]) to `futimens`.

[0]: https://www.man7.org/linux/man-pages/man3/utime.3p.html#FUTURE_DIRECTIONS
2023-01-28 16:19:33 -05:00
NRK
459783bbad openrc: avoid unnecessary malloc inside sig-handler
malloc (called by xasprintf) is not async-signal-safe. beside, the
string here is constant, so there's no need to malloc it all.

eerrorx isn't async-signal-safe either (due to calling fprintf and exit)
but consequence of them are _typically_ not as grave as calling malloc
while it's internal state is inconsistent.

Bug: https://github.com/OpenRC/openrc/issues/589
2023-01-28 13:08:00 -05:00
Sam James
a28bdc7e5c openrc-shutdown: mark handler as noreturn, use _unused macro 2023-01-25 01:11:25 -05:00
Sam James
bcae7d03b4 openrc: mark handle_bad_signal as noreturn
For -Wmissing-noreturn.
2023-01-25 00:51:13 -05:00
Sam James
ccc2b71145 supervise-daemon: mark various functions as noreturn
For -Wmissing-noreturn.
2023-01-25 00:50:43 -05:00
Sam James
78c0693c50 openrc-shutdown: mark stop_shutdown as noreturn, fix typo/indentation
For -Wmissing-noreturn.
2023-01-25 00:50:15 -05:00
Sam James
ddf4a3a7a0 shared: move _noreturn definition into helpers.h 2023-01-25 00:49:47 -05:00
Sam James
a6568c304f libeinfo: fix -Wunused-but-set-variable 2023-01-25 00:49:22 -05:00
Sam James
d6a5264a9d librc: fix 'init' memory leak
From scan-build w/ clang-16.0.0_pre20230107:
```
../src/librc/librc.c:759:14: warning: Potential leak of memory pointed to by 'init' [unix.Malloc]
                                                return false;
                                                       ^~~~~
```
2023-01-25 00:48:26 -05:00
Sam James
9f227e8b49 openrc-run: drop strlen dead store 2023-01-25 00:08:30 -05:00
Sam James
3bb5450320 openrc-shutdown: fix need_warning dead store
It's already initialised to false at the start and it's clear when reading
what the flow is.

While at it, fix some indentation and adjust whitespace to make more readable.
2023-01-25 00:07:03 -05:00
Sam James
a689fdb7be openrc-run: fix -Wunused-but-set-variable 2023-01-25 00:06:27 -05:00
Sam James
fc4f15d6cd openrc: fix double-assignment to dir
This one is a bit odd, it didn't get fixed in e273b4e08e,
and goes all the way back to cb9da6a262.
2023-01-25 00:05:32 -05:00
Sam James
19f329d2f4 openrc, openrc-run: Fix -Wstrict-prototypes
These become fine with C23 because () starts to mean (void) then, but for
previous language versions, it's deprecated, and it causes an annoying
warning when building with Clang by default.

Plus, GCC lacks specific flags to trigger what C23 *does* ban, so a lot
of people are going around building with -Wstrict-prototypes, so let's
just fix this to be consistent with the rest of the codebase anyway
to fend off false positive reports.
2023-01-25 00:05:05 -05:00
William Hubbs
0b86c06c3c update cirrus ci to latest FreeBSD images 2023-01-24 11:32:11 -06:00
Mike Frysinger
fea9d9a7f0 add CoC based on the Contributor Covenant project 2023-01-21 22:01:15 -06:00
Matt Whitlock
9dfd2b2737 start-stop-daemon, supervise-daemon: use closefrom()/close_range()
On systems with a very large RLIMIT_NOFILE, calling close() in a loop
from 3 to getdtablesize() effects an enormous number of system calls.
There are better alternatives. Both BSD and Linux have the closefrom()
system call that closes all file descriptors with indices not less than
a specified minimum. Have start-stop-daemon call closefrom() on systems
where it's implemented, falling back to the old loop elsewhere.

Likewise, calling fcntl(i, F_SETFD, FD_CLOEXEC) in a loop from 3 to
getdtablesize() raises a similar performance concern. Linux 5.11 and
onward has a close_range() system call with a CLOSE_RANGE_CLOEXEC flag
that sets the FD_CLOEXEC flag on all file descriptors in a specified
range. Have supervise-daemon utilize this feature on systems where it's
implemented, falling back to the old loop elsewhere.
2023-01-20 21:44:37 -06:00
Matt Whitlock
de295bd0c6 start-stop-daemon: remove unnecessary carve-out for pipe FD
1364e6631c exempted the write end of the
synchronization pipe from the close() loop in the child process, but
this is unnecessary, as the pipe is opened with O_CLOEXEC, and the child
process calls execvp() soon after the close() loop, with the intervening
code not needing the pipe. Indeed, the pipe only needs to remain open in
the child process until after the call to setsid(), which occurs well
before the close() loop. So, eliminate the needless carve-out from the
close() loop, in preparation for introducing closefrom().
2023-01-20 21:44:37 -06:00
Mike Frysinger
6f44445958 checkpath: add missing sticky/set*id mode bits to check
We incorrectly masked out the upper 3 bits when checking to see if the
permissions need updating leading us to run chmod when not needed.

Fixes #482.
2023-01-15 15:31:25 -05:00
Mike Frysinger
52dcb4aaa3 netmount: add fuse.glusterfs
Fixes #495.
2023-01-15 15:24:51 -05:00
Mike Frysinger
c6d6ed0c9c openrc-run: add status to basic usage message
Fixes #491.
2023-01-15 15:19:53 -05:00
Mike Frysinger
b778c72f81 checkpath: fix initial dirfd opening
dirfd is uninitialized at this point, and even if it were, it doesn't
make sense to use since the path is "/" -- the dirfd is ignored when
the path is absolute.  Switch to AT_FDCWD to avoid all that.
2023-01-15 15:17:18 -05:00
Mike Frysinger
32715e1144 man: update path to internal runtime state
Fixes #498.
2023-01-15 15:10:22 -05:00
Mike Frysinger
ec04e08707 init: add missing eend to /run mount #554
Fixes #554.
2023-01-15 14:58:27 -05:00
Ivan Bushchik
dd05e60ced LICENSE: Change year to 2023 (from 2015!!!) 2023-01-08 09:05:18 -05:00
William Hubbs
9ef74594df version 0.46 2023-01-05 00:31:37 -06:00
William Hubbs
59e9637647 update news 2023-01-05 00:22:41 -06:00
Nikolaos Chatzikonstantinou
35077afb68 build: fix run_command warning
The default behavior of check: false is going to change to true in the
future, see <https://github.com/mesonbuild/meson/issues/9300>.

Thus we are explicit about the desired behavior. The error in uname is
important but with test we check ourselves using returncode().

This fixes #556.
2022-12-08 11:06:09 -06:00
William Hubbs
02b064a591 src/swclock: make the reference file a required argument 2022-12-08 09:56:50 -06:00
William Hubbs
839083bb52 make the location of the swclock reference file configurable
This fixes #565.
2022-12-08 09:56:40 -06:00
Mike Gilbert
1364e6631c start-stop-daemon: use a pipe to sync parent/child processes
This fixes #557.
2022-12-07 17:12:24 -06:00
Jakub Jirutka
953172c6c6 supervise-daemon: don't overwrite empty supervise_daemon_args
If supervise_daemon_args is not set *or empty*, it defaults to
`start_stop_daemon_args`. This is bad because supervise-daemon doesn't
accept the same options as `start-stop-daemon`. So if we set e.g.
`start_stop_daemon_args="--wait 50"`, but not `supervise_daemon_args`,
and the user adds `supervisor=supervise-daemon` to the corresponding
/etc/conf.d/<service> file, the service will fail to start due to
unrecognized option "wait".

It would be best to remove this fallback, but that might break some
existing scripts that depend on it. So this commit just changes it to
use `start_stop_daemon_args` as the default for `supervise_daemon_args`
only if `supervise_daemon_args` is not set at all, but not if it's
empty.

This at least simplifies workarounds; we can just add
`supervise_daemon_args="$supervise_daemon_args"` to init scripts.

This fixes #558.
2022-12-07 16:42:14 -06:00
Sam James
0525de4f18 librc-depend: fix -Wmismatched-dealloc
Despite this being a 'deptree', it's actually
xmalloc'd in the same function (rc_deptree_update),
and so should be free'd, not rc_deptree_free'd,
as rc_deptree_load* wasn't used to allocate it.

```
[71/213] Compiling C object src/librc/librc.so.1.p/librc-depend.c.o
../src/librc/librc-depend.c: In function ‘rc_deptree_update’:
../src/librc/librc-depend.c:1077:9: warning: ‘rc_deptree_free’ called on pointer returned from a mismatched allocation function [-Wmismatched-dealloc]
 1077 |         rc_deptree_free(deptree);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../src/shared/misc.h:29,
                 from ../src/librc/librc.h:57,
                 from ../src/librc/librc-depend.c:21:
In function ‘xmalloc’,
    inlined from ‘rc_deptree_update’ at ../src/librc/librc-depend.c:775:12:
../src/shared/helpers.h:64:23: note: returned from ‘malloc’
   64 |         void *value = malloc(size);
      |                       ^~~~~~~~~~~~
```

This fixes #563.
2022-12-07 11:35:16 -06:00
Stefan Linke
9380347f04 Avoid warning on grep 3.8 in hwclock
Starting with grep version 3.8, the hwclock init script logs warnings
about stray backslashes:

> hwclock | * Setting system clock using the hardware clock [UTC] ...
> hwclock |grep: warning: stray \ before -
> hwclock |grep: warning: stray \ before -

This is caused by the check for existence of the `--noadjfile` argument
in function `get_noadjfile()`.

Replacing the affected logic with an explicit argument denoting the
pattern as such resolves the issue.

Fixes #548
2022-09-07 11:59:30 -04:00
Matt Whitlock
112b69860f start-stop-daemon, supervise-daemon: set autogroup nicelevel
As described in "Why nice levels are a placebo and have been for a very
long time, and no one seems to have noticed"[1], the Linux kernel in its
default configuration on many Linux distributions autogroups tasks by
session ID and "fairly" allocates CPU time among such autogroups. The
nice levels of tasks within each autogroup are only relative to
other tasks within the same autogroup. Effectively, this means that the
traditional nice level is rendered moot for tools like start-stop-daemon
and supervise-daemon, which start each daemon in its own session and
thus in its own autogroup. Linux does provide a means to change the
niceness of autogroups relative to each other, so let's have start-stop-
daemon and supervise-daemon make use of this feature where available so
that -N,--nicelevel/SSD_NICELEVEL will actually do what the user
intends. On systems where autogroups are not supported or are disabled,
this commit introduces no change in behavior.

Note that the setsid() call in the child process of start-stop-daemon is
moved to much earlier. This is necessary so that the new process will be
assigned to a new autogroup before the autogroup nicelevel is set. To
avoid inadvertently acquiring /dev/tty as the controlling terminal of
the new session after setsid() has given up the controlling terminal
inherited from the parent process, tty_fd is opened before the call to
setsid().

[1] https://www.reddit.com/r/linux/comments/d7hx2c/why_nice_levels_are_a_placebo_and_have_been_for_a/
This fixes #542.
2022-09-06 17:26:22 -05:00
Sören Tempel
d21dde73ba init.d/root: don't remount swap
While refactoring the changes proposed in #533 a minor error was
introduced were the root service will now attempt to remount swap.
This will fail with the error message `mountinfo: 'swap' is not a
mountpoint`.

This fixes #546
2022-09-04 18:44:47 -05:00
William Hubbs
9b08de926b Revert "start-stop-daemon: use vfork to avoid races"
This is broken, so revert it and reopen #532.

This reverts commit 9e5ce59a21.
2022-09-02 17:27:39 -05:00
Sören Tempel
f60d42e901 init.d/root: also remount / with options provided in /etc/fstab
Without this commit, the root OpenRC service remounts all mounted
filesystems (except /) with the options defined in /etc/fstab via
fstabinfo. It is presently unclear to me why / was excluded from
remounting in 497ff7ee41 and unfortunately
neither the commit nor the associated Bugzilla issue [1] provides
further information on this.

At Alpine, our initramfs does currently not remount / with all options
defined in /etc/fstab [2]. As part of the discussion on the Alpine side
of things we wondered why OpenRC does not remount / since this would be
the easier solution for us. For this reason, this commit changes the
behavior of the OpenRC root services accordingly to also remount / with
the options defined in /etc/fstab.

[1]: https://bugs.gentoo.org/401573
[2]: https://gitlab.alpinelinux.org/alpine/mkinitfs/-/merge_requests/103
This fixes #533.
2022-09-02 13:41:44 -05:00
Arusekk
9e5ce59a21 start-stop-daemon: use vfork to avoid races
While running `rc-service start docker` on Gentoo,
I found that the command does not start the service 90% of the time,
with an enigmatic 'service crashed' message.

The root cause of this is apparently rc-service spawning a pty,
running start-stop-daemon inside that pty, and exitting,
before start-stop-daemon child process calls setsid(),
which results in the child process being killed with SIGHUP (SI_KERNEL).

Theoretically this bug was present ever since the file was created in
5af58b4514 ("Rewrite the core parts in C. We now provide...")
(or even before that), but it should have been only a minor issue before
45bd125dcc ("Use a pty for prefixed output instead of pipes for...").
Not sure why nobody has had the issue so far (it has been present for
almost 15 years).

As here setsid() is the last call before execve(), the most natural
locking mechanism is vfork(), as it gives back control to parent
process only after execve() or process termination.
So this way the bug can be fixed by adding a single letter. :-)

Another way to ensure this would be using an O_CLOEXEC file descriptor
or some custom lock, which would need to be released not before setsid().

Fixes: 5af58b4514 ("Rewrite the core parts in C. We now provide...")
Fixes #532.
2022-09-02 12:41:09 -05:00
xdavidwu
95dc83bfbc openrc: fix help messages
The two lines seem to both belong to --override, but made into seperate
array elements accidentally, making options after --override and their
help mismatch. This fixes it.
2022-07-21 03:53:42 -04:00
psykose
14b153c1a4 fix quoting of loggers in start-stop-daemon
previously broken in 6034866d1c
caused *_logger options to be passed unquoted, so
`error_logger="logger -t .."` would pass -t to s-s-d and fail to start
the service.

Fixes: #531
2022-07-03 12:40:34 -05:00
William Hubbs
3cc4c01485 remove trailing space 2022-06-28 17:21:54 -05:00
William Hubbs
414f398498 modules.in: always return 0, make loading more verbose 2022-06-27 17:32:42 -05:00
William Hubbs
107b23819d restore the init symlink for sysvinit mode
This symlink got lost in the transition to meson.

X-Gentoo-Bug: 850754
X-Gentoo-Bug-URL: https://bugs.gentoo.org/850754
2022-06-10 10:28:57 -05:00
William Hubbs
d2b3144070 clean up hostname service script
- use _ throw-away variable to get rid of a shellcheck warning
- remove tests for /etc/hostname and just try to read it
- drop reference to bash HOSTNAME variable.
- make source of host name more accurate

X-Gentoo-Bug: 850577
X-Gentoo-Bug-URL: https://bugs.gentoo.org/850577
2022-06-08 13:40:29 -05:00
89 changed files with 930 additions and 660 deletions

View File

@@ -4,8 +4,8 @@
test_task:
freebsd_instance:
matrix:
image: freebsd-13-0-release-amd64
image: freebsd-12-3-release-amd64
image: freebsd-13-2-release-amd64
image: freebsd-13-3-release-amd64
env:
OS: FreeBSD
procfs_script: >

142
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,142 @@
# OpenRC Code of Conduct
This code of conduct outlines our expectations for participants within the
community, as well as steps for reporting unacceptable behavior. We are
committed to providing a welcoming and inspiring community for all and
expect our code of conduct to be honored. Anyone who violates this code
of conduct may be banned from the community.
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement via integrated
"Report Content" functionality.
See the GitHub documentation for more details:
https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@@ -1,5 +1,5 @@
Copyright (c) 2007-2008, Roy Marples <roy@marples.name>
Copyright (c) 2007-2015, the OpenRC authors
Copyright (c) 2007-2023, the OpenRC authors
All rights reserved.
Redistribution and use in source and binary forms, with or without

78
NEWS.md
View File

@@ -4,6 +4,84 @@ OpenRC NEWS
This file will contain a list of notable changes for each release. Note
the information in this file is in reverse order.
## OpenRC 0.54
This release drops the support for the split-usr build option.
Also, it drops the support for ncurses/termcap and uses ansi codes
directly for color support on terminals that support them.
## OpenRC 0.53
The names of cgroups for services started by OpenRC are now prefixed by
"openrc." This is done because some services, like docker, create their
own cgroups.
It is now possible to override the mount options used to mount the
cgroups filesystems.
## OpenRC 0.52
This release drops the "runscript" and "rc" binaries.
These binaries have been deprecated for multiple years, so it should be
fine to remove them at this point.
There was an issue before this release with the default setting for
cgroups being inconsistent. This is fixed.
Start-stop-daemon did not work correctly on Linux 6.6 systems.
This has been fixed in this release as well.
## OpenRC 0.51
The default RC_CGROUP_MODE has been updated to unified.
This benefits users since it will assign each service to its own cgroup,
making resource nanagement better over all.
OUTPUT_LOGGER and ERROR_LOGGER have been implemented for
supervise-daemon. For mor einformation on these settings, please check
the man page.
## OpenRC 0.50
This is a bug fix release which fixes a significant performance issue on
musl libc systems.
## OpenRC 0.49
This release adds support for glibc's builtin
strlcpy, strlcat etc functions, which will be in posix next.
Also, it fixes completions.
## OpenRC 0.48
This release is a maintenance release; it has no user-facing changes.
## OpenRC 0.47
This release is primarily an internal cleanup release.
The only user-visible difference is that unicode is now on by default.
## OpenRC 0.46
The path for the reference file for the swclock service is now
configurable in conf.d/swclock.
In the past, if supervise_daemon_args was not set *or empty*, it defaulted to
`start_stop_daemon_args`. This was bad because supervise-daemon doesn't
accept the same options as `start-stop-daemon`. So if we set e.g.
`start_stop_daemon_args="--wait 50"`, but not `supervise_daemon_args`,
and the user adds `supervisor=supervise-daemon` to the corresponding
conf.d/<service> file, the service will fail to start due to
unrecognized option "wait".
It would be best to remove this fallback, but that might break some
existing scripts that depend on it. So we are changing it to
use `start_stop_daemon_args` as the default for `supervise_daemon_args`
only if `supervise_daemon_args` is not set at all, but not if it's
empty.
This fallback will be dropped in a future release.
## OpenRC 0.45
The old make-based build system is removed in this release.

View File

@@ -85,29 +85,26 @@ _rc_service()
else
# no option was typed
if [[ ${COMP_CWORD} -eq 1 ]]; then # if first word typed
words="$(rc-service --list | grep ^${cur})" # complete for init scripts
COMPREPLY=($(for i in ${words} ; do \
[[ ${i} == ${cur}* ]] && echo ${i} ; \
# complete for init scripts
COMPREPLY=($(for i in $(rc-service --list) ; do \
[[ ${i} == "${cur}"* ]] && echo ${i} ; \
done))
return 0
elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function
rc-service --exists "$prev" || return
shopt -s extglob
while read -r _ line; do
if [[ $line == +([[:alnum:]_]):* ]]; then
opts+="${line%%:*} "
fi
done < <(rc-service "$prev" describe 2>&1)
shopt -u extglob
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
fi
if [[ ${action} == '--exists' ]] || [[ ${action} == '-e' ]] || \
[[ ${action} == '--resolve' ]] || [[ ${action} == '-r' ]]; then
words="$(rc-service --list | grep ^${cur})"
COMPREPLY=($(for i in ${words} ; do \
[[ ${i} == ${cur}* ]] && echo ${i} ; \
COMPREPLY=($(for i in $(rc-service --list) ; do \
[[ ${i} == "${cur}"* ]] && echo ${i} ; \
done))
return 0
fi

2
conf.d/cgroups Normal file
View File

@@ -0,0 +1,2 @@
# override cgroup mount options
#cgroup_opts=nodev,noexec,nosuid

View File

@@ -7,6 +7,7 @@ conf_common = [
'localmount',
'netmount',
'swap',
'swclock',
]
conf_net = [

6
conf.d/swclock Normal file
View File

@@ -0,0 +1,6 @@
# This is the location of the reference file swclock uses to set the
# system date and time.
# This is the default path. If you are using it, you do not need to
# uncomment it. If you are using the default and have /var on its own
# file system, you need to add the appropriate rc_after setting.
# swclock_file=/var/lib/misc/openrc-shutdowntime

View File

@@ -88,8 +88,8 @@
# MISC CONFIGURATION VARIABLES
# There variables are shared between many init scripts
# Set unicode to YES to turn on unicode support for keyboards and screens.
#unicode="NO"
# Set unicode to NO to turn off unicode support for keyboards and screens.
#unicode="YES"
# This is how long fuser should wait for a remote server to respond. The
# default is 60 seconds, but it can be adjusted here.
@@ -97,8 +97,8 @@
# Below is the default list of network fstypes.
#
# afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre ncpfs
# nfs nfs4 ocfs2 shfs smbfs
# afs ceph cifs coda davfs fuse fuse.glusterfs fuse.sshfs gfs glusterfs lustre
# ncpfs nfs nfs4 ocfs2 shfs smbfs
#
# If you would like to add to this list, you can do so by adding your
# own fstypes to the following variable.
@@ -116,12 +116,13 @@
# Some daemons are started and stopped via start-stop-daemon.
# We can set some things on a per service basis, like the nicelevel.
#SSD_NICELEVEL="0"
# These need to be exported
#export SSD_NICELEVEL="0"
# Or the ionice level. The format is class[:data] , just like the
# --ionice start-stop-daemon parameter.
#SSD_IONICELEVEL="0:0"
#export SSD_IONICELEVEL="0:0"
# Or the OOM score adjustment.
#SSD_OOM_SCORE_ADJ="0"
#export SSD_OOM_SCORE_ADJ="0"
# Pass ulimit parameters
# If you are using bash in POSIX mode for your shell, note that the
@@ -198,7 +199,10 @@ rc_tty_number=12
# cgroups version 1 on /sys/fs/cgroup.
# "legacy" mounts cgroups version 1 on /sys/fs/cgroup
# "unified" mounts cgroups version 2 on /sys/fs/cgroup
#rc_cgroup_mode="hybrid"
#rc_cgroup_mode="unified"
# override cgroup controller name
#rc_cgroup_name=openrc
# This is a list of controllers which should be enabled for cgroups version 2
# when hybrid mode is being used.

View File

@@ -11,7 +11,9 @@
description="Mount the control groups."
cgroup_opts=nodev,noexec,nosuid
: "${cgroup_opts:="nodev,noexec,nosuid"}"
rc_cgroup_name=${rc_cgroup_name:-openrc}
depend()
{
@@ -29,13 +31,13 @@ cgroup1_base()
eend $?
fi
if ! mountinfo -q /sys/fs/cgroup/openrc; then
if ! mountinfo -q /sys/fs/cgroup/"${rc_cgroup_name}"; then
local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh"
mkdir /sys/fs/cgroup/openrc
mkdir /sys/fs/cgroup/"${rc_cgroup_name}"
mount -n -t cgroup \
-o none,${cgroup_opts},name=openrc,release_agent="$agent" \
openrc /sys/fs/cgroup/openrc
printf 1 > /sys/fs/cgroup/openrc/notify_on_release
-o none,${cgroup_opts},name="${rc_cgroup_name}",release_agent="$agent" \
"${rc_cgroup_name}" /sys/fs/cgroup/"${rc_cgroup_name}"
printf 1 > /sys/fs/cgroup/"${rc_cgroup_name}"/notify_on_release
fi
return 0
}
@@ -74,6 +76,7 @@ cgroup2_base()
mkdir -p "${base}"
mount -t cgroup2 none -o "${cgroup_opts},nsdelegate" "${base}" 2> /dev/null ||
mount -t cgroup2 none -o "${cgroup_opts}" "${base}"
mkdir -p ${base}/"${rc_cgroup_name}"
return 0
}
@@ -81,13 +84,13 @@ cgroup2_controllers()
{
grep -qw cgroup2 /proc/filesystems || return 0
local active cgroup_path x y
cgroup_path="$(cgroup2_find_path)"
cgroup_path="$(cgroup2_find_path)/${rc_cgroup_name}"
[ -z "${cgroup_path}" ] && return 0
[ ! -e "${cgroup_path}/cgroup.controllers" ] && return 0
[ ! -e "${cgroup_path}/cgroup.subtree_control" ]&& return 0
read -r active < "${cgroup_path}/cgroup.controllers"
for x in ${active}; do
case "$rc_cgroup_mode" in
case "${rc_cgroup_mode:-unified}" in
unified)
echo "+${x}" > "${cgroup_path}/cgroup.subtree_control"
;;
@@ -128,7 +131,7 @@ cgroups_unified()
mount_cgroups()
{
case "${rc_cgroup_mode:-hybrid}" in
case "${rc_cgroup_mode:-unified}" in
hybrid) cgroups_hybrid ;;
legacy) cgroups_legacy ;;
unified) cgroups_unified ;;

View File

@@ -19,20 +19,18 @@ depend()
start()
{
local h source x
if [ -s /etc/hostname ] && [ -r /etc/hostname ]; then
read h x </etc/hostname
source="from /etc/hostname"
else
# HOSTNAME variable used to be defined in caps in conf.d/hostname.
# It is also a magic variable in bash.
h=${hostname:-${HOSTNAME}} # checkbashisms: false positive (HOSTNAME var)
local h source
if read -r h _ 2> /dev/null < @SYSCONFDIR@/hostname; then
source="@SYSCONFDIR@/hostname"
elif [ -n "${hostname}" ]; then
h=${hostname}
source="@SYSCONFDIR@/conf.d/${RC_SVCNAME}"
fi
if [ -z "$h" ]; then
einfo "Using default system hostname"
return 0
fi
ebegin "Setting hostname to $h $source"
ebegin "Setting hostname to $h from $source"
hostname "$h"
eend $? "Failed to set the hostname"
}

View File

@@ -72,7 +72,7 @@ get_noadjfile()
{
if ! yesno $clock_adjfile; then
# Some implementations don't handle adjustments
if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
if LC_ALL=C hwclock --help 2>&1 | grep -q -e "--noadjfile"; then
echo --noadjfile
fi
fi

View File

@@ -42,7 +42,7 @@ start()
fi
local wkeys= kmode="-a" msg="ASCII"
if yesno $unicode; then
if yesno ${unicode:-yes}; then
kmode="-u"
msg="UTF-8"
fi

View File

@@ -56,10 +56,10 @@ load_modules()
ebegin "Loading module $x"
case "$RC_UNAME" in
FreeBSD) kldload "$x"; rc=$? ;;
Linux) modprobe --first-time -q --use-blacklist "$x"; rc=$? ;;
Linux) modprobe --first-time --use-blacklist --verbose "$x"; rc=$? ;;
*) ;;
esac
eend $rc "Failed to load $x"
eend
done
return 0
}
@@ -80,9 +80,10 @@ FreeBSD_modules()
for x in $modules; do
ebegin "Loading module $x"
kldload "$x"
eend $? "Failed to load $x" && : $(( cnt += 1 ))
eend && : $(( cnt += 1 ))
done
einfo "Autoloaded $cnt module(s)"
return 0
}
Linux_modules()
@@ -122,6 +123,7 @@ Linux_modules()
eval modprobe --first-time --use-blacklist --verbose "$x" "$args"
done
[ -n "$list" ] && eend
return 0
}
start()

View File

@@ -49,9 +49,7 @@ start()
local mountpoint
for mountpoint in $(fstabinfo); do
case "${mountpoint}" in
/)
;;
/*)
/*) # Don't remount swap etc.
mountinfo -q "${mountpoint}" && \
fstabinfo --remount "${mountpoint}"
;;

View File

@@ -25,7 +25,7 @@ start()
# Save the encoding for use immediately at boot
if checkpath -W "$RC_LIBEXECDIR"; then
mkdir -p "$RC_LIBEXECDIR"/console
if yesno ${unicode:-${UNICODE}}; then
if yesno ${unicode:-yes}; then
echo "" > "$RC_LIBEXECDIR"/console/unicode
else
rm -f "$RC_LIBEXECDIR"/console/unicode

View File

@@ -10,6 +10,7 @@
# except according to the terms contained in the LICENSE file.
description="Sets the local clock to the mtime of a given file."
swclock_file="${swclock_file:-/var/lib/misc/openrc-shutdowntime}"
depend()
{
@@ -22,7 +23,7 @@ depend()
start()
{
ebegin "Setting the local clock based on last shutdown time"
if ! swclock 2> /dev/null; then
if ! swclock "${swclock_file}" 2> /dev/null; then
swclock --warn @SBINDIR@/openrc-run
fi
eend $?
@@ -31,6 +32,6 @@ start()
stop()
{
ebegin "Saving the shutdown time"
swclock --save
swclock --save "${swclock_file}"
eend $?
}

View File

@@ -28,7 +28,7 @@ start()
# Set terminal encoding to either ASCII or UNICODE.
# See utf-8(7) for more information.
local termencoding="%@" termmsg="ASCII"
if yesno ${unicode}; then
if yesno ${unicode:-yes}; then
termencoding="%G"
termmsg="UTF-8"
fi
@@ -43,7 +43,7 @@ start()
# Save the encoding for use immediately at boot
if checkpath -W "$RC_LIBEXECDIR"; then
mkdir -p "$RC_LIBEXECDIR"/console
if yesno ${unicode:-${UNICODE}}; then
if yesno ${unicode:-yes}; then
echo "" > "$RC_LIBEXECDIR"/console/unicode
else
rm -f "$RC_LIBEXECDIR"/console/unicode

View File

@@ -158,13 +158,6 @@ is true.
prefixes the string
.Fa prefix
to the above functions.
.Sh IMPLEMENTATION NOTES
einfo can optionally be linked against the
.Lb libtermcap
so that we can correctly query the connected console for our color and
cursor escape codes.
If not, then we have a hard coded list of terminals we know about that support
the commonly used codes for color and cursor position.
.Sh ENVIRONMENT
.Va EINFO_QUIET
when set to true makes the

View File

@@ -37,11 +37,11 @@ Brings up any system specific stuff such as
and optionally
.Pa /sys
for Linux based systems. It also mounts
.Pa /lib/rc/init.d
.Pa /run/openrc
as a ramdisk using tmpfs where available unless / is mounted rw at boot.
.Nm
uses
.Pa /lib/rc/init.d
.Pa /run/openrc
to hold state information about the services it runs.
sysinit always runs when the host first starts should not be run again.
.It Ar boot

View File

@@ -47,7 +47,7 @@ services.
.Pp
.Fn rc_deptree_update
updates the service dependency tree, normally
.Pa /lib/rc/init.d/deptree .
.Pa /run/openrc/deptree .
.Fn rc_deptree_update_needed
checks to see if the dependency tree needs updated based on the mtime of it
compared to

View File

@@ -204,7 +204,7 @@ When a function fails it should either return false or NULL and set
.Va errno
unless specified otherwise as above.
.Sh FILES
.Pa /lib/rc/init.d
.Pa /run/openrc
normally holds the volatile state data for services on a RAM backed disk.
.Sh SEE ALSO
.Xr errno 3 ,

View File

@@ -84,6 +84,8 @@ Print the action(s) that would be taken, but don't actually do anything.
The return value is set as if the command was taken and worked.
.It Fl v , -verbose
Print the action(s) that are taken just before doing them.
.It Fl q , -quiet
Run quietly (repeat to suppress errors).
.It Fl P , -progress
Echo a . to the console for each second elapsed whilst waiting.
.El
@@ -183,10 +185,6 @@ Wait
after starting and check that daemon is still running.
Useful for daemons that check configuration after forking or stopping race
conditions where the pidfile is written out after forking.
.It Fl 2 , -stderr Ar logfile
The same thing as
.Fl 1 , -stdout
but with the standard error output.
.El
.Pp
These options are only used for stopping daemons:

View File

@@ -158,6 +158,23 @@ The logfile can also be a named pipe.
The same thing as
.Fl 1 , -stdout
but with the standard error output.
.It Fl -stdout-logger Ar cmd
Run cmd as a child process redirecting the standard output to the
standard input of cmd when started with
.Fl background .
Cmd must be an absolute pathname, but relative to the path optionally given with
.Fl r , -chroot .
This process must be prepared to accept input on stdin and be able to
log it or send it to another location.
.It Fl -stderr-logger Ar cmd
Run cmd as a child process and
Redirect the standard error of the process to the standard input of cmd
when started with
.Fl background .
Cmd must be an absolute pathname, but relative to the path optionally given with
.Fl r , -chroot .
This process must be prepared to accept input on stdin and be able to
log it or send it to another location.
.It Fl -capabilities Ar cap-list
Start the daemon with the listed inheritable, ambient and bounding capabilities.
The format is the same as in cap_iab(3).

View File

@@ -1,5 +1,5 @@
project('OpenRC', 'c',
version : '0.45',
version : '0.54',
license: 'BSD-2',
default_options : [
'c_std=c99',
@@ -36,7 +36,7 @@ endif
option_os = get_option('os')
if option_os == ''
uname = find_program('uname')
r = run_command(uname, '-s')
r = run_command(uname, '-s', check: true)
os = r.stdout().strip()
os = '-'.join(os.split('/'))
else
@@ -83,16 +83,9 @@ else
pkg_prefix = option_pkg_prefix
endif
if get_option('split-usr') == 'auto'
split_usr = run_command('test', '-L', '/bin').returncode() != 0
else
split_usr = get_option('split-usr') == 'true'
endif
rootprefix = get_option('rootprefix')
rootprefix_default = fs.is_symlink('/bin') ? '/usr' : '/'
if rootprefix == ''
rootprefix = rootprefix_default
rootprefix = '/'
endif
bindir = rootprefix / get_option('bindir')
@@ -133,15 +126,6 @@ else
cc_selinux_flags = []
endif
termcap = get_option('termcap')
if termcap != ''
termcap_dep = dependency(termcap)
termcap_flags = '-DHAVE_TERMCAP'
else
termcap_dep = []
termcap_flags = []
endif
if get_option('buildtype').startswith('debug')
cc_debug_flags = ['-DRC_DEBUG']
else
@@ -176,7 +160,10 @@ cc_warning_flags_test = [
'-Wsequence-point',
'-Wshadow',
'-Wwrite-strings',
'-Werror=implicit-int',
'-Werror=implicit-function-declaration',
'-Werror=int-conversion',
'-Werror=incompatible-function-pointer-types',
]
cc_warning_flags = cc.get_supported_arguments(cc_warning_flags_test)
cc_flags = [cc_debug_flags, cc_os_flags, cc_warning_flags]
@@ -192,6 +179,16 @@ if cc.compiles(malloc_attribute_test, name : 'malloc attribute with arguments')
add_project_arguments('-DHAVE_MALLOC_EXTENDED_ATTRIBUTE', language: 'c')
endif
if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include <unistd.h>')
add_project_arguments('-DHAVE_CLOSE_RANGE', language: 'c')
elif cc.has_header('linux/close_range.h')
add_project_arguments('-DHAVE_LINUX_CLOSE_RANGE_H', language: 'c')
endif
if cc.has_function('strlcpy', prefix: '#define _GNU_SOURCE\n#include <string.h>')
add_project_arguments('-DHAVE_STRLCPY', language: 'c')
endif
incdir = include_directories('src/shared')
einfo_incdir = include_directories('src/libeinfo')
rc_incdir = include_directories('src/librc')
@@ -226,4 +223,6 @@ meson.add_install_script('tools/meson_runlevels.sh',
get_option('sysvinit') ? 'yes' : 'no')
meson.add_install_script('tools/meson_final.sh',
rc_libexecdir,
os)
sbindir,
os,
get_option('sysvinit') ? 'yes' : 'no')

View File

@@ -26,14 +26,7 @@ option('selinux', type : 'feature', value : 'auto',
description : 'enable SELinux support')
option('shell', type : 'string', value : '/bin/sh',
description : 'Default posix compatible shell')
option('split-usr', type : 'combo',
choices : ['auto', 'true', 'false'],
description : '''/bin, /sbin aren't symlinks into /usr''')
option('sysvinit', type : 'boolean', value : false,
description : 'enable SysVinit compatibility (linux only)')
option('termcap', type : 'combo',
choices :
[ '', 'ncurses', 'termcap' ],
description : 'the termcap library to use')
option('zsh-completions', type : 'boolean',
description : 'install zsh completions')

View File

@@ -12,7 +12,7 @@
# This file may not be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
cgroup=/sys/fs/cgroup/openrc
cgroup=/sys/fs/cgroup/"${rc_cgroup_name:-openrc}"
PATH=/bin:/usr/bin:/sbin:/usr/sbin
if [ -d ${cgroup}/"$1" ]; then
rmdir ${cgroup}/"$1"

View File

@@ -79,6 +79,7 @@ elif ! mountinfo -q /run; then
exit 1
fi
fi
eend
fi
checkpath -d "$RC_SVCDIR"

View File

@@ -11,6 +11,8 @@
extra_stopped_commands="${extra_stopped_commands} cgroup_cleanup"
description_cgroup_cleanup="Kill all processes in the cgroup"
cg2_sv_name="${RC_SVCNAME}.sv"
cgroup_find_path()
{
local OIFS name dir result
@@ -35,9 +37,9 @@ cgroup_get_pids()
cgroup_pids=
cgroup_procs="$(cgroup2_find_path)"
if [ -n "${cgroup_procs}" ]; then
cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs"
cgroup_procs="${cgroup_procs}/${rc_cgroup_name}/${cg2_sv_name}/cgroup.procs"
else
cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks"
cgroup_procs="/sys/fs/cgroup/"${rc_cgroup_name}"/${RC_SVCNAME}/tasks"
fi
[ -f "${cgroup_procs}" ] || return 0
while read -r p; do
@@ -51,7 +53,7 @@ cgroup_running()
{
[ -d "/sys/fs/cgroup/unified/${RC_SVCNAME}" ] ||
[ -d "/sys/fs/cgroup/${RC_SVCNAME}" ] ||
[ -d "/sys/fs/cgroup/openrc/${RC_SVCNAME}" ]
[ -d "/sys/fs/cgroup/"${rc_cgroup_name}"/${RC_SVCNAME}" ]
}
cgroup_set_values()
@@ -61,7 +63,7 @@ cgroup_set_values()
local controller h
controller="$1"
h=$(cgroup_find_path "$1")
cgroup="/sys/fs/cgroup/${1}${h}openrc_${RC_SVCNAME}"
cgroup="/sys/fs/cgroup/${1}${h}"${rc_cgroup_name}"_${RC_SVCNAME}"
[ -d "$cgroup" ] || mkdir -p "$cgroup"
set -- $2
@@ -108,7 +110,7 @@ cgroup_add_service()
[ -w "${d}"/tasks ] && printf "%d" 0 > "${d}"/tasks
done
openrc_cgroup=/sys/fs/cgroup/openrc
openrc_cgroup=/sys/fs/cgroup/"${rc_cgroup_name}"
if [ -d "$openrc_cgroup" ]; then
cgroup="$openrc_cgroup/$RC_SVCNAME"
mkdir -p "$cgroup"
@@ -154,7 +156,7 @@ cgroup_set_limits()
cgroup2_find_path()
{
if grep -qw cgroup2 /proc/filesystems; then
case "${rc_cgroup_mode:-hybrid}" in
case "${rc_cgroup_mode:-unified}" in
hybrid) printf "/sys/fs/cgroup/unified" ;;
unified) printf "/sys/fs/cgroup" ;;
esac
@@ -167,7 +169,7 @@ cgroup2_remove()
local cgroup_path rc_cgroup_path
cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}"
[ ! -d "${rc_cgroup_path}" ] ||
[ ! -e "${rc_cgroup_path}"/cgroup.events ] &&
return 0
@@ -191,7 +193,7 @@ cgroup2_set_limits()
cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0
mountinfo -q "${cgroup_path}"|| return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}"
[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
[ -f "${rc_cgroup_path}"/cgroup.procs ] &&
printf 0 > "${rc_cgroup_path}"/cgroup.procs
@@ -210,7 +212,7 @@ cgroup2_kill_cgroup() {
local cgroup_path
cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 1
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}"
if [ -f "${rc_cgroup_path}"/cgroup.kill ]; then
printf "%d" 1 > "${rc_cgroup_path}"/cgroup.kill
fi

View File

@@ -2,8 +2,10 @@
# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
# Released under the 2-clause BSD license.
net_fs_list="afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre
ncpfs nfs nfs4 ocfs2 shfs smbfs"
net_fs_list="
afs ceph cifs coda davfs fuse fuse.glusterfs fuse.sshfs gfs glusterfs lustre
ncpfs nfs nfs4 ocfs2 shfs smbfs
"
is_net_fs()
{
[ -z "$1" ] && return 1

View File

@@ -47,8 +47,8 @@ ssd_start()
${directory:+--chdir} $directory \
${output_log+--stdout} $output_log \
${error_log+--stderr} $error_log \
${output_logger:+--stdout-logger} "$output_logger" \
${error_logger:+--stderr-logger} "$error_logger" \
${output_logger:+--stdout-logger \"$output_logger\"} \
${error_logger:+--stderr-logger \"$error_logger\"} \
${capabilities+--capabilities} "$capabilities" \
${secbits:+--secbits} "$secbits" \
${no_new_privs:+--no-new-privs} \

View File

@@ -30,6 +30,8 @@ supervise_start()
${chroot:+--chroot} $chroot \
${output_log+--stdout} ${output_log} \
${error_log+--stderr} $error_log \
${output_logger:+--stdout-logger \"$output_logger\"} \
${error_logger:+--stderr-logger \"$error_logger\"} \
${pidfile:+--pidfile} $pidfile \
${respawn_delay:+--respawn-delay} $respawn_delay \
${respawn_max:+--respawn-max} $respawn_max \
@@ -38,10 +40,10 @@ supervise_start()
${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \
${capabilities+--capabilities} "$capabilities" \
${secbits:+--secbits} "$secbits" \
${no_new_privs:+--no_new_privs} \
${no_new_privs:+--no-new-privs} \
${command_user+--user} $command_user \
${umask+--umask} $umask \
${supervise_daemon_args:-${start_stop_daemon_args}} \
${supervise_daemon_args-${start_stop_daemon_args}} \
$command \
-- $command_args $command_args_foreground
rc=$?

View File

@@ -17,25 +17,24 @@
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <grp.h>
#include <libgen.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "selinux.h"
#include "_usage.h"
#include "helpers.h"
typedef enum {
inode_unknown = 0,
@@ -89,7 +88,7 @@ static int get_dirfd(char *path, bool symlinks)
if (!path || *path != '/')
eerrorx("%s: empty or relative path", applet);
dirfd = openat(dirfd, "/", O_RDONLY);
dirfd = openat(AT_FDCWD, "/", O_RDONLY);
if (dirfd == -1)
eerrorx("%s: unable to open the root directory: %s",
applet, strerror(errno));
@@ -285,7 +284,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
return -1;
}
if (mode && (st.st_mode & 0777) != mode) {
if (mode && (st.st_mode & 07777) != mode) {
if ((type != inode_dir) && (st.st_nlink > 1)) {
eerror("%s: chmod: Too many hard links to %s", applet, path);
close(readfd);

View File

@@ -12,20 +12,17 @@
#define SYSLOG_NAMES
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <strings.h>
#include "einfo.h"
#include "helpers.h"
@@ -81,7 +78,7 @@ int main(int argc, char **argv)
if (strcmp(applet, "eend") == 0 ||
strcmp(applet, "ewend") == 0 ||
strcmp(applet, "veend") == 0 ||
strcmp(applet, "vweend") == 0 ||
strcmp(applet, "vewend") == 0 ||
strcmp(applet, "ewaitfile") == 0)
{
errno = 0;

View File

@@ -16,13 +16,14 @@
*/
#include <sys/wait.h>
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <spawn.h>
/* Yay for linux and its non liking of POSIX functions.
Okay, we could use getfsent but the man page says use getmntent instead
@@ -30,6 +31,7 @@
#ifdef __linux__
# define HAVE_GETMNTENT
# include <mntent.h>
# define ENT mntent
# define START_ENT fp = setmntent ("/etc/fstab", "r");
# define GET_ENT getmntent (fp)
@@ -43,6 +45,7 @@
#else
# define HAVE_GETFSENT
# include <fstab.h>
# define ENT fstab
# define START_ENT
# define GET_ENT getfsent ()
@@ -58,8 +61,10 @@
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
extern char **environ;
const char *applet = NULL;
const char *extraopts = NULL;
@@ -110,7 +115,7 @@ do_mount(struct ENT *ent, bool remount)
{
char *argv[10];
pid_t pid;
int status;
int status, err;
argv[0] = UNCONST("mount");
argv[1] = UNCONST("-o");
@@ -135,23 +140,14 @@ do_mount(struct ENT *ent, bool remount)
argv[8] = NULL;
#endif
}
switch (pid = vfork()) {
case -1:
eerrorx("%s: vfork: %s", applet, strerror(errno));
/* NOTREACHED */
case 0:
execvp(argv[0], argv);
eerror("%s: execvp: %s", applet, strerror(errno));
_exit(EXIT_FAILURE);
/* NOTREACHED */
default:
waitpid(pid, &status, 0);
if (WIFEXITED(status))
return WEXITSTATUS(status);
else
return -1;
/* NOTREACHED */
}
err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ);
if (err)
eerrorx("%s: posix_spawnp: %s", applet, strerror(err));
while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
if (WIFEXITED(status))
return WEXITSTATUS(status);
else
return -1;
}
#define OUTPUT_FILE (1 << 1)

View File

@@ -10,13 +10,9 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "rc.h"
#include "misc.h"
int main(int argc, char **argv)
{

View File

@@ -10,13 +10,9 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "rc.h"
#include "misc.h"
int main(int argc, char **argv)
{

View File

@@ -19,7 +19,6 @@
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -28,11 +27,12 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdbool.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *extraopts = "[signal number]";

View File

@@ -13,13 +13,8 @@
#ifndef __EINFO_H__
#define __EINFO_H__
#if defined(__GNUC__)
# define EINFO_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
# define EINFO_XPRINTF(a, b) __attribute__((__noreturn__,__format__(__printf__, a, b)))
#else
# define EINFO_PRINTF(a, b)
# define EINFO_XPRINTF(a, b)
#endif
#define EINFO_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
#define EINFO_XPRINTF(a, b) __attribute__((__noreturn__, __format__(__printf__, a, b)))
#include <sys/types.h>
#include <stdbool.h>
@@ -74,22 +69,22 @@ void elog(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
* The x suffix means function will exit() returning failure.
*/
/*@{*/
int einfon(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eerrorn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int einfo(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void ewarnx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int eerror(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void eerrorx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int einfon(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eerrorn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int einfo(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void ewarnx(const char * EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int eerror(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void eerrorx(const char * EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int einfovn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ebeginvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int ewendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int einfov(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnv(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int einfovn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnvn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ebeginvn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eendvn(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int ewendvn(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int einfov(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnv(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
/*@}*/
/*! @ingroup ebegin

View File

@@ -4,7 +4,7 @@
*/
/*
* Copyright (c) 2007-2015 The OpenRC Authors.
* Copyright (c) 2007-2024 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
*
@@ -15,24 +15,17 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
#ifdef HAVE_TERMCAP
# include <termcap.h>
#endif
#include <unistd.h>
#include "einfo.h"
@@ -57,8 +50,7 @@
#define HILITE 6
#define BRACKET 4
/* We fallback to these escape codes if termcap isn't available
* like say /usr isn't mounted */
/* ANSI escape codes which mimic termcap */
#define AF "\033[3%dm"
#define CE "\033[K"
#define CH "\033[%dC"
@@ -101,13 +93,7 @@ static char *goto_column = NULL;
static const char *term = NULL;
static bool term_is_cons25 = false;
/* Termcap buffers and pointers
* Static buffers suck hard, but some termcap implementations require them */
#ifdef HAVE_TERMCAP
static char termcapbuf[2048];
static char tcapbuf[512];
#else
/* No curses support, so we hardcode a list of colour capable terms
/* Hardcoded list of colour capable terms
* Only terminals without "color" in the name need to be explicitly listed */
static const char *const color_terms[] = {
"Eterm",
@@ -146,13 +132,11 @@ static const char *const color_terms[] = {
"wsvt25",
"xterm",
"xterm-debian",
"xterm-kitty",
NULL
};
#endif
/* strlcat and strlcpy are nice, shame glibc does not define them */
#ifdef __GLIBC__
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
#ifndef HAVE_STRLCPY
static size_t
strlcat(char *dst, const char *src, size_t size)
{
@@ -180,7 +164,6 @@ strlcat(char *dst, const char *src, size_t size)
return dst_n + (s - src);
}
# endif
#endif
static bool
@@ -243,7 +226,6 @@ is_verbose(void)
}
/* Fake tgoto call - very crapy, but works for our needs */
#ifndef HAVE_TERMCAP
static char *
tgoto(const char *cap, int col, int line)
{
@@ -306,7 +288,6 @@ tgoto(const char *cap, int col, int line)
*p = '\0';
return buf;
}
#endif
static bool
colour_terminal(FILE * EINFO_RESTRICT f)
@@ -319,9 +300,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
const char *bold;
char tmp[100];
unsigned int i = 0;
#ifdef HAVE_TERMCAP
char *bp;
#endif
if (f && !isatty(fileno(f)))
return false;
@@ -343,65 +321,33 @@ colour_terminal(FILE * EINFO_RESTRICT f)
if (strcmp(term, "cons25") == 0)
term_is_cons25 = true;
#ifdef HAVE_TERMCAP
/* Check termcap to see if we can do colour or not */
if (tgetent(termcapbuf, term) == 1) {
bp = tcapbuf;
_af = tgetstr("AF", &bp);
_ce = tgetstr("ce", &bp);
_ch = tgetstr("ch", &bp);
/* Our ch use also works with RI .... for now */
if (!_ch)
_ch = tgetstr("RI", &bp);
_md = tgetstr("md", &bp);
_me = tgetstr("me", &bp);
_up = tgetstr("up", &bp);
}
if (strstr(term, "color"))
in_colour = 1;
/* Cheat here as vanilla BSD has the whole termcap info in /usr
* which is not available to us when we boot */
if (term_is_cons25 || strcmp(term, "wsvt25") == 0) {
#else
if (strstr(term, "color"))
while (color_terms[i] && in_colour != 1) {
if (strcmp(color_terms[i], term) == 0) {
in_colour = 1;
while (color_terms[i] && in_colour != 1) {
if (strcmp(color_terms[i], term) == 0) {
in_colour = 1;
}
i++;
}
if (in_colour != 1) {
in_colour = 0;
return false;
}
#endif
if (!_af)
_af = AF;
if (!_ce)
_ce = CE;
if (!_ch)
_ch = CH;
if (!_md)
_md = MD;
if (!_me)
_me = ME;
if (!_up)
_up = UP;
#ifdef HAVE_TERMCAP
i++;
}
if (!_af || !_ce || !_me || !_md || !_up) {
if (in_colour != 1) {
in_colour = 0;
return false;
}
/* Many termcap databases don't have ch or RI even though they
* do work */
if (!_af)
_af = AF;
if (!_ce)
_ce = CE;
if (!_ch)
_ch = CH;
#endif
if (!_md)
_md = MD;
if (!_me)
_me = ME;
if (!_up)
_up = UP;
/* Now setup our colours */
p = ebuffer;
@@ -677,15 +623,14 @@ ewarn(const char *EINFO_RESTRICT fmt, ...)
void
ewarnx(const char *EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
if (fmt && !is_quiet()) {
va_start(ap, fmt);
elogv(LOG_WARNING, fmt, ap);
retval = _ewarnvn(fmt, ap);
_ewarnvn(fmt, ap);
va_end(ap);
retval += fprintf(stderr, "\n");
fprintf(stderr, "\n");
}
exit(EXIT_FAILURE);
}

View File

@@ -1,9 +1,7 @@
libeinfo_version = '1'
libeinfo = library('einfo', ['libeinfo.c'],
c_args : termcap_flags,
include_directories : incdir,
dependencies : termcap_dep,
link_depends : 'einfo.map',
version : libeinfo_version,
install : true,

View File

@@ -15,10 +15,21 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "queue.h"
#include "librc.h"
#include "helpers.h"
#if defined(__linux__) || (defined (__FreeBSD_kernel__) && defined(__GLIBC__)) \
|| defined(__GNU__)
@@ -391,7 +402,7 @@ rc_service_daemon_set(const char *service, const char *exec,
bool retval = false;
DIR *dp;
struct dirent *d;
RC_STRINGLIST *match;
RC_STRINGLIST *match, *renamelist;
int i = 0;
FILE *fp;
@@ -405,11 +416,17 @@ rc_service_daemon_set(const char *service, const char *exec,
/* Regardless, erase any existing daemon info */
if ((dp = opendir(dirpath))) {
match = _match_list(exec, argv, pidfile);
renamelist = rc_stringlist_new();
while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
xasprintf(&file, "%s/%s", dirpath, d->d_name);
if (rc_stringlist_find(renamelist, file)) {
free(file);
continue;
}
nfiles++;
if (!*oldfile) {
@@ -421,11 +438,15 @@ rc_service_daemon_set(const char *service, const char *exec,
} else {
rename(file, oldfile);
strlcpy(oldfile, file, sizeof(oldfile));
/* Add renamed file to renamelist, as this new file name could
* be read again from readdir() */
rc_stringlist_add(renamelist, oldfile);
}
free(file);
}
closedir(dp);
rc_stringlist_free(match);
rc_stringlist_free(renamelist);
}
/* Now store our daemon info */

View File

@@ -16,9 +16,22 @@
*/
#include <sys/utsname.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "queue.h"
#include "librc.h"
#include "helpers.h"
#include "misc.h"
#define GENDEP RC_LIBEXECDIR "/sh/gendepends.sh"
@@ -1074,6 +1087,6 @@ rc_deptree_update(void)
}
rc_stringlist_free(config);
rc_deptree_free(deptree);
free(deptree);
return retval;
}

View File

@@ -16,11 +16,21 @@
*/
#include <fnmatch.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include "queue.h"
#include "librc.h"
#include "helpers.h"
#include "misc.h"
bool
rc_yesno(const char *value)
@@ -117,7 +127,7 @@ rc_getline(char **line, size_t *len, FILE *fp)
}
char *
rc_proc_getent(const char *ent _unused)
rc_proc_getent(const char *ent RC_UNUSED)
{
#ifdef __linux__
FILE *fp;
@@ -277,6 +287,7 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
overrides = rc_stringlist_new();
/* A list of variables which may be overridden on the kernel command line */
rc_stringlist_add(overrides, "rc_interactive");
rc_stringlist_add(overrides, "rc_parallel");
TAILQ_FOREACH(override, overrides, entries) {

View File

@@ -15,8 +15,14 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
#include "librc.h"
#include "helpers.h"
RC_STRINGLIST *
rc_stringlist_new(void)

View File

@@ -15,9 +15,26 @@
* except according to the terms contained in the LICENSE file.
*/
#include <helpers.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include "queue.h"
#include "librc.h"
#include <helpers.h>
#include "misc.h"
#include "rc.h"
#ifdef __FreeBSD__
# include <sys/sysctl.h>
#endif
@@ -232,7 +249,7 @@ detect_prefix(const char *systype)
}
static const char *
detect_container(const char *systype _unused)
detect_container(const char *systype RC_UNUSED)
{
#ifdef __FreeBSD__
if (systype) {
@@ -296,7 +313,7 @@ detect_container(const char *systype _unused)
}
static const char *
detect_vm(const char *systype _unused)
detect_vm(const char *systype RC_UNUSED)
{
#ifdef __NetBSD__
if (systype) {
@@ -755,8 +772,10 @@ rc_service_mark(const char *service, const RC_SERVICE state)
RC_SVCDIR "/%s/%s",
rc_parse_service_state(RC_SERVICE_WASINACTIVE),
base);
if (symlink(init, was) == -1)
if (symlink(init, was) == -1) {
free(init);
return false;
}
skip_wasinactive = true;
}
if (unlink(file) == -1) {

View File

@@ -25,7 +25,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>

View File

@@ -10,24 +10,18 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "helpers.h"
const char *applet = NULL;

View File

@@ -15,15 +15,14 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/param.h>
#if defined(__DragonFly__) || defined(__FreeBSD__)
# include <sys/ucred.h>
# include <sys/mount.h>
# define F_FLAGS f_flags
#elif defined(BSD) && !defined(__GNU__)
# include <sys/statvfs.h>
# define statfs statvfs
# define F_FLAGS f_flag
#elif defined(__linux__) || (defined(__FreeBSD_kernel__) && \
@@ -33,17 +32,19 @@
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <regex.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *procmounts = "/proc/mounts";

View File

@@ -27,16 +27,16 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <utmp.h>
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
#endif
#include "helpers.h"
#include "rc.h"
#include "plugin.h"
#include "wtmp.h"

View File

@@ -6,12 +6,3 @@ executable('openrc-run',
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)
executable('runscript',
['openrc-run.c', misc_c, plugin_c, selinux_c, usage_c, version_h],
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags],
link_with: [libeinfo, librc],
dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, selinux_dep, util_dep, crypt_dep],
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)

View File

@@ -15,28 +15,26 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include <stdbool.h>
#if defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) \
|| defined(__GNU__)
@@ -54,6 +52,7 @@
#include "plugin.h"
#include "selinux.h"
#include "_usage.h"
#include "helpers.h"
#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
@@ -62,7 +61,7 @@
#define WARN_TIMEOUT 10 /* warn about this every N seconds */
const char *applet = NULL;
const char *extraopts = "stop | start | restart | describe | zap";
const char *extraopts = "stop | start | restart | status | describe | zap";
const char getoptstring[] = "dDsSvl:Z" getoptstring_COMMON;
const struct option longopts[] = {
{ "debug", 0, NULL, 'd'},
@@ -108,8 +107,9 @@ static RC_STRINGLIST *deptypes_mwua; /* need+want+use+after deps for stopping */
static void
handle_signal(int sig)
{
int serrno = errno;
char *signame = NULL;
int serrno = errno, status;
pid_t pid;
const char *signame = NULL;
struct winsize ws;
switch (sig) {
@@ -118,12 +118,13 @@ handle_signal(int sig)
break;
case SIGCHLD:
if (signal_pipe[1] > -1) {
if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
eerror("%s: send: %s",
service, strerror(errno));
} else
rc_waitpid(-1);
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (signal_pipe[1] > -1 && pid == service_pid) {
if (write(signal_pipe[1], &status, sizeof(status)) == -1)
eerror("%s: send: %s",
service, strerror(errno));
}
}
break;
case SIGWINCH:
@@ -135,20 +136,19 @@ handle_signal(int sig)
case SIGINT:
if (!signame)
xasprintf(&signame, "SIGINT");
signame = "SIGINT";
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
xasprintf(&signame, "SIGTERM");
signame = "SIGTERM";
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
xasprintf(&signame, "SIGQUIT");
signame = "SIGQUIT";
/* Send the signal to our children too */
if (service_pid > 0)
kill(service_pid, sig);
eerror("%s: caught %s, aborting", applet, signame);
free(signame);
exit(EXIT_FAILURE);
/* NOTREACHED */
@@ -161,7 +161,7 @@ handle_signal(int sig)
}
static void
unhotplug()
unhotplug(void)
{
char *file = NULL;
@@ -440,6 +440,7 @@ svc_exec(const char *arg1, const char *arg2)
if (errno != EINTR) {
eerror("%s: poll: %s",
service, strerror(errno));
ret = -1;
break;
}
}
@@ -450,9 +451,20 @@ svc_exec(const char *arg1, const char *arg2)
write_prefix(buffer, bytes, &prefixed);
}
/* Only SIGCHLD signals come down this pipe */
if (fd[0].revents & (POLLIN | POLLHUP))
/* signal_pipe receives service_pid's exit status */
if (fd[0].revents & (POLLIN | POLLHUP)) {
if ((s = read(signal_pipe[0], &ret, sizeof(ret))) != sizeof(ret)) {
eerror("%s: receive failed: %s", service,
s < 0 ? strerror(errno) : "short read");
ret = -1;
break;
}
ret = WEXITSTATUS(ret);
if (ret != 0 && errno == ECHILD)
/* killall5 -9 could cause this */
ret = 0;
break;
}
}
}
@@ -475,11 +487,6 @@ svc_exec(const char *arg1, const char *arg2)
master_tty = -1;
}
ret = rc_waitpid(service_pid);
ret = WEXITSTATUS(ret);
if (ret != 0 && errno == ECHILD)
/* killall5 -9 could cause this */
ret = 0;
service_pid = 0;
return ret;
@@ -614,7 +621,7 @@ svc_start_check(void)
}
if (exclusive_fd == -1)
exclusive_fd = svc_lock(applet);
exclusive_fd = svc_lock(applet, !deps);
if (exclusive_fd == -1) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
@@ -645,7 +652,7 @@ svc_start_deps(void)
bool first;
RC_STRING *svc, *svc2;
RC_SERVICE state;
int depoptions = RC_DEP_TRACE, n;
int depoptions = RC_DEP_TRACE;
size_t len;
char *p, *tmp;
pid_t pid;
@@ -755,7 +762,6 @@ svc_start_deps(void)
rc_stringlist_free(use_services);
use_services = NULL;
len = 0;
n = 0;
TAILQ_FOREACH(svc, tmplist, entries) {
rc_service_schedule_start(svc->value, service);
use_services = rc_deptree_depend(deptree,
@@ -765,7 +771,6 @@ svc_start_deps(void)
rc_stringlist_free(use_services);
use_services = NULL;
len += strlen(svc->value) + 2;
n++;
}
len += 5;
@@ -788,7 +793,7 @@ svc_start_deps(void)
services = NULL;
}
static void svc_start_real()
static void svc_start_real(void)
{
bool started;
RC_STRING *svc, *svc2;
@@ -868,7 +873,7 @@ svc_stop_check(RC_SERVICE *state)
exit(EXIT_FAILURE);
if (exclusive_fd == -1)
exclusive_fd = svc_lock(applet);
exclusive_fd = svc_lock(applet, !deps);
if (exclusive_fd == -1) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
@@ -1045,26 +1050,6 @@ svc_stop(void)
static void
svc_restart(void)
{
/* This is hairy and a better way needs to be found I think!
* The issue is this - openvpn need net and dns. net can restart
* dns via resolvconf, so you could have openvpn trying to restart
* dnsmasq which in turn is waiting on net which in turn is waiting
* on dnsmasq.
* The work around is for resolvconf to restart its services with
* --nodeps which means just that.
* The downside is that there is a small window when our status is
* invalid.
* One workaround would be to introduce a new status,
* or status locking. */
if (!deps) {
RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
svc_exec("stop", "start");
else
svc_exec("start", NULL);
return;
}
if (!(rc_service_state(service) & RC_SERVICE_STOPPED)) {
get_started_services();
svc_stop();
@@ -1112,7 +1097,6 @@ service_plugable(void)
int main(int argc, char **argv)
{
bool doneone = false;
bool runscript = false;
int retval, opt, depoptions = RC_DEP_TRACE;
RC_STRING *svc;
char *path = NULL;
@@ -1130,8 +1114,6 @@ int main(int argc, char **argv)
}
applet = basename_c(argv[0]);
if (strcmp(applet, "runscript") == 0)
runscript = true;
if (stat(argv[1], &stbuf) != 0) {
fprintf(stderr, "openrc-run `%s': %s\n",
@@ -1165,7 +1147,6 @@ int main(int argc, char **argv)
dir = save;
} else
file = basename_c(argv[1]);
ll = strlen(dir) + strlen(file) + 2;
xasprintf(&service, "%s/%s", dir, file);
if (stat(service, &stbuf) != 0) {
free(service);
@@ -1305,9 +1286,6 @@ int main(int argc, char **argv)
applet_list = rc_stringlist_new();
rc_stringlist_add(applet_list, applet);
if (runscript)
ewarn("%s uses runscript, please convert to openrc-run.", service);
/* Now run each option */
retval = EXIT_SUCCESS;
while (optind < argc) {

View File

@@ -12,24 +12,23 @@
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <utmp.h>
#include <utmpx.h>
#include <pwd.h>
#include <fcntl.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
#include <utmpx.h>
#include "broadcast.h"
#include "helpers.h"
@@ -43,12 +42,7 @@ static sigjmp_buf jbuf;
/*
* Alarm handler
*/
/*ARGSUSED*/
# ifdef __GNUC__
static void handler(int arg __attribute__((unused)))
# else
static void handler(int arg)
# endif
RC_NORETURN static void handler(int arg RC_UNUSED)
{
siglongjmp(jbuf, 1);
}

View File

@@ -19,6 +19,7 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
@@ -26,9 +27,11 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <utmp.h>
#include "broadcast.h"
#include "einfo.h"
@@ -167,13 +170,13 @@ static void sleep_no_interrupt(int seconds)
duration = remaining;
}
static void stop_shutdown(int sig)
RC_NORETURN static void stop_shutdown(int sig)
{
(void) sig;
unlink(nologin_file);
unlink(shutdown_pid);
einfo("Shutdown canceled");
exit(0);
einfo("Shutdown cancelled");
exit(0);
}
int main(int argc, char **argv)
@@ -304,7 +307,6 @@ int main(int argc, char **argv)
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
while (shutdown_delay > 0) {
need_warning = false;
if (shutdown_delay > 180)
need_warning = (shutdown_delay % 60 == 0);
else if (shutdown_delay > 60)
@@ -313,11 +315,12 @@ int main(int argc, char **argv)
need_warning = (shutdown_delay % 15 == 0);
else
need_warning = true;
if (shutdown_delay <= 5)
create_nologin(shutdown_delay);
if (need_warning) {
xasprintf(&msg, "\rThe system will %s in %d minutes\r\n",
state, shutdown_delay);
xasprintf(&msg, "\rThe system will %s in %d minutes\r\n",
state, shutdown_delay);
broadcast(msg);
free(msg);
}

View File

@@ -17,11 +17,10 @@
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "einfo.h"
#include "sysvinit.h"

View File

@@ -6,12 +6,3 @@ executable('openrc',
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)
executable('rc',
['rc.c', 'rc-logger.c', misc_c, plugin_c, usage_c, version_h],
c_args : cc_branding_flags,
link_with: [libeinfo, librc],
dependencies: [dl_dep, util_dep],
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)

View File

@@ -16,10 +16,7 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <poll.h>
@@ -27,6 +24,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
@@ -42,9 +42,9 @@
#include "einfo.h"
#include "rc-logger.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "helpers.h"
#define TMPLOG RC_SVCDIR "/rc.log"
#define DEFAULTLOG "/var/log/rc.log"

View File

@@ -13,6 +13,9 @@
#ifndef RC_LOGGER_H
#define RC_LOGGER_H
#include <stdbool.h>
#include <sys/types.h>
extern pid_t rc_logger_pid;
extern int rc_logger_tty;
extern bool rc_in_logger;

View File

@@ -20,26 +20,21 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
@@ -49,9 +44,9 @@
#include "rc-logger.h"
#include "misc.h"
#include "plugin.h"
#include "version.h"
#include "_usage.h"
#include "helpers.h"
const char *extraopts = NULL;
const char getoptstring[] = "a:no:s:S" getoptstring_COMMON;
@@ -64,8 +59,7 @@ const struct option longopts[] = {
};
const char * const longopts_help[] = {
"do not stop any services",
"override the next runlevel to change into\n",
"when leaving single user or boot runlevels",
"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
"runs the service specified with the rest\nof the arguments",
"output the RC system type, if any",
longopts_help_COMMON
@@ -93,6 +87,7 @@ static RC_HOOK hook_out;
struct termios *termios_orig = NULL;
RC_PIDLIST service_pids;
RC_PIDLIST free_these_pids;
static void
clean_failed(void)
@@ -122,8 +117,7 @@ clean_failed(void)
static void
cleanup(void)
{
RC_PID *p1 = LIST_FIRST(&service_pids);
RC_PID *p2;
RC_PID *p, *tmp;
if (!rc_in_logger && !rc_in_plugin &&
applet && (strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0))
@@ -145,10 +139,13 @@ cleanup(void)
rc_logger_close();
}
while (p1) {
p2 = LIST_NEXT(p1, entries);
free(p1);
p1 = p2;
LIST_FOREACH_SAFE(p, &service_pids, entries, tmp) {
LIST_REMOVE(p, entries);
free(p);
}
LIST_FOREACH_SAFE(p, &free_these_pids, entries, tmp) {
LIST_REMOVE(p, entries);
free(p);
}
rc_stringlist_free(main_hotplugged_services);
@@ -350,22 +347,46 @@ static char *get_krunlevel(void)
static void
add_pid(pid_t pid)
{
sigset_t sset, old;
RC_PID *p = xmalloc(sizeof(*p));
p->pid = pid;
/* this list will be accessed inside the SIGCHLD signal handler.
* so we need to ensure that the SIGCHLD handler doesn't get invoked
* while the list is at an inconsistent state.
*/
sigemptyset(&sset);
sigaddset(&sset, SIGCHLD);
sigprocmask(SIG_SETMASK, &sset, &old);
LIST_INSERT_HEAD(&service_pids, p, entries);
sigprocmask(SIG_SETMASK, &old, NULL);
}
static void
remove_pid(pid_t pid)
remove_pid(pid_t pid, bool inside_signal)
{
RC_PID *p;
sigset_t sset, old;
RC_PID *p, *tmp;
LIST_FOREACH(p, &service_pids, entries)
if (p->pid == pid) {
LIST_REMOVE(p, entries);
free(p);
return;
}
/* same rationale for blocking SIGCHLD as add_pid() */
sigemptyset(&sset);
sigaddset(&sset, SIGCHLD);
sigprocmask(SIG_SETMASK, &sset, &old);
LIST_FOREACH(p, &service_pids, entries) {
if (p->pid == pid) {
LIST_REMOVE(p, entries);
LIST_INSERT_HEAD(&free_these_pids, p, entries);
break;
}
}
/* only call free if we're not inside a signal handler */
if (!inside_signal) {
LIST_FOREACH_SAFE(p, &free_these_pids, entries, tmp) {
LIST_REMOVE(p, entries);
free(p);
}
}
sigprocmask(SIG_SETMASK, &old, NULL);
}
static void
@@ -383,7 +404,7 @@ static void
handle_signal(int sig)
{
int serrno = errno;
char *signame = NULL;
const char *signame = NULL;
pid_t pid;
RC_PID *pi;
int status = 0;
@@ -403,7 +424,7 @@ handle_signal(int sig)
/* Remove that pid from our list */
if (pid > 0)
remove_pid(pid);
remove_pid(pid, true);
break;
case SIGWINCH:
@@ -415,15 +436,15 @@ handle_signal(int sig)
case SIGINT:
if (!signame)
xasprintf(&signame, "SIGINT");
signame = "SIGINT";
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
xasprintf(&signame, "SIGTERM");
signame = "SIGTERM";
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
xasprintf(&signame, "SIGQUIT");
signame = "SIGQUIT";
eerrorx("%s: caught %s, aborting", applet, signame);
/* NOTREACHED */
case SIGUSR1:
@@ -453,7 +474,7 @@ handle_signal(int sig)
}
static void
do_sysinit()
do_sysinit(void)
{
struct utsname uts;
const char *sys;
@@ -506,8 +527,7 @@ runlevel_config(const char *service, const char *level)
char *conf, *dir;
bool retval;
dir = dirname(init);
dir = dirname(init);
dir = dirname(dirname(init));
xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level);
retval = exists(conf);
free(conf);
@@ -613,7 +633,7 @@ stop:
add_pid(pid);
if (!parallel) {
rc_waitpid(pid);
remove_pid(pid);
remove_pid(pid, false);
}
}
}
@@ -679,7 +699,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
add_pid(pid);
if (!parallel) {
rc_waitpid(pid);
remove_pid(pid);
remove_pid(pid, false);
}
}
}
@@ -697,7 +717,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
}
#ifdef RC_DEBUG
static void
RC_NORETURN static void
handle_bad_signal(int sig)
{
char pid[10];
@@ -752,6 +772,7 @@ int main(int argc, char **argv)
applet = basename_c(argv[0]);
LIST_INIT(&service_pids);
LIST_INIT(&free_these_pids);
atexit(cleanup);
if (!applet)
eerrorx("arguments required");
@@ -816,8 +837,6 @@ int main(int argc, char **argv)
}
}
if (strcmp(applet, "rc") == 0)
ewarn("rc is deprecated, please use openrc instead.");
newlevel = argv[optind++];
/* To make life easier, we only have the shutdown runlevel as
* nothing really needs to know that we're rebooting.

View File

@@ -10,20 +10,11 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "einfo.h"

View File

@@ -15,27 +15,20 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *extraopts = NULL;

View File

@@ -15,7 +15,9 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -24,8 +26,8 @@
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *extraopts = NULL;

View File

@@ -16,17 +16,21 @@
*/
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <inttypes.h>
#include <errno.h>
#include <time.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
enum format_t {
FORMAT_DEFAULT,
@@ -61,8 +65,8 @@ const char * const longopts_help[] = {
longopts_help_COMMON
};
const char *usagestring = "" \
"Usage: rc-status [options] -f ini <runlevel>...\n" \
" or: rc-status [options] [-a | -c | -l | -m | -r | -s | -u]";
"Usage: rc-status [options] [-f ini] <runlevel>...\n" \
" or: rc-status [options] [-f ini] [-a | -c | -l | -m | -r | -s | -u]";
static RC_DEPTREE *deptree;
static RC_STRINGLIST *types;
@@ -293,6 +297,7 @@ int main(int argc, char **argv)
TAILQ_FOREACH(l, levels, entries)
printf("%s\n", l->value);
goto exit;
/* NOTREACHED */
case 'm':
services = rc_services_in_runlevel(NULL);
levels = rc_runlevel_list();
@@ -312,8 +317,9 @@ int main(int argc, char **argv)
free(s->value);
free(s);
}
print_services(NULL, services, FORMAT_DEFAULT);
print_services(NULL, services, format);
goto exit;
/* NOTREACHED */
case 'r':
runlevel = rc_runlevel_get();
printf("%s\n", runlevel);
@@ -324,12 +330,12 @@ int main(int argc, char **argv)
TAILQ_FOREACH_SAFE(s, services, entries, t)
if (!rc_service_value_get(s->value, "child_pid"))
TAILQ_REMOVE(services, s, entries);
print_services(NULL, services, FORMAT_DEFAULT);
print_services(NULL, services, format);
goto exit;
/* NOTREACHED */
case 's':
services = rc_services_in_runlevel(NULL);
print_services(NULL, services, FORMAT_DEFAULT);
print_services(NULL, services, format);
goto exit;
/* NOTREACHED */
case 'u':
@@ -344,7 +350,7 @@ int main(int argc, char **argv)
break;
}
}
print_services(NULL, services, FORMAT_DEFAULT);
print_services(NULL, services, format);
goto exit;
/* NOTREACHED */
@@ -444,6 +450,7 @@ int main(int argc, char **argv)
* be added to the list
*/
unsetenv("RC_SVCNAME");
print_level("Dynamic", "needed/wanted", format);
print_services(NULL, nservices, format);
print_level("Dynamic", "manual", format);

View File

@@ -17,7 +17,6 @@
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,6 +28,7 @@
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *extraopts = NULL;
@@ -88,7 +88,7 @@ delete(const char *runlevel, const char *service)
errno = 0;
if (rc_service_delete(runlevel, service)) {
einfo("service %s removed from runlevel %s",
einfo("service %s deleted from runlevel %s",
service, runlevel);
return 1;
}
@@ -97,7 +97,7 @@ delete(const char *runlevel, const char *service)
eerror("%s: service `%s' is not in the runlevel `%s'",
applet, service, runlevel);
else
eerror("%s: failed to remove service `%s' from runlevel `%s': %s",
eerror("%s: failed to delete service `%s' from runlevel `%s': %s",
applet, service, runlevel, strerror (errno));
return retval;
@@ -144,7 +144,7 @@ static int
delstack(const char *runlevel, const char *stack)
{
if (rc_runlevel_unstack(runlevel, stack)) {
einfo("runlevel %s removed from runlevel %s", stack, runlevel);
einfo("runlevel %s deleted from runlevel %s", stack, runlevel);
return 1;
}
@@ -152,7 +152,7 @@ delstack(const char *runlevel, const char *stack)
eerror("%s: runlevel `%s' is not in the runlevel `%s'",
applet, stack, runlevel);
else
eerror("%s: failed to remove runlevel `%s' from runlevel `%s': %s",
eerror("%s: failed to delete runlevel `%s' from runlevel `%s': %s",
applet, stack, runlevel, strerror (errno));
return -1;

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2022 The OpenRC Authors.
* Copyright (c) 2022-2023 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
*
@@ -30,12 +30,12 @@
#include <errno.h>
#include <endian.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "rc.h"
#include "einfo.h"
#include "helpers.h"
#include "_usage.h"
@@ -455,7 +455,7 @@ int main(int argc, char **argv)
static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix";
static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure";
int opt, fd, dfd, program_ret = 0;
char *seed_dir = NULL;
const char *seed_dir = NULL;
uint8_t new_seed[MAX_SEED_LEN];
size_t new_seed_len;
bool new_seed_creditable;
@@ -470,7 +470,7 @@ int main(int argc, char **argv)
switch (opt) {
case LONGOPT_SEED_DIR:
if (!seed_dir)
seed_dir = xstrdup(optarg);
seed_dir = optarg;
break;
case LONGOPT_SKIP_CREDIT:
skip_credit = true;
@@ -479,7 +479,7 @@ int main(int argc, char **argv)
}
}
if (!seed_dir)
seed_dir = xstrdup(DEFAULT_SEED_DIR);
seed_dir = DEFAULT_SEED_DIR;
if (getuid())
eerrorx("%s: superuser access is required", applet);
umask(0077);

View File

@@ -10,24 +10,16 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "helpers.h"
const char *applet = NULL;

View File

@@ -13,19 +13,13 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "version.h"
#include "helpers.h"
#if lint
# define _noreturn
#endif
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
# define _noreturn __attribute__ ((__noreturn__))
#else
# define _noreturn
#endif
void set_quiet_options(void)
{
@@ -42,7 +36,7 @@ void set_quiet_options(void)
}
}
_noreturn void show_version(void)
RC_NORETURN void show_version(void)
{
const char *systype = NULL;
@@ -57,7 +51,7 @@ _noreturn void show_version(void)
exit(EXIT_SUCCESS);
}
_noreturn void usage(int exit_status)
RC_NORETURN void usage(int exit_status)
{
const char * const has_arg[] = { "", "<arg>", "[arg]" };
int i;

View File

@@ -11,6 +11,7 @@
*/
#include <getopt.h>
#include <stdlib.h>
#define getoptstring_COMMON "ChqVv"

View File

@@ -18,29 +18,27 @@
#ifndef __HELPERS_H__
#define __HELPERS_H__
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define ERRX fprintf (stderr, "out of memory\n"); exit (1)
#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
#ifdef lint
# define _unused
#endif
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
# define _dead __attribute__((__noreturn__))
# define _unused __attribute__((__unused__))
# define _xasprintf(a, b) __attribute__((__format__(__printf__, a, b)))
#else
# define _dead
# define _unused
# define _xasprintf(a, b)
#endif
#define RC_UNUSED __attribute__((__unused__))
#define RC_NORETURN __attribute__((__noreturn__))
#define RC_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#ifdef __GLIBC__
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
#ifndef HAVE_STRLCPY
# define strlcpy(dst, src, size) snprintf(dst, size, "%s", src)
# endif
#endif
#ifndef timespecsub
@@ -55,11 +53,7 @@
} while (/* CONSTCOND */ 0)
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <sys/stat.h>
_unused static void *xmalloc (size_t size)
RC_UNUSED static void *xmalloc (size_t size)
{
void *value = malloc(size);
@@ -70,7 +64,7 @@ _unused static void *xmalloc (size_t size)
/* NOTREACHED */
}
_unused static void *xrealloc(void *ptr, size_t size)
RC_UNUSED static void *xrealloc(void *ptr, size_t size)
{
void *value = realloc(ptr, size);
@@ -81,7 +75,7 @@ _unused static void *xrealloc(void *ptr, size_t size)
/* NOTREACHED */
}
_unused static char *xstrdup(const char *str)
RC_UNUSED static char *xstrdup(const char *str)
{
char *value;
@@ -103,7 +97,7 @@ _unused static char *xstrdup(const char *str)
* basename_c never modifies the argument. As such, if there is a trailing
* slash then an empty string is returned.
*/
_unused static const char *basename_c(const char *path)
RC_UNUSED static const char *basename_c(const char *path)
{
const char *slash = strrchr(path, '/');
@@ -112,14 +106,14 @@ _unused static const char *basename_c(const char *path)
return (path);
}
_unused static bool exists(const char *pathname)
RC_UNUSED static bool exists(const char *pathname)
{
struct stat buf;
return (stat(pathname, &buf) == 0);
}
_unused static bool existss(const char *pathname)
RC_UNUSED static bool existss(const char *pathname)
{
struct stat buf;
@@ -129,12 +123,12 @@ _unused static bool existss(const char *pathname)
/*
* This is an OpenRC specific version of the asprintf() function.
* We do this to avoid defining the _GNU_SOURCE feature test macro on
* glibc systems and to insure that we have a consistent function across
* glibc systems and to ensure that we have a consistent function across
* platforms. This also allows us to call our xmalloc and xrealloc
* functions to handle memory allocation.
* this function was originally written by Mike Frysinger.
*/
_unused _xasprintf(2,3) static int xasprintf(char **strp, const char *fmt, ...)
RC_UNUSED RC_PRINTF(2,3) static int xasprintf(char **strp, const char *fmt, ...)
{
va_list ap;
int len;

View File

@@ -10,6 +10,10 @@ schedules_c = files([
'schedules.c',
])
pipes_c = files([
'pipes.c',
])
if selinux_dep.found()
selinux_c = files([
'selinux.c',

View File

@@ -15,22 +15,30 @@
* except according to the terms contained in the LICENSE file.
*/
#include <sys/file.h>
#include <sys/types.h>
#include <sys/utsname.h>
#ifdef __linux__
# include <sys/sysinfo.h>
#ifdef HAVE_CLOSE_RANGE
/* For close_range() */
# define _GNU_SOURCE
#endif
#include <sys/time.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#ifdef HAVE_LINUX_CLOSE_RANGE_H
# include <linux/close_range.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/time.h>
#ifdef __linux__
# include <sys/syscall.h> /* for close_range */
# include <sys/sysinfo.h>
#endif
#include <sys/types.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
@@ -40,6 +48,7 @@
#include "rc.h"
#include "misc.h"
#include "version.h"
#include "helpers.h"
extern char **environ;
@@ -234,7 +243,7 @@ signal_setup_restart(int sig, void (*handler)(int))
}
int
svc_lock(const char *applet)
svc_lock(const char *applet, bool ignore_lock_failure)
{
char *file = NULL;
int fd;
@@ -245,6 +254,14 @@ svc_lock(const char *applet)
if (fd == -1)
return -1;
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
if (ignore_lock_failure) {
/* Two services with a need b, and b's start()
* calling restart --no-deps on a would cause
* harmless errors: just ignore them.
* See https://github.com/OpenRC/openrc/issues/224
*/
exit(EXIT_SUCCESS);
}
eerror("Call to flock failed: %s", strerror(errno));
close(fd);
return -1;
@@ -274,7 +291,7 @@ exec_service(const char *service, const char *arg)
sigset_t old;
struct sigaction sa;
fd = svc_lock(basename_c(service));
fd = svc_lock(basename_c(service), false);
if (fd == -1)
return -1;
@@ -492,3 +509,30 @@ pid_t get_pid(const char *applet,const char *pidfile)
return pid;
}
#ifndef HAVE_CLOSE_RANGE
static inline int close_range(int first RC_UNUSED,
int last RC_UNUSED,
unsigned int flags RC_UNUSED)
{
#ifdef SYS_close_range
return syscall(SYS_close_range, first, last, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
#ifndef CLOSE_RANGE_CLOEXEC
# define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif
void
cloexec_fds_from(int first)
{
int i;
if (close_range(first, UINT_MAX, CLOSE_RANGE_CLOEXEC) < 0) {
for (i = getdtablesize() - 1; i >= first; --i)
fcntl(i, F_SETFD, FD_CLOEXEC);
}
}

View File

@@ -19,6 +19,7 @@
#define __RC_MISC_H__
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -27,6 +28,7 @@
#include <unistd.h>
#include "helpers.h"
#include "rc.h"
#define RC_LEVEL_BOOT "boot"
#define RC_LEVEL_DEFAULT "default"
@@ -48,7 +50,7 @@ void env_filter(void);
void env_config(void);
int signal_setup(int sig, void (*handler)(int));
int signal_setup_restart(int sig, void (*handler)(int));
int svc_lock(const char *);
int svc_lock(const char *, bool);
int svc_unlock(const char *, int);
pid_t exec_service(const char *, const char *);
@@ -71,4 +73,6 @@ void from_time_t(char *time_string, time_t tv);
time_t to_time_t(char *timestring);
pid_t get_pid(const char *applet, const char *pidfile);
void cloexec_fds_from(int);
#endif

View File

@@ -16,8 +16,8 @@
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include "pipes.h"

View File

@@ -17,12 +17,10 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -32,8 +30,8 @@
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "plugin.h"
#include "helpers.h"
#define RC_PLUGIN_HOOK "rc_plugin_hook"

View File

@@ -18,6 +18,11 @@
#ifndef __LIBRC_PLUGIN_H__
#define __LIBRC_PLUGIN_H__
#include <stdbool.h>
#include <sys/types.h>
#include "rc.h"
/* A simple flag to say if we're in a plugin process or not.
* Mainly used in atexit code. */
extern bool rc_in_plugin;

View File

@@ -30,16 +30,11 @@
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "schedules.h"
#include "helpers.h"

View File

@@ -13,6 +13,9 @@
#ifndef __RC_SCHEDULES_H
#define __RC_SCHEDULES_H
#include <stdbool.h>
#include <sys/types.h>
void free_schedulelist(void);
int parse_signal(const char *applet, const char *sig);
void parse_schedule(const char *applet, const char *string, int timeout);

View File

@@ -15,14 +15,12 @@
* except according to the terms contained in the LICENSE file.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <utmp.h>
#include "wtmp.h"

View File

@@ -19,6 +19,7 @@
#define __RC_WTMP_H__
#include <utmp.h>
#include <sys/types.h>
void log_wtmp(const char *user, const char *id, pid_t pid, int type,
const char *line);

View File

@@ -10,14 +10,9 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char **argv)
{

View File

@@ -1,5 +1,5 @@
executable('start-stop-daemon',
['start-stop-daemon.c', 'pipes.c', misc_c, schedules_c,
['start-stop-daemon.c', pipes_c, misc_c, schedules_c,
selinux_c, usage_c, version_h],
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
link_with: [libeinfo, librc],

View File

@@ -26,47 +26,44 @@
# define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/syscall.h> /* For io priority */
#include <sys/prctl.h> /* For prctl */
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <grp.h>
#include <pwd.h>
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef __linux__
# include <sys/syscall.h> /* For io priority */
# include <sys/prctl.h> /* For prctl */
#endif
#include <termios.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_PAM
#include <security/pam_appl.h>
# include <security/pam_appl.h>
/* We are not supporting authentication conversations */
static struct pam_conv conv = { NULL, NULL};
#endif
#ifdef HAVE_CAP
#include <sys/capability.h>
# include <sys/capability.h>
#endif
#include <sched.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
@@ -182,9 +179,9 @@ extern char **environ;
# define SYS_ioprio_set __NR_ioprio_set
#endif
#if !defined(__DragonFly__)
static inline int ioprio_set(int which _unused,
int who _unused,
int ioprio _unused)
static inline int ioprio_set(int which RC_UNUSED,
int who RC_UNUSED,
int ioprio RC_UNUSED)
{
#ifdef SYS_ioprio_set
return syscall(SYS_ioprio_set, which, who, ioprio);
@@ -207,20 +204,20 @@ handle_signal(int sig)
{
int status;
int serrno = errno;
char *signame = NULL;
const char *signame = NULL;
switch (sig) {
case SIGINT:
if (!signame)
xasprintf(&signame, "SIGINT");
signame = "SIGINT";
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
xasprintf(&signame, "SIGTERM");
signame = "SIGTERM";
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
xasprintf(&signame, "SIGQUIT");
signame = "SIGQUIT";
eerrorx("%s: caught %s, aborting", applet, signame);
/* NOTREACHED */
@@ -239,9 +236,6 @@ handle_signal(int sig)
eerror("%s: caught unknown signal %d", applet, sig);
}
/* free signame */
free(signame);
/* Restore errno */
errno = serrno;
}
@@ -354,6 +348,9 @@ int main(int argc, char **argv)
#ifdef PR_SET_NO_NEW_PRIVS
bool no_new_privs = false;
#endif
int pipefd[2];
char readbuf[1];
ssize_t ss;
applet = basename_c(argv[0]);
atexit(cleanup);
@@ -864,12 +861,17 @@ int main(int argc, char **argv)
if (background)
signal_setup(SIGCHLD, handle_signal);
/* Use a pipe to sync the parent/child processes. */
if (pipe2(pipefd, O_CLOEXEC) == -1)
eerrorx("%s: pipe2: %s", applet, strerror(errno));
if ((pid = fork()) == -1)
eerrorx("%s: fork: %s", applet, strerror(errno));
/* Child process - lets go! */
if (pid == 0) {
pid_t mypid = getpid();
close(pipefd[0]); /* Close the read end of the pipe. */
umask(numask);
#ifdef TIOCNOTTY
@@ -878,11 +880,23 @@ int main(int argc, char **argv)
devnull_fd = open("/dev/null", O_RDWR);
/* Must call setsid() before setting autogroup nicelevel
* but after opening tty_fd. */
setsid();
if (nicelevel != INT_MIN) {
if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
eerrorx("%s: setpriority %d: %s",
applet, nicelevel,
strerror(errno));
/* Open in "r+" mode to avoid creating if non-existent. */
fp = fopen("/proc/self/autogroup", "r+");
if (fp) {
fprintf(fp, "%d\n", nicelevel);
fclose(fp);
} else if (errno != ENOENT)
eerrorx("%s: autogroup nice %d: %s", applet,
nicelevel, strerror(errno));
}
if (ionicec != -1 &&
@@ -1084,8 +1098,7 @@ int main(int argc, char **argv)
|| rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO);
for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
cloexec_fds_from(3);
if (scheduler != NULL) {
int scheduler_index;
@@ -1118,7 +1131,6 @@ int main(int argc, char **argv)
eerrorx("Failed to set scheduler parameters: %s", strerror(errno));
}
setsid();
execvp(exec, argv);
#ifdef HAVE_PAM
if (changeuser != NULL && pamr == PAM_SUCCESS)
@@ -1129,6 +1141,18 @@ int main(int argc, char **argv)
}
/* Parent process */
close(pipefd[1]); /* Close the write end of the pipe. */
/* The child never writes to the pipe, so this read will block until
* the child calls exec or exits. */
while ((ss = read(pipefd[0], readbuf, 1)) == -1 && errno == EINTR);
if (ss == -1)
eerrorx("%s: failed to read from pipe: %s",
applet, strerror(errno));
close(pipefd[0]);
if (!background) {
/* As we're not backgrounding the process, wait for our pid
* to return */

View File

@@ -1,5 +1,5 @@
executable('supervise-daemon',
['supervise-daemon.c', misc_c, plugin_c, schedules_c, usage_c, version_h],
['supervise-daemon.c', pipes_c, misc_c, plugin_c, schedules_c, usage_c, version_h],
c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
link_with: [libeinfo, librc],
dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep],

View File

@@ -22,20 +22,6 @@
#define ONE_SECOND 1000000000
#define ONE_MS 1000000
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/syscall.h> /* For io priority */
#include <sys/prctl.h> /* For prctl */
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -47,7 +33,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <strings.h>
#ifdef __linux__
# include <sys/syscall.h> /* For io priority */
# include <sys/prctl.h> /* For prctl */
#endif
#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
@@ -66,6 +62,7 @@ static struct pam_conv conv = { NULL, NULL};
#include "queue.h"
#include "rc.h"
#include "misc.h"
#include "pipes.h"
#include "plugin.h"
#include "schedules.h"
#include "_usage.h"
@@ -83,6 +80,8 @@ enum {
LONGOPT_OOM_SCORE_ADJ,
LONGOPT_NO_NEW_PRIVS,
LONGOPT_SECBITS,
LONGOPT_STDERR_LOGGER,
LONGOPT_STDOUT_LOGGER,
};
const char *applet = NULL;
@@ -114,6 +113,8 @@ const struct option longopts[] = {
{ "user", 1, NULL, 'u'},
{ "stdout", 1, NULL, '1'},
{ "stderr", 1, NULL, '2'},
{ "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER},
{ "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER},
{ "reexec", 0, NULL, '3'},
longopts_COMMON
};
@@ -142,6 +143,8 @@ const char * const longopts_help[] = {
"Change the process user",
"Redirect stdout to file",
"Redirect stderr to file",
"Redirect stdout to process",
"Redirect stderr to process",
"reexec (used internally)",
longopts_help_COMMON
};
@@ -164,6 +167,8 @@ static int stdout_fd;
static int stderr_fd;
static char *redirect_stderr = NULL;
static char *redirect_stdout = NULL;
static char *stderr_process = NULL;
static char *stdout_process = NULL;
#ifdef TIOCNOTTY
static int tty_fd = -1;
#endif
@@ -191,8 +196,8 @@ extern char **environ;
# define SYS_ioprio_set __NR_ioprio_set
#endif
#if !defined(__DragonFly__)
static inline int ioprio_set(int which _unused, int who _unused,
int ioprio _unused)
static inline int ioprio_set(int which RC_UNUSED, int who RC_UNUSED,
int ioprio RC_UNUSED)
{
#ifdef SYS_ioprio_set
return syscall(SYS_ioprio_set, which, who, ioprio);
@@ -207,7 +212,7 @@ static void cleanup(void)
free(changeuser);
}
static void re_exec_supervisor(void)
RC_NORETURN static void re_exec_supervisor(void)
{
syslog(LOG_WARNING, "Re-executing for %s", svcname);
execlp("supervise-daemon", "supervise-daemon", svcname, "--reexec",
@@ -353,7 +358,7 @@ static pid_t exec_command(const char *cmd)
return pid;
}
static void child_process(char *exec, char **argv)
RC_NORETURN static void child_process(char *exec, char **argv)
{
RC_STRINGLIST *env_list;
RC_STRING *env;
@@ -391,6 +396,14 @@ static void child_process(char *exec, char **argv)
if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
eerrorx("%s: setpriority %d: %s", applet, nicelevel,
strerror(errno));
/* Open in "r+" mode to avoid creating if non-existent. */
fp = fopen("/proc/self/autogroup", "r+");
if (fp) {
fprintf(fp, "%d\n", nicelevel);
fclose(fp);
} else if (errno != ENOENT)
eerrorx("%s: autogroup nice %d: %s", applet,
nicelevel, strerror(errno));
}
if (ionicec != -1 && ioprio_set(1, getpid(), ionicec | ioniced) == -1)
@@ -545,6 +558,12 @@ static void child_process(char *exec, char **argv)
eerrorx("%s: unable to open the logfile"
" for stdout `%s': %s",
applet, redirect_stdout, strerror(errno));
} else if (stdout_process) {
stdout_fd = rc_pipe_command(stdout_process);
if (stdout_fd == -1)
eerrorx("%s: unable to open the logging process"
" for stdout `%s': %s",
applet, stdout_process, strerror(errno));
}
if (redirect_stderr) {
if ((stderr_fd = open(redirect_stderr,
@@ -553,16 +572,22 @@ static void child_process(char *exec, char **argv)
eerrorx("%s: unable to open the logfile"
" for stderr `%s': %s",
applet, redirect_stderr, strerror(errno));
} else if (stderr_process) {
stderr_fd = rc_pipe_command(stderr_process);
if (stderr_fd == -1)
eerrorx("%s: unable to open the logging process"
" for stderr `%s': %s",
applet, stderr_process, strerror(errno));
}
dup2(stdin_fd, STDIN_FILENO);
if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
if (redirect_stdout || stdout_process || rc_yesno(getenv("EINFO_QUIET")))
dup2(stdout_fd, STDOUT_FILENO);
if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
if (redirect_stderr || stderr_process || rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO);
for (i = getdtablesize() - 1; i >= 3; --i)
fcntl(i, F_SETFD, FD_CLOEXEC);
cloexec_fds_from(3);
cmdline = make_cmdline(argv);
syslog(LOG_INFO, "Child command line: %s", cmdline);
free(cmdline);
@@ -575,7 +600,7 @@ static void child_process(char *exec, char **argv)
eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
}
static void supervisor(char *exec, char **argv)
RC_NORETURN static void supervisor(char *exec, char **argv)
{
FILE *fp;
char buf[2048];
@@ -1035,6 +1060,14 @@ int main(int argc, char **argv)
reexec = true;
break;
case LONGOPT_STDOUT_LOGGER: /* --stdout-logger "command to run for stdout logging" */
stdout_process = optarg;
break;
case LONGOPT_STDERR_LOGGER: /* --stderr-logger "command to run for stderr logging" */
stderr_process = optarg;
break;
case_RC_COMMON_GETOPT
}

View File

@@ -19,22 +19,18 @@
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <unistd.h>
#include <utime.h>
#include <string.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "_usage.h"
#include "helpers.h"
#define RC_SHUTDOWNTIME RC_SVCDIR "/shutdowntime"
const char *applet = NULL;
const char *extraopts = "file";
@@ -54,7 +50,7 @@ const char *usagestring = NULL;
int main(int argc, char **argv)
{
int opt, sflag = 0, wflag = 0;
const char *file = RC_SHUTDOWNTIME;
const char *file = NULL;
struct stat sb;
struct timeval tv;
@@ -75,16 +71,16 @@ int main(int argc, char **argv)
if (optind < argc)
file = argv[optind++];
else
eerrorx("swclock: Reference file was not specified");
if (sflag) {
if (stat(file, &sb) == -1) {
opt = open(file, O_WRONLY | O_CREAT, 0644);
if (opt == -1)
eerrorx("swclock: open: %s", strerror(errno));
close(opt);
} else
if (utime(file, NULL) == -1)
eerrorx("swclock: utime: %s", strerror(errno));
int fd = open(file, O_WRONLY | O_CREAT, 0644);
if (fd == -1)
eerrorx("swclock: open: %s", strerror(errno));
if (futimens(fd, NULL) == -1)
eerrorx("swclock: futimens: %s", strerror(errno));
close(fd);
return 0;
}

View File

@@ -12,24 +12,14 @@
#define SYSLOG_NAMES
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "einfo.h"
#include "rc.h"
#include "misc.h"
#include "helpers.h"
const char *applet = NULL;

View File

@@ -1,55 +1,54 @@
Using supervise-daemon
======================
# Using supervise-daemon
Beginning with OpenRC-0.21 we have our own daemon supervisor,
supervise-daemon., which can start a daemon and restart it if it
`supervise-daemon`, which can start a daemon and restart it if it
terminates unexpectedly.
The following is a brief guide on using this capability.
* Use Default start, stop and status functions
* **Use Default start, stop and status functions**.
If you write your own start, stop and status functions in your service
script, none of this will work. You must allow OpenRC to use the default
functions.
* Daemons must not fork
Any daemon that you would like to have monitored by supervise-daemon
* **Daemons must not fork**.
Any daemon that you would like to have monitored by `supervise-daemon`
must not fork. Instead, it must stay in the foreground. If the daemon
forks, the supervisor will be unable to monitor it.
If the daemon can be configured to not fork, this should be done in the
daemon's configuration file, or by adding a command line option that
instructs it not to fork to the command_args_foreground variable shown
instructs it not to fork to the `command_args_foreground` variable shown
below.
# Health Checks
## Health checks
Health checks are a way to make sure a service monitored by
supervise-daemon stays healthy. To configure a health check for a
service, you need to write a healthcheck() function, and optionally an
unhealthy() function in the service script. Also, you will need to set
the healthcheck_timer and optionally healthcheck_delay variables.
`supervise-daemon` stays healthy. To configure a health check for a
service, you need to write a `healthcheck()` function, and optionally an
`unhealthy()` function in the service script. Also, you will need to set
the `healthcheck_timer` and optionally `healthcheck_delay` variables.
## healthcheck() function
### healthcheck() function
The healthcheck() function is run repeatedly based on the settings of
the healthcheck_* variables. This function should return zero if the
The `healthcheck()` function is run repeatedly based on the settings of
the `healthcheck_*` variables. This function should return zero if the
service is currently healthy or non-zero otherwise.
## unhealthy() function
### unhealthy() function
If the healthcheck() function returns non-zero, the unhealthy() function
If the `healthcheck()` function returns non-zero, the `unhealthy()` function
is run, then the service is restarted. Since the service will be
restarted by the supervisor, the unhealthy function should not try to
restart it; the purpose of the function is to allow any cleanup tasks
other than restarting the service to be run.
# Variable Settings
## Variable settings
The most important setting is the supervisor variable. At the top of
your service script, you should set this variable as follows:
``` sh
```sh
supervisor=supervise-daemon
```
@@ -57,29 +56,29 @@ Several other variables affect the way services behave under
supervise-daemon. They are documented on the openrc-run man page, but I
will list them here for convenience:
``` sh
```sh
command_args_foreground="arguments"
```
This should be used if the daemon you want to monitor
This should be used if the daemon you want to monitor
forks and goes to the background by default. This should be set to the
command line option that instructs the daemon to stay in the foreground.
``` sh
```sh
healthcheck_delay=seconds
```
This is the delay, in seconds, before the first health check is run.
If it is not set, we use the value of healthcheck_timer.
If it is not set, we use the value of `healthcheck_timer`.
``` sh
```sh
healthcheck_timer=seconds
```
This is the number of seconds between health checks. If it is not set,
no health checks will be run.
``` sh
```sh
respawn_delay
```
@@ -87,7 +86,7 @@ This is the number of seconds to delay before attempting to respawn a
supervised process after it dies unexpectedly.
The default is to respawn immediately.
``` sh
```sh
respawn_max=x
```
@@ -95,17 +94,17 @@ This is the maximum number of times to respawn a supervised process
during the given respawn period.
The default is 10. 0 means unlimited.
``` sh
```sh
respawn_period=seconds
```
This works in conjunction with respawn_max and respawn_delay above to
This works in conjunction with `respawn_max` and `respawn_delay` above to
decide if a process should not be respawned for some reason.
For example, if respawn period is 10 and respawn_max is 2, the process
For example, if respawn period is 10 and `respawn_max` is 2, the process
would need to die 3 times within 10 seconds to no longer be respawned.
Note that respawn_delay will delay all of this, so in the above scenario
a respawn_delay of greater than 5 will cause infinite respawns.
Note that `respawn_delay` will delay all of this, so in the above scenario
a `respawn_delay` of greater than 5 will cause infinite respawns.
By default, this is unset and respawn_max applies to the entire lifetime
By default, this is unset and `respawn_max` applies to the entire lifetime
of the service.

View File

@@ -4,10 +4,14 @@ set -e
set -u
rc_libexecdir="$1"
os="$2"
sbindir="$2"
os="$3"
sysvinit="$4"
if [ ${os} != Linux ]; then
if [ "${os}" != Linux ]; then
install -d "${DESTDIR}/${rc_libexecdir}"/init.d
fi
install -d "${DESTDIR}/${rc_libexecdir}"/tmp
install -m 644 "${MESON_BUILD_ROOT}/src/shared/version" "${DESTDIR}/${rc_libexecdir}"
if [ "${os}" = Linux ] && [ "${sysvinit}" = yes ]; then
ln -sf openrc-init "${DESTDIR}/${sbindir}"/init
fi