Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a3abfe9aa6 | ||
| 
						 | 
					c0303de192 | ||
| 
						 | 
					5443196bcd | ||
| 
						 | 
					df8a3008a1 | 
							
								
								
									
										256
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										256
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,225 +1,20 @@
 | 
				
			|||||||
commit eecf868e3c4a763b08cd4b3803f4839e8e710413
 | 
					commit c0303de1923940cdf4ba5921c1ec128cb0748559
 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: clarify a log message
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit a5cd486a7fbb5acf8e8f3085500fd86c23dd8641
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Update ChangeLog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 6e6b4ac5fa935eb8052d293f2b8378e0395572e1
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: log the command line we run to spawn the child process
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 558ff4d5fb90b751ebc2852ea907873af2c236fa
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: log with the service name instead of "supervise-daemon"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 490f855aef581a720c6c0be0d8407fe6d279f9f5
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    implement "unsupervised" status
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    The unsupervised status is to be used when a supervisor of a supervised
 | 
					 | 
				
			||||||
    service dies but leaves the service daemon itself running.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit d1491e201d3ad364e25a55b29ff8035775a6acac
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: remove child_pid from saved options during shutdown
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    This allows us to detect when the supervisor dies unexpectedly because
 | 
					 | 
				
			||||||
    in that case child_pid will still exist.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 3231af937590b1c00af1a459009472a371aeb04a
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rc_service_value_set: remove the option if NULL is the value
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    This allows the equivalent of "unsetting" a value for a service.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit a5758e7aeffbeb9766ba3055a3fc347f0ccd3d35
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon.sh: fix status function with no namespaces
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 61a9393ce12fda412bdca4002ac71e7df82384df
 | 
					 | 
				
			||||||
Author: Patrick McLean <chutzpah@gentoo.org>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cgroups_cleanup: clean up shutdown signaling
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    - do not sleep for the full 90 seconds if processes are dead
 | 
					 | 
				
			||||||
    - re-arrange the order of signals we attempt to send to the processes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 161d22cb074ecef7003e19682d72a8ee61c14490
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    version 0.34.3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 3a96ca1c966c3cc44a2e0e51b383ab47d078bcc1
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Update ChangeLog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 934530914bd507476b428d3f6572bbb1c5bbfd16
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    add "unsupervised" status and return code 64 to supervise-daemon status function
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    This is to be used if the service is being supervised and the
 | 
					 | 
				
			||||||
    supervisor is somehow killed.
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Currently, this is very linux specific, but I will expand to other
 | 
					 | 
				
			||||||
    platforms, patches are welcome.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit b717625cd27950c3f00b5345bc1cee9700e79498
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    version 0.34.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit b47539613431521e5e99bc388e6a9d8eb0e48801
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Update ChangeLog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit e7b1d898ca7896d6443ba1e5167eb6bcf3f92929
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: fix build issue for >=glibc-2.26
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    X-Gentoo-Bug: 635334
 | 
					 | 
				
			||||||
    X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=635334
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 5cd09a6f44aa7d16ab7de1453e37d01448426031
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    version 0.34.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit f3c70bf5b5aa18e8dc94d4949f05568e0741c5cb
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Update ChangeLog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit f5acc66db7d1a0bfad6a40eefc0240b80f52df94
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rc_find_pids: ignore pids that are not in our pid namespace
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    X-Gentoo-Bug: 634634
 | 
					 | 
				
			||||||
    X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=634634
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit fdce4769f2e0f4175163ffa181c7b3b2192f7b22
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: multiple fixes
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    - Harden against dying by handling all signals that would terminate the
 | 
					 | 
				
			||||||
    program and adding --reexec support
 | 
					 | 
				
			||||||
    - factor the supervisor into its own function
 | 
					 | 
				
			||||||
    - fix test for whether we are already running
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 35b1996704f6635bb29ea3604410e133209e6432
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    supervise-daemon: elevate some log messages to warnings
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Prior to this change, we were logging unexpected terminations of daemons
 | 
					 | 
				
			||||||
    we were supervising at the info level. This change moves the logs to
 | 
					 | 
				
			||||||
    warnings.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 3c8e7ed255edb8df0d548d6ce514544d5422cbf0
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    version 0.34
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit acaed1f910a2a00fdd5b6aeab752c552075a7292
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Update ChangeLog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 91109e31d81ecd48f5690ad6f63103fca545dec7
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    update news
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 2b6eeea01d1c64d58929788f4bfa0758393885bf
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    man: remove service(8) man page
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit a15de23e5713d840d871c526b46050983dc6ea1e
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    typo fix
 | 
					    typo fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
commit efa9ba485d9328f780f3e60dc18339c75974c6c6
 | 
					commit 5443196bcdcd7c995d13d6822bcee50d0ab5e1be
 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    init.d/sysfs.in: fix reference to RC_LIBEXECDIR
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    The sysfs init script referred to @LIBEXECDIR@ before this change, but
 | 
					 | 
				
			||||||
    it is better to refer to RC_LIBEXECDIR so that we get rid of a sed
 | 
					 | 
				
			||||||
    substitution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit d4ddd72701ff5533a1ba07b1da60806859c63d88
 | 
					 | 
				
			||||||
Author: Chris Cromer <chris@cromer.cl>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    add option to make agetty startup quiet
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    This fixes #150
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 1e9af2cd421423404ffe1491bd35af76c2885f1f
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fix compiler warning
 | 
					    fix compiler warning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
commit 3c05db74f6e733890e9035c183a774db3d512512
 | 
					commit df8a3008a1473ae7238483db7827cb63cfc39789
 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    remove service binary
 | 
					    version 0.32.1
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    The service binary was just a synonym for rc-service, so use rc-service
 | 
					 | 
				
			||||||
    instead of service. If you want a "service" binary, it should be
 | 
					 | 
				
			||||||
    something that can determine which service manager you are running and
 | 
					 | 
				
			||||||
    run the appropriate service manager commands.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit edc54b03770d5f58d1a4969d06c28660003dfb04
 | 
					 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    version 0.33
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
commit 8e53a3fa8a33fb714064ddbe38bff2213fcf6837
 | 
					commit 8e53a3fa8a33fb714064ddbe38bff2213fcf6837
 | 
				
			||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
@@ -1570,3 +1365,46 @@ Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			|||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    src/rc/rc: do not try to start services if fork fails
 | 
					    src/rc/rc: do not try to start services if fork fails
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit 003657c973ea338a19f2b7294190af9d76cf5cea
 | 
				
			||||||
 | 
					Author: Robin H. Johnson <robbat2@gentoo.org>
 | 
				
			||||||
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    init.d/loopback: drop scope on loopback
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Busybox does not support the 'scope' argument on 'ip address add' or 'ip
 | 
				
			||||||
 | 
					    route add', this is documented in BUSYBOX.md, but is no longer actually
 | 
				
			||||||
 | 
					    needed, as the kernel does get it right without manual specification,
 | 
				
			||||||
 | 
					    and the ifconfig variant already relies on the kernel to get it right.
 | 
				
			||||||
 | 
					    This is part of #103.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    X-Gentoo-Bug: 487208
 | 
				
			||||||
 | 
					    X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=487208
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit 4fd144c0a6526963c70f18cb34a65354c2f0a48c
 | 
				
			||||||
 | 
					Author: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    src/rc/rc-misc.c: report error if call to flock() fails
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    X-Gentoo-Bug: 597390
 | 
				
			||||||
 | 
					    X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=597390
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit c44c904a61418189c989e978b0237e5b161263ef
 | 
				
			||||||
 | 
					Author: Joe Maloney <jpm820@gmail.com>
 | 
				
			||||||
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    init.d.misc/wpa_supplicant: find wireless interface for FreeBSD
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    This fixes #101.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit 78146b0e14cb57dda8a3aed3d4f8d6b1db7a3c7e
 | 
				
			||||||
 | 
					Author: Sven Wegener <swegener@gentoo.org>
 | 
				
			||||||
 | 
					Commit: William Hubbs <w.d.hubbs@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do_service: Initialize idx to 0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    If index is not explicitly specified for service_started_daemon, it will
 | 
				
			||||||
 | 
					    look for daemons by random index.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    This fixes #100.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
NAME=		openrc
 | 
					NAME=		openrc
 | 
				
			||||||
VERSION=	0.34.3
 | 
					VERSION=	0.32.1
 | 
				
			||||||
PKG=		${NAME}-${VERSION}
 | 
					PKG=		${NAME}-${VERSION}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -3,15 +3,6 @@
 | 
				
			|||||||
This file will contain a list of notable changes for each release. Note
 | 
					This file will contain a list of notable changes for each release. Note
 | 
				
			||||||
the information in this file is in reverse order.
 | 
					the information in this file is in reverse order.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## OpenRC 0.33
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This version removes the "service" binary which was just a copy of
 | 
					 | 
				
			||||||
"rc-service" provided for compatibility.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you still need the "service" binary, as opposed to "rc-service", it is
 | 
					 | 
				
			||||||
recommended that you use something like Debian's init-system-helpers.
 | 
					 | 
				
			||||||
Otherwise, just use "rc-service" in place of "service".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC 0.31
 | 
					## OpenRC 0.31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This version adds support for Control Groups version 2, which is
 | 
					This version adds support for Control Groups version 2, which is
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
# make agetty quiet
 | 
					 | 
				
			||||||
#quiet="yes"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Set the baud rate of the terminal line
 | 
					# Set the baud rate of the terminal line
 | 
				
			||||||
#baud=""
 | 
					#baud=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								guide.md
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								guide.md
									
									
									
									
									
								
							@@ -53,6 +53,9 @@ Calling `openrc` without any arguments will try to reset all services so
 | 
				
			|||||||
that the current runlevel is satisfied; if you manually started apache it will be 
 | 
					that the current runlevel is satisfied; if you manually started apache it will be 
 | 
				
			||||||
stopped, and if squid died but is in the current runlevel it'll be restarted.
 | 
					stopped, and if squid died but is in the current runlevel it'll be restarted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is a `service` helper that emulates the syntax seen on e.g. older Redhat
 | 
				
			||||||
 | 
					and Ubuntu (`service nginx start` etc.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Runlevels
 | 
					# Runlevels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OpenRC has a concept of runlevels, similar to what sysvinit historically 
 | 
					OpenRC has a concept of runlevels, similar to what sysvinit historically 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@ term_type="${term_type:-linux}"
 | 
				
			|||||||
command=/sbin/agetty
 | 
					command=/sbin/agetty
 | 
				
			||||||
command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
 | 
					command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
 | 
				
			||||||
pidfile="/run/${RC_SVCNAME}.pid"
 | 
					pidfile="/run/${RC_SVCNAME}.pid"
 | 
				
			||||||
export EINFO_QUIET="${quiet:-yes}"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend() {
 | 
					depend() {
 | 
				
			||||||
	after local
 | 
						after local
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,7 +118,7 @@ cgroup1_base()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ! mountinfo -q /sys/fs/cgroup/openrc; then
 | 
						if ! mountinfo -q /sys/fs/cgroup/openrc; then
 | 
				
			||||||
		local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh"
 | 
							local agent="@LIBEXECDIR@/sh/cgroup-release-agent.sh"
 | 
				
			||||||
		mkdir /sys/fs/cgroup/openrc
 | 
							mkdir /sys/fs/cgroup/openrc
 | 
				
			||||||
		mount -n -t cgroup \
 | 
							mount -n -t cgroup \
 | 
				
			||||||
			-o none,${sysfs_opts},name=openrc,release_agent="$agent" \
 | 
								-o none,${sysfs_opts},name=openrc,release_agent="$agent" \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ MAN3=		einfo.3 \
 | 
				
			|||||||
		rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
 | 
							rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
 | 
				
			||||||
		rc_runlevel.3 rc_service.3 rc_stringlist.3
 | 
							rc_runlevel.3 rc_service.3 rc_stringlist.3
 | 
				
			||||||
MAN8=		rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
 | 
					MAN8=		rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
 | 
				
			||||||
		start-stop-daemon.8 supervise-daemon.8
 | 
							service.8 start-stop-daemon.8 supervise-daemon.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${OS},Linux)
 | 
					ifeq (${OS},Linux)
 | 
				
			||||||
MAN8 += rc-sstat.8 openrc-init.8 openrc-shutdown.8
 | 
					MAN8 += rc-sstat.8 openrc-init.8 openrc-shutdown.8
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								man/service.8
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								man/service.8
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.so rc-service.8
 | 
				
			||||||
@@ -203,21 +203,15 @@ cgroup_cleanup()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	cgroup_running || return 0
 | 
						cgroup_running || return 0
 | 
				
			||||||
	ebegin "starting cgroups cleanup"
 | 
						ebegin "starting cgroups cleanup"
 | 
				
			||||||
	local pids loops=0
 | 
						local pids
 | 
				
			||||||
	pids="$(cgroup_get_pids)"
 | 
						pids="$(cgroup_get_pids)"
 | 
				
			||||||
	if [ -n "${pids}" ]; then
 | 
						if [ -n "${pids}" ]; then
 | 
				
			||||||
		kill -s CONT ${pids} 2> /dev/null
 | 
					 | 
				
			||||||
		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
							kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
				
			||||||
 | 
							kill -s CONT ${pids} 2> /dev/null
 | 
				
			||||||
		yesno "${rc_send_sighup:-no}" &&
 | 
							yesno "${rc_send_sighup:-no}" &&
 | 
				
			||||||
			kill -s HUP ${pids} 2> /dev/null
 | 
								kill -s HUP ${pids} 2> /dev/null
 | 
				
			||||||
		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
							sleep "${rc_timeout_stopsec:-90}"
 | 
				
			||||||
		while [ -n "$(cgroup_get_pids)" ] &&
 | 
							yesno "${rc_send_sigkill:-yes}" &&
 | 
				
			||||||
			[ "${loops}" -lt "${rc_timeout_stopsec:-90}" ]; do
 | 
					 | 
				
			||||||
			loops=$((loops+1))
 | 
					 | 
				
			||||||
			sleep 1
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		pids="$(cgroup_get_pids)"
 | 
					 | 
				
			||||||
		[ -n "${pids}" ] && yesno "${rc_send_sigkill:-yes}" &&
 | 
					 | 
				
			||||||
			kill -s KILL ${pids} 2> /dev/null
 | 
								kill -s KILL ${pids} 2> /dev/null
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	cgroup2_remove
 | 
						cgroup2_remove
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,41 +56,7 @@ supervise_stop()
 | 
				
			|||||||
	eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
						eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_check_supervised()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local child_pid start_time
 | 
					 | 
				
			||||||
	child_pid="$(service_get_value "child_pid")"
 | 
					 | 
				
			||||||
	start_time="$(service_get_value "start_time")"
 | 
					 | 
				
			||||||
	if [ -n "${child_pid}" ] && [ -n "${start_time}" ]; then
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_status()
 | 
					supervise_status()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if service_stopping; then
 | 
						_status
 | 
				
			||||||
		ewarn "status: stopping"
 | 
					 | 
				
			||||||
		return 4
 | 
					 | 
				
			||||||
	elif service_starting; then
 | 
					 | 
				
			||||||
		ewarn "status: starting"
 | 
					 | 
				
			||||||
		return 8
 | 
					 | 
				
			||||||
	elif service_inactive; then
 | 
					 | 
				
			||||||
		ewarn "status: inactive"
 | 
					 | 
				
			||||||
		return 16
 | 
					 | 
				
			||||||
	elif service_started; then
 | 
					 | 
				
			||||||
		if service_crashed; then
 | 
					 | 
				
			||||||
			if ! _check_supervised; then
 | 
					 | 
				
			||||||
				eerror "status: unsupervised"
 | 
					 | 
				
			||||||
				return 64
 | 
					 | 
				
			||||||
			fi
 | 
					 | 
				
			||||||
			eerror "status: crashed"
 | 
					 | 
				
			||||||
			return 32
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		einfo "status: started"
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		einfo "status: stopped"
 | 
					 | 
				
			||||||
		return 3
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,6 @@ bool rc_conf_yesno(const char *var);
 | 
				
			|||||||
void env_filter(void);
 | 
					void env_filter(void);
 | 
				
			||||||
void env_config(void);
 | 
					void env_config(void);
 | 
				
			||||||
int signal_setup(int sig, void (*handler)(int));
 | 
					int signal_setup(int sig, void (*handler)(int));
 | 
				
			||||||
int signal_setup_restart(int sig, void (*handler)(int));
 | 
					 | 
				
			||||||
int svc_lock(const char *);
 | 
					int svc_lock(const char *);
 | 
				
			||||||
int svc_unlock(const char *, int);
 | 
					int svc_unlock(const char *, int);
 | 
				
			||||||
pid_t exec_service(const char *, const char *);
 | 
					pid_t exec_service(const char *, const char *);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,12 +80,9 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
	DIR *procdir;
 | 
						DIR *procdir;
 | 
				
			||||||
	struct dirent *entry;
 | 
						struct dirent *entry;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
	bool container_pid = false;
 | 
						bool container_pid = false;
 | 
				
			||||||
	bool openvz_host = false;
 | 
						bool openvz_host = false;
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	char my_ns[30];
 | 
					 | 
				
			||||||
	char proc_ns[30];
 | 
					 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	pid_t p;
 | 
						pid_t p;
 | 
				
			||||||
	char buffer[PATH_MAX];
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
@@ -134,14 +131,6 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(my_ns, 0, sizeof(my_ns));
 | 
					 | 
				
			||||||
	memset(proc_ns, 0, sizeof(proc_ns));
 | 
					 | 
				
			||||||
	if (exists("/proc/self/ns/pid")) {
 | 
					 | 
				
			||||||
		rc = readlink("/proc/self/ns/pid", my_ns, sizeof(my_ns));
 | 
					 | 
				
			||||||
		if (rc <= 0)
 | 
					 | 
				
			||||||
			my_ns[0] = '\0';
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while ((entry = readdir(procdir)) != NULL) {
 | 
						while ((entry = readdir(procdir)) != NULL) {
 | 
				
			||||||
		if (sscanf(entry->d_name, "%d", &p) != 1)
 | 
							if (sscanf(entry->d_name, "%d", &p) != 1)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@@ -149,14 +138,6 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (pid != 0 && pid != p)
 | 
							if (pid != 0 && pid != p)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		snprintf(buffer, sizeof(buffer), "/proc/%d/ns/pid", p);
 | 
					 | 
				
			||||||
		if (exists(buffer)) {
 | 
					 | 
				
			||||||
			rc = readlink(buffer, proc_ns, sizeof(proc_ns));
 | 
					 | 
				
			||||||
			if (rc <= 0)
 | 
					 | 
				
			||||||
				proc_ns[0] = '\0';
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (strcmp(my_ns, proc_ns))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (uid) {
 | 
							if (uid) {
 | 
				
			||||||
			snprintf(buffer, sizeof(buffer), "/proc/%d", p);
 | 
								snprintf(buffer, sizeof(buffer), "/proc/%d", p);
 | 
				
			||||||
			if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
 | 
								if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -894,14 +894,11 @@ rc_service_value_set(const char *service, const char *option,
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(p, sizeof(file) - (p - file), "/%s", option);
 | 
						snprintf(p, sizeof(file) - (p - file), "/%s", option);
 | 
				
			||||||
	if (value) {
 | 
					 | 
				
			||||||
	if (!(fp = fopen(file, "w")))
 | 
						if (!(fp = fopen(file, "w")))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
						if (value)
 | 
				
			||||||
		fprintf(fp, "%s", value);
 | 
							fprintf(fp, "%s", value);
 | 
				
			||||||
	fclose(fp);
 | 
						fclose(fp);
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		unlink(file);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_service_value_set)
 | 
					librc_hidden_def(rc_service_value_set)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ SBINDIR=	${PREFIX}/sbin
 | 
				
			|||||||
LINKDIR=	${LIBEXECDIR}
 | 
					LINKDIR=	${LIBEXECDIR}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BINPROGS=	rc-status
 | 
					BINPROGS=	rc-status
 | 
				
			||||||
SBINPROGS = openrc openrc-run rc rc-service rc-update runscript \
 | 
					SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service \
 | 
				
			||||||
			start-stop-daemon supervise-daemon
 | 
								start-stop-daemon supervise-daemon
 | 
				
			||||||
RC_BINPROGS=	einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
 | 
					RC_BINPROGS=	einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
 | 
				
			||||||
				eindent eoutdent esyslog eval_ecolors ewaitfile \
 | 
									eindent eoutdent esyslog eval_ecolors ewaitfile \
 | 
				
			||||||
@@ -150,7 +150,7 @@ rc-depend: rc-depend.o _usage.o rc-misc.o
 | 
				
			|||||||
rc-status: rc-status.o _usage.o rc-misc.o
 | 
					rc-status: rc-status.o _usage.o rc-misc.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rc-service: rc-service.o _usage.o rc-misc.o
 | 
					rc-service service: rc-service.o _usage.o rc-misc.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rc-update: rc-update.o _usage.o rc-misc.o
 | 
					rc-update: rc-update.o _usage.o rc-misc.o
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -217,18 +217,6 @@ signal_setup(int sig, void (*handler)(int))
 | 
				
			|||||||
	return sigaction(sig, &sa, NULL);
 | 
						return sigaction(sig, &sa, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					 | 
				
			||||||
signal_setup_restart(int sig, void (*handler)(int))
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct sigaction sa;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&sa, 0, sizeof (sa));
 | 
					 | 
				
			||||||
	sigemptyset(&sa.sa_mask);
 | 
					 | 
				
			||||||
	sa.sa_handler = handler;
 | 
					 | 
				
			||||||
	sa.sa_flags = SA_RESTART;
 | 
					 | 
				
			||||||
	return sigaction(sig, &sa, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
svc_lock(const char *applet)
 | 
					svc_lock(const char *applet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,8 +128,6 @@ print_service(const char *service)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	char status[60];
 | 
						char status[60];
 | 
				
			||||||
	char uptime [40];
 | 
						char uptime [40];
 | 
				
			||||||
	char *child_pid = NULL;
 | 
					 | 
				
			||||||
	char *start_time = NULL;
 | 
					 | 
				
			||||||
	int cols =  printf(" %s", service);
 | 
						int cols =  printf(" %s", service);
 | 
				
			||||||
	const char *c = ecolor(ECOLOR_GOOD);
 | 
						const char *c = ecolor(ECOLOR_GOOD);
 | 
				
			||||||
	RC_SERVICE state = rc_service_state(service);
 | 
						RC_SERVICE state = rc_service_state(service);
 | 
				
			||||||
@@ -149,14 +147,7 @@ print_service(const char *service)
 | 
				
			|||||||
		    rc_service_daemons_crashed(service) &&
 | 
							    rc_service_daemons_crashed(service) &&
 | 
				
			||||||
		    errno != EACCES)
 | 
							    errno != EACCES)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			child_pid = rc_service_value_get(service, "child_pid");
 | 
					 | 
				
			||||||
			start_time = rc_service_value_get(service, "start_time");
 | 
					 | 
				
			||||||
			if (start_time && child_pid)
 | 
					 | 
				
			||||||
				snprintf(status, sizeof(status), " unsupervised ");
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
			snprintf(status, sizeof(status), " crashed ");
 | 
								snprintf(status, sizeof(status), " crashed ");
 | 
				
			||||||
			free(child_pid);
 | 
					 | 
				
			||||||
			free(start_time);
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			get_uptime(service, uptime, 40);
 | 
								get_uptime(service, uptime, 40);
 | 
				
			||||||
			snprintf(status, sizeof(status), " started %s", uptime);
 | 
								snprintf(status, sizeof(status), " started %s", uptime);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,7 +67,7 @@ static struct pam_conv conv = { NULL, NULL};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
const char *extraopts = NULL;
 | 
					const char *extraopts = NULL;
 | 
				
			||||||
const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:R:r:Su:1:2:3" \
 | 
					const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:R:r:Su:1:2:" \
 | 
				
			||||||
	getoptstring_COMMON;
 | 
						getoptstring_COMMON;
 | 
				
			||||||
const struct option longopts[] = {
 | 
					const struct option longopts[] = {
 | 
				
			||||||
	{ "respawn-delay",        1, NULL, 'D'},
 | 
						{ "respawn-delay",        1, NULL, 'D'},
 | 
				
			||||||
@@ -87,7 +87,6 @@ const struct option longopts[] = {
 | 
				
			|||||||
	{ "user",         1, NULL, 'u'},
 | 
						{ "user",         1, NULL, 'u'},
 | 
				
			||||||
	{ "stdout",       1, NULL, '1'},
 | 
						{ "stdout",       1, NULL, '1'},
 | 
				
			||||||
	{ "stderr",       1, NULL, '2'},
 | 
						{ "stderr",       1, NULL, '2'},
 | 
				
			||||||
	{ "reexec",       0, NULL, '3'},
 | 
					 | 
				
			||||||
	longopts_COMMON
 | 
						longopts_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char * const longopts_help[] = {
 | 
					const char * const longopts_help[] = {
 | 
				
			||||||
@@ -108,7 +107,6 @@ const char * const longopts_help[] = {
 | 
				
			|||||||
	"Change the process user",
 | 
						"Change the process user",
 | 
				
			||||||
	"Redirect stdout to file",
 | 
						"Redirect stdout to file",
 | 
				
			||||||
	"Redirect stderr to file",
 | 
						"Redirect stderr to file",
 | 
				
			||||||
	"reexec (used internally)",
 | 
					 | 
				
			||||||
	longopts_help_COMMON
 | 
						longopts_help_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char *usagestring = NULL;
 | 
					const char *usagestring = NULL;
 | 
				
			||||||
@@ -129,13 +127,6 @@ static bool exiting = false;
 | 
				
			|||||||
#ifdef TIOCNOTTY
 | 
					#ifdef TIOCNOTTY
 | 
				
			||||||
static int tty_fd = -1;
 | 
					static int tty_fd = -1;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
static pid_t child_pid;
 | 
					 | 
				
			||||||
static int respawn_count = 0;
 | 
					 | 
				
			||||||
static int respawn_delay = 0;
 | 
					 | 
				
			||||||
static int respawn_max = 10;
 | 
					 | 
				
			||||||
static int respawn_period = 5;
 | 
					 | 
				
			||||||
static char *pidfile = NULL;
 | 
					 | 
				
			||||||
static char *svcname = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern char **environ;
 | 
					extern char **environ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -159,71 +150,8 @@ static void cleanup(void)
 | 
				
			|||||||
	free(changeuser);
 | 
						free(changeuser);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void re_exec(void)
 | 
					static void child_process(char *exec, char **argv, char *svcname,
 | 
				
			||||||
{
 | 
							int start_count)
 | 
				
			||||||
	syslog(LOG_WARNING, "Re-executing supervise-daemon");
 | 
					 | 
				
			||||||
	execlp("supervise-daemon", "supervise-daemon", "--reexec", (char *) NULL);
 | 
					 | 
				
			||||||
	syslog(LOG_ERR, "Unable to execute supervise-daemon: %s",
 | 
					 | 
				
			||||||
			strerror(errno));
 | 
					 | 
				
			||||||
	exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_signal(int sig)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int serrno = errno;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	syslog(LOG_WARNING, "caught signal %d", sig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sig == SIGTERM)
 | 
					 | 
				
			||||||
		exiting = true;
 | 
					 | 
				
			||||||
	/* Restore errno */
 | 
					 | 
				
			||||||
	errno = serrno;
 | 
					 | 
				
			||||||
	if (! exiting)
 | 
					 | 
				
			||||||
		re_exec();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char * expand_home(const char *home, const char *path)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char *opath, *ppath, *p, *nh;
 | 
					 | 
				
			||||||
	size_t len;
 | 
					 | 
				
			||||||
	struct passwd *pw;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!path || *path != '~')
 | 
					 | 
				
			||||||
		return xstrdup(path);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	opath = ppath = xstrdup(path);
 | 
					 | 
				
			||||||
	if (ppath[1] != '/' && ppath[1] != '\0') {
 | 
					 | 
				
			||||||
		p = strchr(ppath + 1, '/');
 | 
					 | 
				
			||||||
		if (p)
 | 
					 | 
				
			||||||
			*p = '\0';
 | 
					 | 
				
			||||||
		pw = getpwnam(ppath + 1);
 | 
					 | 
				
			||||||
		if (pw) {
 | 
					 | 
				
			||||||
			home = pw->pw_dir;
 | 
					 | 
				
			||||||
			ppath = p;
 | 
					 | 
				
			||||||
			if (ppath)
 | 
					 | 
				
			||||||
				*ppath = '/';
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			home = NULL;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		ppath++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!home) {
 | 
					 | 
				
			||||||
	free(opath);
 | 
					 | 
				
			||||||
		return xstrdup(path);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!ppath) {
 | 
					 | 
				
			||||||
		free(opath);
 | 
					 | 
				
			||||||
		return xstrdup(home);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = strlen(ppath) + strlen(home) + 1;
 | 
					 | 
				
			||||||
	nh = xmalloc(len);
 | 
					 | 
				
			||||||
	snprintf(nh, len, "%s%s", home, ppath);
 | 
					 | 
				
			||||||
	free(opath);
 | 
					 | 
				
			||||||
	return nh;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void child_process(char *exec, char **argv)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RC_STRINGLIST *env_list;
 | 
						RC_STRINGLIST *env_list;
 | 
				
			||||||
	RC_STRING *env;
 | 
						RC_STRING *env;
 | 
				
			||||||
@@ -251,10 +179,8 @@ static void child_process(char *exec, char **argv)
 | 
				
			|||||||
start_time = time(NULL);
 | 
					start_time = time(NULL);
 | 
				
			||||||
from_time_t(start_time_string, start_time);
 | 
					from_time_t(start_time_string, start_time);
 | 
				
			||||||
		rc_service_value_set(svcname, "start_time", start_time_string);
 | 
							rc_service_value_set(svcname, "start_time", start_time_string);
 | 
				
			||||||
		sprintf(start_count_string, "%i", respawn_count);
 | 
					sprintf(start_count_string, "%i", start_count);
 | 
				
			||||||
		rc_service_value_set(svcname, "start_count", start_count_string);
 | 
							rc_service_value_set(svcname, "start_count", start_count_string);
 | 
				
			||||||
		sprintf(start_count_string, "%d", getpid());
 | 
					 | 
				
			||||||
		rc_service_value_set(svcname, "child_pid", start_count_string);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nicelevel) {
 | 
						if (nicelevel) {
 | 
				
			||||||
@@ -397,7 +323,7 @@ static void child_process(char *exec, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	*cmdline = '\0';
 | 
						*cmdline = '\0';
 | 
				
			||||||
	c = argv;
 | 
						c = argv;
 | 
				
			||||||
	while (c && *c) {
 | 
						while (*c) {
 | 
				
			||||||
		strcat(cmdline, *c);
 | 
							strcat(cmdline, *c);
 | 
				
			||||||
		strcat(cmdline, " ");
 | 
							strcat(cmdline, " ");
 | 
				
			||||||
		c++;
 | 
							c++;
 | 
				
			||||||
@@ -412,156 +338,108 @@ static void child_process(char *exec, char **argv)
 | 
				
			|||||||
	eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
 | 
						eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void supervisor(char *exec, char **argv)
 | 
					static void handle_signal(int sig)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILE *fp;
 | 
						int serrno = errno;
 | 
				
			||||||
	int i;
 | 
						char signame[10] = { '\0' };
 | 
				
			||||||
	int nkilled;
 | 
					 | 
				
			||||||
	time_t respawn_now= 0;
 | 
					 | 
				
			||||||
	time_t first_spawn= 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef RC_DEBUG
 | 
						switch (sig) {
 | 
				
			||||||
	signal_setup_restart(SIGHUP, handle_signal);
 | 
						case SIGINT:
 | 
				
			||||||
	signal_setup_restart(SIGINT, handle_signal);
 | 
							snprintf(signame, sizeof(signame), "SIGINT");
 | 
				
			||||||
	signal_setup_restart(SIGQUIT, handle_signal);
 | 
							break;
 | 
				
			||||||
	signal_setup_restart(SIGILL, handle_signal);
 | 
						case SIGTERM:
 | 
				
			||||||
	signal_setup_restart(SIGABRT, handle_signal);
 | 
							snprintf(signame, sizeof(signame), "SIGTERM");
 | 
				
			||||||
	signal_setup_restart(SIGFPE, handle_signal);
 | 
							break;
 | 
				
			||||||
	signal_setup_restart(SIGSEGV, handle_signal);
 | 
						case SIGQUIT:
 | 
				
			||||||
	signal_setup_restart(SIGPIPE, handle_signal);
 | 
							snprintf(signame, sizeof(signame), "SIGQUIT");
 | 
				
			||||||
	signal_setup_restart(SIGALRM, handle_signal);
 | 
							break;
 | 
				
			||||||
	signal_setup(SIGTERM, handle_signal);
 | 
						}
 | 
				
			||||||
	signal_setup_restart(SIGUSR1, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGUSR2, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGBUS, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPOLL, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPROF, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGSYS, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGTRAP, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGVTALRM, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGXCPU, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGXFSZ, handle_signal);
 | 
					 | 
				
			||||||
#ifdef SIGEMT
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGEMT, handle_signal);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGIO, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPWR, handle_signal);
 | 
					 | 
				
			||||||
#ifdef SIGUNUSED
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGUNUSED, handle_signal);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef SIGRTMIN
 | 
					 | 
				
			||||||
	for (i = SIGRTMIN; i <= SIGRTMAX; i++)
 | 
					 | 
				
			||||||
		signal_setup_restart(i, handle_signal);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fp = fopen(pidfile, "w");
 | 
						if (*signame != 0) {
 | 
				
			||||||
	if (! fp)
 | 
							syslog(LOG_INFO, "%s: caught signal %s, exiting", applet, signame);
 | 
				
			||||||
		eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
					 | 
				
			||||||
	fprintf(fp, "%d\n", getpid());
 | 
					 | 
				
			||||||
	fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (svcname)
 | 
					 | 
				
			||||||
		rc_service_daemon_set(svcname, exec, (const char * const *) argv,
 | 
					 | 
				
			||||||
				pidfile, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* remove the controlling tty */
 | 
					 | 
				
			||||||
#ifdef TIOCNOTTY
 | 
					 | 
				
			||||||
	ioctl(tty_fd, TIOCNOTTY, 0);
 | 
					 | 
				
			||||||
	close(tty_fd);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Supervisor main loop
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	i = 0;
 | 
					 | 
				
			||||||
	while (!exiting) {
 | 
					 | 
				
			||||||
		wait(&i);
 | 
					 | 
				
			||||||
		if (exiting) {
 | 
					 | 
				
			||||||
			signal_setup(SIGCHLD, SIG_IGN);
 | 
					 | 
				
			||||||
			syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
 | 
					 | 
				
			||||||
			nkilled = run_stop_schedule(applet, exec, NULL, child_pid, 0,
 | 
					 | 
				
			||||||
					false, false, true);
 | 
					 | 
				
			||||||
			if (nkilled > 0)
 | 
					 | 
				
			||||||
				syslog(LOG_INFO, "killed %d processes", nkilled);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			sleep(respawn_delay);
 | 
					 | 
				
			||||||
			if (respawn_max > 0 && respawn_period > 0) {
 | 
					 | 
				
			||||||
				respawn_now = time(NULL);
 | 
					 | 
				
			||||||
				if (first_spawn == 0)
 | 
					 | 
				
			||||||
					first_spawn = respawn_now;
 | 
					 | 
				
			||||||
				if (respawn_now - first_spawn > respawn_period) {
 | 
					 | 
				
			||||||
					respawn_count = 0;
 | 
					 | 
				
			||||||
					first_spawn = 0;
 | 
					 | 
				
			||||||
				} else
 | 
					 | 
				
			||||||
					respawn_count++;
 | 
					 | 
				
			||||||
				if (respawn_count >= respawn_max) {
 | 
					 | 
				
			||||||
					syslog(LOG_WARNING,
 | 
					 | 
				
			||||||
							"respawned \"%s\" too many times, exiting", exec);
 | 
					 | 
				
			||||||
		exiting = true;
 | 
							exiting = true;
 | 
				
			||||||
					continue;
 | 
						} else
 | 
				
			||||||
				}
 | 
							syslog(LOG_INFO, "%s: caught unknown signal %d", applet, sig);
 | 
				
			||||||
			}
 | 
					
 | 
				
			||||||
			if (WIFEXITED(i))
 | 
						/* Restore errno */
 | 
				
			||||||
				syslog(LOG_WARNING, "%s, pid %d, exited with return code %d",
 | 
						errno = serrno;
 | 
				
			||||||
						exec, child_pid, WEXITSTATUS(i));
 | 
					 | 
				
			||||||
			else if (WIFSIGNALED(i))
 | 
					 | 
				
			||||||
				syslog(LOG_WARNING, "%s, pid %d, terminated by signal %d",
 | 
					 | 
				
			||||||
						exec, child_pid, WTERMSIG(i));
 | 
					 | 
				
			||||||
			child_pid = fork();
 | 
					 | 
				
			||||||
			if (child_pid == -1)
 | 
					 | 
				
			||||||
				eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
			if (child_pid == 0)
 | 
					 | 
				
			||||||
				child_process(exec, argv);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pidfile && exists(pidfile))
 | 
					static char * expand_home(const char *home, const char *path)
 | 
				
			||||||
		unlink(pidfile);
 | 
					{
 | 
				
			||||||
	if (svcname) {
 | 
						char *opath, *ppath, *p, *nh;
 | 
				
			||||||
		rc_service_daemon_set(svcname, exec, (const char *const *)argv,
 | 
						size_t len;
 | 
				
			||||||
				pidfile, false);
 | 
						struct passwd *pw;
 | 
				
			||||||
		rc_service_mark(svcname, RC_SERVICE_STOPPED);
 | 
					
 | 
				
			||||||
		rc_service_value_set(svcname, "child_pid", NULL);
 | 
						if (!path || *path != '~')
 | 
				
			||||||
 | 
							return xstrdup(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opath = ppath = xstrdup(path);
 | 
				
			||||||
 | 
						if (ppath[1] != '/' && ppath[1] != '\0') {
 | 
				
			||||||
 | 
							p = strchr(ppath + 1, '/');
 | 
				
			||||||
 | 
							if (p)
 | 
				
			||||||
 | 
								*p = '\0';
 | 
				
			||||||
 | 
							pw = getpwnam(ppath + 1);
 | 
				
			||||||
 | 
							if (pw) {
 | 
				
			||||||
 | 
								home = pw->pw_dir;
 | 
				
			||||||
 | 
								ppath = p;
 | 
				
			||||||
 | 
								if (ppath)
 | 
				
			||||||
 | 
									*ppath = '/';
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								home = NULL;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							ppath++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!home) {
 | 
				
			||||||
 | 
						free(opath);
 | 
				
			||||||
 | 
							return xstrdup(path);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	exit(EXIT_SUCCESS);
 | 
						if (!ppath) {
 | 
				
			||||||
 | 
							free(opath);
 | 
				
			||||||
 | 
							return xstrdup(home);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = strlen(ppath) + strlen(home) + 1;
 | 
				
			||||||
 | 
						nh = xmalloc(len);
 | 
				
			||||||
 | 
						snprintf(nh, len, "%s%s", home, ppath);
 | 
				
			||||||
 | 
						free(opath);
 | 
				
			||||||
 | 
						return nh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int opt;
 | 
						int opt;
 | 
				
			||||||
	char **c;
 | 
					 | 
				
			||||||
	int x;
 | 
					 | 
				
			||||||
	bool start = false;
 | 
						bool start = false;
 | 
				
			||||||
	bool stop = false;
 | 
						bool stop = false;
 | 
				
			||||||
	bool reexec = false;
 | 
					 | 
				
			||||||
	char *exec = NULL;
 | 
						char *exec = NULL;
 | 
				
			||||||
 | 
						char *pidfile = NULL;
 | 
				
			||||||
	char *retry = NULL;
 | 
						char *retry = NULL;
 | 
				
			||||||
 | 
						int nkilled;
 | 
				
			||||||
	int sig = SIGTERM;
 | 
						int sig = SIGTERM;
 | 
				
			||||||
	char *home = NULL;
 | 
						char *home = NULL;
 | 
				
			||||||
	int tid = 0;
 | 
						int tid = 0;
 | 
				
			||||||
	pid_t pid;
 | 
						pid_t child_pid, pid;
 | 
				
			||||||
 | 
						char *svcname = getenv("RC_SVCNAME");
 | 
				
			||||||
	char *tmp;
 | 
						char *tmp;
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	char *token;
 | 
						char *token;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int n;
 | 
						int n;
 | 
				
			||||||
	char exec_file[PATH_MAX];
 | 
						char exec_file[PATH_MAX];
 | 
				
			||||||
	char name[PATH_MAX];
 | 
						int respawn_count = 0;
 | 
				
			||||||
 | 
						int respawn_delay = 0;
 | 
				
			||||||
 | 
						int respawn_max = 10;
 | 
				
			||||||
 | 
						int respawn_period = 5;
 | 
				
			||||||
 | 
						time_t respawn_now= 0;
 | 
				
			||||||
 | 
						time_t first_spawn= 0;
 | 
				
			||||||
	struct timespec ts;
 | 
						struct timespec ts;
 | 
				
			||||||
	struct passwd *pw;
 | 
						struct passwd *pw;
 | 
				
			||||||
	struct group *gr;
 | 
						struct group *gr;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	mode_t numask = 022;
 | 
						mode_t numask = 022;
 | 
				
			||||||
	int child_argc = 0;
 | 
					 | 
				
			||||||
	char **child_argv = NULL;
 | 
					 | 
				
			||||||
	char *str = NULL;
 | 
					 | 
				
			||||||
	char cmdline[PATH_MAX];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	atexit(cleanup);
 | 
						atexit(cleanup);
 | 
				
			||||||
	svcname = getenv("RC_SVCNAME");
 | 
					 | 
				
			||||||
	openlog(svcname, LOG_PID, LOG_DAEMON);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((tmp = getenv("SSD_NICELEVEL")))
 | 
						if ((tmp = getenv("SSD_NICELEVEL")))
 | 
				
			||||||
		if (sscanf(tmp, "%d", &nicelevel) != 1)
 | 
							if (sscanf(tmp, "%d", &nicelevel) != 1)
 | 
				
			||||||
@@ -615,8 +493,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		case 'P':  /* --respawn-period time */
 | 
							case 'P':  /* --respawn-period time */
 | 
				
			||||||
			n = sscanf(optarg, "%d", &respawn_period);
 | 
								n = sscanf(optarg, "%d", &respawn_period);
 | 
				
			||||||
			if (n	!= 1 || respawn_period < 1)
 | 
								if (n	!= 1 || respawn_delay < 1)
 | 
				
			||||||
				eerrorx("Invalid respawn-period value '%s'", optarg);
 | 
									eerrorx("Invalid respawn-delay value '%s'", optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 'S':  /* --start */
 | 
							case 'S':  /* --start */
 | 
				
			||||||
@@ -712,65 +590,37 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		case '2':  /* --stderr /path/to/stderr.logfile */
 | 
							case '2':  /* --stderr /path/to/stderr.logfile */
 | 
				
			||||||
			redirect_stderr = optarg;
 | 
								redirect_stderr = optarg;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case '3':  /* --reexec */
 | 
					 | 
				
			||||||
			reexec = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case_RC_COMMON_GETOPT
 | 
							case_RC_COMMON_GETOPT
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pidfile && !reexec)
 | 
						if (!pidfile)
 | 
				
			||||||
		eerrorx("%s: --pidfile must be specified", applet);
 | 
							eerrorx("%s: --pidfile must be specified", applet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*cmdline = '\0';
 | 
					 | 
				
			||||||
	c = argv;
 | 
					 | 
				
			||||||
	while (c && *c) {
 | 
					 | 
				
			||||||
		strcat(cmdline, *c);
 | 
					 | 
				
			||||||
		strcat(cmdline, " ");
 | 
					 | 
				
			||||||
		c++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	endpwent();
 | 
						endpwent();
 | 
				
			||||||
	argc -= optind;
 | 
						argc -= optind;
 | 
				
			||||||
	argv += optind;
 | 
						argv += optind;
 | 
				
			||||||
	exec = *argv;
 | 
						exec = *argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (start) {
 | 
				
			||||||
 | 
							if (!exec)
 | 
				
			||||||
 | 
								eerrorx("%s: nothing to start", applet);
 | 
				
			||||||
 | 
							if (respawn_delay * respawn_max > respawn_period) {
 | 
				
			||||||
 | 
								ewarn("%s: Please increase the value of --respawn-period to more "
 | 
				
			||||||
 | 
									"than %d to avoid infinite respawning", applet, 
 | 
				
			||||||
 | 
									respawn_delay * respawn_max);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (retry)
 | 
				
			||||||
 | 
								parse_schedule(applet, retry, sig);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								parse_schedule(applet, NULL, sig);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Expand ~ */
 | 
						/* Expand ~ */
 | 
				
			||||||
	if (ch_dir && *ch_dir == '~')
 | 
						if (ch_dir && *ch_dir == '~')
 | 
				
			||||||
		ch_dir = expand_home(home, ch_dir);
 | 
							ch_dir = expand_home(home, ch_dir);
 | 
				
			||||||
	if (ch_root && *ch_root == '~')
 | 
						if (ch_root && *ch_root == '~')
 | 
				
			||||||
		ch_root = expand_home(home, ch_root);
 | 
							ch_root = expand_home(home, ch_root);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	umask(numask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (reexec) {
 | 
					 | 
				
			||||||
		str = rc_service_value_get(svcname, "argc");
 | 
					 | 
				
			||||||
		sscanf(str, "%d", &child_argc);
 | 
					 | 
				
			||||||
		child_argv = xmalloc((child_argc + 1) * sizeof(char *));
 | 
					 | 
				
			||||||
		memset(child_argv, 0, (child_argc + 1) * sizeof(char *));
 | 
					 | 
				
			||||||
		for (x = 0; x < child_argc; x++) {
 | 
					 | 
				
			||||||
			sprintf(name, "argv_%d", x);
 | 
					 | 
				
			||||||
			str = rc_service_value_get(svcname, name);
 | 
					 | 
				
			||||||
			child_argv[x] = str;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		free(str);
 | 
					 | 
				
			||||||
		str = rc_service_value_get(svcname, "child_pid");
 | 
					 | 
				
			||||||
		sscanf(str, "%d", &child_pid);
 | 
					 | 
				
			||||||
		free(str);
 | 
					 | 
				
			||||||
		exec = rc_service_value_get(svcname, "exec");
 | 
					 | 
				
			||||||
		pidfile = rc_service_value_get(svcname, "pidfile");
 | 
					 | 
				
			||||||
		retry = rc_service_value_get(svcname, "retry");
 | 
					 | 
				
			||||||
		if (retry) {
 | 
					 | 
				
			||||||
			parse_schedule(applet, retry, sig);
 | 
					 | 
				
			||||||
			rc_service_value_set(svcname, "retry", retry);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			parse_schedule(applet, NULL, sig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		str = rc_service_value_get(svcname, "respawn_delay");
 | 
					 | 
				
			||||||
		sscanf(str, "%d", &respawn_delay);
 | 
					 | 
				
			||||||
		str = rc_service_value_get(svcname, "respawn_max");
 | 
					 | 
				
			||||||
		sscanf(str, "%d", &respawn_max);
 | 
					 | 
				
			||||||
		supervisor(exec, child_argv);
 | 
					 | 
				
			||||||
	} else if (start) {
 | 
					 | 
				
			||||||
	if (exec) {
 | 
						if (exec) {
 | 
				
			||||||
		if (*exec == '~')
 | 
							if (*exec == '~')
 | 
				
			||||||
			exec = expand_home(home, exec);
 | 
								exec = expand_home(home, exec);
 | 
				
			||||||
@@ -802,85 +652,19 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			free(tmp);
 | 
								free(tmp);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			if ( !exists(exec_file))
 | 
						}
 | 
				
			||||||
 | 
						if (start && !exists(exec_file))
 | 
				
			||||||
		eerrorx("%s: %s does not exist", applet,
 | 
							eerrorx("%s: %s does not exist", applet,
 | 
				
			||||||
		    *exec_file ? exec_file : exec);
 | 
							    *exec_file ? exec_file : exec);
 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			eerrorx("%s: nothing to start", applet);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pid = get_pid(applet, pidfile);
 | 
						if (stop) {
 | 
				
			||||||
		if (pid != -1)
 | 
					 | 
				
			||||||
			if (do_stop(applet, exec, (const char * const *)argv, pid, uid,
 | 
					 | 
				
			||||||
						0, false, true) > 0)
 | 
					 | 
				
			||||||
				eerrorx("%s: %s is already running", applet, exec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (respawn_delay * respawn_max > respawn_period)
 | 
					 | 
				
			||||||
			ewarn("%s: Please increase the value of --respawn-period to more "
 | 
					 | 
				
			||||||
				"than %d to avoid infinite respawning", applet, 
 | 
					 | 
				
			||||||
				respawn_delay * respawn_max);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (retry) {
 | 
					 | 
				
			||||||
			parse_schedule(applet, retry, sig);
 | 
					 | 
				
			||||||
			rc_service_value_set(svcname, "retry", retry);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			parse_schedule(applet, NULL, sig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		einfov("Detaching to start `%s'", exec);
 | 
					 | 
				
			||||||
		syslog(LOG_INFO, "Supervisor command line: %s", cmdline);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Remove existing pidfile */
 | 
					 | 
				
			||||||
		if (pidfile)
 | 
					 | 
				
			||||||
			unlink(pidfile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Make sure we can write a pid file */
 | 
					 | 
				
			||||||
		fp = fopen(pidfile, "w");
 | 
					 | 
				
			||||||
		if (! fp)
 | 
					 | 
				
			||||||
			eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
					 | 
				
			||||||
		fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rc_service_value_set(svcname, "pidfile", pidfile);
 | 
					 | 
				
			||||||
		sprintf(name, "%i", respawn_delay);
 | 
					 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_delay", name);
 | 
					 | 
				
			||||||
		sprintf(name, "%i", respawn_max);
 | 
					 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_max", name);
 | 
					 | 
				
			||||||
		sprintf(name, "%i", respawn_period);
 | 
					 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_period", name);
 | 
					 | 
				
			||||||
		child_pid = fork();
 | 
					 | 
				
			||||||
		if (child_pid == -1)
 | 
					 | 
				
			||||||
			eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
		if (child_pid != 0)
 | 
					 | 
				
			||||||
			/* first parent process, do nothing. */
 | 
					 | 
				
			||||||
			exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
#ifdef TIOCNOTTY
 | 
					 | 
				
			||||||
		tty_fd = open("/dev/tty", O_RDWR);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		devnull_fd = open("/dev/null", O_RDWR);
 | 
					 | 
				
			||||||
		child_pid = fork();
 | 
					 | 
				
			||||||
		if (child_pid == -1)
 | 
					 | 
				
			||||||
			eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
		else if (child_pid != 0) {
 | 
					 | 
				
			||||||
			c = argv;
 | 
					 | 
				
			||||||
			x = 0;
 | 
					 | 
				
			||||||
			while (c && *c) {
 | 
					 | 
				
			||||||
				snprintf(name, sizeof(name), "argv_%-d",x);
 | 
					 | 
				
			||||||
				rc_service_value_set(svcname, name, *c);
 | 
					 | 
				
			||||||
				x++;
 | 
					 | 
				
			||||||
				c++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			sprintf(name, "%d", x);
 | 
					 | 
				
			||||||
				rc_service_value_set(svcname, "argc", name);
 | 
					 | 
				
			||||||
			rc_service_value_set(svcname, "exec", exec);
 | 
					 | 
				
			||||||
			supervisor(exec, argv);
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			child_process(exec, argv);
 | 
					 | 
				
			||||||
	} else if (stop) {
 | 
					 | 
				
			||||||
		pid = get_pid(applet, pidfile);
 | 
							pid = get_pid(applet, pidfile);
 | 
				
			||||||
		if (pid != -1) {
 | 
							if (pid != -1) {
 | 
				
			||||||
			i = kill(pid, SIGTERM);
 | 
								i = kill(pid, SIGTERM);
 | 
				
			||||||
			if (i != 0)
 | 
								if (i != 0)
 | 
				
			||||||
				/* We failed to send the signal */
 | 
									/* We failed to send the signal */
 | 
				
			||||||
				ewarn("Unable to shut down the supervisor");
 | 
									exit(EXIT_FAILURE);
 | 
				
			||||||
			else {
 | 
					
 | 
				
			||||||
			/* wait for the supervisor to go down */
 | 
								/* wait for the supervisor to go down */
 | 
				
			||||||
			while (kill(pid, 0) == 0) {
 | 
								while (kill(pid, 0) == 0) {
 | 
				
			||||||
				ts.tv_sec = 0;
 | 
									ts.tv_sec = 0;
 | 
				
			||||||
@@ -888,7 +672,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
				nanosleep(&ts, NULL);
 | 
									nanosleep(&ts, NULL);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Even if we have not actually killed anything, we should
 | 
							/* Even if we have not actually killed anything, we should
 | 
				
			||||||
		 * remove information about it as it may have unexpectedly
 | 
							 * remove information about it as it may have unexpectedly
 | 
				
			||||||
@@ -904,4 +687,119 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
							exit(EXIT_SUCCESS);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pid = get_pid(applet, pidfile);
 | 
				
			||||||
 | 
						if (pid != -1)
 | 
				
			||||||
 | 
							if (kill(pid, 0) == 0)
 | 
				
			||||||
 | 
								eerrorx("%s: %s is already running", applet, exec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						einfov("Detaching to start `%s'", exec);
 | 
				
			||||||
 | 
						eindentv();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Remove existing pidfile */
 | 
				
			||||||
 | 
						if (pidfile)
 | 
				
			||||||
 | 
							unlink(pidfile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Make sure we can write a pid file
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						fp = fopen(pidfile, "w");
 | 
				
			||||||
 | 
						if (! fp)
 | 
				
			||||||
 | 
							eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
				
			||||||
 | 
						fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						child_pid = fork();
 | 
				
			||||||
 | 
						if (child_pid == -1)
 | 
				
			||||||
 | 
							eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* first parent process, do nothing. */
 | 
				
			||||||
 | 
						if (child_pid != 0)
 | 
				
			||||||
 | 
							exit(EXIT_SUCCESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TIOCNOTTY
 | 
				
			||||||
 | 
						tty_fd = open("/dev/tty", O_RDWR);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						devnull_fd = open("/dev/null", O_RDWR);
 | 
				
			||||||
 | 
						child_pid = fork();
 | 
				
			||||||
 | 
						if (child_pid == -1)
 | 
				
			||||||
 | 
							eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (child_pid != 0) {
 | 
				
			||||||
 | 
							/* this is the supervisor */
 | 
				
			||||||
 | 
							umask(numask);
 | 
				
			||||||
 | 
							openlog(applet, LOG_PID, LOG_DAEMON);
 | 
				
			||||||
 | 
							signal_setup(SIGTERM, handle_signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fp = fopen(pidfile, "w");
 | 
				
			||||||
 | 
							if (! fp)
 | 
				
			||||||
 | 
								eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
				
			||||||
 | 
							fprintf(fp, "%d\n", getpid());
 | 
				
			||||||
 | 
							fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (svcname)
 | 
				
			||||||
 | 
								rc_service_daemon_set(svcname, exec,
 | 
				
			||||||
 | 
														(const char * const *) argv, pidfile, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* remove the controlling tty */
 | 
				
			||||||
 | 
					#ifdef TIOCNOTTY
 | 
				
			||||||
 | 
							ioctl(tty_fd, TIOCNOTTY, 0);
 | 
				
			||||||
 | 
							close(tty_fd);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Supervisor main loop
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							i = 0;
 | 
				
			||||||
 | 
							while (!exiting) {
 | 
				
			||||||
 | 
								wait(&i);
 | 
				
			||||||
 | 
								if (exiting) {
 | 
				
			||||||
 | 
									signal_setup(SIGCHLD, SIG_IGN);
 | 
				
			||||||
 | 
									syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
 | 
				
			||||||
 | 
									nkilled = run_stop_schedule(applet, exec, NULL, child_pid,
 | 
				
			||||||
 | 
											0, false, false, true);
 | 
				
			||||||
 | 
									if (nkilled > 0)
 | 
				
			||||||
 | 
										syslog(LOG_INFO, "killed %d processes", nkilled);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									sleep(respawn_delay);
 | 
				
			||||||
 | 
									if (respawn_max > 0 && respawn_period > 0) {
 | 
				
			||||||
 | 
										respawn_now = time(NULL);
 | 
				
			||||||
 | 
										if (first_spawn == 0)
 | 
				
			||||||
 | 
											first_spawn = respawn_now;
 | 
				
			||||||
 | 
										if (respawn_now - first_spawn > respawn_period) {
 | 
				
			||||||
 | 
											respawn_count = 0;
 | 
				
			||||||
 | 
											first_spawn = 0;
 | 
				
			||||||
 | 
										} else
 | 
				
			||||||
 | 
											respawn_count++;
 | 
				
			||||||
 | 
										if (respawn_count >= respawn_max) {
 | 
				
			||||||
 | 
											syslog(LOG_INFO, "respawned \"%s\" too many times, "
 | 
				
			||||||
 | 
													"exiting", exec);
 | 
				
			||||||
 | 
											exiting = true;
 | 
				
			||||||
 | 
											continue;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (WIFEXITED(i))
 | 
				
			||||||
 | 
										syslog(LOG_INFO, "%s, pid %d, exited with return code %d",
 | 
				
			||||||
 | 
												exec, child_pid, WEXITSTATUS(i));
 | 
				
			||||||
 | 
									else if (WIFSIGNALED(i))
 | 
				
			||||||
 | 
										syslog(LOG_INFO, "%s, pid %d, terminated by signal %d",
 | 
				
			||||||
 | 
												exec, child_pid, WTERMSIG(i));
 | 
				
			||||||
 | 
									child_pid = fork();
 | 
				
			||||||
 | 
									if (child_pid == -1)
 | 
				
			||||||
 | 
										eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
				
			||||||
 | 
									if (child_pid == 0)
 | 
				
			||||||
 | 
										child_process(exec, argv, svcname, respawn_count);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pidfile && exists(pidfile))
 | 
				
			||||||
 | 
								unlink(pidfile);
 | 
				
			||||||
 | 
							if (svcname) {
 | 
				
			||||||
 | 
								rc_service_daemon_set(svcname, exec,
 | 
				
			||||||
 | 
								    (const char *const *)argv,
 | 
				
			||||||
 | 
								    pidfile, false);
 | 
				
			||||||
 | 
								rc_service_mark(svcname, RC_SERVICE_STOPPED);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							exit(EXIT_SUCCESS);
 | 
				
			||||||
 | 
						} else if (child_pid == 0)
 | 
				
			||||||
 | 
							child_process(exec, argv, svcname, respawn_count);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user