Compare commits
	
		
			5 Commits
		
	
	
		
			cgroup-nam
			...
			0.45.2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3e5420b911 | ||
|   | 9666279210 | ||
|   | c7032602dd | ||
|   | c253eb0412 | ||
|   | 8accc2d780 | 
| @@ -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: > | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								NEWS.md
									
									
									
									
									
								
							| @@ -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. | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -1,2 +0,0 @@ | ||||
| # override cgroup mount options | ||||
| #cgroup_opts=nodev,noexec,nosuid | ||||
| @@ -7,7 +7,6 @@ conf_common = [ | ||||
|   'localmount', | ||||
|   'netmount', | ||||
|   'swap', | ||||
|   'swclock', | ||||
|   ] | ||||
|  | ||||
| conf_net = [ | ||||
|   | ||||
| @@ -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 | ||||
							
								
								
									
										20
									
								
								etc/rc.conf
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								etc/rc.conf
									
									
									
									
									
								
							| @@ -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. | ||||
|   | ||||
| @@ -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 ;; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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}" | ||||
| 			;; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 $? | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 , | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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). | ||||
|   | ||||
							
								
								
									
										35
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								meson.build
									
									
									
									
									
								
							| @@ -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') | ||||
|   | ||||
| @@ -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') | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -79,7 +79,6 @@ elif ! mountinfo -q /run; then | ||||
| 			exit 1 | ||||
| 		fi | ||||
| 	fi | ||||
| 	eend | ||||
| fi | ||||
|  | ||||
| checkpath -d "$RC_SVCDIR" | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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=$? | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
| 	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) | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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]"; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,6 +343,25 @@ colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| 	if (strcmp(term, "cons25") == 0) | ||||
| 		term_is_cons25 = true; | ||||
|  | ||||
| #ifdef HAVE_TERMCAP | ||||
| 	/* Check termcap to see if we can do colour or not */ | ||||
| 	if (tgetent(termcapbuf, term) == 1) { | ||||
| 		bp = tcapbuf; | ||||
| 		_af = tgetstr("AF", &bp); | ||||
| 		_ce = tgetstr("ce", &bp); | ||||
| 		_ch = tgetstr("ch", &bp); | ||||
| 		/* Our ch use also works with RI .... for now */ | ||||
| 		if (!_ch) | ||||
| 			_ch = tgetstr("RI", &bp); | ||||
| 		_md = tgetstr("md", &bp); | ||||
| 		_me = tgetstr("me", &bp); | ||||
| 		_up = tgetstr("up", &bp); | ||||
| 	} | ||||
|  | ||||
| 	/* 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; | ||||
|  | ||||
| @@ -335,7 +376,7 @@ colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| 			in_colour = 0; | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| #endif | ||||
| 		if (!_af) | ||||
| 			_af = AF; | ||||
| 		if (!_ce) | ||||
| @@ -348,6 +389,19 @@ colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| 			_me = ME; | ||||
| 		if (!_up) | ||||
| 			_up = UP; | ||||
| #ifdef HAVE_TERMCAP | ||||
| 	} | ||||
|  | ||||
| 	if (!_af || !_ce || !_me || !_md || !_up) { | ||||
| 		in_colour = 0; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	/* Many termcap databases don't have ch or RI even though they | ||||
| 	 * do work */ | ||||
| 	if (!_ch) | ||||
| 		_ch = CH; | ||||
| #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); | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 */ | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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"; | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
| 		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,21 +450,10 @@ 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; | ||||
| 			/* Only SIGCHLD signals come down this pipe */ | ||||
| 			if (fd[0].revents & (POLLIN | POLLHUP)) | ||||
| 				break; | ||||
| 		} | ||||
| 				ret = WEXITSTATUS(ret); | ||||
| 				if (ret != 0 && errno == ECHILD) | ||||
| 					/* killall5 -9 could cause this */ | ||||
| 					ret = 0; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	free(buffer); | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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,7 +313,6 @@ 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) { | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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) { | ||||
| 	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); | ||||
| 		    return; | ||||
| 	    } | ||||
| 	} | ||||
| 	sigprocmask(SIG_SETMASK, &old, NULL); | ||||
| } | ||||
|  | ||||
| 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. | ||||
|   | ||||
| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -11,7 +11,6 @@ | ||||
|  */ | ||||
|  | ||||
| #include <getopt.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #define getoptstring_COMMON "ChqVv" | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -10,10 +10,6 @@ schedules_c = files([ | ||||
|   'schedules.c', | ||||
|   ]) | ||||
|  | ||||
| pipes_c = files([ | ||||
| 	'pipes.c', | ||||
| 	]) | ||||
|  | ||||
| if selinux_dep.found() | ||||
|   selinux_c = files([ | ||||
|     'selinux.c', | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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], | ||||
|   | ||||
| @@ -16,8 +16,8 @@ | ||||
|  */ | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <sys/types.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| 
 | ||||
| #include "pipes.h" | ||||
| 
 | ||||
| @@ -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 */ | ||||
|   | ||||
| @@ -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], | ||||
|   | ||||
| @@ -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 | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| 		if (stat(file, &sb) == -1) { | ||||
| 			opt = open(file, O_WRONLY | O_CREAT, 0644); | ||||
| 			if (opt == -1) | ||||
| 				eerrorx("swclock: open: %s", strerror(errno)); | ||||
| 		if (futimens(fd, NULL) == -1) | ||||
| 			eerrorx("swclock: futimens: %s", strerror(errno)); | ||||
| 		close(fd); | ||||
| 			close(opt); | ||||
| 		} else | ||||
| 			if (utime(file, NULL) == -1) | ||||
| 				eerrorx("swclock: utime: %s", strerror(errno)); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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,7 +57,7 @@ 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" | ||||
| ``` | ||||
|  | ||||
| @@ -64,21 +65,21 @@ 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. | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user