Compare commits

..

5 Commits

Author SHA1 Message Date
William Hubbs
3e5420b911 version 0.45.2 2022-07-03 12:54:05 -05:00
psykose
9666279210 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:50:51 -05:00
William Hubbs
c7032602dd version 0.45.1 2022-06-10 10:40:38 -05:00
William Hubbs
c253eb0412 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:35:08 -05:00
William Hubbs
8accc2d780 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-10 10:35:08 -05:00
87 changed files with 649 additions and 914 deletions

View File

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

View File

@@ -1,142 +0,0 @@
# 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-2023, the OpenRC authors
Copyright (c) 2007-2015, the OpenRC authors
All rights reserved.
Redistribution and use in source and binary forms, with or without

78
NEWS.md
View File

@@ -4,84 +4,6 @@ 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,26 +85,29 @@ _rc_service()
else
# no option was typed
if [[ ${COMP_CWORD} -eq 1 ]]; then # if first word typed
# complete for init scripts
COMPREPLY=($(for i in $(rc-service --list) ; do \
[[ ${i} == "${cur}"* ]] && echo ${i} ; \
words="$(rc-service --list | grep ^${cur})" # complete for init scripts
COMPREPLY=($(for i in ${words} ; 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
COMPREPLY=($(for i in $(rc-service --list) ; do \
[[ ${i} == "${cur}"* ]] && echo ${i} ; \
words="$(rc-service --list | grep ^${cur})"
COMPREPLY=($(for i in ${words} ; do \
[[ ${i} == ${cur}* ]] && echo ${i} ; \
done))
return 0
fi

View File

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

View File

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

View File

@@ -1,6 +0,0 @@
# 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 NO to turn off unicode support for keyboards and screens.
#unicode="YES"
# Set unicode to YES to turn on unicode support for keyboards and screens.
#unicode="NO"
# 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.glusterfs fuse.sshfs gfs glusterfs lustre
# ncpfs nfs nfs4 ocfs2 shfs smbfs
# afs ceph cifs coda davfs fuse 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,13 +116,12 @@
# Some daemons are started and stopped via start-stop-daemon.
# We can set some things on a per service basis, like the nicelevel.
# These need to be exported
#export SSD_NICELEVEL="0"
#SSD_NICELEVEL="0"
# Or the ionice level. The format is class[:data] , just like the
# --ionice start-stop-daemon parameter.
#export SSD_IONICELEVEL="0:0"
#SSD_IONICELEVEL="0:0"
# Or the OOM score adjustment.
#export SSD_OOM_SCORE_ADJ="0"
#SSD_OOM_SCORE_ADJ="0"
# Pass ulimit parameters
# If you are using bash in POSIX mode for your shell, note that the
@@ -199,10 +198,7 @@ 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="unified"
# override cgroup controller name
#rc_cgroup_name=openrc
#rc_cgroup_mode="hybrid"
# This is a list of controllers which should be enabled for cgroups version 2
# when hybrid mode is being used.

View File

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

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 -e "--noadjfile"; then
if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
echo --noadjfile
fi
fi

View File

@@ -42,7 +42,7 @@ start()
fi
local wkeys= kmode="-a" msg="ASCII"
if yesno ${unicode:-yes}; then
if yesno $unicode; 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 --use-blacklist --verbose "$x"; rc=$? ;;
Linux) modprobe --first-time -q --use-blacklist "$x"; rc=$? ;;
*) ;;
esac
eend
eend $rc "Failed to load $x"
done
return 0
}
@@ -80,10 +80,9 @@ FreeBSD_modules()
for x in $modules; do
ebegin "Loading module $x"
kldload "$x"
eend && : $(( cnt += 1 ))
eend $? "Failed to load $x" && : $(( cnt += 1 ))
done
einfo "Autoloaded $cnt module(s)"
return 0
}
Linux_modules()
@@ -123,7 +122,6 @@ Linux_modules()
eval modprobe --first-time --use-blacklist --verbose "$x" "$args"
done
[ -n "$list" ] && eend
return 0
}
start()

View File

@@ -49,7 +49,9 @@ 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:-yes}; then
if yesno ${unicode:-${UNICODE}}; then
echo "" > "$RC_LIBEXECDIR"/console/unicode
else
rm -f "$RC_LIBEXECDIR"/console/unicode

View File

@@ -10,7 +10,6 @@
# 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()
{
@@ -23,7 +22,7 @@ depend()
start()
{
ebegin "Setting the local clock based on last shutdown time"
if ! swclock "${swclock_file}" 2> /dev/null; then
if ! swclock 2> /dev/null; then
swclock --warn @SBINDIR@/openrc-run
fi
eend $?
@@ -32,6 +31,6 @@ start()
stop()
{
ebegin "Saving the shutdown time"
swclock --save "${swclock_file}"
swclock --save
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:-yes}; then
if yesno ${unicode}; 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:-yes}; then
if yesno ${unicode:-${UNICODE}}; then
echo "" > "$RC_LIBEXECDIR"/console/unicode
else
rm -f "$RC_LIBEXECDIR"/console/unicode

View File

@@ -158,6 +158,13 @@ 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 /run/openrc
.Pa /lib/rc/init.d
as a ramdisk using tmpfs where available unless / is mounted rw at boot.
.Nm
uses
.Pa /run/openrc
.Pa /lib/rc/init.d
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 /run/openrc/deptree .
.Pa /lib/rc/init.d/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 /run/openrc
.Pa /lib/rc/init.d
normally holds the volatile state data for services on a RAM backed disk.
.Sh SEE ALSO
.Xr errno 3 ,

View File

@@ -84,8 +84,6 @@ 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
@@ -185,6 +183,10 @@ 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,23 +158,6 @@ 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.54',
version : '0.45.2',
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', check: true)
r = run_command(uname, '-s')
os = r.stdout().strip()
os = '-'.join(os.split('/'))
else
@@ -83,9 +83,16 @@ 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 = rootprefix_default
endif
bindir = rootprefix / get_option('bindir')
@@ -126,6 +133,15 @@ 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
@@ -160,10 +176,7 @@ 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]
@@ -179,16 +192,6 @@ 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')

View File

@@ -26,7 +26,14 @@ 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/"${rc_cgroup_name:-openrc}"
cgroup=/sys/fs/cgroup/openrc
PATH=/bin:/usr/bin:/sbin:/usr/sbin
if [ -d ${cgroup}/"$1" ]; then
rmdir ${cgroup}/"$1"

View File

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

View File

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

View File

@@ -2,10 +2,8 @@
# 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.glusterfs fuse.sshfs gfs glusterfs lustre
ncpfs nfs nfs4 ocfs2 shfs smbfs
"
net_fs_list="afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre
ncpfs nfs nfs4 ocfs2 shfs smbfs"
is_net_fs()
{
[ -z "$1" ] && return 1

View File

@@ -30,8 +30,6 @@ 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 \
@@ -40,10 +38,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,24 +17,25 @@
*/
#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,
@@ -88,7 +89,7 @@ static int get_dirfd(char *path, bool symlinks)
if (!path || *path != '/')
eerrorx("%s: empty or relative path", applet);
dirfd = openat(AT_FDCWD, "/", O_RDONLY);
dirfd = openat(dirfd, "/", O_RDONLY);
if (dirfd == -1)
eerrorx("%s: unable to open the root directory: %s",
applet, strerror(errno));
@@ -284,7 +285,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
return -1;
}
if (mode && (st.st_mode & 07777) != mode) {
if (mode && (st.st_mode & 0777) != 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,17 +12,20 @@
#define SYSLOG_NAMES
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <strings.h>
#include <unistd.h>
#include "einfo.h"
#include "helpers.h"
@@ -78,7 +81,7 @@ int main(int argc, char **argv)
if (strcmp(applet, "eend") == 0 ||
strcmp(applet, "ewend") == 0 ||
strcmp(applet, "veend") == 0 ||
strcmp(applet, "vewend") == 0 ||
strcmp(applet, "vweend") == 0 ||
strcmp(applet, "ewaitfile") == 0)
{
errno = 0;

View File

@@ -16,14 +16,13 @@
*/
#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
@@ -31,7 +30,6 @@
#ifdef __linux__
# define HAVE_GETMNTENT
# include <mntent.h>
# define ENT mntent
# define START_ENT fp = setmntent ("/etc/fstab", "r");
# define GET_ENT getmntent (fp)
@@ -45,7 +43,6 @@
#else
# define HAVE_GETFSENT
# include <fstab.h>
# define ENT fstab
# define START_ENT
# define GET_ENT getfsent ()
@@ -61,10 +58,8 @@
#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;
@@ -115,7 +110,7 @@ do_mount(struct ENT *ent, bool remount)
{
char *argv[10];
pid_t pid;
int status, err;
int status;
argv[0] = UNCONST("mount");
argv[1] = UNCONST("-o");
@@ -140,14 +135,23 @@ do_mount(struct ENT *ent, bool remount)
argv[8] = NULL;
#endif
}
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;
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 */
}
}
#define OUTPUT_FILE (1 << 1)

View File

@@ -10,9 +10,13 @@
* 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,9 +10,13 @@
* 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,6 +19,7 @@
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,12 +28,11 @@
#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,8 +13,13 @@
#ifndef __EINFO_H__
#define __EINFO_H__
#define EINFO_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
#define EINFO_XPRINTF(a, b) __attribute__((__noreturn__, __format__(__printf__, a, b)))
#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
#include <sys/types.h>
#include <stdbool.h>
@@ -69,22 +74,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-2024 The OpenRC Authors.
* 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/HEAD/AUTHORS
*
@@ -15,17 +15,24 @@
* 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"
@@ -50,7 +57,8 @@
#define HILITE 6
#define BRACKET 4
/* ANSI escape codes which mimic termcap */
/* We fallback to these escape codes if termcap isn't available
* like say /usr isn't mounted */
#define AF "\033[3%dm"
#define CE "\033[K"
#define CH "\033[%dC"
@@ -93,7 +101,13 @@ static char *goto_column = NULL;
static const char *term = NULL;
static bool term_is_cons25 = false;
/* Hardcoded list of colour capable terms
/* 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
* Only terminals without "color" in the name need to be explicitly listed */
static const char *const color_terms[] = {
"Eterm",
@@ -132,11 +146,13 @@ static const char *const color_terms[] = {
"wsvt25",
"xterm",
"xterm-debian",
"xterm-kitty",
NULL
};
#endif
#ifndef HAVE_STRLCPY
/* strlcat and strlcpy are nice, shame glibc does not define them */
#ifdef __GLIBC__
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
static size_t
strlcat(char *dst, const char *src, size_t size)
{
@@ -164,6 +180,7 @@ strlcat(char *dst, const char *src, size_t size)
return dst_n + (s - src);
}
# endif
#endif
static bool
@@ -226,6 +243,7 @@ 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)
{
@@ -288,6 +306,7 @@ tgoto(const char *cap, int col, int line)
*p = '\0';
return buf;
}
#endif
static bool
colour_terminal(FILE * EINFO_RESTRICT f)
@@ -300,6 +319,9 @@ 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;
@@ -321,33 +343,65 @@ colour_terminal(FILE * EINFO_RESTRICT f)
if (strcmp(term, "cons25") == 0)
term_is_cons25 = true;
if (strstr(term, "color"))
in_colour = 1;
while (color_terms[i] && in_colour != 1) {
if (strcmp(color_terms[i], term) == 0) {
in_colour = 1;
}
i++;
#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 (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"))
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
}
if (!_af || !_ce || !_me || !_md || !_up) {
in_colour = 0;
return false;
}
if (!_af)
_af = AF;
if (!_ce)
_ce = CE;
/* Many termcap databases don't have ch or RI even though they
* do work */
if (!_ch)
_ch = CH;
if (!_md)
_md = MD;
if (!_me)
_me = ME;
if (!_up)
_up = UP;
#endif
/* Now setup our colours */
p = ebuffer;
@@ -623,14 +677,15 @@ 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);
_ewarnvn(fmt, ap);
retval = _ewarnvn(fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
retval += fprintf(stderr, "\n");
}
exit(EXIT_FAILURE);
}

View File

@@ -1,7 +1,9 @@
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,21 +15,10 @@
* 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__)
@@ -402,7 +391,7 @@ rc_service_daemon_set(const char *service, const char *exec,
bool retval = false;
DIR *dp;
struct dirent *d;
RC_STRINGLIST *match, *renamelist;
RC_STRINGLIST *match;
int i = 0;
FILE *fp;
@@ -416,17 +405,11 @@ 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) {
@@ -438,15 +421,11 @@ 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,22 +16,9 @@
*/
#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"
@@ -1087,6 +1074,6 @@ rc_deptree_update(void)
}
rc_stringlist_free(config);
free(deptree);
rc_deptree_free(deptree);
return retval;
}

View File

@@ -16,21 +16,11 @@
*/
#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)
@@ -127,7 +117,7 @@ rc_getline(char **line, size_t *len, FILE *fp)
}
char *
rc_proc_getent(const char *ent RC_UNUSED)
rc_proc_getent(const char *ent _unused)
{
#ifdef __linux__
FILE *fp;
@@ -287,7 +277,6 @@ 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,14 +15,8 @@
* 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,26 +15,9 @@
* 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 "misc.h"
#include "rc.h"
#include <helpers.h>
#ifdef __FreeBSD__
# include <sys/sysctl.h>
#endif
@@ -249,7 +232,7 @@ detect_prefix(const char *systype)
}
static const char *
detect_container(const char *systype RC_UNUSED)
detect_container(const char *systype _unused)
{
#ifdef __FreeBSD__
if (systype) {
@@ -313,7 +296,7 @@ detect_container(const char *systype RC_UNUSED)
}
static const char *
detect_vm(const char *systype RC_UNUSED)
detect_vm(const char *systype _unused)
{
#ifdef __NetBSD__
if (systype) {
@@ -772,10 +755,8 @@ 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) {
free(init);
if (symlink(init, was) == -1)
return false;
}
skip_wasinactive = true;
}
if (unlink(file) == -1) {

View File

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

View File

@@ -10,18 +10,24 @@
* 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 <sys/types.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

@@ -15,14 +15,15 @@
* 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__) && \
@@ -32,19 +33,17 @@
#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,3 +6,12 @@ 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,26 +15,28 @@
* 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__)
@@ -52,7 +54,6 @@
#include "plugin.h"
#include "selinux.h"
#include "_usage.h"
#include "helpers.h"
#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
@@ -61,7 +62,7 @@
#define WARN_TIMEOUT 10 /* warn about this every N seconds */
const char *applet = NULL;
const char *extraopts = "stop | start | restart | status | describe | zap";
const char *extraopts = "stop | start | restart | describe | zap";
const char getoptstring[] = "dDsSvl:Z" getoptstring_COMMON;
const struct option longopts[] = {
{ "debug", 0, NULL, 'd'},
@@ -107,9 +108,8 @@ static RC_STRINGLIST *deptypes_mwua; /* need+want+use+after deps for stopping */
static void
handle_signal(int sig)
{
int serrno = errno, status;
pid_t pid;
const char *signame = NULL;
int serrno = errno;
char *signame = NULL;
struct winsize ws;
switch (sig) {
@@ -118,13 +118,12 @@ handle_signal(int sig)
break;
case SIGCHLD:
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));
}
}
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);
break;
case SIGWINCH:
@@ -136,19 +135,20 @@ handle_signal(int sig)
case SIGINT:
if (!signame)
signame = "SIGINT";
xasprintf(&signame, "SIGINT");
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
signame = "SIGTERM";
xasprintf(&signame, "SIGTERM");
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
signame = "SIGQUIT";
xasprintf(&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(void)
unhotplug()
{
char *file = NULL;
@@ -440,7 +440,6 @@ svc_exec(const char *arg1, const char *arg2)
if (errno != EINTR) {
eerror("%s: poll: %s",
service, strerror(errno));
ret = -1;
break;
}
}
@@ -451,20 +450,9 @@ svc_exec(const char *arg1, const char *arg2)
write_prefix(buffer, bytes, &prefixed);
}
/* 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;
/* Only SIGCHLD signals come down this pipe */
if (fd[0].revents & (POLLIN | POLLHUP))
break;
}
}
}
@@ -487,6 +475,11 @@ 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;
@@ -621,7 +614,7 @@ svc_start_check(void)
}
if (exclusive_fd == -1)
exclusive_fd = svc_lock(applet, !deps);
exclusive_fd = svc_lock(applet);
if (exclusive_fd == -1) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
@@ -652,7 +645,7 @@ svc_start_deps(void)
bool first;
RC_STRING *svc, *svc2;
RC_SERVICE state;
int depoptions = RC_DEP_TRACE;
int depoptions = RC_DEP_TRACE, n;
size_t len;
char *p, *tmp;
pid_t pid;
@@ -762,6 +755,7 @@ 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,
@@ -771,6 +765,7 @@ svc_start_deps(void)
rc_stringlist_free(use_services);
use_services = NULL;
len += strlen(svc->value) + 2;
n++;
}
len += 5;
@@ -793,7 +788,7 @@ svc_start_deps(void)
services = NULL;
}
static void svc_start_real(void)
static void svc_start_real()
{
bool started;
RC_STRING *svc, *svc2;
@@ -873,7 +868,7 @@ svc_stop_check(RC_SERVICE *state)
exit(EXIT_FAILURE);
if (exclusive_fd == -1)
exclusive_fd = svc_lock(applet, !deps);
exclusive_fd = svc_lock(applet);
if (exclusive_fd == -1) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
@@ -1050,6 +1045,26 @@ 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();
@@ -1097,6 +1112,7 @@ 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;
@@ -1114,6 +1130,8 @@ 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",
@@ -1147,6 +1165,7 @@ 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);
@@ -1286,6 +1305,9 @@ 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,23 +12,24 @@
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
#include <fcntl.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/utsname.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 <signal.h>
#include <setjmp.h>
#include <paths.h>
#include <sys/utsname.h>
#include "broadcast.h"
#include "helpers.h"
@@ -42,7 +43,12 @@ static sigjmp_buf jbuf;
/*
* Alarm handler
*/
RC_NORETURN static void handler(int arg RC_UNUSED)
/*ARGSUSED*/
# ifdef __GNUC__
static void handler(int arg __attribute__((unused)))
# else
static void handler(int arg)
# endif
{
siglongjmp(jbuf, 1);
}

View File

@@ -19,7 +19,6 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
@@ -27,11 +26,9 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <utmp.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include "broadcast.h"
#include "einfo.h"
@@ -170,13 +167,13 @@ static void sleep_no_interrupt(int seconds)
duration = remaining;
}
RC_NORETURN static void stop_shutdown(int sig)
static void stop_shutdown(int sig)
{
(void) sig;
unlink(nologin_file);
unlink(shutdown_pid);
einfo("Shutdown cancelled");
exit(0);
einfo("Shutdown canceled");
exit(0);
}
int main(int argc, char **argv)
@@ -307,6 +304,7 @@ 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)
@@ -315,12 +313,11 @@ 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,10 +17,11 @@
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "einfo.h"
#include "sysvinit.h"

View File

@@ -6,3 +6,12 @@ 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,7 +16,10 @@
* except according to the terms contained in the LICENSE file.
*/
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <ctype.h>
#include <fcntl.h>
#include <poll.h>
@@ -24,9 +27,6 @@
#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,9 +13,6 @@
#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,21 +20,26 @@
* 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 <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <strings.h>
#include <termios.h>
#include <unistd.h>
@@ -44,9 +49,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;
@@ -59,7 +64,8 @@ const struct option longopts[] = {
};
const char * const longopts_help[] = {
"do not stop any services",
"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
"override the next runlevel to change into\n",
"when 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
@@ -87,7 +93,6 @@ static RC_HOOK hook_out;
struct termios *termios_orig = NULL;
RC_PIDLIST service_pids;
RC_PIDLIST free_these_pids;
static void
clean_failed(void)
@@ -117,7 +122,8 @@ clean_failed(void)
static void
cleanup(void)
{
RC_PID *p, *tmp;
RC_PID *p1 = LIST_FIRST(&service_pids);
RC_PID *p2;
if (!rc_in_logger && !rc_in_plugin &&
applet && (strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0))
@@ -139,13 +145,10 @@ cleanup(void)
rc_logger_close();
}
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);
while (p1) {
p2 = LIST_NEXT(p1, entries);
free(p1);
p1 = p2;
}
rc_stringlist_free(main_hotplugged_services);
@@ -347,46 +350,22 @@ 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, bool inside_signal)
remove_pid(pid_t pid)
{
sigset_t sset, old;
RC_PID *p, *tmp;
RC_PID *p;
/* 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);
LIST_FOREACH(p, &service_pids, entries)
if (p->pid == pid) {
LIST_REMOVE(p, entries);
free(p);
return;
}
}
static void
@@ -404,7 +383,7 @@ static void
handle_signal(int sig)
{
int serrno = errno;
const char *signame = NULL;
char *signame = NULL;
pid_t pid;
RC_PID *pi;
int status = 0;
@@ -424,7 +403,7 @@ handle_signal(int sig)
/* Remove that pid from our list */
if (pid > 0)
remove_pid(pid, true);
remove_pid(pid);
break;
case SIGWINCH:
@@ -436,15 +415,15 @@ handle_signal(int sig)
case SIGINT:
if (!signame)
signame = "SIGINT";
xasprintf(&signame, "SIGINT");
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
signame = "SIGTERM";
xasprintf(&signame, "SIGTERM");
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
signame = "SIGQUIT";
xasprintf(&signame, "SIGQUIT");
eerrorx("%s: caught %s, aborting", applet, signame);
/* NOTREACHED */
case SIGUSR1:
@@ -474,7 +453,7 @@ handle_signal(int sig)
}
static void
do_sysinit(void)
do_sysinit()
{
struct utsname uts;
const char *sys;
@@ -527,7 +506,8 @@ runlevel_config(const char *service, const char *level)
char *conf, *dir;
bool retval;
dir = dirname(dirname(init));
dir = dirname(init);
dir = dirname(init);
xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level);
retval = exists(conf);
free(conf);
@@ -633,7 +613,7 @@ stop:
add_pid(pid);
if (!parallel) {
rc_waitpid(pid);
remove_pid(pid, false);
remove_pid(pid);
}
}
}
@@ -699,7 +679,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
add_pid(pid);
if (!parallel) {
rc_waitpid(pid);
remove_pid(pid, false);
remove_pid(pid);
}
}
}
@@ -717,7 +697,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
}
#ifdef RC_DEBUG
RC_NORETURN static void
static void
handle_bad_signal(int sig)
{
char pid[10];
@@ -772,7 +752,6 @@ 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");
@@ -837,6 +816,8 @@ 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,11 +10,20 @@
* 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,20 +15,27 @@
* 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,9 +15,7 @@
* 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>
@@ -26,8 +24,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,21 +16,17 @@
*/
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.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,
@@ -65,8 +61,8 @@ const char * const longopts_help[] = {
longopts_help_COMMON
};
const char *usagestring = "" \
"Usage: rc-status [options] [-f ini] <runlevel>...\n" \
" or: rc-status [options] [-f ini] [-a | -c | -l | -m | -r | -s | -u]";
"Usage: rc-status [options] -f ini <runlevel>...\n" \
" or: rc-status [options] [-a | -c | -l | -m | -r | -s | -u]";
static RC_DEPTREE *deptree;
static RC_STRINGLIST *types;
@@ -297,7 +293,6 @@ 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();
@@ -317,9 +312,8 @@ int main(int argc, char **argv)
free(s->value);
free(s);
}
print_services(NULL, services, format);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
case 'r':
runlevel = rc_runlevel_get();
printf("%s\n", runlevel);
@@ -330,12 +324,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);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
case 's':
services = rc_services_in_runlevel(NULL);
print_services(NULL, services, format);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
case 'u':
@@ -350,7 +344,7 @@ int main(int argc, char **argv)
break;
}
}
print_services(NULL, services, format);
print_services(NULL, services, FORMAT_DEFAULT);
goto exit;
/* NOTREACHED */
@@ -450,7 +444,6 @@ 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,6 +17,7 @@
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -28,7 +29,6 @@
#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 deleted from runlevel %s",
einfo("service %s removed 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 delete service `%s' from runlevel `%s': %s",
eerror("%s: failed to remove 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 deleted from runlevel %s", stack, runlevel);
einfo("runlevel %s removed 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 delete runlevel `%s' from runlevel `%s': %s",
eerror("%s: failed to remove runlevel `%s' from runlevel `%s': %s",
applet, stack, runlevel, strerror (errno));
return -1;

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2022-2023 The OpenRC Authors.
* Copyright (c) 2022 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;
const char *seed_dir = NULL;
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 = optarg;
seed_dir = xstrdup(optarg);
break;
case LONGOPT_SKIP_CREDIT:
skip_credit = true;
@@ -479,7 +479,7 @@ int main(int argc, char **argv)
}
}
if (!seed_dir)
seed_dir = DEFAULT_SEED_DIR;
seed_dir = xstrdup(DEFAULT_SEED_DIR);
if (getuid())
eerrorx("%s: superuser access is required", applet);
umask(0077);

View File

@@ -10,16 +10,24 @@
* 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,13 +13,19 @@
#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)
{
@@ -36,7 +42,7 @@ void set_quiet_options(void)
}
}
RC_NORETURN void show_version(void)
_noreturn void show_version(void)
{
const char *systype = NULL;
@@ -51,7 +57,7 @@ RC_NORETURN void show_version(void)
exit(EXIT_SUCCESS);
}
RC_NORETURN void usage(int exit_status)
_noreturn void usage(int exit_status)
{
const char * const has_arg[] = { "", "<arg>", "[arg]" };
int i;

View File

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

View File

@@ -18,27 +18,29 @@
#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 *)(uintptr_t)(const void *)(a))
#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#define RC_UNUSED __attribute__((__unused__))
#define RC_NORETURN __attribute__((__noreturn__))
#define RC_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
#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 ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#ifndef HAVE_STRLCPY
#ifdef __GLIBC__
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
# define strlcpy(dst, src, size) snprintf(dst, size, "%s", src)
# endif
#endif
#ifndef timespecsub
@@ -53,7 +55,11 @@
} while (/* CONSTCOND */ 0)
#endif
RC_UNUSED static void *xmalloc (size_t size)
#include <stdarg.h>
#include <stdbool.h>
#include <sys/stat.h>
_unused static void *xmalloc (size_t size)
{
void *value = malloc(size);
@@ -64,7 +70,7 @@ RC_UNUSED static void *xmalloc (size_t size)
/* NOTREACHED */
}
RC_UNUSED static void *xrealloc(void *ptr, size_t size)
_unused static void *xrealloc(void *ptr, size_t size)
{
void *value = realloc(ptr, size);
@@ -75,7 +81,7 @@ RC_UNUSED static void *xrealloc(void *ptr, size_t size)
/* NOTREACHED */
}
RC_UNUSED static char *xstrdup(const char *str)
_unused static char *xstrdup(const char *str)
{
char *value;
@@ -97,7 +103,7 @@ RC_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.
*/
RC_UNUSED static const char *basename_c(const char *path)
_unused static const char *basename_c(const char *path)
{
const char *slash = strrchr(path, '/');
@@ -106,14 +112,14 @@ RC_UNUSED static const char *basename_c(const char *path)
return (path);
}
RC_UNUSED static bool exists(const char *pathname)
_unused static bool exists(const char *pathname)
{
struct stat buf;
return (stat(pathname, &buf) == 0);
}
RC_UNUSED static bool existss(const char *pathname)
_unused static bool existss(const char *pathname)
{
struct stat buf;
@@ -123,12 +129,12 @@ RC_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 ensure that we have a consistent function across
* glibc systems and to insure 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.
*/
RC_UNUSED RC_PRINTF(2,3) static int xasprintf(char **strp, const char *fmt, ...)
_unused _xasprintf(2,3) static int xasprintf(char **strp, const char *fmt, ...)
{
va_list ap;
int len;

View File

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

View File

@@ -15,30 +15,22 @@
* except according to the terms contained in the LICENSE file.
*/
#ifdef HAVE_CLOSE_RANGE
/* For close_range() */
# define _GNU_SOURCE
#include <sys/file.h>
#include <sys/types.h>
#include <sys/utsname.h>
#ifdef __linux__
# include <sys/sysinfo.h>
#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>
@@ -48,7 +40,6 @@
#include "rc.h"
#include "misc.h"
#include "version.h"
#include "helpers.h"
extern char **environ;
@@ -243,7 +234,7 @@ signal_setup_restart(int sig, void (*handler)(int))
}
int
svc_lock(const char *applet, bool ignore_lock_failure)
svc_lock(const char *applet)
{
char *file = NULL;
int fd;
@@ -254,14 +245,6 @@ svc_lock(const char *applet, bool ignore_lock_failure)
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;
@@ -291,7 +274,7 @@ exec_service(const char *service, const char *arg)
sigset_t old;
struct sigaction sa;
fd = svc_lock(basename_c(service), false);
fd = svc_lock(basename_c(service));
if (fd == -1)
return -1;
@@ -509,30 +492,3 @@ 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,7 +19,6 @@
#define __RC_MISC_H__
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -28,7 +27,6 @@
#include <unistd.h>
#include "helpers.h"
#include "rc.h"
#define RC_LEVEL_BOOT "boot"
#define RC_LEVEL_DEFAULT "default"
@@ -50,7 +48,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 *, bool);
int svc_lock(const char *);
int svc_unlock(const char *, int);
pid_t exec_service(const char *, const char *);
@@ -73,6 +71,4 @@ 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

@@ -17,10 +17,12 @@
#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>
@@ -30,8 +32,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,11 +18,6 @@
#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,11 +30,16 @@
#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,9 +13,6 @@
#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,12 +15,14 @@
* 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,7 +19,6 @@
#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,9 +10,14 @@
* 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

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

View File

@@ -26,44 +26,47 @@
# 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"
@@ -179,9 +182,9 @@ extern char **environ;
# define SYS_ioprio_set __NR_ioprio_set
#endif
#if !defined(__DragonFly__)
static inline int ioprio_set(int which RC_UNUSED,
int who RC_UNUSED,
int ioprio RC_UNUSED)
static inline int ioprio_set(int which _unused,
int who _unused,
int ioprio _unused)
{
#ifdef SYS_ioprio_set
return syscall(SYS_ioprio_set, which, who, ioprio);
@@ -204,20 +207,20 @@ handle_signal(int sig)
{
int status;
int serrno = errno;
const char *signame = NULL;
char *signame = NULL;
switch (sig) {
case SIGINT:
if (!signame)
signame = "SIGINT";
xasprintf(&signame, "SIGINT");
/* FALLTHROUGH */
case SIGTERM:
if (!signame)
signame = "SIGTERM";
xasprintf(&signame, "SIGTERM");
/* FALLTHROUGH */
case SIGQUIT:
if (!signame)
signame = "SIGQUIT";
xasprintf(&signame, "SIGQUIT");
eerrorx("%s: caught %s, aborting", applet, signame);
/* NOTREACHED */
@@ -236,6 +239,9 @@ handle_signal(int sig)
eerror("%s: caught unknown signal %d", applet, sig);
}
/* free signame */
free(signame);
/* Restore errno */
errno = serrno;
}
@@ -348,9 +354,6 @@ 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);
@@ -861,17 +864,12 @@ 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
@@ -880,23 +878,11 @@ 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 &&
@@ -1098,7 +1084,8 @@ int main(int argc, char **argv)
|| rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO);
cloexec_fds_from(3);
for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
if (scheduler != NULL) {
int scheduler_index;
@@ -1131,6 +1118,7 @@ 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)
@@ -1141,18 +1129,6 @@ 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', pipes_c, misc_c, plugin_c, schedules_c, usage_c, version_h],
['supervise-daemon.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,6 +22,20 @@
#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>
@@ -33,17 +47,7 @@
#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>
@@ -62,7 +66,6 @@ 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"
@@ -80,8 +83,6 @@ enum {
LONGOPT_OOM_SCORE_ADJ,
LONGOPT_NO_NEW_PRIVS,
LONGOPT_SECBITS,
LONGOPT_STDERR_LOGGER,
LONGOPT_STDOUT_LOGGER,
};
const char *applet = NULL;
@@ -113,8 +114,6 @@ 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
};
@@ -143,8 +142,6 @@ 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
};
@@ -167,8 +164,6 @@ 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
@@ -196,8 +191,8 @@ extern char **environ;
# define SYS_ioprio_set __NR_ioprio_set
#endif
#if !defined(__DragonFly__)
static inline int ioprio_set(int which RC_UNUSED, int who RC_UNUSED,
int ioprio RC_UNUSED)
static inline int ioprio_set(int which _unused, int who _unused,
int ioprio _unused)
{
#ifdef SYS_ioprio_set
return syscall(SYS_ioprio_set, which, who, ioprio);
@@ -212,7 +207,7 @@ static void cleanup(void)
free(changeuser);
}
RC_NORETURN static void re_exec_supervisor(void)
static void re_exec_supervisor(void)
{
syslog(LOG_WARNING, "Re-executing for %s", svcname);
execlp("supervise-daemon", "supervise-daemon", svcname, "--reexec",
@@ -358,7 +353,7 @@ static pid_t exec_command(const char *cmd)
return pid;
}
RC_NORETURN static void child_process(char *exec, char **argv)
static void child_process(char *exec, char **argv)
{
RC_STRINGLIST *env_list;
RC_STRING *env;
@@ -396,14 +391,6 @@ RC_NORETURN 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)
@@ -558,12 +545,6 @@ RC_NORETURN 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,
@@ -572,22 +553,16 @@ RC_NORETURN 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 || stdout_process || rc_yesno(getenv("EINFO_QUIET")))
if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
dup2(stdout_fd, STDOUT_FILENO);
if (redirect_stderr || stderr_process || rc_yesno(getenv("EINFO_QUIET")))
if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO);
cloexec_fds_from(3);
for (i = getdtablesize() - 1; i >= 3; --i)
fcntl(i, F_SETFD, FD_CLOEXEC);
cmdline = make_cmdline(argv);
syslog(LOG_INFO, "Child command line: %s", cmdline);
free(cmdline);
@@ -600,7 +575,7 @@ RC_NORETURN static void child_process(char *exec, char **argv)
eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
}
RC_NORETURN static void supervisor(char *exec, char **argv)
static void supervisor(char *exec, char **argv)
{
FILE *fp;
char buf[2048];
@@ -1060,14 +1035,6 @@ 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,18 +19,22 @@
*/
#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";
@@ -50,7 +54,7 @@ const char *usagestring = NULL;
int main(int argc, char **argv)
{
int opt, sflag = 0, wflag = 0;
const char *file = NULL;
const char *file = RC_SHUTDOWNTIME;
struct stat sb;
struct timeval tv;
@@ -71,16 +75,16 @@ int main(int argc, char **argv)
if (optind < argc)
file = argv[optind++];
else
eerrorx("swclock: Reference file was not specified");
if (sflag) {
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);
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));
return 0;
}

View File

@@ -12,14 +12,24 @@
#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 "helpers.h"
#include "misc.h"
const char *applet = NULL;

View File

@@ -1,54 +1,55 @@
# 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
```
@@ -56,29 +57,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
```
@@ -86,7 +87,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
```
@@ -94,17 +95,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

@@ -11,7 +11,8 @@ sysvinit="$4"
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
ln -s openrc-init "${DESTDIR}/${sbindir}"/init
fi