Compare commits

...

65 Commits
0.40.3 ... 0.42

Author SHA1 Message Date
William Hubbs
a177d15641 version 0.42 2019-08-20 13:13:30 -05:00
William Hubbs
2b4c486043 Update ChangeLog 2019-08-20 13:09:50 -05:00
William Hubbs
ed24d28163 update sysvinit support files 2019-08-20 13:08:44 -05:00
William Hubbs
1bc96141e6 fix single user mode 2019-08-19 14:55:54 -05:00
William Hubbs
c7000aeaab optimize loops for installing gettys 2019-08-15 18:40:51 -05:00
William Hubbs
5c5129b534 Remove "single" runlevel directory
Single user mode should be handled in the init process directly.
2019-08-15 18:40:51 -05:00
William Hubbs
0dabda6f6f fix sysvinit compatibility
This allows openrc to direct sysvinit to shut down the system by setting
the INIT_HALT environment variable appropriately. Also, we do not try to
communicate with sysvinit if its fifo does not exist.
2019-08-15 12:02:30 -05:00
William Hubbs
92de9a693b Add documentation for openrc-init and update the NEWS file 2019-08-02 16:29:03 -05:00
William Hubbs
a71aebcae1 init.d/agetty: provide the getty virtual service 2019-07-29 17:39:11 -05:00
William Hubbs
61596b16d2 Install gettys if the MKSYSVINIT switch is set to yes
The default is to put one getty in the "single" runlevel and 6 in the
"default" runlevel.
2019-07-29 17:38:47 -05:00
William Hubbs
104eb3420b Add the "single" runlevel 2019-07-29 16:27:14 -05:00
Chloe Kudryavtsev
70b8df3e9c clarify supervise-daemon-guide
1. The given default for respawn_max is wrong.
2. The example for respawn_period is nonsensical.

This fixes #311.
2019-07-26 12:52:52 -05:00
William Hubbs
cac41092e4 add ability for openrc-shutdown to communicate with sysvinit
This fixes #315.
2019-07-25 14:47:18 -05:00
Martin Wilke
7ddc281ab6 Fix build with Clang
This fixes #313.
2019-07-24 12:32:23 -05:00
William Hubbs
c092ff6da1 Add Sony Interactive Entertainment as an author 2019-07-22 10:46:32 -05:00
William Hubbs
54780a4582 supervise-daemon: allow --respawn-max to be zero 2019-03-29 14:09:08 -05:00
William Hubbs
44f5a72d1a remove hidden-visibility.h
I am removing this on the advice of a member of the Gentoo toolchain
team. It was explained to me that this doesn't offer any significant
benefits to OpenRC.

If anyone ffeels differently, please open a pull request reverting
this and adding an explanation of what it does and how to know which
functions to mark hidden in the future.

This fixes #301.
2019-02-26 17:47:55 -06:00
William Hubbs
0d378974bf openrc-init: fix waitpid checks
The do_openrc() function was not waiting properly for the child process
which started the runlevel to return. We need to repeatedly call
waitpid() until its return value matches the pid of the child process or
the child process does not exist.

This fixes #216.
This fixes #300.
2019-02-25 18:55:13 -06:00
William Hubbs
028da5c2e3 librc: fix potential buffer overflow in pid_is_argv
This fixes #299.
2019-02-23 17:44:07 -06:00
William Hubbs
d8dbb890aa Revert "src/librc/librc-daemon.c: fix buffer overrun in pid_is_argv"
This reverts commit 084877eb52.
The mentioned commit caused some systems to have some services reported
as crashed.

This fixes #297.
This fixes #298.
2019-02-23 16:24:55 -06:00
William Hubbs
56c006ebd6 Update ChangeLog 2019-02-22 19:03:41 -06:00
William Hubbs
067088bbff move ci scripts to their own directory
This fixes #296.
2019-02-22 18:50:13 -06:00
William Hubbs
52d4e56674 combine test directories
This fixes #295.
2019-02-22 18:08:19 -06:00
William Hubbs
6e6902c28b remove unused test ignore patterns 2019-02-22 16:27:52 -06:00
William Hubbs
084823182a remove unused test data files 2019-02-22 13:25:51 -06:00
Georgy Yakovlev
7478c104fc librc/librc-depend.c: fix NULL pointer dereference
In some cases deptree or depinfo can be NULL, check
before dereferencing.

Fixes https://github.com/OpenRC/openrc/issues/293
Fixes https://github.com/OpenRC/openrc/pulls/294
X-Gentoo-Bug: 659906
X-Gentoo-Bug-URL: https://bugs.gentoo.org/659906
2019-02-21 17:49:54 -06:00
Georgy Yakovlev
065b7ecc0d use cirrus-ci for FreeBSD builds
This fixes #265.
2019-02-19 13:59:01 -06:00
Sergei Trofimovich
b054aca50b src/test/runtests.sh: drop 'readelf'-based tests
The 'readelf'-based tests cover a few situations:
1. undefined symbols in shared libraries
2. unexpected exports in shared libraries

Bug #575958 shows that [2.] implementation is too simplistic
in assuming that presence of relocation equals to export presence.

It is incorrect for PLT stubs and local symbols.
Let's just drop these tests.

If one needs to cover [1.] it is better to use LDFLAGS=-Wl,--no-undefined.

This closes #292.

X-Reported-by: Benda Xu
X-Gentoo-Bug: https://bugs.gentoo.org/575958
X-Gentoo-Bug-URL: https://bugs.gentoo.org/575958
2019-02-19 11:50:11 -06:00
William Hubbs
f9e7a00ba9 rc-status: style fixes 2019-02-15 20:36:46 -06:00
William Hubbs
f1f48011ac update ChangeLog 2019-02-15 14:37:57 -06:00
William Hubbs
427a1ce299 rc-status: add -f option to allow formatting output
The -f option can be used when showing the status of services in
runlevels to allow making the output more easily parsable.
Currently, the .ini format is the only one supported.
2019-02-15 14:21:43 -06:00
William Hubbs
f43cec34ca rc-status.c: small style changes 2019-02-14 13:14:31 -06:00
William Hubbs
d64c9d2050 add experimental support for an alternate shell for service scripts
This is for #288.
2019-02-13 18:22:25 -06:00
Edan Bedrik
b2b2c57a38 librc: fix realpath() return value check
This fixes #226.
2019-02-12 17:56:17 -06:00
William Hubbs
155b845194 improve shutdown documentation
This fixes #290.
2019-02-12 16:54:12 -06:00
Austin English
9b578808fb travis: try enabling musl-gcc
This fixes #261.
2019-02-11 13:56:55 -06:00
Austin English
03164dd38d fix build with muslc
This fixes #261.
2019-02-11 13:56:33 -06:00
Austin English
2b82766452 test/skel.runtests.sh: remove unused file
git grep shows no usage, and `make test` passes

This fixes #256.
2019-02-11 11:54:10 -06:00
Felix Neumärker
3eef6e9127 zsh-completion: _rc-service support extra actions
- use rc-service <service> describe to get action list

This is for #285.
2019-01-21 17:41:59 -06:00
Felix Neumärker
77f09900a2 zsh-completion: _rc-service fix flag/command combinations
- handle `rc-service -<flag> <service> <action>` correctly

This is for #285.
2019-01-21 17:41:38 -06:00
Kim Jahn
50d77a4e5d man/openrc.8: add openrc-run.8 to see also
This fixes #283.
2019-01-18 13:40:06 -06:00
Mike Frysinger
2d31b0a3f8 man: supervise-daemon: fix various style issues
The .Dt header is supposed to be all caps.  This was mixing case.

The options block was being incorrectly indented due to a missing .El.

Some of the new options were missing the .It block, so add that.

Finally, the -D option was missing capitalization.
2019-01-01 18:36:40 -05:00
William Hubbs
b84d0bac4d travis-ci: add IRC notifications 2018-12-29 11:37:06 -06:00
William Hubbs
1ff3a37c60 start-stop-daemon: fix compiler warning 2018-12-28 09:31:38 -06:00
William Hubbs
7e95d924c9 bash-completions/rc-service: allow tab to be used again
X-Gentoo-Bug: 670290
X-Gentoo-Bug-URL: https://bugs.gentoo.org/670290
2018-12-27 16:31:15 -06:00
a15b532a02 scripts: fix halt, poweroff and reboot wrappers
These are designed to emulate the sysvinit equivalents, so pass "now" as
the time argument if no arguments are given.

This fixes #268.
2018-12-27 13:52:16 -06:00
philhofer
3e00fbc9b0 fix leading whitespace
Clean up code indented with mixed tabs and spaces.
No actual code changes.

This fixes #280.
2018-12-27 13:13:09 -06:00
philhofer
846e460075 fix potential out-of-bounds reads
readlink(3) does not nul-terminate the result it sticks
into the supplied buffer. Consequently, the code

  rc = readlink(path, buf, sizeof(buf));

does not necessarily produce a C string.

The code in rc_find_pid() produces some C strings this way
and passes them to strlen() and strcmp(), which can lead
to an out-of-bounds read.

In this case, since the code already takes care to
zero-initialize the buffers before passing them
to readlink(3), only allow sizeof(buf)-1 bytes to
be returned.

(While fixing this issue, I fixed two other locations that
used the same problematic pattern.)

This fixes #270.
2018-12-27 11:28:27 -06:00
William Hubbs
a32b14bbb4 Do not use UT_LINESIZE or __UT_LINESIZE
These are not standard.
For more information see issue #279.
This fixes #279.
2018-12-25 12:13:23 -06:00
philhofer
084877eb52 src/librc/librc-daemon.c: fix buffer overrun in pid_is_argv
The contents of /proc/<pid>/cmdline are read into
a stack buffer using

  bytes = read(fd, buffer, sizeof(buffer));

followed by appending a null terminator to the buffer with

  buffer[bytes] = '\0';

If bytes == sizeof(buffer), then this write is out-of-bounds.

Refactor the code to use rc_getfile instead, since PATH_MAX
is not the maximum size of /proc/<pid>/cmdline. (I hit this
issue in practice while compiling Linux; it tripped the
stack-smashing protector.)

This is roughly the same buffer overflow condition
that was fixed by commit 0ddee9b7d2
This fixes #269.
2018-12-24 11:55:48 -06:00
philhofer
97e74f9734 src/rc/supervise-daemon.c: formatting fixes
Fix misleading indentation and other erroneous whitespace.
This fixes #273.
2018-12-24 10:36:12 -06:00
William Hubbs
d328de198d remove /run migration script again
This time it was done correctly.
I missed a '\' the last time.
2018-12-23 21:04:00 -06:00
philhofer
a9fc26ac13 src/rc/supervise-daemon.c: do not pass NULL to strcmp
The following will cause a segfault due to NULL being
passed to strcmp(3)

$ RC_SVCNAME=foo supervise-daemon

Fix the bounds check on argc in main. If argc<=1, then
it is not safe to dereference argv[1].
2018-12-23 21:01:39 -05:00
philhofer
40f7046696 src/rc/openrc-run.c: remove duplicate statement
The statement

  ll = strlen(applet);

appears twice in the same block without any
intervening assignment to the variables
'll' or 'applet'

Remove the second (duplicate) statement.
2018-12-23 20:27:06 -05:00
William Hubbs
894995176e Revert "remove /run migration script"
For some reason removing this broke the build.

This reverts commit 5246ea7b6f.
2018-12-23 18:13:06 -06:00
William Hubbs
5246ea7b6f remove /run migration script
We have used /run for some time now and we have had this migration
script for 6 years. Linux users should have upgraded by now to a version
of OpenRC which stores its information in /run.
2018-12-23 17:49:34 -06:00
William Hubbs
ed8b768c4a fix compiler warnings 2018-12-21 12:06:15 -06:00
William Hubbs
825caa14de supervise-daemon: do not use the exec_service() function
In order to run healthcheck() and the unhealthy() function, add an
exec_command call to the supervisor.
Another difference is This function also logs errors instead of
attempting to display them.

This is for #271.
2018-12-20 17:39:31 -06:00
William Hubbs
d5c396cbfc Add debug logging to start-stop-daemon and rc-supervisor
This will make it easier to track down why the supervisor intermittently
hangs after it runs for a long time.
2018-12-18 11:29:26 -06:00
William Hubbs
5427783fdf standardize the default shell
I do not know of a need to have the default shell be a build-time
configurable setting. All *nix systems I am aware of have /bin/sh as a
default posix compatible shell.
If some systems running OpenRC do not make that assumption about
/bin/sh, I will consider bringing this back, so feel free to open an
issue.
2018-12-08 12:06:26 -06:00
William Hubbs
d95425b08a rc-cgroup.sh: remove shebang line
This is not a stand-alone script, so it does not need the shebang line.
This also means it is not necessary to run this through sed.
2018-12-07 15:31:13 -06:00
William Hubbs
76420d9849 init.d/agetty: set default respawn period to 60 seconds
Without a respawn period setting, the supervisor will give up on
respawning agetty after it is respawned respawn_max times. For most
daemons giving up like this is reasonable, but not for agettys. Agettys
should always be respawned unless they are respawning too fafst,.

If an agetty is respawning faster than 10 times in 60 seconds, this
seems to be too fast.
2018-12-06 16:37:40 -06:00
William Hubbs
bebc604438 supervise-daemon: fix busy loop
This fixes #264.
2018-12-06 16:22:15 -06:00
Alexander Zubkov
9dae4f2e38 supervise-daemon: redirect std{in,out,err} to /dev/null after demonizing
This fixes #239.
2018-12-04 16:53:39 -06:00
William Hubbs
d126542dc6 version 0.41 2018-12-03 18:14:34 -06:00
76 changed files with 1398 additions and 1740 deletions

15
.cirrus.yml Normal file
View File

@@ -0,0 +1,15 @@
# Cirrus CI integration
# https://cirrus-ci.org
test_task:
freebsd_instance:
matrix:
image: freebsd-12-0-release-amd64
image: freebsd-11-2-release-amd64
env:
OS: FreeBSD
procfs_script: >
[ -f /proc/curproc ] || mount -t procfs proc /proc
pkg_install_script: pkg install -y bash gawk gmake gsed
gsed_hack_script: rm /usr/bin/sed && ln -s /usr/local/bin/gsed /usr/bin/sed
test_script: bash ci/cirrus.sh

View File

@@ -9,6 +9,20 @@ os:
compiler:
- gcc
- clang
- musl-gcc
addons:
apt:
packages:
- musl-tools
notifications:
irc:
channels:
- "irc.freenode.org#openrc"
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
script:
- ./test/travis.sh
- ./ci/travis.sh

View File

@@ -82,6 +82,7 @@ Semen Maryasin <marsoft@ya.ru>
Sergei Trofimovich <slyfox@gentoo.org>
Seth Robertson <in-gentoo@baka.org>
S. Gilles <sgilles@umd.edu>
Sony Interactive Entertainment, llc.
Stefan Knoblich <s.knoblich@axsentis.de>
Stef Simoens <stef.simoens@scarlet.be>
Steve L <slong@rathaus.eclipse.co.uk>

1660
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,9 @@ ifeq (${MKZSHCOMP},yes)
SUBDIR+= zsh-completion
endif
# We need to ensure that runlevels is done last
# We need to ensure that runlevels is done last other than test
SUBDIR+= runlevels
SUBDIR+= test
INSTALLAFTER= _installafter

View File

@@ -1,3 +1,3 @@
NAME= openrc
VERSION= 0.40
VERSION= 0.42
PKG= ${NAME}-${VERSION}

19
NEWS.md
View File

@@ -4,6 +4,25 @@ 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.42
openrc-shutdown now has the ability to shut down sysvinit-based systems.
A guide has been added for migrating systems using another init system
to openrc-init.
## OpenRC 0.41.
This version adds the ability to format the output of rc-status when
showing the status of services in a runlevel so that it may be parsed.
Currently, the -f switch only accepts ini as an argument which
causes the output to be in the .ini format.
This version adds an experimental build time switch to allow setting the
default shell to use for service scripts.
By default, this is set to /bin/sh if it is changed, the new shell must
be able to understand posix-compatible syntax.
## OpenRC 0.40
In this version, the keymaps and termencoding services on Linux needed

View File

@@ -38,6 +38,7 @@ PKG_PREFIX=/usr/pkg
LOCAL_PREFIX=/usr/local
PREFIX=/usr/local
BRANDING=\"Gentoo/$(uname -s)\"
SH=/bin/sh
```
## Notes

View File

@@ -91,11 +91,14 @@ _rc_service()
done))
return 0
elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function
filename=$(rc-service --resolve ${prev})
opts=$(cat ${filename} | grep "^\w*()" | sed "s/().*$//") # Greps the functions included in the init script
if [[ "x${opts}" == "x" ]] ; then # if no options found loosen the grep algorhythm
opts=$(cat ${filename} | grep "\w*()" | sed "s/().*$//")
fi
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

21
ci/cirrus.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
# Copyright (c) 2007-2018 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
#
# This file is part of OpenRC. It is subject to the license terms in
# the LICENSE file found in the top-level directory of this
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
# This file may not be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
set -e
set -u
set -x
# These are steps to run on Cirrus CI under a jailed FreeBSD system.
# See $TOP/.cirrus.yml for more info about the Cirrus CI setup.
cpus=$(getconf NPROCESSORS_CONF || echo 1)
gmake -j"${cpus}" -O
gmake test

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

50
init-guide.md Normal file
View File

@@ -0,0 +1,50 @@
# OpenRC init process guide
OpenRC now includes an init process which can be used on Linux systems
in place of sysvinit.
## migrating a live system to openrc-init
Configuring a live system to use this init process is very
straight-forward, but the steps must be completed in this order.
* have your boot loader add "init=/sbin/openrc-init" to the kernel command line
The details of how to do this will vary from distro to distro, so they are
out of scope for this document.
* Install gettys into the runlevels where you need them.
If you are using the provided /etc/init.d/agetty script,, you should
first create symlinks in /etc/init.d to it for the ports where you
want gettys to run, e.g. the following will work if you want gettys on
tty1-tty6.
```
# cd /etc/init.d
# for x in tty1 tty2 tty3 tty4 tty5 tty6; do
ln -snf agetty agetty.$x
done
```
Once this is done, use ```rc-update``` as normal to install the agetty
services in the appropriate runlevels.
* Reboot your system.
At this point you are running under openrc-init, and you should use
openrc-shutdown to handle shutting down, powering off, rebooting etc.
## optional sysvinit compatibility
If you build and install OpenRC with MKSYSVINIT=yes, you will build and install
wrappers that make openrc-init compatible with sysvinit -- you will have
commands like "halt" "shutdown" "reboot" and "poweroff".
If you want this functionality on a live system, you should first
migrate the system to openrc-init, remove sysvinit, then rebuild and
install this package with MKSYSVINIT=yes.
package.
migrating your system to openrc-init.

View File

@@ -12,6 +12,7 @@
description="start agetty on a terminal line"
supervisor=supervise-daemon
port="${RC_SVCNAME#*.}"
respawn_period="${respawn_period:-60}"
term_type="${term_type:-linux}"
command=/sbin/agetty
command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
@@ -20,6 +21,7 @@ pidfile="/run/${RC_SVCNAME}.pid"
depend() {
after local
keyword -prefix
provide getty
}
start_pre() {

View File

@@ -17,15 +17,35 @@
.Sh SYNOPSIS
.Nm
.Op Fl c , -cancel
.Nm
.Op Fl R , -reexec
.Nm
.Op Fl w , -write-only
.Nm
.Op Fl d , -no-write
.Op Fl D , -dry-run
.Op Fl H , -halt
time
.Nm
.Op Fl d , -no-write
.Op Fl D , -dry-run
.Op Fl k , -kexec
time
.Nm
.Op Fl d , -no-write
.Op Fl D , -dry-run
.Op Fl p , -poweroff
.Op Fl R , -reexec
time
.Nm
.Op Fl d , -no-write
.Op Fl D , -dry-run
.Op Fl r , -reboot
time
.Nm
.Op Fl d , -no-write
.Op Fl D , -dry-run
.Op Fl s , -single
.Op Fl w , -write-only
time
.Sh DESCRIPTION
.Nm
is the utility that communicates with
@@ -56,7 +76,7 @@ Stop all services, kill all processes and reboot the system.
.It Fl s , -single
Stop all services, kill all processes and move to single user mode.
.It Fl w , -write-only
Stop all services, kill all processes and move to single user mode.
Wrrite a wtmp shutdown record and do nothing else.
.El
.Sh SEE ALSO
.Xr openrc-init 8 ,

View File

@@ -66,6 +66,7 @@ and
.Xr shutdown 8
and let them call these special runlevels.
.Sh SEE ALSO
.Xr openrc-run 8 ,
.Xr rc-status 8 ,
.Xr rc-update 8 ,
.Xr init 8 ,

View File

@@ -17,6 +17,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl aclsuC
.Op Fl f Ar ini
.Op Ar runlevel
.Sh DESCRIPTION
.Nm
@@ -37,6 +38,9 @@ The options are as follows:
Show all runlevels and their services.
.It Fl c , -crashed
List all services that have crashed.
.It Fl f , -format
Select a format for the output. Currently, the only one that can be
specified is ini, which outputs in *.ini format.
.It Fl l , -list
List all defined runlevels.
.It Fl m , -manual

View File

@@ -9,7 +9,7 @@
.\" except according to the terms contained in the LICENSE file.
.\"
.Dd April 27, 2016
.Dt supervise-DAEMON 8 SMM
.Dt SUPERVISE-DAEMON 8 SMM
.Os OpenRC
.Sh NAME
.Nm supervise-daemon
@@ -88,16 +88,17 @@ owned by the user. You can optionally append a
name here also.
.It Fl v , -verbose
Print the action(s) that are taken just before doing them.
.El
.Pp
The options are as follows:
.Bl -tag -width indent
.Fl a , -healthcheck-timer Ar seconds
.It Fl a , -healthcheck-timer Ar seconds
Run the healthcheck() command, possibly followed by the unhealthy()
command every time this number of seconds passes.
.Fl A , -healthcheck-delay Ar seconds
.It Fl A , -healthcheck-delay Ar seconds
Wait this long before the first health check.
.It Fl D , -respawn-delay Ar seconds
wait this number of seconds before restarting a daemon after it crashes.
Wait this number of seconds before restarting a daemon after it crashes.
The default is 0.
.It Fl d , -chdir Ar path
chdir to this directory before starting the daemon.

View File

@@ -11,7 +11,7 @@
SFX= .Linux.in
PKG_PREFIX?= /usr
CPPFLAGS+= -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L
CPPFLAGS+= -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE -D_XOPEN_SOURCE
LIBDL= -Wl,-Bdynamic -ldl
ifeq (${MKSELINUX},yes)

View File

@@ -19,7 +19,7 @@ _PKG_SED:= $(shell ${_PKG_SED_SH})
_LCL_SED_SH= if test "${PREFIX}" = "${LOCAL_PREFIX}"; then echo "-e 's:@LOCAL_PREFIX@::g'"; else echo "-e 's:@LOCAL_PREFIX@:${LOCAL_PREFIX}:g'"; fi
_LCL_SED:= $(shell ${_LCL_SED_SH})
SED_REPLACE= -e 's:@SHELL@:${SH}:g' -e 's:@LIB@:${LIBNAME}:g' -e 's:@SYSCONFDIR@:${SYSCONFDIR}:g' -e 's:@LIBEXECDIR@:${LIBEXECDIR}:g' -e 's:@PREFIX@:${PREFIX}:g' -e 's:@BINDIR@:${BINDIR}:g' -e 's:@SBINDIR@:${SBINDIR}:g' ${_PKG_SED} ${_LCL_SED}
SED_REPLACE= -e 's:@SHELL@:${SH}:' -e 's:@LIB@:${LIBNAME}:g' -e 's:@SYSCONFDIR@:${SYSCONFDIR}:g' -e 's:@LIBEXECDIR@:${LIBEXECDIR}:g' -e 's:@PREFIX@:${PREFIX}:g' -e 's:@BINDIR@:${BINDIR}:g' -e 's:@SBINDIR@:${SBINDIR}:g' ${_PKG_SED} ${_LCL_SED}
# Tweak our shell scripts
%.sh: %.sh.in
@@ -53,7 +53,6 @@ realinstall: ${BIN} ${CONF} ${INC}
install: all realinstall ${INSTALLAFTER}
check test::
@if test -e runtests.sh ; then ./runtests.sh || exit $$? ; fi
# A lot of scripts don't have anything to clean
# Also, some rm implentation require a file argument regardless of error

View File

@@ -90,6 +90,12 @@ install:
fi; \
ln -snf ${INITDIR}/"$$x" ${SHUTDOWNDIR}/"$$x" || exit $$?; done \
fi
if test "${MKSYSVINIT}" = yes && test "${OS}" = Linux; then \
for x in tty1 tty2 tty3 tty4 tty5 tty6; do \
ln -snf ${INITDIR}/agetty ${DESTDIR}/${INITDIR}/"agetty.$$x" || exit $$?; \
ln -snf ${INITDIR}/agetty.$$x ${DEFAULTDIR}/"agetty.$$x" || exit $$?; \
done; \
fi
check test::

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
option_arg=
poweroff_arg=
@@ -21,4 +21,9 @@ if [ -z "${poweroff_arg}" ]; then
poweroff_arg=--poweroff
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "$@"
script_args="$@"
if [ -z "${script_args}" ]; then
script_args=now
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "${script_args}"

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
option_arg=
poweroff_arg=
@@ -20,4 +20,9 @@ if [ -z "${poweroff_arg}" ]; then
poweroff_arg=--poweroff
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "$@"
script_args="$@"
if [ -z "${script_args}" ]; then
script_args=now
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "${script_args}"

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
option_arg=
poweroff_arg=
@@ -22,4 +22,9 @@ if [ -z "${poweroff_arg}" ]; then
poweroff_arg=--reboot
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "$@"
script_args="$@"
if [ -z "${script_args}" ]; then
script_args=now
fi
exec @SBINDIR@/openrc-shutdown ${option_arg} ${poweroff_arg} "${script_args}"

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
shutdown_arg=
while getopts :akrhPHfFnct: opt; do

2
sh/.gitignore vendored
View File

@@ -4,6 +4,4 @@ openrc-run.sh
cgroup-release-agent.sh
init.sh
init-early.sh
rc-cgroup.sh
migrate-to-run.sh
binfmt.sh

View File

@@ -2,7 +2,7 @@ DIR= ${LIBEXECDIR}/sh
SRCS= init.sh.in functions.sh.in gendepends.sh.in \
openrc-run.sh.in ${SRCS-${OS}}
INC= rc-mount.sh functions.sh rc-functions.sh runit.sh s6.sh \
start-stop-daemon.sh supervise-daemon.sh
start-stop-daemon.sh supervise-daemon.sh ${INC-${OS}}
BIN= gendepends.sh init.sh openrc-run.sh ${BIN-${OS}}
INSTALLAFTER= _installafter
@@ -13,10 +13,9 @@ include ${MK}/os.mk
SRCS-FreeBSD=
BIN-FreeBSD=
SRCS-Linux= binfmt.sh.in cgroup-release-agent.sh.in init-early.sh.in \
migrate-to-run.sh.in rc-cgroup.sh.in
BIN-Linux= binfmt.sh cgroup-release-agent.sh init-early.sh migrate-to-run.sh \
rc-cgroup.sh
SRCS-Linux= binfmt.sh.in cgroup-release-agent.sh.in init-early.sh.in
BIN-Linux= binfmt.sh cgroup-release-agent.sh init-early.sh
INC-Linux= rc-cgroup.sh
SRCS-NetBSD=
BIN-NetBSD=
@@ -32,4 +31,3 @@ _installafter:
ln -snf ${LIBEXECDIR}/sh/functions.sh ${DESTDIR}/${INITDIR} || exit $$?
check test::
./runtests.sh

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# This is a reimplementation of the systemd binfmt.d code to register
# misc binary formats with the kernel.
#

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# This is run by the kernel after the last task is removed from a
# control group in the openrc hierarchy.

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 2007-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,4 +1,4 @@
#!@SHELL@
#!/bin/sh
# Copyright (c) 1999-2007 Gentoo Foundation
# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
# Released under the 2-clause BSD license.

View File

@@ -1,36 +0,0 @@
#!@SHELL@
# Copyright (c) 2012-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
#
# This file is part of OpenRC. It is subject to the license terms in
# the LICENSE file found in the top-level directory of this
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
# This file may not be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
. "@LIBEXECDIR@/sh/functions.sh"
if [ -e /run/openrc/softlevel ]; then
einfo "The OpenRC dependency data has already been migrated."
exit 0
fi
if [ ! -d /run ]; then
eerror "/run is not a directory."
eerror "moving /run to /run.pre-openrc"
mv /run /run.pre-openrc
mkdir /run
fi
rm -rf /run/openrc
if ! mountinfo -q -f tmpfs /run; then
ln -s "@LIBEXECDIR@"/init.d /run/openrc
else
cp -a "@LIBEXECDIR@/init.d" /run/openrc
rc-update -u
fi
einfo "The OpenRC dependency data was migrated successfully."
exit 0

View File

@@ -1,4 +1,3 @@
#!@SHELL@
# Copyright (c) 2012-2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS

View File

@@ -1,7 +1,7 @@
# Copyright (c) 2007-2008 Roy Marples <roy@marples.name>
# Released under the 2-clause BSD license.
SUBDIR= test libeinfo librc rc
SUBDIR= libeinfo librc rc
MK= ../mk
include ${MK}/subdir.mk

View File

@@ -1,26 +0,0 @@
/*
* Written by Mike Frysinger
* Placed in the Public Domain
*/
#ifndef _HIDDEN_VISIBILITY_H_
#define _HIDDEN_VISIBILITY_H_
#if defined(__ELF__) && defined(__GNUC__)
# define __hidden_asmname(name) __hidden_asmname1 (__USER_LABEL_PREFIX__, name)
# define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name)
# define __hidden_asmname2(prefix, name) #prefix name
# define __hidden_proto(name, internal) \
extern __typeof (name) name __asm__ (__hidden_asmname (#internal)) \
__attribute__ ((visibility ("hidden")));
# define __hidden_ver(local, internal, name) \
extern __typeof (name) __EI_##name __asm__(__hidden_asmname (#internal)); \
extern __typeof (name) __EI_##name __attribute__((alias (__hidden_asmname1 (,#local))))
# define hidden_proto(name) __hidden_proto(name, __RC_##name)
# define hidden_def(name) __hidden_ver(__RC_##name, name, name);
#else
# define hidden_proto(name)
# define hidden_def(name)
#endif
#endif

View File

@@ -15,7 +15,7 @@
* except according to the terms contained in the LICENSE file.
*/
const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
static const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -39,34 +39,6 @@ const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include "einfo.h"
#include "helpers.h"
#include "hidden-visibility.h"
hidden_proto(ecolor)
hidden_proto(ebegin)
hidden_proto(ebeginv)
hidden_proto(ebracket)
hidden_proto(eend)
hidden_proto(eendv)
hidden_proto(eerror)
hidden_proto(eerrorn)
hidden_proto(eerrorx)
hidden_proto(eindent)
hidden_proto(eindentv)
hidden_proto(einfo)
hidden_proto(einfon)
hidden_proto(einfov)
hidden_proto(einfovn)
hidden_proto(elog)
hidden_proto(eoutdent)
hidden_proto(eoutdentv)
hidden_proto(eprefix)
hidden_proto(ewarn)
hidden_proto(ewarnn)
hidden_proto(ewarnv)
hidden_proto(ewarnvn)
hidden_proto(ewarnx)
hidden_proto(ewend)
hidden_proto(ewendv)
/* Incase we cannot work out how many columns from ioctl, supply a default */
#define DEFAULT_COLS 80
@@ -510,7 +482,6 @@ eprefix(const char *EINFO_RESTRICT prefix)
{
_eprefix = prefix;
}
hidden_def(eprefix)
static void EINFO_PRINTF(2, 0)
elogv(int level, const char *EINFO_RESTRICT fmt, va_list ap)
@@ -537,7 +508,6 @@ elog(int level, const char *EINFO_RESTRICT fmt, ...)
elogv(level, fmt, ap);
va_end(ap);
}
hidden_def(elog)
static int
_eindent(FILE * EINFO_RESTRICT stream)
@@ -576,7 +546,6 @@ _ecolor(FILE * EINFO_RESTRICT f, ECOLOR color)
return ecolors_str[i];
return "";
}
hidden_def(ecolor)
const char *
ecolor(ECOLOR color)
@@ -643,7 +612,6 @@ einfon(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("einfon");
return retval;
}
hidden_def(einfon)
int
ewarnn(const char *EINFO_RESTRICT fmt, ...)
@@ -659,7 +627,6 @@ ewarnn(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewarnn");
return retval;
}
hidden_def(ewarnn)
int
eerrorn(const char *EINFO_RESTRICT fmt, ...)
@@ -675,7 +642,6 @@ eerrorn(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("errorn");
return retval;
}
hidden_def(eerrorn)
int
einfo(const char *EINFO_RESTRICT fmt, ...)
@@ -692,7 +658,6 @@ einfo(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("einfo");
return retval;
}
hidden_def(einfo)
int
ewarn(const char *EINFO_RESTRICT fmt, ...)
@@ -710,7 +675,6 @@ ewarn(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewarn");
return retval;
}
hidden_def(ewarn)
void
ewarnx(const char *EINFO_RESTRICT fmt, ...)
@@ -727,7 +691,6 @@ ewarnx(const char *EINFO_RESTRICT fmt, ...)
}
exit(EXIT_FAILURE);
}
hidden_def(ewarnx)
int
eerror(const char *EINFO_RESTRICT fmt, ...)
@@ -745,7 +708,6 @@ eerror(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("eerror");
return retval;
}
hidden_def(eerror)
void
eerrorx(const char *EINFO_RESTRICT fmt, ...)
@@ -761,7 +723,6 @@ eerrorx(const char *EINFO_RESTRICT fmt, ...)
}
exit(EXIT_FAILURE);
}
hidden_def(eerrorx)
int
ebegin(const char *EINFO_RESTRICT fmt, ...)
@@ -780,7 +741,6 @@ ebegin(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ebegin");
return retval;
}
hidden_def(ebegin)
static void
_eend(FILE * EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg)
@@ -854,7 +814,6 @@ eend(int retval, const char *EINFO_RESTRICT fmt, ...)
LASTCMD("eend");
return retval;
}
hidden_def(eend)
int
ewend(int retval, const char *EINFO_RESTRICT fmt, ...)
@@ -869,14 +828,12 @@ ewend(int retval, const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewend");
return retval;
}
hidden_def(ewend)
void
ebracket(int col, ECOLOR color, const char *msg)
{
_eend(stdout, col, color, msg);
}
hidden_def(ebracket)
void
eindent(void)
@@ -898,7 +855,6 @@ eindent(void)
setenv("EINFO_INDENT", num, 1);
free(num);
}
hidden_def(eindent)
void eoutdent(void)
{
@@ -924,7 +880,6 @@ void eoutdent(void)
}
errno = serrno;
}
hidden_def(eoutdent)
int
einfovn(const char *EINFO_RESTRICT fmt, ...)
@@ -940,7 +895,6 @@ einfovn(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("einfovn");
return retval;
}
hidden_def(einfovn)
int
ewarnvn(const char *EINFO_RESTRICT fmt, ...)
@@ -956,7 +910,6 @@ ewarnvn(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewarnvn");
return retval;
}
hidden_def(ewarnvn)
int
einfov(const char *EINFO_RESTRICT fmt, ...)
@@ -973,7 +926,6 @@ einfov(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("einfov");
return retval;
}
hidden_def(einfov)
int
ewarnv(const char *EINFO_RESTRICT fmt, ...)
@@ -990,7 +942,6 @@ ewarnv(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewarnv");
return retval;
}
hidden_def(ewarnv)
int
ebeginv(const char *EINFO_RESTRICT fmt, ...)
@@ -1010,7 +961,6 @@ ebeginv(const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ebeginv");
return retval;
}
hidden_def(ebeginv)
int
eendv(int retval, const char *EINFO_RESTRICT fmt, ...)
@@ -1025,7 +975,6 @@ eendv(int retval, const char *EINFO_RESTRICT fmt, ...)
LASTCMD("eendv");
return retval;
}
hidden_def(eendv)
int
ewendv(int retval, const char *EINFO_RESTRICT fmt, ...)
@@ -1040,7 +989,6 @@ ewendv(int retval, const char *EINFO_RESTRICT fmt, ...)
LASTCMD("ewendv");
return retval;
}
hidden_def(ewendv)
void
eindentv(void)
@@ -1048,7 +996,6 @@ eindentv(void)
if (is_verbose())
eindent();
}
hidden_def(eindentv)
void
eoutdentv(void)
@@ -1056,4 +1003,3 @@ eoutdentv(void)
if (is_verbose())
eoutdent();
}
hidden_def(eoutdentv)

View File

@@ -59,7 +59,7 @@ pid_is_argv(pid_t pid, const char *const *argv)
free(cmdline);
return false;
}
bytes = read(fd, buffer, sizeof(buffer));
bytes = read(fd, buffer, sizeof(buffer) - 1);
close(fd);
free(cmdline);
if (bytes == -1)
@@ -141,7 +141,7 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
memset(my_ns, 0, sizeof(my_ns));
memset(proc_ns, 0, sizeof(proc_ns));
if (exists("/proc/self/ns/pid")) {
rc = readlink("/proc/self/ns/pid", my_ns, sizeof(my_ns));
rc = readlink("/proc/self/ns/pid", my_ns, sizeof(my_ns)-1);
if (rc <= 0)
my_ns[0] = '\0';
}
@@ -155,7 +155,7 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
continue;
xasprintf(&buffer, "/proc/%d/ns/pid", p);
if (exists(buffer)) {
rc = readlink(buffer, proc_ns, sizeof(proc_ns));
rc = readlink(buffer, proc_ns, sizeof(proc_ns)-1);
if (rc <= 0)
proc_ns[0] = '\0';
}
@@ -208,7 +208,6 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
closedir(procdir);
return pids;
}
librc_hidden_def(rc_find_pids)
#elif BSD
@@ -313,7 +312,6 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
return pids;
}
librc_hidden_def(rc_find_pids)
#else
# error "Platform not supported!"
@@ -455,7 +453,6 @@ rc_service_daemon_set(const char *service, const char *exec,
free(dirpath);
return retval;
}
librc_hidden_def(rc_service_daemon_set)
bool
rc_service_started_daemon(const char *service,
@@ -495,7 +492,6 @@ rc_service_started_daemon(const char *service,
free(dirpath);
return retval;
}
librc_hidden_def(rc_service_started_daemon)
bool
rc_service_daemons_crashed(const char *service)
@@ -615,7 +611,7 @@ rc_service_daemons_crashed(const char *service)
i = 0;
TAILQ_FOREACH(s, list, entries)
argv[i++] = s->value;
argv[i] = '\0';
argv[i] = NULL;
}
}
@@ -653,4 +649,3 @@ rc_service_daemons_crashed(const char *service)
return retval;
}
librc_hidden_def(rc_service_daemons_crashed)

View File

@@ -78,16 +78,16 @@ rc_deptree_free(RC_DEPTREE *deptree)
}
free(deptree);
}
librc_hidden_def(rc_deptree_free)
static RC_DEPINFO *
get_depinfo(const RC_DEPTREE *deptree, const char *service)
{
RC_DEPINFO *di;
TAILQ_FOREACH(di, deptree, entries)
if (strcmp(di->service, service) == 0)
return di;
if (deptree) {
TAILQ_FOREACH(di, deptree, entries)
if (strcmp(di->service, service) == 0)
return di;
}
return NULL;
}
@@ -96,9 +96,11 @@ get_deptype(const RC_DEPINFO *depinfo, const char *type)
{
RC_DEPTYPE *dt;
TAILQ_FOREACH(dt, &depinfo->depends, entries)
if (strcmp(dt->type, type) == 0)
return dt;
if (depinfo) {
TAILQ_FOREACH(dt, &depinfo->depends, entries)
if (strcmp(dt->type, type) == 0)
return dt;
}
return NULL;
}
@@ -106,7 +108,6 @@ RC_DEPTREE *
rc_deptree_load(void) {
return rc_deptree_load_file(RC_DEPTREE_CACHE);
}
librc_hidden_def(rc_deptree_load)
RC_DEPTREE *
rc_deptree_load_file(const char *deptree_file)
@@ -170,7 +171,6 @@ rc_deptree_load_file(const char *deptree_file)
return deptree;
}
librc_hidden_def(rc_deptree_load_file)
static bool
valid_service(const char *runlevel, const char *service, const char *type)
@@ -456,7 +456,6 @@ rc_deptree_depend(const RC_DEPTREE *deptree,
rc_stringlist_add(svcs, svc->value);
return svcs;
}
librc_hidden_def(rc_deptree_depend)
RC_STRINGLIST *
rc_deptree_depends(const RC_DEPTREE *deptree,
@@ -484,7 +483,6 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
rc_stringlist_free(visited);
return sorted;
}
librc_hidden_def(rc_deptree_depends)
RC_STRINGLIST *
rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
@@ -540,7 +538,6 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
rc_stringlist_free(types);
return services;
}
librc_hidden_def(rc_deptree_order)
/* Given a time, recurse the target path to find out if there are
@@ -616,11 +613,11 @@ mtime_check(const char *source, const char *target, bool newer,
return false;
mtime = buf.st_mtime;
retval = deep_mtime_check(target,newer,&mtime,file);
if (rel) {
*rel = mtime;
}
return retval;
retval = deep_mtime_check(target,newer,&mtime,file);
if (rel) {
*rel = mtime;
}
return retval;
}
bool
@@ -630,7 +627,6 @@ rc_newer_than(const char *source, const char *target,
return mtime_check(source, target, true, newest, file);
}
librc_hidden_def(rc_newer_than)
bool
rc_older_than(const char *source, const char *target,
@@ -638,7 +634,6 @@ rc_older_than(const char *source, const char *target,
{
return mtime_check(source, target, false, oldest, file);
}
librc_hidden_def(rc_older_than)
typedef struct deppair
{
@@ -734,7 +729,6 @@ rc_deptree_update_needed(time_t *newest, char *file)
return newer;
}
librc_hidden_def(rc_deptree_update_needed)
/* This is a 7 phase operation
Phase 1 is a shell script which loads each init script and config in turn
@@ -1081,4 +1075,3 @@ rc_deptree_update(void)
rc_deptree_free(deptree);
return retval;
}
librc_hidden_def(rc_deptree_update)

View File

@@ -43,7 +43,6 @@ rc_yesno(const char *value)
return false;
}
librc_hidden_def(rc_yesno)
/**
@@ -91,7 +90,6 @@ rc_getfile(const char *file, char **buffer, size_t *len)
fclose(fp);
return ret;
}
librc_hidden_def(rc_getfile)
ssize_t
rc_getline(char **line, size_t *len, FILE *fp)
@@ -116,7 +114,6 @@ rc_getline(char **line, size_t *len, FILE *fp)
}
return last;
}
librc_hidden_def(rc_getline)
char *
rc_proc_getent(const char *ent _unused)
@@ -163,7 +160,6 @@ rc_proc_getent(const char *ent _unused)
return NULL;
#endif
}
librc_hidden_def(rc_proc_getent)
RC_STRINGLIST *
rc_config_list(const char *file)
@@ -202,7 +198,6 @@ rc_config_list(const char *file)
return list;
}
librc_hidden_def(rc_config_list)
static void rc_config_set_value(RC_STRINGLIST *config, char *value)
{
@@ -277,7 +272,6 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
char *tmp = NULL;
char *value = NULL;
size_t varlen = 0;
size_t len = 0;
overrides = rc_stringlist_new();
@@ -295,7 +289,6 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
}
if (value != NULL) {
len = varlen + strlen(value) + 2;
xasprintf(&tmp, "%s=%s", override->value, value);
}
@@ -375,7 +368,6 @@ rc_config_load(const char *file)
return config;
}
librc_hidden_def(rc_config_load)
char *
rc_config_value(RC_STRINGLIST *list, const char *entry)
@@ -394,7 +386,6 @@ rc_config_value(RC_STRINGLIST *list, const char *entry)
}
return NULL;
}
librc_hidden_def(rc_config_value)
/* Global for caching the strings loaded from rc.conf to avoid reparsing for
* each rc_conf_value call */
@@ -425,7 +416,7 @@ rc_conf_value(const char *setting)
}
rc_conf = rc_config_directory(rc_conf);
rc_conf = rc_config_kcl(rc_conf);
rc_conf = rc_config_kcl(rc_conf);
/* Convert old uppercase to lowercase */
TAILQ_FOREACH(s, rc_conf, entries) {
@@ -440,4 +431,3 @@ rc_conf_value(const char *setting)
return rc_config_value(rc_conf, setting);
}
librc_hidden_def(rc_conf_value)

View File

@@ -25,7 +25,6 @@ rc_stringlist_new(void)
TAILQ_INIT(l);
return l;
}
librc_hidden_def(rc_stringlist_new)
RC_STRING *
rc_stringlist_add(RC_STRINGLIST *list, const char *value)
@@ -36,7 +35,6 @@ rc_stringlist_add(RC_STRINGLIST *list, const char *value)
TAILQ_INSERT_TAIL(list, s, entries);
return s;
}
librc_hidden_def(rc_stringlist_add)
RC_STRING *
rc_stringlist_addu(RC_STRINGLIST *list, const char *value)
@@ -51,7 +49,6 @@ rc_stringlist_addu(RC_STRINGLIST *list, const char *value)
return rc_stringlist_add(list, value);
}
librc_hidden_def(rc_stringlist_addu)
bool
rc_stringlist_delete(RC_STRINGLIST *list, const char *value)
@@ -69,7 +66,6 @@ rc_stringlist_delete(RC_STRINGLIST *list, const char *value)
errno = EEXIST;
return false;
}
librc_hidden_def(rc_stringlist_delete)
RC_STRING *
rc_stringlist_find(RC_STRINGLIST *list, const char *value)
@@ -83,7 +79,6 @@ rc_stringlist_find(RC_STRINGLIST *list, const char *value)
}
return NULL;
}
librc_hidden_def(rc_stringlist_find)
RC_STRINGLIST *
rc_stringlist_split(const char *value, const char *sep)
@@ -98,7 +93,6 @@ rc_stringlist_split(const char *value, const char *sep)
return list;
}
librc_hidden_def(rc_stringlist_split)
void
rc_stringlist_sort(RC_STRINGLIST **list)
@@ -128,7 +122,6 @@ rc_stringlist_sort(RC_STRINGLIST **list)
free(l);
*list = new;
}
librc_hidden_def(rc_stringlist_sort)
void
rc_stringlist_free(RC_STRINGLIST *list)
@@ -148,4 +141,3 @@ rc_stringlist_free(RC_STRINGLIST *list)
}
free(list);
}
librc_hidden_def(rc_stringlist_free)

View File

@@ -15,7 +15,7 @@
* except according to the terms contained in the LICENSE file.
*/
const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
static const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include "queue.h"
#include "librc.h"
@@ -351,7 +351,6 @@ rc_sys(void)
return sys;
}
librc_hidden_def(rc_sys)
static const char *
rc_parse_service_state(RC_SERVICE state)
@@ -426,20 +425,17 @@ rc_runlevel_starting(void)
{
return exists(RC_STARTING);
}
librc_hidden_def(rc_runlevel_starting)
bool
rc_runlevel_stopping(void)
{
return exists(RC_STOPPING);
}
librc_hidden_def(rc_runlevel_stopping)
RC_STRINGLIST *rc_runlevel_list(void)
{
return ls_dir(RC_RUNLEVELDIR, LS_DIR);
}
librc_hidden_def(rc_runlevel_list)
char *
rc_runlevel_get(void)
@@ -466,7 +462,6 @@ rc_runlevel_get(void)
return runlevel;
}
librc_hidden_def(rc_runlevel_get)
bool
rc_runlevel_set(const char *runlevel)
@@ -479,7 +474,6 @@ rc_runlevel_set(const char *runlevel)
fclose(fp);
return true;
}
librc_hidden_def(rc_runlevel_set)
bool
rc_runlevel_exists(const char *runlevel)
@@ -494,7 +488,6 @@ rc_runlevel_exists(const char *runlevel)
return true;
return false;
}
librc_hidden_def(rc_runlevel_exists)
bool
rc_runlevel_stack(const char *dst, const char *src)
@@ -507,7 +500,6 @@ rc_runlevel_stack(const char *dst, const char *src)
snprintf(d, sizeof(s), "%s/%s/%s", RC_RUNLEVELDIR, dst, src);
return (symlink(s, d) == 0 ? true : false);
}
librc_hidden_def(rc_runlevel_stack)
bool
rc_runlevel_unstack(const char *dst, const char *src)
@@ -517,7 +509,6 @@ rc_runlevel_unstack(const char *dst, const char *src)
snprintf(path, sizeof(path), "%s/%s/%s", RC_RUNLEVELDIR, dst, src);
return (unlink(path) == 0 ? true : false);
}
librc_hidden_def(rc_runlevel_unstack)
RC_STRINGLIST *
rc_runlevel_stacks(const char *runlevel)
@@ -530,7 +521,6 @@ rc_runlevel_stacks(const char *runlevel)
rc_stringlist_free(ancestor_list);
return stack;
}
librc_hidden_def(rc_runlevel_stacks)
/* Resolve a service name to its full path */
char *
@@ -558,7 +548,7 @@ rc_service_resolve(const char *service)
if (*file) {
memset(buffer, 0, sizeof(buffer));
r = readlink(file, buffer, sizeof(buffer));
r = readlink(file, buffer, sizeof(buffer)-1);
if (r > 0)
return xstrdup(buffer);
}
@@ -584,7 +574,6 @@ rc_service_resolve(const char *service)
return NULL;
}
librc_hidden_def(rc_service_resolve)
bool
rc_service_exists(const char *service)
@@ -623,7 +612,6 @@ rc_service_exists(const char *service)
free(file);
return retval;
}
librc_hidden_def(rc_service_exists)
#define OPTSTR \
". '%s'; echo $extra_commands $extra_started_commands $extra_stopped_commands"
@@ -665,7 +653,6 @@ rc_service_extra_commands(const char *service)
free(cmd);
return commands;
}
librc_hidden_def(rc_service_extra_commands)
#define DESCSTR ". '%s'; echo \"${description%s%s}\""
char *
@@ -695,7 +682,6 @@ rc_service_description(const char *service, const char *option)
free(cmd);
return desc;
}
librc_hidden_def(rc_service_description)
bool
rc_service_in_runlevel(const char *service, const char *runlevel)
@@ -706,7 +692,6 @@ rc_service_in_runlevel(const char *service, const char *runlevel)
runlevel, basename_c(service));
return exists(file);
}
librc_hidden_def(rc_service_in_runlevel)
bool
rc_service_mark(const char *service, const RC_SERVICE state)
@@ -826,7 +811,6 @@ rc_service_mark(const char *service, const RC_SERVICE state)
free(init);
return true;
}
librc_hidden_def(rc_service_mark)
RC_SERVICE
rc_service_state(const char *service)
@@ -869,7 +853,6 @@ rc_service_state(const char *service)
return state;
}
librc_hidden_def(rc_service_state)
char *
rc_service_value_get(const char *service, const char *option)
@@ -884,7 +867,6 @@ rc_service_value_get(const char *service, const char *option)
return buffer;
}
librc_hidden_def(rc_service_value_get)
bool
rc_service_value_set(const char *service, const char *option,
@@ -909,7 +891,6 @@ rc_service_value_set(const char *service, const char *option,
}
return true;
}
librc_hidden_def(rc_service_value_set)
bool
@@ -936,7 +917,6 @@ rc_service_schedule_start(const char *service, const char *service_to_start)
free(init);
return retval;
}
librc_hidden_def(rc_service_schedule_start)
bool
rc_service_schedule_clear(const char *service)
@@ -949,7 +929,6 @@ rc_service_schedule_clear(const char *service)
return true;
return false;
}
librc_hidden_def(rc_service_schedule_clear)
RC_STRINGLIST *
rc_services_in_runlevel(const char *runlevel)
@@ -987,7 +966,6 @@ rc_services_in_runlevel(const char *runlevel)
list = rc_stringlist_new();
return list;
}
librc_hidden_def(rc_services_in_runlevel)
RC_STRINGLIST *
rc_services_in_runlevel_stacked(const char *runlevel)
@@ -1004,7 +982,6 @@ rc_services_in_runlevel_stacked(const char *runlevel)
}
return list;
}
librc_hidden_def(rc_services_in_runlevel_stacked)
RC_STRINGLIST *
rc_services_in_state(RC_SERVICE state)
@@ -1038,7 +1015,6 @@ rc_services_in_state(RC_SERVICE state)
rc_stringlist_free(dirs);
return list;
}
librc_hidden_def(rc_services_in_state)
bool
rc_service_add(const char *runlevel, const char *service)
@@ -1047,7 +1023,6 @@ rc_service_add(const char *runlevel, const char *service)
char *init;
char file[PATH_MAX];
char path[MAXPATHLEN] = { '\0' };
char *p = NULL;
char binit[PATH_MAX];
char *i;
@@ -1068,8 +1043,7 @@ rc_service_add(const char *runlevel, const char *service)
/* We need to ensure that only things in /etc/init.d are added
* to the boot runlevel */
if (strcmp(runlevel, RC_LEVEL_BOOT) == 0) {
p = realpath(dirname(init), path);
if (!*p) {
if (realpath(dirname(init), path) == NULL) {
free(init);
return false;
}
@@ -1086,7 +1060,6 @@ rc_service_add(const char *runlevel, const char *service)
free(init);
return retval;
}
librc_hidden_def(rc_service_add)
bool
rc_service_delete(const char *runlevel, const char *service)
@@ -1099,7 +1072,6 @@ rc_service_delete(const char *runlevel, const char *service)
return true;
return false;
}
librc_hidden_def(rc_service_delete)
RC_STRINGLIST *
rc_services_scheduled_by(const char *service)
@@ -1118,7 +1090,6 @@ rc_services_scheduled_by(const char *service)
rc_stringlist_free(dirs);
return list;
}
librc_hidden_def(rc_services_scheduled_by)
RC_STRINGLIST *
rc_services_scheduled(const char *service)
@@ -1129,4 +1100,3 @@ rc_services_scheduled(const char *service)
basename_c(service));
return ls_dir(dir, LS_INITD);
}
librc_hidden_def(rc_services_scheduled)

View File

@@ -56,67 +56,4 @@
#include "rc.h"
#include "rc-misc.h"
#include "hidden-visibility.h"
#define librc_hidden_proto(x) hidden_proto(x)
#define librc_hidden_def(x) hidden_def(x)
librc_hidden_proto(rc_conf_value)
librc_hidden_proto(rc_config_list)
librc_hidden_proto(rc_config_load)
librc_hidden_proto(rc_config_value)
librc_hidden_proto(rc_deptree_depend)
librc_hidden_proto(rc_deptree_depends)
librc_hidden_proto(rc_deptree_free)
librc_hidden_proto(rc_deptree_load)
librc_hidden_proto(rc_deptree_load_file)
librc_hidden_proto(rc_deptree_order)
librc_hidden_proto(rc_deptree_update)
librc_hidden_proto(rc_deptree_update_needed)
librc_hidden_proto(rc_find_pids)
librc_hidden_proto(rc_getfile)
librc_hidden_proto(rc_getline)
librc_hidden_proto(rc_newer_than)
librc_hidden_proto(rc_proc_getent)
librc_hidden_proto(rc_older_than)
librc_hidden_proto(rc_runlevel_exists)
librc_hidden_proto(rc_runlevel_get)
librc_hidden_proto(rc_runlevel_list)
librc_hidden_proto(rc_runlevel_set)
librc_hidden_proto(rc_runlevel_stack)
librc_hidden_proto(rc_runlevel_stacks)
librc_hidden_proto(rc_runlevel_starting)
librc_hidden_proto(rc_runlevel_stopping)
librc_hidden_proto(rc_runlevel_unstack)
librc_hidden_proto(rc_service_add)
librc_hidden_proto(rc_service_daemons_crashed)
librc_hidden_proto(rc_service_daemon_set)
librc_hidden_proto(rc_service_delete)
librc_hidden_proto(rc_service_description)
librc_hidden_proto(rc_service_exists)
librc_hidden_proto(rc_service_extra_commands)
librc_hidden_proto(rc_service_in_runlevel)
librc_hidden_proto(rc_service_mark)
librc_hidden_proto(rc_service_resolve)
librc_hidden_proto(rc_service_schedule_clear)
librc_hidden_proto(rc_service_schedule_start)
librc_hidden_proto(rc_services_in_runlevel)
librc_hidden_proto(rc_services_in_runlevel_stacked)
librc_hidden_proto(rc_services_in_state)
librc_hidden_proto(rc_services_scheduled)
librc_hidden_proto(rc_services_scheduled_by)
librc_hidden_proto(rc_service_started_daemon)
librc_hidden_proto(rc_service_state)
librc_hidden_proto(rc_service_value_get)
librc_hidden_proto(rc_service_value_set)
librc_hidden_proto(rc_stringlist_add)
librc_hidden_proto(rc_stringlist_addu)
librc_hidden_proto(rc_stringlist_delete)
librc_hidden_proto(rc_stringlist_find)
librc_hidden_proto(rc_stringlist_free)
librc_hidden_proto(rc_stringlist_new)
librc_hidden_proto(rc_stringlist_split)
librc_hidden_proto(rc_stringlist_sort)
librc_hidden_proto(rc_sys)
librc_hidden_proto(rc_yesno)
#endif

View File

@@ -14,7 +14,8 @@ SRCS+= rc-selinux.c
endif
ifeq (${OS},Linux)
SRCS+= kill_all.c openrc-init.c openrc-shutdown.c broadcast.c rc-wtmp.c
SRCS+= kill_all.c openrc-init.c openrc-shutdown.c rc-sysvinit.c broadcast.c \
rc-wtmp.c
endif
CLEANFILES= version.h rc-selinux.o
@@ -112,7 +113,7 @@ veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
fstabinfo: fstabinfo.o _usage.o rc-misc.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
openrc-init: openrc-init.o rc-wtmp.o
openrc-init: openrc-init.o rc-plugin.o rc-wtmp.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
is_newer_than: is_newer_than.o rc-misc.o
@@ -134,7 +135,7 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
openrc-shutdown: openrc-shutdown.o rc-misc.o _usage.o broadcast.o rc-wtmp.o
openrc-shutdown: openrc-shutdown.o rc-misc.o _usage.o broadcast.o rc-wtmp.o rc-sysvinit.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o

View File

@@ -37,10 +37,6 @@
# define _PATH_DEV "/dev/"
#endif
#ifndef UT_LINESIZE
#define UT_LINESIZE __UT_LINESIZE
#endif
static sigjmp_buf jbuf;
/*
@@ -62,7 +58,7 @@ static void getuidtty(char **userp, char **ttyp)
uid_t uid;
char *tty;
static char uidbuf[32];
static char ttynm[UT_LINESIZE + 4];
char *ttynm = NULL;
uid = getuid();
if ((pwd = getpwuid(uid)) != NULL) {
@@ -82,10 +78,8 @@ static void getuidtty(char **userp, char **ttyp)
if (tty[0] == '/')
tty++;
}
snprintf(ttynm, sizeof(ttynm), "(%.*s) ",
UT_LINESIZE, tty);
} else
ttynm[0] = 0;
xasprintf(&ttynm, "(%s) ", tty);
}
*userp = uidbuf;
*ttyp = ttynm;
@@ -133,7 +127,7 @@ void broadcast(char *text)
char *p;
char *line = NULL;
struct sigaction sa;
int fd;
volatile int fd;
FILE *tp;
int flags;
char *term = NULL;
@@ -156,6 +150,7 @@ void broadcast(char *text)
xasprintf(&line, "\007\r\nBroadcast message from %s@%s %s(%s):\r\n\r\n",
user, name.nodename, tty, date);
free(tty);
/*
* Fork to avoid hanging in a write()

View File

@@ -35,9 +35,9 @@
const char *applet = NULL;
static int syslog_decode(char *name, CODE *codetab)
static int syslog_decode(char *name, const CODE *codetab)
{
CODE *c;
const CODE *c;
if (isdigit((unsigned char)*name))
return atoi(name);

View File

@@ -19,6 +19,7 @@
*/
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
@@ -37,46 +38,52 @@
#include "helpers.h"
#include "rc.h"
#include "rc-plugin.h"
#include "rc-wtmp.h"
#include "version.h"
static const char *path_default = "/sbin:/usr/sbin:/bin:/usr/bin";
static const char *rc_default_runlevel = "default";
static pid_t do_openrc(const char *runlevel)
static void do_openrc(const char *runlevel)
{
pid_t pid;
sigset_t signals;
sigset_t all_signals;
sigset_t our_signals;
sigfillset(&all_signals);
/* block all signals */
sigprocmask(SIG_BLOCK, &all_signals, &our_signals);
pid = fork();
switch (pid) {
case -1:
perror("fork");
exit(1);
break;
case 0:
setsid();
/* unblock all signals */
sigemptyset(&signals);
sigprocmask(SIG_SETMASK, &signals, NULL);
sigprocmask(SIG_UNBLOCK, &all_signals, NULL);
printf("Starting %s runlevel\n", runlevel);
execlp("openrc", "openrc", runlevel, NULL);
perror("exec");
exit(1);
break;
default:
/* restore our signal mask */
sigprocmask(SIG_SETMASK, &our_signals, NULL);
while (waitpid(pid, NULL, 0) != pid)
if (errno == ECHILD)
break;
break;
}
return pid;
}
static void init(const char *default_runlevel)
{
const char *runlevel = NULL;
pid_t pid;
pid = do_openrc("sysinit");
waitpid(pid, NULL, 0);
pid = do_openrc("boot");
waitpid(pid, NULL, 0);
do_openrc("sysinit");
do_openrc("boot");
if (default_runlevel)
runlevel = default_runlevel;
else
@@ -87,8 +94,7 @@ static void init(const char *default_runlevel)
printf("%s is an invalid runlevel\n", runlevel);
runlevel = rc_default_runlevel;
}
pid = do_openrc(runlevel);
waitpid(pid, NULL, 0);
do_openrc(runlevel);
log_wtmp("reboot", "~~", 0, RUN_LVL, "~~");
}
@@ -100,11 +106,9 @@ static void handle_reexec(char *my_name)
static void handle_shutdown(const char *runlevel, int cmd)
{
pid_t pid;
struct timespec ts;
pid = do_openrc(runlevel);
while (waitpid(pid, NULL, 0) != pid);
do_openrc(runlevel);
printf("Sending the final term signal\n");
kill(-1, SIGTERM);
ts.tv_sec = 3;
@@ -116,12 +120,68 @@ static void handle_shutdown(const char *runlevel, int cmd)
reboot(cmd);
}
static void handle_single(void)
static void run_program(const char *prog)
{
sigset_t full;
sigset_t old;
pid_t pid;
pid = do_openrc("single");
while (waitpid(pid, NULL, 0) != pid);
/* We need to block signals until we have forked */
sigfillset(&full);
sigprocmask(SIG_SETMASK, &full, &old);
pid = fork();
if (pid == -1) {
perror("init");
return;
}
if (pid == 0) {
/* Unmask signals */
sigprocmask(SIG_SETMASK, &old, NULL);
execl(prog, prog, (char *)NULL);
perror("init");
exit(1);
}
/* Unmask signals and wait for child */
sigprocmask(SIG_SETMASK, &old, NULL);
if (rc_waitpid(pid) == -1)
perror("init");
}
static void open_shell(void)
{
const char *shell;
struct passwd *pw;
#ifdef __linux__
const char *sys = rc_sys();
/* VSERVER systems cannot really drop to shells */
if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
{
execlp("halt", "halt", "-f", (char *) NULL);
perror("init");
return;
}
#endif
shell = rc_conf_value("rc_shell");
/* No shell set, so obey env, then passwd, then default to /bin/sh */
if (!shell) {
shell = getenv("SHELL");
if (!shell) {
pw = getpwuid(getuid());
if (pw)
shell = pw->pw_shell;
if (!shell)
shell = "/bin/sh";
}
}
run_program(shell);
}
static void handle_single(void)
{
do_openrc("single");
}
static void reap_zombies(void)
@@ -249,8 +309,11 @@ int main(int argc, char **argv)
handle_shutdown("reboot", RB_AUTOBOOT);
else if (strcmp(buf, "reexec") == 0)
handle_reexec(argv[0]);
else if (strcmp(buf, "single") == 0)
else if (strcmp(buf, "single") == 0) {
handle_single();
open_shell();
init(default_runlevel);
}
}
return 0;
}

View File

@@ -1120,7 +1120,7 @@ int main(int argc, char **argv)
char *dir, *save = NULL, *saveLnk = NULL;
char *pidstr = NULL;
size_t l = 0, ll;
const char *file;
const char *file;
struct stat stbuf;
/* Show help if insufficient args */
@@ -1152,7 +1152,7 @@ int main(int argc, char **argv)
}
lnk = xmalloc(4096);
memset(lnk, 0, 4096);
if (readlink(argv[1], lnk, 4096)) {
if (readlink(argv[1], lnk, 4096-1)) {
dir = dirname(path);
if (strchr(lnk, '/')) {
save = xstrdup(dir);
@@ -1223,7 +1223,6 @@ int main(int argc, char **argv)
/* Make our prefix string */
prefix = xmalloc(sizeof(char) * l + 1);
ll = strlen(applet);
memcpy(prefix, applet, ll);
memset(prefix + ll, ' ', l - ll);
memset(prefix + l, 0, 1);

View File

@@ -35,8 +35,9 @@
#include "rc.h"
#include "helpers.h"
#include "rc-misc.h"
#include "_usage.h"
#include "rc-sysvinit.h"
#include "rc-wtmp.h"
#include "_usage.h"
const char *applet = NULL;
const char *extraopts = NULL;
@@ -67,7 +68,15 @@ const char * const longopts_help[] = {
"write wtmp boot record and exit",
longopts_help_COMMON
};
const char *usagestring = NULL;
const char *usagestring = "" \
"Usage: openrc-shutdown -c | --cancel\n" \
" or: openrc-shutdown -R | --reexec\n" \
" or: openrc-shutdown -w | --write-only\n" \
" or: openmrc-shutdown -H | --halt time\n" \
" or: openrc-shutdown -K | --kexec time\n" \
" or: openrc-shutdown -p | --poweroff time\n" \
" or: openrc-shutdown -r | --reboot time\n" \
" or: openrc-shutdown -s | --single time";
const char *exclusive = "Select one of "
"--cancel, --halt, --kexec, --poweroff, --reexec, --reboot, --single or \n"
"--write-only";
@@ -111,8 +120,8 @@ static void create_nologin(int mins)
t += 60 * mins;
if ((fp = fopen(nologin_file, "w")) != NULL) {
fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t));
fclose(fp);
fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t));
fclose(fp);
}
}
@@ -122,7 +131,7 @@ static void create_nologin(int mins)
static void send_cmd(const char *cmd)
{
FILE *fifo;
size_t ignored;
size_t ignored;
if (do_dryrun) {
einfo("Would send %s to init", cmd);
@@ -160,9 +169,7 @@ static void sleep_no_interrupt(int seconds)
static void stop_shutdown(int sig)
{
/* use the sig parameter so the compiler will not complain */
if (sig == SIGINT)
;
(void) sig;
unlink(nologin_file);
unlink(shutdown_pid);
einfo("Shutdown canceled");
@@ -322,15 +329,30 @@ int main(int argc, char **argv)
syslog(LOG_NOTICE, "The system will %s now", state);
unlink(nologin_file);
unlink(shutdown_pid);
if (do_halt)
send_cmd("halt");
else if (do_kexec)
if (do_halt) {
if (exists("/run/initctl")) {
sysvinit_setenv("INIT_HALT", "HALT");
sysvinit_runlevel('0');
} else
send_cmd("halt");
} else if (do_kexec)
send_cmd("kexec");
else if (do_poweroff)
send_cmd("poweroff");
else if (do_reboot)
send_cmd("reboot");
else if (do_single)
send_cmd("single");
else if (do_poweroff) {
if (exists("/run/initctl")) {
sysvinit_setenv("INIT_HALT", "POWEROFF");
sysvinit_runlevel('0');
} else
send_cmd("poweroff");
} else if (do_reboot) {
if (exists("/run/initctl"))
sysvinit_runlevel('6');
else
send_cmd("reboot");
} else if (do_single) {
if (exists("/run/initctl"))
sysvinit_runlevel('S');
else
send_cmd("single");
}
return 0;
}

View File

@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -270,8 +271,11 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,
einfo("Would send signal %d to PID %d", sig, pi->pid);
nkilled++;
} else {
if (!quiet)
ebeginv("Sending signal %d to PID %d", sig, pi->pid);
if (sig) {
syslog(LOG_DEBUG, "Sending signal %d to PID %d", sig, pi->pid);
if (!quiet)
ebeginv("Sending signal %d to PID %d", sig, pi->pid);
}
errno = 0;
killed = (kill(pi->pid, sig) == 0 ||
errno == ESRCH ? true : false);
@@ -279,6 +283,9 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,
eendv(killed ? 0 : 1,
"%s: failed to send signal %d to PID %d: %s",
applet, sig, pi->pid, strerror(errno));
else if (!killed)
syslog(LOG_ERR, "Failed to send signal %d to PID %d: %s",
sig, pi->pid, strerror(errno));
if (!killed) {
nkilled = -1;
} else {
@@ -310,12 +317,18 @@ int run_stop_schedule(const char *applet,
if (!(pid > 0 || exec || uid || (argv && *argv)))
return 0;
if (exec)
if (exec) {
einfov("Will stop %s", exec);
if (pid > 0)
syslog(LOG_DEBUG, "Will stop %s", exec);
}
if (pid > 0) {
einfov("Will stop PID %d", pid);
if (uid)
syslog(LOG_DEBUG, "Will stop PID %d", pid);
}
if (uid) {
einfov("Will stop processes owned by UID %d", uid);
syslog(LOG_DEBUG, "Will stop processes owned by UID %d", uid);
}
if (argv && *argv) {
einfovn("Will stop processes of `");
if (rc_yesno(getenv("EINFO_VERBOSE"))) {

View File

@@ -27,12 +27,18 @@
#include "rc-misc.h"
#include "_usage.h"
enum format_t {
FORMAT_DEFAULT,
FORMAT_INI,
};
const char *applet = NULL;
const char *extraopts = NULL;
const char *getoptstring = "aclmrsSu" getoptstring_COMMON;
const char *getoptstring = "acf:lmrsSu" getoptstring_COMMON;
const struct option longopts[] = {
{"all", 0, NULL, 'a'},
{"crashed", 0, NULL, 'c'},
{"format", 1, NULL, 'f'},
{"list", 0, NULL, 'l'},
{"manual", 0, NULL, 'm'},
{"runlevel", 0, NULL, 'r'},
@@ -44,6 +50,7 @@ const struct option longopts[] = {
const char * const longopts_help[] = {
"Show services from all run levels",
"Show crashed services",
"format status to be parsable (currently arg must be ini)",
"Show list of run levels",
"Show manually started services",
"Show the name of the current runlevel",
@@ -53,7 +60,7 @@ const char * const longopts_help[] = {
longopts_help_COMMON
};
const char *usagestring = "" \
"Usage: rc-status [options] <runlevel>...\n" \
"Usage: rc-status [options] -f ini <runlevel>...\n" \
" or: rc-status [options] [-a | -c | -l | -m | -r | -s | -u]";
static RC_DEPTREE *deptree;
@@ -62,19 +69,27 @@ static RC_STRINGLIST *types;
static RC_STRINGLIST *levels, *services, *tmp, *alist;
static RC_STRINGLIST *sservices, *nservices, *needsme;
static void
print_level(const char *prefix, const char *level)
static void print_level(const char *prefix, const char *level,
enum format_t format)
{
if (prefix)
printf("%s ", prefix);
printf ("Runlevel: ");
if (isatty(fileno(stdout)))
printf("%s%s%s\n",
ecolor(ECOLOR_HILITE),
level,
ecolor(ECOLOR_NORMAL));
else
printf("%s\n", level);
switch (format) {
case FORMAT_DEFAULT:
if (prefix)
printf("%s ", prefix);
printf ("Runlevel: ");
if (isatty(fileno(stdout)))
printf("%s%s%s\n",
ecolor(ECOLOR_HILITE), level, ecolor(ECOLOR_NORMAL));
else
printf("%s\n", level);
break;
case FORMAT_INI:
printf("%s", "[");
if (prefix)
printf("%s ", prefix);
printf("%s]\n", level);
break;
}
}
static char *get_uptime(const char *service)
@@ -125,14 +140,13 @@ static char *get_uptime(const char *service)
return uptime;
}
static void
print_service(const char *service)
static void print_service(const char *service, enum format_t format)
{
char *status = NULL;
char *uptime = NULL;
char *child_pid = NULL;
char *start_time = NULL;
int cols = printf(" %s", service);
int cols;
const char *c = ecolor(ECOLOR_GOOD);
RC_SERVICE state = rc_service_state(service);
ECOLOR color = ECOLOR_BAD;
@@ -176,14 +190,22 @@ print_service(const char *service)
xasprintf(&status, " stopped ");
errno = 0;
if (c && *c && isatty(fileno(stdout)))
printf("\n");
ebracket(cols, color, status);
switch (format) {
case FORMAT_DEFAULT:
cols = printf(" %s", service);
if (c && *c && isatty(fileno(stdout)))
printf("\n");
ebracket(cols, color, status);
break;
case FORMAT_INI:
printf("%s = %s\n", service, status);
break;
}
free(status);
}
static void
print_services(const char *runlevel, RC_STRINGLIST *svcs)
static void print_services(const char *runlevel, RC_STRINGLIST *svcs,
enum format_t format)
{
RC_STRINGLIST *l = NULL;
RC_STRING *s;
@@ -197,7 +219,7 @@ print_services(const char *runlevel, RC_STRINGLIST *svcs)
TAILQ_FOREACH(s, svcs, entries)
if (!runlevel ||
rc_service_in_runlevel(s->value, runlevel))
print_service(s->value);
print_service(s->value, format);
return;
}
if (!types) {
@@ -217,13 +239,12 @@ print_services(const char *runlevel, RC_STRINGLIST *svcs)
if (!rc_stringlist_find(svcs, s->value))
continue;
if (!runlevel || rc_service_in_runlevel(s->value, runlevel))
print_service(s->value);
print_service(s->value, format);
}
rc_stringlist_free(l);
}
static void
print_stacked_services(const char *runlevel)
static void print_stacked_services(const char *runlevel, enum format_t format)
{
RC_STRINGLIST *stackedlevels, *servicelist;
RC_STRING *stackedlevel;
@@ -232,9 +253,9 @@ print_stacked_services(const char *runlevel)
TAILQ_FOREACH(stackedlevel, stackedlevels, entries) {
if (rc_stringlist_find(levels, stackedlevel->value) != NULL)
continue;
print_level("Stacked", stackedlevel->value);
print_level("Stacked", stackedlevel->value, format);
servicelist = rc_services_in_runlevel(stackedlevel->value);
print_services(stackedlevel->value, servicelist);
print_services(stackedlevel->value, servicelist, format);
rc_stringlist_free(servicelist);
}
rc_stringlist_free(stackedlevels);
@@ -244,7 +265,9 @@ print_stacked_services(const char *runlevel)
int main(int argc, char **argv)
{
RC_SERVICE state;
RC_STRING *s, *l, *t, *level;
RC_STRING *s, *l, *t, *level;
enum format_t format = FORMAT_DEFAULT;
bool levels_given = false;
bool show_all = false;
char *p, *runlevel = NULL;
int opt, retval = 0;
@@ -267,6 +290,12 @@ int main(int argc, char **argv)
}
goto exit;
/* NOTREACHED */
case 'f':
if (strcasecmp(optarg, "ini") == 0)
format = FORMAT_INI;
else
eerrorx("%s: invalid argument to --format switch\n", applet);
break;
case 'l':
levels = rc_runlevel_list();
TAILQ_FOREACH(l, levels, entries)
@@ -291,7 +320,7 @@ int main(int argc, char **argv)
free(s->value);
free(s);
}
print_services(NULL, services);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
case 'r':
runlevel = rc_runlevel_get();
@@ -303,12 +332,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);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
case 's':
services = rc_services_in_runlevel(NULL);
print_services(NULL, services);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
case 'u':
@@ -323,7 +352,7 @@ int main(int argc, char **argv)
break;
}
}
print_services(NULL, services);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
@@ -335,6 +364,7 @@ int main(int argc, char **argv)
opt = (optind < argc) ? 0 : 1;
while (optind < argc) {
if (rc_runlevel_exists(argv[optind])) {
levels_given = true;
rc_stringlist_add(levels, argv[optind++]);
opt++;
} else
@@ -351,21 +381,21 @@ int main(int argc, char **argv)
deptree = _rc_deptree_load(0, NULL);
TAILQ_FOREACH(l, levels, entries) {
print_level(NULL, l->value);
print_level(NULL, l->value, format);
services = rc_services_in_runlevel(l->value);
print_services(l->value, services);
print_stacked_services(l->value);
print_services(l->value, services, format);
print_stacked_services(l->value, format);
rc_stringlist_free(nservices);
nservices = NULL;
rc_stringlist_free(services);
services = NULL;
}
if (show_all || argc < 2) {
if (show_all || !levels_given) {
/* Show hotplugged services */
print_level("Dynamic", "hotplugged");
print_level("Dynamic", "hotplugged", format);
services = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
print_services(NULL, services);
print_services(NULL, services, format);
rc_stringlist_free(services);
services = NULL;
@@ -422,10 +452,10 @@ int main(int argc, char **argv)
* be added to the list
*/
unsetenv("RC_SVCNAME");
print_level("Dynamic", "needed/wanted");
print_services(NULL, nservices);
print_level("Dynamic", "manual");
print_services(NULL, services);
print_level("Dynamic", "needed/wanted", format);
print_services(NULL, nservices, format);
print_level("Dynamic", "manual", format);
print_services(NULL, services, format);
}
exit:

102
src/rc/rc-sysvinit.c Normal file
View File

@@ -0,0 +1,102 @@
/*
* rc-sysvinit.c
* Helper to send a runlevel change to sysvinit
*/
/*
* Copyright (c) 2019 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
*
* This file is part of OpenRC. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "einfo.h"
#include "rc-sysvinit.h"
static void sysvinit_send_cmd(struct init_request *request)
{
int fd;
char *p;
size_t bytes;
ssize_t r;
fd = open("/run/initctl", O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
if (fd < 0) {
if (errno != ENOENT)
eerror("Failed to open initctl fifo: %s", strerror(errno));
return;
}
p = (char *) request;
bytes = sizeof(*request);
do {
r = write(fd, p, bytes);
if (r < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
eerror("Failed to write to /run/initctl: %s", strerror(errno));
return;
}
p += r;
bytes -= r;
} while (bytes > 0);
}
void sysvinit_runlevel(char rl)
{
struct init_request request;
if (!rl)
return;
request = (struct init_request) {
.magic = INIT_MAGIC,
.sleeptime = 0,
.cmd = INIT_CMD_RUNLVL,
.runlevel = rl,
};
sysvinit_send_cmd(&request);
return;
}
/*
* Set environment variables in the init process.
*/
void sysvinit_setenv(char *name, char *value)
{
struct init_request request;
size_t nl;
size_t vl;
memset(&request, 0, sizeof(request));
request.magic = INIT_MAGIC;
request.cmd = INIT_CMD_SETENV;
nl = strlen(name);
if (value)
vl = strlen(value);
else
vl = 0;
if (nl + vl + 3 >= (int)sizeof(request.i.data))
return -1;
memcpy(request.i.data, name, nl);
if (value) {
request.i.data[nl] = '=';
memcpy(request.i.data + nl + 1, value, vl);
}
sysvinit_send_cmd(&request);
return 0;
}

72
src/rc/rc-sysvinit.h Normal file
View File

@@ -0,0 +1,72 @@
/*
* rc-sysvinit.h - Interface to communicate with sysvinit via /run/initctl.
*/
/*
* Copyright (c) 2019 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
*
* This file is part of OpenRC. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
#ifndef _RC_SYSVINIT_H
#define _RC_SYSVINIT_H
/*
* The #defines and structures below are taken from initreq.h in
* sysvinit and must be used by any program wishing to communicate with
* it.
*/
#define INIT_MAGIC 0x03091969
#define INIT_CMD_START 0
#define INIT_CMD_RUNLVL 1
#define INIT_CMD_POWERFAIL 2
#define INIT_CMD_POWERFAILNOW 3
#define INIT_CMD_POWEROK 4
#define INIT_CMD_BSD 5
#define INIT_CMD_SETENV 6
#define INIT_CMD_UNSETENV 7
/*
* This is what BSD 4.4 uses when talking to init.
* Linux doesn't use this right now.
*/
struct init_request_bsd {
char gen_id[8]; /* Beats me.. telnetd uses "fe" */
char tty_id[16]; /* Tty name minus /dev/tty */
char host[64]; /* Hostname */
char term_type[16]; /* Terminal type */
int signal; /* Signal to send */
int pid; /* Process to send to */
char exec_name[128]; /* Program to execute */
char reserved[128]; /* For future expansion. */
};
/*
* Because of legacy interfaces, "runlevel" and "sleeptime"
* aren't in a seperate struct in the union.
*
* The weird sizes are because init expects the whole
* struct to be 384 bytes.
*/
struct init_request {
int magic; /* Magic number */
int cmd; /* What kind of request */
int runlevel; /* Runlevel to change to */
int sleeptime; /* Time between TERM and KILL */
union {
struct init_request_bsd bsd;
char data[368];
} i;
};
void sysvinit_runlevel(char rl);
void sysvinit_setenv(char *name, char *value);
#endif

View File

@@ -43,8 +43,8 @@ void log_wtmp(const char *user, const char *id, pid_t pid, int type,
strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
/* Put the OS version in place of the hostname */
if (uname(&uname_buf) == 0)
/* Put the OS version in place of the hostname */
if (uname(&uname_buf) == 0)
strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
updwtmp(WTMP_FILE, &utmp);

View File

@@ -20,7 +20,7 @@
* except according to the terms contained in the LICENSE file.
*/
const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
static const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/types.h>
#include <sys/ioctl.h>

View File

@@ -492,7 +492,7 @@ int main(int argc, char **argv)
startas = optarg;
break;
case 'w':
if (sscanf(optarg, "%d", &start_wait) != 1)
if (sscanf(optarg, "%u", &start_wait) != 1)
eerrorx("%s: `%s' not a number",
applet, optarg);
break;
@@ -547,7 +547,7 @@ int main(int argc, char **argv)
} else if (name) {
*--argv = name;
++argc;
} else if (exec) {
} else if (exec) {
*--argv = exec;
++argc;
};
@@ -669,7 +669,7 @@ int main(int argc, char **argv)
nav[len++] = p;
for (i = 0; i < opt; i++)
nav[i + len] = argv[i];
nav[i + len] = '\0';
nav[i + len] = NULL;
}
}
}

View File

@@ -184,13 +184,22 @@ static void re_exec_supervisor(void)
static void handle_signal(int sig)
{
int serrno = errno;
pid_t pid;
switch (sig) {
case SIGALRM:
do_healthcheck = 1;
break;
case SIGCHLD:
while (waitpid((pid_t)(-1), NULL, WNOHANG) > 0) {}
if (exiting)
while (waitpid((pid_t)(-1), NULL, WNOHANG) > 0) {}
else {
while ((pid = waitpid((pid_t)(-1), NULL, WNOHANG|WNOWAIT)) > 0) {
if (pid == child_pid)
break;
pid = waitpid(pid, NULL, WNOHANG);
}
}
break;
case SIGTERM:
exiting = 1;
@@ -228,7 +237,7 @@ static char * expand_home(const char *home, const char *path)
ppath++;
if (!home) {
free(opath);
free(opath);
return xstrdup(path);
}
if (!ppath) {
@@ -258,6 +267,56 @@ static char *make_cmdline(char **argv)
return cmdline;
}
static pid_t exec_command(const char *cmd)
{
char *file;
pid_t pid = -1;
sigset_t full;
sigset_t old;
struct sigaction sa;
file = rc_service_resolve(svcname);
if (!exists(file)) {
free(file);
return 0;
}
/* We need to block signals until we have forked */
memset(&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sigfillset(&full);
sigprocmask(SIG_SETMASK, &full, &old);
pid = fork();
if (pid == 0) {
/* Restore default handlers */
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
sigprocmask(SIG_SETMASK, &old, NULL);
/* Safe to run now */
execl(file, file, cmd, (char *) NULL);
syslog(LOG_ERR, "unable to exec `%s': %s\n",
file, strerror(errno));
_exit(EXIT_FAILURE);
}
if (pid == -1)
syslog(LOG_ERR, "fork: %s\n",strerror (errno));
sigprocmask(SIG_SETMASK, &old, NULL);
free(file);
return pid;
}
static void child_process(char *exec, char **argv)
{
RC_STRINGLIST *env_list;
@@ -476,7 +535,7 @@ static void supervisor(char *exec, char **argv)
sigaction(SIGTERM, &sa, NULL);
fp = fopen(pidfile, "w");
if (! fp)
if (!fp)
eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
fprintf(fp, "%d\n", getpid());
fclose(fp);
@@ -498,18 +557,18 @@ static void supervisor(char *exec, char **argv)
alarm(healthcheckdelay);
else if (healthchecktimer)
alarm(healthchecktimer);
fifo_fd = open(fifopath, O_RDONLY |O_NONBLOCK);
failing = 0;
failing = 0;
while (!exiting) {
healthcheck_respawn = 0;
wait_pid = waitpid(child_pid, &i, WNOHANG);
memset(buf, 0, sizeof(buf));
if (fifo_fd >= 0) {
fifo_fd = open(fifopath, O_RDONLY);
if (fifo_fd > 0) {
memset(buf, 0, sizeof(buf));
count = read(fifo_fd, buf, sizeof(buf) - 1);
close(fifo_fd);
if (count != -1)
buf[count] = 0;
}
if (strlen(buf) > 0) {
if (count == 0)
continue;
syslog(LOG_DEBUG, "Received %s from fifo", buf);
if (strncasecmp(buf, "sig", 3) == 0) {
if ((sscanf(buf, "%s %d", cmd, &sig_send) == 2)
@@ -521,18 +580,19 @@ static void supervisor(char *exec, char **argv)
sig_send, child_pid);
}
}
continue;
}
if (do_healthcheck) {
do_healthcheck = 0;
alarm(0);
syslog(LOG_DEBUG, "running health check for %s", svcname);
health_pid = exec_service(svcname, "healthcheck");
health_pid = exec_command("healthcheck");
health_status = rc_waitpid(health_pid);
if (WIFEXITED(health_status) && WEXITSTATUS(health_status) == 0)
alarm(healthchecktimer);
else {
syslog(LOG_WARNING, "health check for %s failed", svcname);
health_pid = exec_service(svcname, "unhealthy");
health_pid = exec_command("unhealthy");
rc_waitpid(health_pid);
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
nkilled = run_stop_schedule(applet, NULL, NULL, child_pid, 0,
@@ -544,7 +604,7 @@ static void supervisor(char *exec, char **argv)
healthcheck_respawn = 1;
}
}
if (exiting ) {
if (exiting) {
alarm(0);
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
nkilled = run_stop_schedule(applet, NULL, NULL, child_pid, 0,
@@ -553,6 +613,7 @@ static void supervisor(char *exec, char **argv)
syslog(LOG_INFO, "killed %d processes", nkilled);
continue;
}
wait_pid = waitpid(child_pid, &i, WNOHANG);
if (wait_pid == child_pid) {
if (WIFEXITED(i))
syslog(LOG_WARNING, "%s, pid %d, exited with return code %d",
@@ -659,7 +720,7 @@ int main(int argc, char **argv)
eerrorx("%s: The RC_SVCNAME environment variable is not set", applet);
openlog(applet, LOG_PID, LOG_DAEMON);
if (argc >= 1 && svcname && strcmp(argv[1], svcname))
if (argc <= 1 || strcmp(argv[1], svcname))
eerrorx("%s: the first argument is %s and must be %s",
applet, argv[1], svcname);
@@ -774,7 +835,7 @@ int main(int argc, char **argv)
case 'm': /* --respawn-max count */
n = sscanf(optarg, "%d", &respawn_max);
if (n != 1 || respawn_max < 1)
if (n != 1 || respawn_max < 0)
eerrorx("Invalid respawn-max value '%s'", optarg);
break;
@@ -982,6 +1043,9 @@ int main(int argc, char **argv)
tty_fd = open("/dev/tty", O_RDWR);
#endif
devnull_fd = open("/dev/null", O_RDWR);
dup2(devnull_fd, STDIN_FILENO);
dup2(devnull_fd, STDOUT_FILENO);
dup2(devnull_fd, STDERR_FILENO);
child_pid = fork();
if (child_pid == -1)
eerrorx("%s: fork: %s", applet, strerror(errno));
@@ -998,8 +1062,8 @@ int main(int argc, char **argv)
c++;
}
xasprintf(&varbuf, "%d", x);
rc_service_value_set(svcname, "argc", varbuf);
free(varbuf);
rc_service_value_set(svcname, "argc", varbuf);
free(varbuf);
rc_service_value_set(svcname, "exec", exec);
supervisor(exec, argv);
} else

6
src/test/.gitignore vendored
View File

@@ -1,6 +0,0 @@
einfo.data.out
einfo.funcs.out
librc.funcs.hidden.out
librc.funcs.hidden.list
rc.data.out
rc.funcs.out

View File

@@ -1 +0,0 @@
EINFO_1.0

View File

@@ -1,52 +0,0 @@
ebegin
ebegin@@EINFO_1.0
ebeginv
ebeginv@@EINFO_1.0
ebracket
ebracket@@EINFO_1.0
ecolor
ecolor@@EINFO_1.0
eend
eend@@EINFO_1.0
eendv
eendv@@EINFO_1.0
eerror
eerror@@EINFO_1.0
eerrorn
eerrorn@@EINFO_1.0
eerrorx
eerrorx@@EINFO_1.0
eindent
eindent@@EINFO_1.0
eindentv
eindentv@@EINFO_1.0
einfo
einfo@@EINFO_1.0
einfon
einfon@@EINFO_1.0
einfov
einfov@@EINFO_1.0
einfovn
einfovn@@EINFO_1.0
elog
elog@@EINFO_1.0
eoutdent
eoutdent@@EINFO_1.0
eoutdentv
eoutdentv@@EINFO_1.0
eprefix
eprefix@@EINFO_1.0
ewarn
ewarn@@EINFO_1.0
ewarnn
ewarnn@@EINFO_1.0
ewarnv
ewarnv@@EINFO_1.0
ewarnvn
ewarnvn@@EINFO_1.0
ewarnx
ewarnx@@EINFO_1.0
ewend
ewend@@EINFO_1.0
ewendv
ewendv@@EINFO_1.0

View File

@@ -1,3 +0,0 @@
RC_1.0
rc_environ_fd
rc_environ_fd@@RC_1.0

View File

@@ -1,116 +0,0 @@
rc_conf_value
rc_conf_value@@RC_1.0
rc_config_list
rc_config_list@@RC_1.0
rc_config_load
rc_config_load@@RC_1.0
rc_config_value
rc_config_value@@RC_1.0
rc_deptree_depend
rc_deptree_depend@@RC_1.0
rc_deptree_depends
rc_deptree_depends@@RC_1.0
rc_deptree_free
rc_deptree_free@@RC_1.0
rc_deptree_load
rc_deptree_load@@RC_1.0
rc_deptree_load_file
rc_deptree_load_file@@RC_1.0
rc_deptree_order
rc_deptree_order@@RC_1.0
rc_deptree_update
rc_deptree_update@@RC_1.0
rc_deptree_update_needed
rc_deptree_update_needed@@RC_1.0
rc_find_pids
rc_find_pids@@RC_1.0
rc_getfile
rc_getfile@@RC_1.0
rc_getline
rc_getline@@RC_1.0
rc_newer_than
rc_newer_than@@RC_1.0
rc_older_than
rc_older_than@@RC_1.0
rc_proc_getent
rc_proc_getent@@RC_1.0
rc_runlevel_exists
rc_runlevel_exists@@RC_1.0
rc_runlevel_get
rc_runlevel_get@@RC_1.0
rc_runlevel_list
rc_runlevel_list@@RC_1.0
rc_runlevel_set
rc_runlevel_set@@RC_1.0
rc_runlevel_stack
rc_runlevel_stack@@RC_1.0
rc_runlevel_stacks
rc_runlevel_stacks@@RC_1.0
rc_runlevel_starting
rc_runlevel_starting@@RC_1.0
rc_runlevel_stopping
rc_runlevel_stopping@@RC_1.0
rc_runlevel_unstack
rc_runlevel_unstack@@RC_1.0
rc_service_add
rc_service_add@@RC_1.0
rc_service_daemon_set
rc_service_daemon_set@@RC_1.0
rc_service_daemons_crashed
rc_service_daemons_crashed@@RC_1.0
rc_service_delete
rc_service_delete@@RC_1.0
rc_service_description
rc_service_description@@RC_1.0
rc_service_exists
rc_service_exists@@RC_1.0
rc_service_extra_commands
rc_service_extra_commands@@RC_1.0
rc_service_in_runlevel
rc_service_in_runlevel@@RC_1.0
rc_service_mark
rc_service_mark@@RC_1.0
rc_service_resolve
rc_service_resolve@@RC_1.0
rc_service_schedule_clear
rc_service_schedule_clear@@RC_1.0
rc_service_schedule_start
rc_service_schedule_start@@RC_1.0
rc_service_started_daemon
rc_service_started_daemon@@RC_1.0
rc_service_state
rc_service_state@@RC_1.0
rc_service_value_get
rc_service_value_get@@RC_1.0
rc_service_value_set
rc_service_value_set@@RC_1.0
rc_services_in_runlevel
rc_services_in_runlevel@@RC_1.0
rc_services_in_runlevel_stacked
rc_services_in_runlevel_stacked@@RC_1.0
rc_services_in_state
rc_services_in_state@@RC_1.0
rc_services_scheduled
rc_services_scheduled@@RC_1.0
rc_services_scheduled_by
rc_services_scheduled_by@@RC_1.0
rc_stringlist_add
rc_stringlist_add@@RC_1.0
rc_stringlist_addu
rc_stringlist_addu@@RC_1.0
rc_stringlist_delete
rc_stringlist_delete@@RC_1.0
rc_stringlist_find
rc_stringlist_find@@RC_1.0
rc_stringlist_free
rc_stringlist_free@@RC_1.0
rc_stringlist_new
rc_stringlist_new@@RC_1.0
rc_stringlist_sort
rc_stringlist_sort@@RC_1.0
rc_stringlist_split
rc_stringlist_split@@RC_1.0
rc_sys
rc_sys@@RC_1.0
rc_yesno
rc_yesno@@RC_1.0

View File

@@ -92,7 +92,8 @@ respawn_max=x
```
This is the maximum number of times to respawn a supervised process
during the given respawn period. The default is unlimited.
during the given respawn period.
The default is 10. 0 means unlimited.
``` sh
respawn_period=seconds
@@ -101,6 +102,10 @@ respawn_period=seconds
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 60, respawn_max is 2 and respawn_delay
is 3 and a process dies more than 4 times, the process will not be
respawned and the supervisor will terminate.
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.
By default, this is unset and respawn_max applies to the entire lifetime
of the service.

View File

@@ -2,7 +2,7 @@ MK= ../../mk
include ${MK}/os.mk
DIR= ${DATADIR}/support/sysvinit
INC= inittab README.md
INC= halt.sh inittab README.md
include ${MK}/scripts.mk

6
support/sysvinit/halt.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
if [ "$INIT_HALT" = HALT ]; then
exec /sbin/halt -dhn
else
exec /sbin/poweroff -dhn
fi

View File

@@ -10,13 +10,15 @@ si::sysinit:/sbin/openrc sysinit
# Further system initialization, brings up the boot runlevel.
rc::bootwait:/sbin/openrc boot
l0u:0:wait:/sbin/telinit u
l0:0:wait:/sbin/openrc shutdown
l0s:0:wait:/sbin/halt -dhip
l0s:0:wait:/sbin/halt.sh
l1:S1:wait:/sbin/openrc single
l2:2:wait:/sbin/openrc nonetwork
l3:3:wait:/sbin/openrc default
l4:4:wait:/sbin/openrc default
l5:5:wait:/sbin/openrc default
l6u:6:wait:/sbin/telinit u
l6:6:wait:/sbin/openrc reboot
l6r:6:wait:/sbin/reboot -d
#z6:6:respawn:/sbin/sulogin
@@ -34,8 +36,8 @@ c5:2345:respawn:/sbin/agetty 38400 tty5 linux
c6:2345:respawn:/sbin/agetty 38400 tty6 linux
# SERIAL CONSOLES
#s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100
#s1:12345:respawn:/sbin/agetty 9600 ttyS1 vt100
#s0:12345:respawn:/sbin/agetty -L 9600 ttyS0 vt100
#s1:12345:respawn:/sbin/agetty -L 9600 ttyS1 vt100
# What to do at the "Three Finger Salute".
ca:12345:ctrlaltdel:/sbin/shutdown -r now

View File

@@ -1,6 +1,6 @@
#!/bin/sh
top_srcdir=${top_srcdir:-../..}
top_srcdir=${top_srcdir:-..}
. ${top_srcdir}/test/setup_env.sh
libeinfo_srcdir="${srcdir}/../libeinfo"
@@ -27,53 +27,6 @@ fail_on_out() {
fi
}
ebegin "Checking exported symbols in libeinfo.so (data)"
checkit einfo.data $(
readelf -Ws ${libeinfo_builddir}/libeinfo.so \
| awk '$4 == "OBJECT" && $5 == "GLOBAL" && $7 != "UND" {print $NF}' \
| LC_ALL=C sort -u
)
ebegin "Checking exported symbols in libeinfo.so (functions)"
checkit einfo.funcs $(
readelf -Ws ${libeinfo_builddir}/libeinfo.so \
| awk '$4 == "FUNC" && $5 == "GLOBAL" && $7 != "UND" {print $NF}' \
| LC_ALL=C sort -u \
| egrep -v \
-e '^_(init|fini)$'
)
ebegin "Checking exported symbols in librc.so (data)"
checkit rc.data $(
readelf -Ws ${librc_builddir}/librc.so \
| awk '$4 == "OBJECT" && $5 == "GLOBAL" && $7 != "UND" {print $NF}' \
| LC_ALL=C sort -u
)
ebegin "Checking exported symbols in librc.so (functions)"
checkit rc.funcs $(
readelf -Ws ${librc_builddir}/librc.so \
| awk '$4 == "FUNC" && $5 == "GLOBAL" && $7 != "UND" {print $NF}' \
| LC_ALL=C sort -u \
| egrep -v \
-e '^_(init|fini)$'
)
ebegin "Checking hidden functions in librc.so"
sed -n '/^librc_hidden_proto/s:.*(\(.*\))$:\1:p' ${librc_srcdir}/librc.h \
| LC_ALL=C sort -u \
> librc.funcs.hidden.list
readelf -Wr $(grep -l '#include[[:space:]]"librc\.h"' ${librc_srcdir}/*.c | sed 's:\.c$:.o:') \
| egrep -v -e 'R_PARISC_(DP|SEG)REL' \
| awk '$5 ~ /^rc_/ {print $5}' \
| LC_ALL=C sort -u \
| egrep -v '^rc_environ_fd$' \
> librc.funcs.hidden.out
syms=$(diff -u librc.funcs.hidden.list librc.funcs.hidden.out | sed -n '/^+[^+]/s:^+::p')
[ -z "${syms}" ]
eend $? "Missing hidden defs:"$'\n'"${syms}"
: $(( ret += $? ))
ebegin "Checking trailing whitespace in code"
# XXX: Should we check man pages too ?
out=$(cd ${top_srcdir}; find */ \

View File

@@ -1,5 +0,0 @@
#!/bin/sh
# top_srcdir=${top_srcdir:-SET/THIS/PATH/OK!?}
. ${top_srcdir}/test/setup_env.sh

View File

@@ -15,7 +15,6 @@
ret=0
tret=0
ebegin "Testing yesno()"
for f in yes YES Yes true TRUE True 1 ; do
if ! yesno $f; then
: $(( tret += 1 ))
@@ -28,7 +27,7 @@ for f in no NO No false FALSE False 0 ; do
echo "!$f!"
fi
done
eend $tret
: $(( ret += $tret ))
eend $ret
exit $ret

View File

@@ -1,27 +1,37 @@
#compdef rc-service
if (( CURRENT == 2 )); then
_arguments -s \
'(-e --exists)'{-e,--exists}"[tests if the service exists or not]" \
'(-l --list)'{-l,--list}'[list all available services]' \
'(-r --resolve)'{-r,--resolve}'[resolve the service name to an init script]' \
'(-C --nocolor)'{-C,--nocolor}'[Disable color output]' \
'(-v --verbose)'{-v,--verbose}'[Run verbosely]' \
'(-q --quiet)'{-q,--quiet}'[Run quietly]'
_values "service" $(rc-service --list)
else
case $words[2] in
-e|--exists|-r|--resolve)
(( CURRENT > 3 )) && return 0
_values "service" $(rc-service --list)
;;
-*)
return 0
;;
*)
_values "action" stop start restart describe zap
;;
esac
fi
_rc_services() {
if [[ -n "${opt_args[(i)-l|--list]}" ]]; then
_nothing
else
_values 'service' $(rc-service -l)
fi
}
_rc_actions() {
local service="${line[1]}"
if [[ -n "${opt_args[(i)-e|--exists|-r|--resolve]}" ]] || ! $(rc-service -e $service) ; then
_nothing
else
local -a actions=(${(f)"$(rc-service -C $service describe 2>&1)"})
shift actions
actions=(${actions# \* })
actions=(${actions/:*})
actions=(stop start restart describe zap ${actions[@]})
_describe -V 'action' actions
fi
}
_arguments -C -s \
'(-e --exists)'{-e,--exists}'[tests if the service exists or not]' \
'(-l --list)'{-l,--list}'[list all available services]' \
'(-r --resolve)'{-r,--resolve}'[resolve the service name to an init script]' \
'(-C --nocolor)'{-C,--nocolor}'[Disable color output]' \
'(-v --verbose)'{-v,--verbose}'[Run verbosely]' \
'(-q --quiet)'{-q,--quiet}'[Run quietly]' \
'1:service:_rc_services' \
'2:action:_rc_actions'
# vim: set et sw=2 ts=2 ft=zsh: