admin/ 0001755 0000000 0000000 00000000000 14675400254 010654 5 ustar root root admin/runit-2.2.0/ 0000755 0000000 0000000 00000000000 14675400254 012451 5 ustar root root admin/runit-2.2.0/doc/ 0000755 0000000 0000000 00000000000 14675400254 013216 5 ustar root root admin/runit-2.2.0/doc/runsvchdir.8.html 0000644 0000000 0000000 00000003500 14675400254 016437 0 ustar root root
runsvchdir(8) manual page
G. Pape
runit
runsvchdir - change services directory of runsvdir(8)
runsvchdir
dir
dir is a services directory for the use with runsvdir(8).
If dir does not start with a slash, it is searched in /etc/runit/runsvdir/.
dir must not start with a dot.
runsvchdir switches to the directory /etc/runit/runsvdir/,
copies current to previous, and replaces current with a symlink pointing
to dir.
Normally /service is a symlink to current, and runsvdir(8) is running
/service/.
runsvchdir prints an error message and exits 111 on
error. runsvchdir exits 0 on success.
/etc/runit/runsvdir/previous
/etc/runit/runsvdir/current
/etc/runit/runsvdir/current.new
runsvdir(8), runit(8), runit-init(8), sv(8), runsv(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/runsv.8.html 0000644 0000000 0000000 00000016057 14675400254 015440 0 ustar root root
runsv(8) manual page
G. Pape
runit
runsv - starts and monitors a service and optionally an appendant log
service
runsv service
service must be a directory.
runsv
switches to the directory service and starts ./run. If ./run exits and ./finish
exists, runsv starts ./finish. If ./finish doesn’t exist or ./finish exits,
runsv restarts ./run.
If ./run or ./finish exit immediately, runsv waits a
second before starting ./finish or restarting ./run.
Two arguments are given
to ./finish. The first one is ./run’s exit code, or -1 if ./run didn’t exit normally.
The second one is the least significant byte of the exit status as determined
by waitpid(2); for instance it is 0 if ./run exited normally, and the signal
number if ./run was terminated by a signal. If runsv cannot start ./run for
some reason, the exit code is 111 and the status is 0.
If the file service/down
exists, runsv does not start ./run immediately. The control interface (see
below) can be used to start the service and to give other commands to runsv.
If the directory service/log exists, runsv creates a pipe, redirects service/run’s
and service/finish’s standard output to the pipe, switches to the directory
service/log and starts ./run (and ./finish) exactly as described above for
the service directory. The standard input of the log service is redirected
to read from the pipe.
runsv maintains status information in a binary format
(compatible to the daemontools’ supervise program) in service/supervise/status
and service/log/supervise/status, and in a human-readable format in service/supervise/stat,
service/log/supervise/stat, service/supervise/pid, service/log/supervise/pid.
The named pipes service/supervise/control, and (optionally) service/log/supervise/control
are provided to give commands to runsv. You can use sv(8) to control the
service or just write one of the following characters to the named pipe:
- u
- Up. If the service is not running, start it. If the service stops, restart
it.
- d
- Down. If the service is running, send it a TERM signal, and then a
CONT signal. If ./run exits, start ./finish if it exists. After it stops, do
not restart service.
- o
- Once. If the service is not running, start it. Do not
restart it if it stops.
- p
- Pause. If the service is running, send it a STOP
signal.
- c
- Continue. If the service is running, send it a CONT signal.
- h
- Hangup.
If the service is running, send it a HUP signal.
- a
- Alarm. If the service
is running, send it a ALRM signal.
- i
- Interrupt. If the service is running,
send it a INT signal.
- q
- Quit. If the service is running, send it a QUIT signal.
- 1
- User-defined 1. If the service is running, send it a USR1 signal.
- 2
- User-defined 2. If the service is running, send it a USR2 signal.
- t
- Terminate. If the service
is running, send it a TERM signal.
- k
- Kill. If the service is running, send
it a KILL signal.
- x
- Exit. If the service is running, send it a TERM signal,
and then a CONT signal. Do not restart the service. If the service is down,
and no log service exists, runsv exits. If the service is down and a log
service exists, runsv closes the standard input of the log service, and
waits for it to terminate. If the log service is down, runsv exits. This
command is ignored if it is given to service/log/supervise/control.
Example:
to send a TERM signal to the socklog-unix service, either do # sv term
/service/socklog-unix
or
# printf t >/service/socklog-unix/supervise/control
printf(1) usually blocks if no runsv process is running in the service
directory.
For each control character c except "d" and "x" sent to the control
pipe, runsv first checks if service/control/c exists and is executable.
If so, it starts service/control/c and waits for it to terminate, before
interpreting the command. If the program exits with return code 0, runsv
refrains from sending the service the corresponding signal. The command
o is always considered as command u. On command d first service/control/t
is checked, and then service/control/d. On command x first service/control/t
is checked, and then service/control/x. Specifically:
1.
runsv checks whether service/control/t exists and is executable and runs it if yes.
2.
If service/control/t exits nonzero, or is not executable or doesn't exist, runsv sends
the service a TERM signal.
3.
runsv sends the service a CONT signal, disregarding service/control/c even if it exists and is executable.
4.
runsv checks whether service/control/d (or control/x) exists and is executable and runs it if yes. Its exit status is ignored.
The control of the optional log service cannot be customized.
If runsv receives a TERM signal, it
acts as if the character x was written to the control pipe.
runsv
exits 111 on an error on startup or if another runsv is running in service.
runsv exits 0 if it was told to exit.
sv(8), chpst(8), svlogd(8),
runit(8), runit-init(8), runsvdir(8), runsvchdir(8), utmpset(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/runscripts.html 0000644 0000000 0000000 00000062477 14675400254 016340 0 ustar root root
runit - collection of run scripts
G. Pape
runit
How to replace init
runit - collection of run scripts
This is a collection of run scripts for popular services to have
them monitored by the
daemontools or
runit package.
If you have additional run scripts or one of these run scripts works for you on
an operating system not stated here, please
let me know.
Thanks go to the following people for contributing run scripts:
Alessandro Bono, Robin S. Socha, Claus Alboege, Paul Jarc, clemens fischer,
Jesse Cablek, Lukas Beeler, Thomas Baden, Ralf Hildebrandt, Antonio Dias,
Erich Schubert, Lang Martin, Tomasz Nidecki, Marek Bartnikowski,
Thomas Schwinge, Gael Canal, Woon Wai Keen, Richard A Downing, Phil Genera,
Stefan Karrmann, Kevin Berry, Karl Chen, Sascha Huedepohl, Jason Smith,
Kevin, marlowe, ed neville, xavier dutoit.
See also
here for some more run
scripts.
atftpd
apache
apache2
atd
bind9
boa
cfengine
cfsd
chrony
clamav
clamsmtpd
courier-imap
cron
cups
dhclient
dhcpcd
dhcpd
dictd
dropbear
exim
expireproctitle
fam
fcron
fetchmail
gdm
getty
gpm
hotwayd
identd
inn
jabberd
junkbuster
kdm
keepalived
klogd
leafnode
logging Linux kernel messages
logging console messages
mdadm
minidentd
mpd
nscd
ntpd
nullidentd
polipo
pop3-ssl
pop3vscan
portmap
postfix
postgresql
powernowd
ppp
privoxy
proftpd
pure-ftpd
radiusd
rmrtg
rsyncd
samba (smbd, nmbd)
shoutcast
spamd
squid
sshd
sshd under tcpserver
statd, mountd
stunnel
subversion
swat
syslogd
taiclockd
tmda-ofmipd
tomcat
tor
vsftpd
wvdial
xdm
xfs
(Debian)
#!/bin/sh
exec in.tftpd --daemon --no-fork --tftpd-timeout 30 \
--retry-timeout 5 --no-tsize --no-blksize --no-multicast \
--maxthread 1000 --verbose=7 /var/atfpd 2>&1
(SunOS, Apache 1.*, patched to run under supervise)
#!/bin/sh
exec 2>&1
exec env -i \
/pack/apache/1.3.27-1/sbin/httpd -F 2>&1
(Debian woody)
#!/bin/sh
exec 1>&2
exec apache-ssl -F
(SunOS)
#!/bin/sh
exec 2>&1
exec env -i /command/pgrphack \
/pack/apache/2.0.43-1/sbin/httpd -DFOREGROUND 2>&1
(HP-UX/GNU, Linux)
#!/bin/sh
TZ=MET-1METDST
export TZ
exec /usr/local/apache2/bin/httpd -DNO_DETACH
(Debian sarge)
#!/bin/sh
exec 2>&1
exec atd -d
(Linux)
#!/bin/sh
MEM="`head -1 ./env/MEM`"
CHROOT="`head -1 ./env/CHROOT`"
exec softlimit -m "${MEM}" \
named -u bind -t "${CHROOT}" -g 2>&1
(HP-UX/GNU, Linux)
#!/bin/sh
exec named -f -t /var/spool/named/ -u named
(SunOS)
#!/bin/sh
exec 2>&1
ulimit -n 1024
exec /pack/boa/current/boa -c /pack/boa/current -d 2>&1
(SunOS)
#!/bin/sh
/pack/cfengine/sbin/cfagent --file /pack/cfengine/etc/cfagent.conf \
-L -v -q exec sleep 3600
(Debian sarge)
#!/bin/sh
exec 2>&1
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
DAEMON=cfsd
CONFIG_FILE=/etc/cfs.conf
# source config file
test ! -r "$CONFIG_FILE" || . "$CONFIG_FILE"
test -n "$CRYPT_ROOT" || exit 0
test -n "$NULL_EXPORT" || exit 0
test -n "$CFS_MOUNT" || exit 0
test -n "$CFS_UMOUNT" || exit 0
sv start portmap || exit 1
exec env \
NODAEMON=1 CFS_MOUNT="$CFS_MOUNT" CFS_UMOUNT="$CFS_UMOUNT" $DAEMON
(LFS)
#!/bin/sh
exec 2>&1
exec chronyd -d -r -s
This service needs a
log service
to be set up.
(RedHat 7)
#!/bin/sh
exec 2>&1
exec setuidgid clamav softlimit -a 40000000 clamd
This service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
exec 2>&1
exec chpst -uclamav clamsmtpd -d 3
This service needs a
log service
to be set up.
(SunOS)
#!/bin/sh
exec 2>&1
PREFIX="/usr/lib/courier-imap"
exec envdir ./env \
tcpserver -v -R 0 143 \
$PREFIX/sbin/imaplogin \
$PREFIX/libexec/authlib/authshadow \
$PREFIX/libexec/authlib/authvchkpw \
$PREFIX/bin/imapd Maildir
See also
this page.
(Debian sarge)
#!/bin/sh
exec 2>&1
exec cron -f -l
(Debian woody)
#!/bin/sh
exec 2>&1
exec cupsd -f
(Debian woody)
#!/bin/sh
exec dhclient -e -d -cf ./config -lf ./leases -pf ./pid eth1
(Linux, DHCP Client Daemon v.scriptconfig-0.1)
#!/bin/sh
exec dhcpcd -a -d -D -H eth0
(Debian woody)
#!/bin/sh
exec 2>&1
exec dhcpd-2.2.x -f -d -cf ./config eth0
This service needs a
log service
to be set up.
(Solaris 8, uses additional dsvclockd service, would get fired off
automatically, but then it's not supervised)
#!/bin/sh
exec 2>&1
exec envdir ./env /usr/lib/inet/dsvclockd -f
#!/bin/sh
if svok /service/dsvclockd; then
sleep 2 # wait to make sure dsvclockd is initialized
exec 2>&1
exec envdir ./env /usr/lib/inet/in.dhcpd -b manual -d # -v
fi
echo dsvclockd is not running - aborting
exec /usr/bin/sleep 5
The in.dhcpd service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
exec 2>&1
exec dictd -d nodetach
(Linux)
#!/bin/sh
exec 2>&1
exec dropbear -F -E -p 22
This service needs a
log service
to be set up.
(Linux, running under
tcpsvd)
#!/bin/sh
exec 2>&1
exec tcpsvd -v -i./peers 0 22 dropbear -i -E
This service needs a
log service
to be set up.
(Linux, FreeBSD)
#!/bin/sh
exec /usr/local/sbin/exim -bdf -q30m
(Linux)
#!/bin/sh
echo -n .
exec sleep 300
(Slackware Linux 9.0)
#!/bin/sh
exec 2>&1
exec fam -L -f -v
This service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
exec 2>&1
sv start /service/portmap || exit 1
exec famd -T 0 -f
(Debian etch)
#!/bin/sh
exec 1>&2
daemon_directory=/usr/lib/postfix \
command_directory=/usr/sbin \
config_directory=/etc/postfix \
queue_directory=/var/spool/postfix \
mail_owner=postfix \
setgid_group=postdrop \
/etc/postfix/postfix-script check || exit 1
exec /usr/lib/postfix/master
(LFS)
#!/bin/sh
exec 2>&1
exec fcron -f -y
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh
INTERVAL=551
exec 2>&1
echo "*** Starting fetchmail service..."
exec env FETCHMAILHOME="./pid" \
chpst -u fetchmail fetchmail -v \
-f ./fetchmail.conf \
--nodetach \
--daemon ${INTERVAL}
(Debian woody)
#!/bin/sh
exec gdm -nodaemon
(Debian)
#!/bin/sh
exec mingetty tty5
The runit package does not care about utmp records
for getties. You should choose a getty that handles its own utmp and wtmp
records.
Debian's mingetty creates its own utmp record.
An agetty run script
(Slackware Linux 9.0)
#!/bin/sh
exec agetty 38400 tty1 linux
A fgetty run script
(Linux)
#!/bin/sh
exec chpst -P fgetty tty4
The runsv program does not automatically create
a new session and separate process group for run scripts, which can
cause some getties to fail due to limited permissions.
The chpst program can be used to alter the
process state for those getties.
(LFS)
#!/bin/sh
exec 2>&1
. /etc/sysconfig/mouse
exec gpm -D -m $MDEVICE -t $PROTOCOL
(LFS)
#!/bin/sh
exec 2>&1
exec tcpsvd -l0 -u nobody 127.0.0.1 110 hotwayd
(Linux, oidentd version 2.0.6)
#!/bin/sh
exec 2>&1
exec oidentd -i -S -t 10 -u daemon -g daemon
This service needs a
log service
to be set up.
(Debian)
#!/bin/sh
exec /usr/local/sbin/oidentd --nosyslog -i -u ident -g ident -l 15 -m \
-C /etc/oidentd/oidentd.conf 2>&1
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh
MEM="`head -1 ./env/MEM`"
exec softlimit -m "${MEM}" \
setuidgid news \
/usr/sw/bin/news/inndstart -f -r
(RedHat 7)
#!/bin/sh
exec 2>&1
if [ -f /usr/local/jabber/jabber.pid ]; then
rm /usr/local/jabber/jabber.pid
fi
exec setuidgid jabberd \
/usr/local/jabber/jabberd/jabberd -D -c /etc/jabber.xml
This service needs a
log service
to be set up.
#!/bin/sh
exec 2>&1
sleep 5 # so that jit starts after jabberd is up
exec setuidgid jabberd \
/usr/local/jabber/jit/jabberd/jabberd -c /etc/jit.xml
This service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
exec 2>&1
DAEMON=junkbuster
exec "$DAEMON" /etc/junkbuster/config
(Debian sid, FreeBSD 5.3-REL)
#!/bin/sh
sv start /service/getty-* || exit 1
exec kdm -nodaemon
(Linux)
#!/bin/sh
exec 2>&1
exec keepalived -n
(Debian woody)
#!/bin/sh
exec klogd -n
(Linux)
#!/bin/sh
exec 2>&1
exec envuidgid news \
tcpserver -v -x rules.cdb -c 10 -U 0 119 \
leafnode
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh -e
exec < /proc/kmsg \
setuidgid loguser \
multilog t n64 ./main
(Debian sarge)
#!/bin/sh
DEBIANCONFIG=/etc/default/mdadm
MAIL_TO=root
test -f $DEBIANCONFIG && . $DEBIANCONFIG
exec mdadm --monitor --scan --mail $MAIL_TO
(Linux)
#!/bin/sh
exec 2>&1
exec envuidgid nobody \
tcpserver -vUR 0 113 \
timeoutafter 60 \
minidentd -v
This service needs a
log service
to be set up.
(Debian sid, FreeBSD 5.3-REL)
#!/bin/sh
MPDCONF=/etc/mpd.conf
exec mpd --stdout --no-daemon $MPDCONF
This service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
secure=""
for table in passwd group
do
if egrep '^'$table':.*nisplus' /etc/nsswitch.conf >/dev/null
then
nscd_nischeck $table || secure="$secure -S $table,yes"
fi
done
exec nscd -d -- $secure
(Linux)
#!/bin/sh
MEM=`head -1 ./env/MEM`
exec softlimit -m "${MEM}" \
ntpd -n
(OpenNTPD on OpenBSD/Linux)
#!/bin/sh
exec /usr/sbin/ntpd -s -d 2>&1
This service needs a
log service
to be set up.
(Debian sarge)
#!/bin/sh
exec 2>&1
exec tcpsvd -u nobody -x nullidentd-cdb -t 60 0 113 nullidentd
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh
exec 2>&1
exec setuidgid polipo \
polipo -c config forbiddenFile="`pwd`"/forbidden diskCacheRoot="`pwd`"/cache
This service needs a
log service
to be set up.
(BSD)
#!/bin/sh
exec tcpserver -R -v -c 50 0 995 /usr/local/sbin/stunnel
-f -p /etc/ssl/stunnel.pem \
-l /var/qmail/bin/qmail-popup -- /var/qmail/bin/qmail-popup
"`cat /var/qmail/control/me`" vchkpw /var/qmail/bin/qmail-pop3d Maildir 2>&1
This service needs a
log service
to be set up.
(RedHat 7)
#!/bin/sh
exec 2>&1
exec setuidgid pop3vscan pop3vscan -d
This service needs a
log service
to be set up.
(LFS, Debian sarge)
#!/bin/sh
exec 2>&1
exec portmap -d
(Debian, SunOS)
#!/bin/sh
exec setuidgid postgres /usr/lib/postgresql/bin/postmaster \
-D /var/lib/postgres/data 2>&1
This service needs a
log service
to be set up.
(Debian)
#!/bin/sh
set -e # barf if modprobe fails
modprobe cpufreq-userspace
test ! -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ||
exec /usr/sbin/powernowd -d
echo "required sysfs objects not found!"
echo "Read /usr/share/doc/powernowd/README.Debian for more information."
sv down "$(pwd)"
(FreeBSD)
#!/bin/sh
exec 2>&1
echo "ppp -ddial dsl "
exec ppp -unit0 -foreground dsl
A pppd run script
(Linux)
#!/bin/sh
exec 2>&1
exec chpst -P pppd call isp nodetach
(Debian sarge)
#!/bin/sh
exec 2>&1
exec chpst -u privoxy:nogroup privoxy --no-daemon /etc/privoxy/config
This service needs a
log service
to be set up.
(Linux, ProFTPD Version 1.2.8rc1,
configure it to use 'ErrorLog "/dev/stdout"')
#!/bin/sh
exec 2>&1
exec proftpd -n -d 1
This service needs a
log service
to be set up.
(Debian woody)
#!/bin/sh
exec 2>&1
exec pure-ftpd -a 50 -E -l pam -u 100
(Slackware Linux 9.0, cistron radius 1.6.1)
#!/bin/sh
exec 2>&1
exec radiusd -f -y -z -lstdout
This service needs a
log service
to be set up.
()
#!/bin/sh
MRTGUID=`id -u mrtg`
MRTGGID=`id -g mrtg`
exec 2>&1
exec tcpserver -l 0 -R -H -q \
-u"${MRTGUID}" -g"${MRTGGID}" 0 5660 /home/mrtg/ext/rmrtg
(SunOS)
#!/bin/sh
exec 2>&1
exec softlimit -d 100000000 tcpserver \
-x /pack/rsync/rsync.service/tcp.rsync.cdb -v -c 100 -U -H -l 0 -R \
1.2.3.4 873 nice -2 /pack/rsync/bin/rsync --daemon --no-detach \
--config /pack/rsync/etc/rsyncd.conf
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh
PATH="/usr/local/samba/bin"
exec 2>&1
exec smbd -F -S -d3
This service needs a
log service
to be set up.
A nmbd run script
(Linux)
#!/bin/sh
PATH="/usr/local/samba/bin"
exec 2>&1
exec nmbd -F -S -d1
This service needs a
log service
to be set up.
(RedHat 7)
#!/bin/sh
exec 2>&1
exec setuidgid sc_serv \
/usr/local/sc_serv/bin/sc_serv /etc/sc_serv.conf
This service needs a
log service
to be set up.
(Debian woody)
#!/bin/sh
exec spamd -m 20 -a -H -s stderr 2>&1
This service needs a
log service
to be set up.
(Debian woody)
#!/bin/sh
exec squid -f ./config -sN
(Debian)
#!/bin/sh
exec 2>&1
exec /usr/sbin/sshd -D -e
This service needs a
log service
to be set up.
(Linux, sshd version OpenSSH_3.4p1)
#!/bin/sh -e
exec 2>&1
exec \
tcpserver -1vpdl0 -Xxtcp.cdb 0 ssh \
sshd -ief config
This service needs a
log service
to be set up.
(Debian woody)
#!/bin/sh
exec 2>&1
NEED_LOCKD=yes
if test -f /proc/ksyms; then
# We need to be conservative and run lockd,
# unless we can prove that it isn't required.
grep -q lockdctl /proc/ksyms || NEED_LOCKD=no
fi
if [ "$NEED_LOCKD" = yes ]; then
rpc.lockd
fi
exec rpc.statd -F -d
This service needs a
log service
to be set up.
(Debian)
#!/bin/sh
sv start portmap statd || exit 1
RPCNFSDCOUNT=8 # Number of servers to be started up by default
RPCMOUNTDOPTS=
trap '/usr/bin/killall -2 nfsd' 0
trap 'exit 2' 1 2 3 15
exportfs -r
rpc.nfsd -- $RPCNFSDCOUNT
rpcinfo -u localhost nfs 3 >/dev/null 2>&1 ||
RPCMOUNTDOPTS="$RPCMOUNTDOPTS --no-nfs-version 3"
exec rpc.mountd -F $RPCMOUNTDOPTS
(BSD)
#!/bin/sh
exec /usr/local/sbin/stunnel -f -d 1234 -r 25 -v3 -a /etc/ssl/mailcerts 2>&1
(Debian)
#!/bin/sh
exec 2>&1
exec /usr/bin/svnserve -d --foreground
#!/bin/sh
exec 2>&1
exec tcpsvd -l0 127.0.0.1 901 swat
(Debian sarge)
#!/bin/sh
exec syslogd -n
#!/bin/sh
exec 2>&1
exec setuidgid taiclock /usr/local/clockspeed/bin/taiclockd
(RedHat 7)
#!/bin/sh
exec /usr/local/tmda/bin/tmda-ofmipd -f -d -R pop3 -p my.host.name:8025 2>&1
This service needs a
log service
to be set up.
(SunOS)
#!/bin/sh
exec 2>&1
exec \
setuidgid apache \
/pack/tomcat/current/bin/catalina.sh run
(Debian sarge)
#!/bin/sh
exec 2>&1
exec chpst -P -u debian-tor:debian-tor tor
(RedHat 7)
#!/bin/sh
exec 2>&1
exec tcpserver -c30 -Xv -llocalhost \
-x/etc/tcp.ftp.cdb -uvsftpd -gvsftpd 0 ftp \
softlimit -d300000 /var/vsftpd/bin/vsftpd
This service needs a
log service
to be set up.
(Slackware Linux 9.0, the service should have a down
file, use svc -o /service/wvdial to bring up a ppp connection)
#!/bin/sh
exec 2>&1
exec wvdial ISP
This service needs a
log service
to be set up.
(Linux)
#!/bin/sh
sv start /service/vc-* || exit 1
exec xdm -nodaemon
(Debian sarge)
#!/bin/sh
SOCKET_DIR=/tmp/.font-unix
mkdir -p $SOCKET_DIR
chown 0:0 $SOCKET_DIR
chmod 1777 $SOCKET_DIR
exec /usr/bin/X11/xfs -nodaemon
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/runsvdir.8.html 0000644 0000000 0000000 00000006064 14675400254 016134 0 ustar root root
runsvdir(8) manual page
G. Pape
runit
runsvdir - starts and monitors a collection of runsv(8) processes
runsvdir
[-P] dir [ log ]
dir must be a directory. log is a space holder
for a readproctitle log, and must be at least seven characters long or
absent.
runsvdir starts a runsv(8) process for each subdirectory, or symlink
to a directory, in the services directory dir, up to a limit of 1000 subdirectories,
and restarts a runsv(8) process if it terminates. runsvdir skips subdirectory
names starting with dots. runsv(8) must be in runsvdir’s PATH.
At least every
five seconds runsvdir checks whether the time of last modification, the
inode, or the device, of the services directory dir has changed. If so,
it re-scans the service directory, and if it sees a new subdirectory, or
new symlink to a directory, in dir, it starts a new runsv(8) process; if
runsvdir sees a subdirectory being removed that was previously there, it
sends the corresponding runsv(8) process a TERM signal, stops monitoring
this process, and so does not restart the runsv(8) process if it exits.
If the log argument is given to runsvdir, all output to standard error
is redirected to this log, which is similar to the daemontools’ readproctitle
log. To see the most recent error messages, use a process-listing tool such
as ps(1). runsvdir writes a dot to the readproctitle log every 15 minutes
so that old error messages expire.
- -P
- use setsid(2) to run each runsv(8)
process in a new session and separate process group.
If runsvdir
receives a TERM signal, it exits with 0 immediately.
If runsvdir receives
a HUP signal, it sends a TERM signal to each runsv(8) process it is monitoring
and then exits with 111.
sv(8), runsv(8), runsvchdir(8), runit(8),
runit-init(8), chpst(8), svlogd(8), utmpset(8), setsid(2)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/benefits.html 0000644 0000000 0000000 00000017744 14675400254 015720 0 ustar root root
runit - benefits
G. Pape
runit
runit - benefits
Service supervision
Clean process state
Reliable logging facility
Fast system boot up and shutdown
Portability
Packaging friendly
Small code size
Service supervision
Each service is associated with a service directory, and each
service daemon runs as a child process of a supervising
runsv process running in this directory.
The runsv program provides a reliable interface
for signalling the service daemon and controlling the service and
supervisor.
Normally the sv program is used to send commands
through this interface, and to query status informations about the service.
The runsv program supervises the corresponding
service daemon.
By default a service is defined to be up, that means, if the service daemon
dies, it will be restarted.
Of course you can tell runsv otherwise.
This reliable interface to control daemons and supervisors obsoletes
pid-guessing programs, such as pidof, killall,
start-stop-daemon, which, due to guessing, are prone to failures
by design.
It also obsoletes so called pid-files, no need for each and every
service daemon to include code to daemonize, to write the new process id
into a file, and to take care that the file is removed properly on shutdown,
which might be very difficult in case of a crash.
Clean process state
runit guarantees each service a clean process state, no matter if the
service is activated for the first time or automatically at boot time,
reactivated, or simply restarted.
This means that the service always is started with the same environment,
resource limits, open file descriptors, and controlling terminals.
You don't necessarily have that with sysv init scripts for example.
It requires a carefully written init script that reliably cleans up and sets
the process state before starting the service daemon.
This adds even more complexity to the init script in comparison with a run
script used by runit.
Many of today's init scripts don't provide a clean process state, here is
an example on what could happen:
# /etc/init.d/foo-daemon start
Starting foo daemon: food.
#
Fine.
Everything works, nothing to worry about.
After rebooting the system this shows up on the screen:
...
Starting foo daemon: food: command not found
failed.
...
The food program is installed in /opt/foo/bin/.
When starting the service for the first time using the init script, the
PATH environment variable contained /opt/foo/bin.
After reboot init started the service using the init script, but
with a different value for the PATH variable, not containing
/opt/foo/bin.
Of course the init script should have set PATH before starting the
daemon; the problem is that it worked in the first place, and that the error
didn't show up until system reboot.
With bad init scripts miraculous things could also happen when just doing
# /etc/init.d/foo-daemon restart
at the command line.
The clean process state includes open file descriptors, obsoleting the
widely used hack in many service daemons to force-close all file descriptors
that might be open, up to the limit of available file descriptors for the
daemon process (often results in 1024 unnecessary close() system calls in a
great number of service daemon implementations).
Reliable logging facility
The runsv program provides a reliable logging
facility for the service daemon.
If configured, runsv creates a pipe, starts and
supervises an additional log service, redirects the log daemon's standard
input to read from the pipe, and redirects the service daemon's standard
output to write to the pipe.
Restarting the service does not require restarting the log service, and vice
versa.
A good choice for a log daemon is runit's service logging daemon
svlogd.
The service daemon and the log daemon can run with different process states,
and under different user id's.
runit supports easy and reliable logging for service daemons running
chroot'ed.
If runsv is told to shutdown a service, e.g. at
system shutdown, it ensures that the log service stays up as long as the
corresponding service daemon is running and possibly writing to the log.
Fast system boot up and shutdown
After the system's one time tasks (stage 1) are done, the system services
are started up in parallel.
The operating system's process scheduler takes care of having the services
available as soon as possible.
On system shutdown, stage 3 uses runsv's control
interface to wait until each service daemon is terminated and all logs are
written.
Again, services are taken down in parallel.
As soon as all services are down, system halt or system reboot is initiated.
Portability
runit comes ready-to-run for Debian GNU/Linux and BSD systems, and
can easily be configured to run on other UNIX systems.
The UNIX system's one time initialization tasks and tasks to shutdown the
system must be identified and runit's stages 1 and 3 configured
accordingly.
Stages 1 and 3 handle one time tasks.
They only run for short and exit soon.
Stage 2 handles the system's uptime tasks (via the
runsvdir program) and is running the whole
system's uptime.
runit's stage 2 is portable across UNIX systems.
runit is well suited for server systems and embedded systems, and
also does its job well on desktop systems.
Packaging friendly
runit's stages 1 and 3 are distribution specific.
They normally are shell scripts, and an operating system distribution with
software package management should adapt these scripts if they need support
for their package management.
The
runit-run
Debian package is an attempt to integrate runit into
Debian GNU/Linux as an alternative to
the default
sysvinit.
Stage 2 is packaging friendly:
all a software package that provides a service needs to do is to include
a service directory in the package, and to provide a symbolic link
to this directory in /service/.
The service will be started within five seconds, and automatically at boot
time.
The package's install and update scripts can use the reliable control
interface to stop, start, restart, or send signals to the service.
On package removal, the symbolic link simply is removed.
The service will be taken down automatically.
Small code size
One of the runit project's principles is to keep the code size
small.
As of version 1.0.0 of runit, the runit.c source contains
330 lines of code; the runsvdir.c source is 274 lines of code, the
runsv.c source 509.
This minimizes the possibility of bugs introduced by programmer's fault,
and makes it more easy for security related people to proofread the source
code.
The runit core programs have a very small memory footprint and do not
allocate memory dynamically.
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/upgrade.html 0000644 0000000 0000000 00000012543 14675400254 015540 0 ustar root root
runit - upgrading from previous versions
G. Pape
runit
runit - upgrading from previous versions
2.1.x to 2.2.0
The chpst program learned a new option -C to run
a program in a sepcific working directory, and the
runit program now respects the magic file
/etc/runit/nosync to make sync (commit filesystem caches to disk)
on shutdown and reboot optional.
2.0.0 to 2.1.2
The chpst program learned a new option -b to run
a program with a different name as the 0th argument.
1.9.0 to 2.0.0
No further action from you is required.
1.8.0 to 1.9.0
The default directory for services is now /service/, and no longer
/var/service/.
To be consistent with the new default location, create a symlink when
upgrading
# ln -s /var/service /
When installing runit on a system that should comply with the Filesystem
Hierarchy Standard (FHS), neither /service/ nor
/var/service/ should be chosen, but /etc/service/.
It is recommended to create a compatibility symlink /service
pointing to /etc/service in this case.
1.7.x to 1.8.0
The runit program, the process no 1, has been
fixed to reap dead processes that re-parented to process no 1 (zombies)
more thoroughly.
Instructions on how to run runit with upstart as init scheme have
been added, svlogd has been changed to use a
new source port for each log message sent through udp, and this release
includes a build fix for AIX.
1.6.0 to 1.7.x
With this version the runsv program starts to
run the ./finish script with two arguments, the exit code and the exit
status of the just finished ./run script.
The timestamp svlogd optionally prepends to log
messages can be specified to be in iso 8601 alike format.
See the man pages for details.
1.5.x to 1.6.0
svlogd has been changed to prepend the optional
timestamp also to log messages sent to the network through UDP, just as it
does for log messages written to a log directory or standard error.
1.4.0 or 1.4.1 to 1.5.x
The svlogd program supports a new configuration
option p to optionally prefix each line written to logs, standard error, or
through UDP with a string, and no longer strips empty lines from the logs.
1.3.x to 1.4.0 or 1.4.1
With this version the runsvctrl, runsvstat,
svwaitdown, and svwaitup programs no longer are being
installed, the functionality of these programs has been incorporated into
the sv program.
The documentation now suggest to put service directories by default into
the /etc/sv/ directory, and a list of frequently asked questions
with answers has been added.
The chpst program understands a new option -d
to limit memory of the data segment per process.
1.2.x to 1.3.x
This release introduces a first test version of the sv
program, which can be used to control the state and query the status of
services monitored by runsv.
Optionally it can be sym-linked into /etc/init.d/ to provide an
interface to LSB init script actions for services controlled by runit.
See the man page for details.
Thanks to Lars Uffmann, instructions on how to run runit under launchd on
MacOSX 10.4 have been added.
1.1.0 to 1.2.x
With this version the runsv program makes
controlling the service through commands normally sent by
runsvctrl configurable;
arbitrary actions through external programs can optionally be specified, and
signalling of the service disabled if desired.
See the man page for details.
runsv now reports the seconds since ./run
has been started when running the ./finish script, instead of the
seconds since ./finish has been started.
It no longer reports immediately failing ./run scripts as ``running''
for up to one second, but as ``down, normally up, want up''.
1.0.x to 1.1.0
The svlogd program now interprets the ``e'' and
``E'' configuration options so that they can be combined to select or
deselect log messages to be written to standard error, similar to the ``+''
and ``-'' options for the rotated log.
It also provides the new ``t'' and ``N'' configuration options, see the
man page for details.
The chpst program supports adjusting the nice
level through the new -n command line option.
Starting with this version, /etc/runit/2 by default runs the
runsvdir program with the -P option.
To adapt edit /etc/runit/2 and change the invocation of
runsvdir accordingly, see
here.
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/runit-init.8.html 0000644 0000000 0000000 00000004161 14675400254 016356 0 ustar root root
runit-init(8) manual page
G. Pape
runit
init - a UNIX process no 1
init [ 0 | 6 ]
runit-init
is the first process the kernel starts. If runit-init is started as process
no 1, it runs and replaces itself with runit(8).
If runit-init is started
while the system is up, it must be either called as init 0 or init 6:
- init
0
- tells the Unix process no 1 to shutdown and halt the system. To signal
runit(8) the system halt request, runit-init removes all permissions of
the file /etc/runit/reboot (chmod 0), and sets the execute by owner permission
of the file /etc/runit/stopit (chmod 100). Then a CONT signal is sent to
runit(8).
- init 6
- tells the Unix process no 1 to shutdown and reboot the
system. To signal runit(8) the system reboot request, runit-init sets the
execute by owner permission of the files /etc/runit/reboot and /etc/runit/stopit
(chmod 100). Then a CONT signal is sent to runit(8).
runit-init
returns 111 on error, 0 in all other cases.
runit(8), runsvdir(8),
runsvchdir(8), sv(8), runsv(8), chpst(8), utmpset(8), svlogd(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/debian 0000777 0000000 0000000 00000000000 14675400254 016513 2../etc/debian ustar root root admin/runit-2.2.0/doc/chpst.8.html 0000644 0000000 0000000 00000014453 14675400254 015402 0 ustar root root
chpst(8) manual page
G. Pape
runit
chpst - runs a program with a changed process state
chpst [-vVP012]
[-u user] [-U user] [-b argv0] [-e dir] [-/ root] [-C pwd] [-n inc] [-l|-L lock] [-m bytes] [-d bytes]
[-o n] [-p n] [-f bytes] [-c bytes] [-t seconds] prog
prog consists of one or
more arguments.
chpst changes the process state according to the given options,
and runs prog.
- -u [:]user[:group]
- setuidgid. Set uid and gid to the
user’s uid and gid, as found in /etc/passwd. If user is followed by a colon
and a group, set the gid to group’s gid, as found in /etc/group, instead
of user’s gid. If group consists of a colon-separated list of group names,
chpst sets the group ids of all listed groups. If user is prefixed with
a colon, the user and all group arguments are interpreted as uid and gids
respectively, and not looked up in the password or group file. All initial
supplementary groups are removed.
- -U [:]user[:group]
- envuidgid. Set the environment
variables $UID and $GID to the user’s uid and gid, as found in /etc/passwd.
If user is followed by a colon and a group, set $GID to the group’s gid,
as found in /etc/group, instead of user’s gid. If user is prefixed with a
colon, the user and group arguments are interpreted as uid and gid respectively,
and not looked up in the password or group file.
- -b argv0
- argv0. Run prog
with argv0 as the 0th argument.
- -e dir
- envdir. Set various
environment variables as specified by files in the directory dir: If dir
contains a file named k whose first line is v, chpst removes the environment
variable k if it exists, and then adds the environment variable k with
the value v. The name k must not contain =. Spaces and tabs at the end of
v are removed, and nulls in v are changed to newlines. If the file k is
empty (0 bytes long), chpst removes the environment variable k if it exists,
without adding a new variable.
- -/ root
- chroot. Change the root directory to
root before starting prog.
- -C pwd
- chdir. Change the working directory to
pwd before starting prog.
When combined with -/, the working directory is changed after the chroot.
- -n inc
- nice. Add inc to the nice(2) value before
starting prog. inc must be an integer, and may start with a minus or plus.
- -l lock
- lock. Open the file lock for writing, and obtain an exclusive lock
on it. lock will be created if it does not exist. If lock is locked by another
process, wait until a new lock can be obtained.
- -L lock
- The same as -l, but
fail immediately if lock is locked by another process.
- -m bytes
- limit memory.
Limit the data segment, stack segment, locked physical pages, and total
of all segment per process to bytes bytes each.
- -d bytes
- limit data segment.
Limit the data segment per process to bytes bytes.
- -o n
- limit open files.
Limit the number of open file descriptors per process to n.
- -p n
- limit processes.
Limit the number of processes per uid to n.
- -f bytes
- limit output size. Limit
the output file size to bytes bytes.
- -c bytes
- limit core size. Limit the core
file size to bytes bytes.
- -t seconds
- limit CPU time. Limit CPU time to seconds seconds, delivering a SIGXCPU thereafter.
- -v
- verbose. Print verbose messages to standard error.
This includes warnings about limits unsupported by the system.
- -V
- version string. Print a version string to standard error.
- -P
- pgrphack.
Run prog in a new process group.
- -0
- Close standard input before starting
prog.
- -1
- Close standard output before starting prog.
- -2
- Close standard error
before starting prog.
chpst exits 100 when called with wrong options.
It prints an error message and exits 111 if it has trouble changing the
process state. Otherwise its exit code is the same as that of prog.
If
chpst is called as envdir, envuidgid, pgrphack, setlock, setuidgid, or
softlimit, it emulates the functionality of these programs from the daemontools
package respectively.
sv(8), runsv(8), setsid(2), runit(8), runit-init(8),
runsvdir(8), runsvchdir(8)
http://smarden.org/runit/
http://cr.yp.to/daemontools.html
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/faq.html 0000644 0000000 0000000 00000030452 14675400254 014657 0 ustar root root
runit - Frequently asked questions
G. Pape
runit
runit - Frequently asked questions
What's runit, why is it that different
I need some help with runit, what should I do
What's the license, is runit free software
How do I run a service under runit service supervision
How do I create a new service directory
How do I create a new service directory with an appendant log service
How do I tell runit about a new service
How do I start, stop, or restart a service
How can I send signals to a service daemon
How can I query the status of a service
How do I remove a service
How do I make a service depend on another service
What about runlevels
What about LSB init scripts compliance
Is it possible to allow a user other than root to control a service
Does runit support user-specific services?
Does runit work on a read-only filesystem
What's runit, why is it that different
What is this runit init scheme about?
Why is it that different from sysvinit and other init schemes?
Answer:
Please see the introduction, and web page about
runit's benefits.
I need some help with runit, what should I do
I have a question, runit is doing something wrong, or I'm doing something
wrong, what should I do?
Answer:
First see the documentation, especially this list of
frequently asked questions, and the man pages
if you have a question about a specific runit program.
If that still doesn't answer your question, try to search the
supervision mailing list archive.
Finally, if this fails, feel free to post your question to the
supervision mailing list.
What's the license, is runit free software
I would like to distribute runit, in source and binary form.
Am I allowed to do so?
Answer:
runit is free software, it's licensed under a three-clause BSD alike
license.
See the file package/COPYING in the runit tarball.
How do I run a service under runit service supervision
I want a service to be run under runit service supervision, so that it's
automatically started on system boot, and supervised while system uptime.
How does that work?
Answer:
runit doesn't use the usual /etc/init.d/ init script interface,
but uses a directory per service.
To integrate a service into the runit init scheme,
create a service directory for the service, and
tell runit about it.
How do I create a new service directory
How do I create a service directory for the use with runit?
Answer:
Service directories usually are placed into the /etc/sv/
directory.
Create a new directory for your service in /etc/sv/, put a
./run script into it, and make the script executable.
Note that for the use with runit,
service daemons must not put themself into the
background, but must run in the foreground.
Here's a simple example for a getty service:
$ cat /etc/sv/getty-2/run
#!/bin/sh
exec getty 38400 tty2 linux
$
Note the exec in the last line, it tells the shell that
interprets the script to replace itself with the service daemon
getty; this is necessary to make
controlling the service work properly.
How do I create a new service directory with an appendant log service
How do I create a service directory with an appendant log service for the
use with runit?
Answer:
First create the service directory for the service.
Then create a subdirectory ./log in the service directory, again
put a ./run script into it, and make the script executable.
The ./run script must run a service logging daemon, normally
this is the svlogd program.
See the runsv man page for details.
Here's an example of a ./log/run script:
$ cat /etc/sv/socklog-klog/log/run
#!/bin/sh
exec chpst -ulog svlogd -tt ./main
$
How do I tell runit about a new service
I created a service directory for a service that should run under runit
service supervision.
How do I tell runit about the new service directory, so that it picks
up and runs the service by default?
Answer:
Create a symbolic link in /service/ pointing to the service
directory, runit will pick up the service within the next five seconds,
and automatically start it on system boot.
E.g.:
# ln -s /etc/sv/getty-2 /service/
How do I start, stop, or restart a service
I want to stop a service temporarily, and probably restart is later, or
I want to have it restarted immediately.
How can I control a service running under runit service supervision?
Answer:
Use the sv program.
E.g., to restart the socklog-unix service, do:
# sv restart socklog-unix
How can I send signals to a service daemon
I want to send a service daemon the HUP signal, to have it re-read its
configuration, or I want to send it the INT signal.
How can a send signals to a service daemon?
Answer:
Use the sv program.
E.g., to send the dhcp service the HUP signal, do:
# sv hup dhcp
How can I query the status of a service
I want to now the status of a service, whether it is up and available,
or down as requested, or so.
How can I find out this information?
Answer:
User the sv program.
E.g., to query or check the status of the socklog-unix service,
do:
# sv status socklog-unix
or
# sv check socklog-unix
How do I remove a service
I want to remove a service that currently runs under runit service
supervision.
How do I tell runit?
Answer:
Remove the symbolic link in /service/ pointing to the service
directory, runit recognizes the removed service within the next five
seconds, then stops the service, the optional log service, and finally the
supervisor process.
E.g.:
# rm /service/getty-2
How do I make a service depend on another service
I have a service that needs another service to be available before it can
start.
How can I tell runit about this dependency?
Answer:
Make sure in the ./run script of the dependant service that the
service it depends on is available before the service daemon starts.
The sv program can be used for that.
E.g. the cron service wants the socklog-unix system
logging service to be available before starting the cron service
daemon, so no logs get lost:
$ cat /etc/sv/cron/run
#!/bin/sh
sv start socklog-unix || exit 1
exec cron -f
$
See also the documentation.
What about runlevels
Other init schemes support runlevels, what about runit?
Answer:
runit supports runlevels, even more flexible than traditional init schemes.
See the documentation.
What about LSB init scripts compliance
I know about the sv program to control a service,
but have applications that rely on the /etc/init.d/ scripts
interface as defined through LSB.
Do I need to change the application to work with runit?
Answer:
You don't need to change the application.
The sv program supports the /etc/init.d/
script interface
as defined through LSB.
To make this script interface work for a service, create a symbolic link
in /etc/init.d/, named as the service daemon, pointing to the
sv program, e.g. for the cron service:
# ln -s /bin/sv /etc/init.d/cron
# /etc/init.d/cron restart
ok: run: cron: (pid 5869) 0s
#
Is it possible to allow a user other than root to control a service
Using the sv program to control a service, or query
its status informations, only works as root.
Is it possible to allow non-root users to control a service too?
Answer:
Yes, you simply need to adjust file system permissions for the
./supervise/ subdirectory in the service directory.
E.g.: to allow the user burdon to control the service
dhcp, change to the dhcp service directory, and do
# chmod 755 ./supervise
# chown burdon ./supervise/ok ./supervise/control ./supervise/status
This works similarly with groups, of course.
Does runit support user-specific services?
It's very nice to simply
create symbolic links to add system-wide services.
Does this work for user-specific services too?
Answer:
Yes.
E.g.: to provide the user floyd with facility to manage services
through ~/service/, create a service
runsvdir-floyd with the following run script and a usual log/run
script, and tell runit about the service
#!/bin/sh
exec 2>&1
exec chpst -ufloyd runsvdir /home/floyd/service
Now floyd can create services on his own, and manage them through
symbolic links in ~/service/ to have them run under his user id.
Does runit work on a read-only filesystem
On my system /etc/ is mounted read-only by default.
runit uses many files in /etc/ it needs to write to, like
/etc/runit/stopit, and the ./supervise/
subdirectories in the service directories.
How can I make runit work on my system?
Answer:
Use symbolic links, runit deals with them well, even with dangling
symlinks.
E.g., make a ramdisk available at a moint point, say /var/run/,
and create symbolic links for the files and directories that runit needs
to write access to pointing into /var/run/:
# ln -s /var/run/runit.stopit /etc/runit/stopit
# ln -s /var/run/sv.getty-2 /etc/sv/getty-2/supervise
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/sv.8.html 0000644 0000000 0000000 00000020341 14675400254 014702 0 ustar root root
sv(8) manual page
G. Pape
runit
sv - control and manage services monitored by runsv(8)
sv [-v]
[-w sec] command services
/etc/init.d/service [-w sec] command
The
sv program reports the current status and controls the state of services
monitored by the runsv(8) supervisor.
services consists of one or more arguments,
each argument naming a directory service used by runsv(8). If service doesn’t
start with a dot or slash and doesn’t end with a slash, it is searched in
the default services directory /service/, otherwise relative to the current
directory.
command is one of up, down, status, once, pause, cont, hup, alarm,
interrupt, 1, 2, term, kill, or exit, or start, stop, restart, shutdown,
force-stop, force-reload, force-restart, force-shutdown.
The sv program can
be sym-linked to /etc/init.d/ to provide an LSB init script interface. The
service to be controlled then is specified by the base name of the ‘‘init
script’’.
- status
- Report the current status of the service, and the
appendant log service if available, to standard output.
- up
- If the service
is not running, start it. If the service stops, restart it.
- down
- If the service
is running, send it the TERM signal, and the CONT signal. If ./run exits,
start ./finish if it exists. After it stops, do not restart service.
- once
- If the service is not running, start it. Do not restart it if it stops.
- pause
cont hup alarm interrupt quit 1 2 term kill
- If the service is running,
send it the STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, or KILL
signal respectively.
- exit
- If the service is running, send it the TERM signal,
and the CONT signal. Do not restart the service. If the service is down,
and no log service exists, runsv(8) exits. If the service is down and a
log service exists, runsv(8) closes the standard input of the log service
and waits for it to terminate. If the log service is down, runsv(8) exits.
This command is ignored if it is given to an appendant log service.
sv actually
looks only at the first character of these commands.
- status
- Same as status.
- start
- Same as up, but wait
up to 7 seconds for the command to take effect. Then report the status or
timeout. If the script ./check exists in the service directory, sv runs this
script to check whether the service is up and available; it’s considered
to be available if ./check exits with 0.
- stop
- Same as down, but wait up to
7 seconds for the service to become down. Then report the status or timeout.
- reload
- Same as hup, and additionally report the status afterwards.
- restart
- Send the commands term, cont, and up to the service, and wait up to 7 seconds
for the service to restart. Then report the status or timeout. If the script
./check exists in the service directory, sv runs this script to check whether
the service is up and available again; it’s considered to be available if
./check exits with 0.
- shutdown
- Same as exit, but wait up to 7 seconds for
the runsv(8) process to terminate. Then report the status or timeout.
- force-stop
- Same as down, but wait up to 7 seconds for the service to become down. Then
report the status, and on timeout send the service the kill command.
- force-reload
- Send the service the term and cont commands, and wait up to 7 seconds for
the service to restart. Then report the status, and on timeout send the
service the kill command.
- force-restart
- Send the service the term, cont and
up commands, and wait up to 7 seconds for the service to restart. Then report
the status, and on timeout send the service the kill command. If the script
./check exists in the service directory, sv runs this script to check whether
the service is up and available again; it’s considered to be available if
./check exits with 0.
- force-shutdown
- Same as exit, but wait up to 7 seconds
for the runsv(8) process to terminate. Then report the status, and on timeout
send the service the kill command.
- try-restart
- if the service is running,
send it the term and cont commands, and wait up to 7 seconds for the service
to restart. Then report the status or timeout.
- check
- Check for the service to be in the state that’s been requested. Wait up to
7 seconds for the service to reach the requested state, then report the
status or timeout. If the requested state of the service is up, and the
script ./check exists in the service directory, sv runs this script to check
whether the service is up and running; it’s considered to be up if ./check
exits with 0.
- -v
- If the command is up, down, term, once, cont, or
exit, then wait up to 7 seconds for the command to take effect. Then report
the status or timeout.
- -w sec
- Override the default timeout of 7 seconds with
sec seconds. This option implies -v.
- SVDIR
- The environment variable
$SVDIR overrides the default services directory /service/.
- SVWAIT
- The environment
variable $SVWAIT overrides the default 7 seconds to wait for a command
to take effect. It is overridden by the -w option.
sv exits 0, if
the command was successfully sent to all services, and, if it was told
to wait, the command has taken effect to all services.
For each service
that caused an error (e.g. the directory is not controlled by a runsv(8)
process, or sv timed out while waiting), sv increases the exit code by
one and exits non zero. The maximum is 99. sv exits 100 on error.
If sv is
called with a base name other than sv: it exits 1 on timeout or trouble
sending the command; if the command is status, it exits 3 if the service
is down, and 4 if the status is unknown; it exits 2 on wrong usage, and
151 on error.
runsv(8), chpst(8), svlogd(8), runsvdir(8), runsvchdir(8),
runit(8), runit-init(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/install.html 0000644 0000000 0000000 00000003256 14675400254 015560 0 ustar root root
runit - installation
G. Pape
runit
runit - installation
runit installs into
/package.
If you don't have a /package directory, create it now:
# mkdir -p /package
# chmod 1755 /package
Download
runit-2.2.0.tar.gz into /package
(sha256sum)
and unpack the archive
# cd /package
# gunzip runit-2.2.0.tar
# tar -xpf runit-2.2.0.tar
# rm runit-2.2.0.tar
# cd admin/runit-2.2.0
On MacOSX, do
# echo 'cc -Xlinker -x' >src/conf-ld
# cp src/Makefile src/Makefile.old
# sed -e 's/ -static//' <src/Makefile.old >src/Makefile
Now compile and install the runit programs
# package/install
If you want to make the man pages available in the /usr/local/man/
hierarchy, do:
# package/install-man
To report success:
# mail pape-runit-2.2.0@xxiv.smarden.org <compile/sysdeps
If you use runit regularly, please
contribute to the project.
Refer to replacing init for
replacing init with runit, or to
use with traditional init for running
runit's service supervision with your system's current init
scheme.
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/utmpset.8.html 0000644 0000000 0000000 00000004053 14675400254 015755 0 ustar root root
utmpset(8) manual page
G. Pape
runit
utmpset - logout a line from utmp and wtmp file
utmpset [ -w
] line
The utmpset program modifies the user accounting database
utmp(5) and optionally wtmp(5) to indicate that the user on the terminal
line has logged out.
Ordinary init(8) processes handle utmp file records
for local login accounting. The runit(8) program doesn’t include code to
update the utmp file, the getty(8) processes are handled the same as all
other services.
To enable local login accounting, add utmpset to the getty(8)
finish scripts, e.g.:
$ cat /service/getty-5/finish
#!/bin/sh
exec utmpset -w tty5
$
- -w
- wtmp. Additionally to the utmp file, write an empty record for
line to the wtmp file.
utmpset returns 111 on error, 1 on wrong
usage, 0 in all other cases.
sv(8), runsv(8), runit(8), runit-init(8)
runsvdir(8), runsvchdir(8), chpst(8), svlogd(8), getty(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/index.html 0000644 0000000 0000000 00000026240 14675400254 015217 0 ustar root root
runit - a UNIX init scheme with service supervision
G. Pape
runit - a UNIX init scheme with service supervision
How to install runit
Upgrading from previous versions of runit
Benefits
How to replace init
How to use runit with current init
How to use dietlibc
Frequently asked questions
Runlevels
Service dependencies
A collection of run scripts
The runit program
The runit-init program
The sv program
The runsvdir program
The runsvchdir program
The runsv program
The svlogd program
The chpst program
The utmpset program
runit is a
cross-platform Unix init scheme with service supervision, a replacement for
sysvinit,
and other init schemes.
It runs on GNU/Linux, *BSD, MacOSX, Solaris,
and can easily be adapted to other Unix operating systems.
If runit runs for you on any other operating system, please
let me know.
runit is discussed on the
<supervision@list.skarnet.org>
mailing list.
Please contact this list and not me privately.
To subscribe send an empty email to
<supervision-subscribe@list.skarnet.org>.
Mailing list archives are available at
skarnet.org, and
gmane.org.
The program runit is intended to run as Unix
process no 1, it is automatically started by the
runit-init /sbin/init-replacement
if this is started by the kernel.
runit performs the system's booting,
running and shutting down in three stages:
- Stage 1:
runit starts /etc/runit/1 and waits for it to
terminate.
The system's one time initialization tasks are done here.
/etc/runit/1 has full control over /dev/console to be
able to start an emergency shell in case the one time initialization
tasks fail.
- Stage 2:
runit starts /etc/runit/2 which should not return
until the system is going to halt or reboot; if it crashes, it will be
restarted.
Normally, /etc/runit/2 runs
runsvdir.
In Stage 2 runit optionally handles the INT signal (ctrl-alt-del
keyboard request on Linux/i386).
- Stage 3:
If runit is told to halt or reboot the system, or Stage 2 returns
without errors, it terminates Stage 2 if it is running, and runs
/etc/runit/3.
The systems tasks to shutdown and halt or reboot are done here.
These are working examples for Debian sarge:
/etc/runit/1,
/etc/runit/2,
/etc/runit/3.
The program runit-init is intended to
replace /sbin/init.
The command init 0 tells runit to halt the system,
and init 6 to reboot.
Runlevels are handled through the
runsvdir and
runsvchdir programs.
Service dependencies are resolved
automatically.
runit is optimized for reliability and small size.
The amount of code in process no 1 should be minimal.
See How to install runit for installing
runit, and How to replace init for
configuring runit to run as process no 1.
See How to use with current init if you want to
use runit without replacing the current init scheme.
Please read the list of
Frequently asked questions with answers.
If runit on Linux is compiled and linked with the
dietlibc, it yields in a
statically linked runit binary of 8.5k size and this
ps axuw output on my system:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 20 16 ? S 2002 0:02 runit
I recommend doing this; for instructions, see
How to use dietlibc.
The following distributions are known to include or package runit:
If you know of more distributions, please
let me know.
runit in use:
I replaced sysvinit successfully with runit on several server
systems and a laptop running Debian/GNU Linux sarge, woody, and potato.
Here is an example:
# strings /proc/1/exe |grep Id
$Id: runit.c,v 1.7 2002/02/13 09:59:52 pape Exp $
# uptime
11:59:13 up 365 days, 23:22, 3 users, load average: 0.01, 0.02, 0.00
# ps axuw |head -n20
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 20 16 ? S 2002 0:07 runit
root 2 0.0 0.0 0 0 ? SW 2002 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SWN 2002 0:51 [ksoftirqd_CPU0]
root 4 0.0 0.0 0 0 ? SW 2002 144:38 [kswapd]
root 5 0.0 0.0 0 0 ? SW 2002 0:08 [bdflush]
root 6 0.0 0.0 0 0 ? SW 2002 7:24 [kupdated]
root 168 0.0 0.0 1652 168 ? S 2002 0:27 /usr/sbin/cron
root 174 0.0 0.0 36 24 ? S 2002 1:06 runsvdir /var/service log: ...............................................................................................
root 176 0.0 0.0 20 20 ? S 2002 0:00 runsv qmail-send
root 177 0.0 0.0 20 20 ? S 2002 0:00 runsv getty-5
root 178 0.0 0.0 20 20 ? S 2002 0:00 runsv getty-4
root 179 0.0 0.0 20 20 ? S 2002 0:00 runsv getty-3
root 180 0.0 0.0 20 20 ? S 2002 0:00 runsv getty-2
root 182 0.0 0.0 20 20 ? S 2002 0:00 runsv socklog-unix
root 183 0.0 0.0 1256 4 tty5 S 2002 0:00 /sbin/getty 38400 tty5 linux
root 184 0.0 0.0 1256 4 tty3 S 2002 0:00 getty 38400 tty3 linux
root 185 0.0 0.0 20 20 ? S 2002 0:00 runsv socklog-klog
root 186 0.0 0.0 20 20 ? S 2002 0:00 runsv ssh
root 187 0.0 0.0 1256 4 tty4 S 2002 0:00 getty 38400 tty4 linux
# pstree
runit-+-bdflush
|-cron
|-gcache
|-keventd
|-ksoftirqd_CPU0
|-kswapd
|-kupdated
`-runsvdir-+-runsv-+-multilog
| `-qmail-send-+-qmail-clean
| |-qmail-lspawn
| `-qmail-rspawn---qmail-remote
|-4*[runsv---getty]
|-2*[runsv-+-multilog]
| `-socklog]
|-runsv-+-multilog
| `-sshd-+-sshd---sshd---bash---bash---pstree
| `-sshd---sshd---rsync
|-runsv---clockspeed
|-runsv-+-dnscache
| `-multilog
|-runsv---apache-ssl-+-9*[apache-ssl]
| |-gcache
| `-4*[multilog]
|-7*[runsv-+-multilog]
| `-tcpserver]
|-4*[runsv-+-multilog]
| `-tinydns]
|-runsv---uncat
|-2*[runsv-+-multilog]
| `-tcpsvd]
|-runsv-+-svlogd
| `-tcpsvd-+-smtpfront-qmail
| `-smtpfront-qmail---qmail-queue
`-runsv-+-svlogd
`-tcpsvd---bincimap-up---bincimapd
See http://smarden.org/runit/
for recent informations.
Related links:
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/svlogd.8.html 0000644 0000000 0000000 00000027315 14675400254 015560 0 ustar root root
svlogd(8) manual page
G. Pape
runit
svlogd - runit’s service logging daemon
svlogd [-tttv] [-r c] [-R
xyz] [-l len] [-b buflen] logs
logs consists of one or more arguments,
each specifying a directory.
svlogd continuously reads log data from its
standard input, optionally filters log messages, and writes the data to
one or more automatically rotated logs.
Recent log files can automatically
be processed by an arbitrary processor program when they are rotated, and
svlogd can be told to alert selected log messages to standard error, and
through udp.
svlogd runs until it sees end-of-file on standard input or is
sent a TERM signal, see below.
A log directory log contains
some number of old log files, and the current log file current. Old log
files have a file name starting with @ followed by a precise timestamp
(see the daemontools’ tai64n program), indicating when current was rotated
and renamed to this file.
A log directory additionally contains the lock
file lock, maybe state and newstate, and optionally the file config. svlogd
creates necessary files if they don’t exist.
If svlogd has trouble opening
a log directory, it prints a warning, and ignores this log directory. If
svlogd is unable to open all log directories given at the command line,
it exits with an error. This can happen on start-up or after receiving a
HUP signal.
svlogd appends selected log messages to the
current log file. If current has size bytes or more (or there is a new-line
within the last len of size bytes), or is older than a specified amount
of time, current is rotated:
svlogd closes current, changes permission
of current to 0755, renames current to @timestamp.s, and starts with a new
empty current. If svlogd sees num or more old log files in the log directory,
it removes the oldest one. Note that this doesn’t decrease the number of
log files if there are already more than num log files, this must be done
manually, e.g. for keeping 10 log files:
ls -1 \@* |sort |sed -ne ’10,$p’ |xargs
rm
If svlogd is told to process recent log files, it saves current
to @timestamp.u, feeds @timestamp.u through ‘‘sh -c "processor"’’ and writes the
output to @timestamp.t. If the processor finishes successfully, @timestamp.t
is renamed to @timestamp.s, and @timestamp.u is deleted; otherwise @timestamp.t
is deleted and the processor is started again. svlogd also saves any output
that the processor writes to file descriptor 5, and makes that output available
on file descriptor 4 when running processor on the next log file rotation.
A processor is run in the background. If svlogd sees a previously started
processor still running when trying to start a new one for the same log,
it blocks until the currently running processor has finished successfully.
Only the HUP signal works in that situation. Note that this may block any
program feeding its log data to svlogd.
On startup, and after receiving
a HUP signal, svlogd checks for each log directory log if the configuration
file log/config exists, and if so, reads the file line by line and adjusts
configuration for log as follows:
If the line is empty, or starts with
a ‘‘#’’, it is ignored. A line of the form
- ssize
- sets the maximum file size
of current when svlogd should rotate the current log file to size bytes.
Default is 1000000. If size is zero, svlogd doesn’t rotate log files. You
should set size to at least (2 * len).
- nnum
- sets the number of old log files
svlogd should maintain to num. If svlogd sees more that num old log files
in log after log file rotation, it deletes the oldest one. Default is 10.
If num is zero, svlogd doesn’t remove old log files.
- Nmin
- sets the minimum
number of old log files svlogd should maintain to min. min must be less
than num. If min is set, and svlogd cannot write to current because the
filesystem is full, and it sees more than min old log files, it deletes
the oldest one.
- ttimeout
- sets the maximum age of the current log file when
svlogd should rotate the current log file to timeout seconds. If current
is timeout seconds old, and is not empty, svlogd forces log file rotation.
- !processor
- tells svlogd to feed each recent log file through processor
(see above) on log file rotation. By default log files are not processed.
- ua.b.c.d[:port]
- tells svlogd to transmit the first len characters of selected
log messages to the IP address a.b.c.d, port number port. If port isn’t set,
the default port for syslog is used (514). len can be set through the -l
option, see below. If svlogd has trouble sending udp packets, it writes
error messages to the log directory. Attention: logging through udp is unreliable,
and should be used in private networks only.
- Ua.b.c.d[:port]
- is the same as
the u line above, but the log messages are no longer written to the log
directory, but transmitted through udp only. Error messages from svlogd
concerning sending udp packages still go to the log directory.
- pprefix
- tells
svlogd to prefix each line to be written to the log directory, to standard
error, or through UDP, with prefix.
If a line starts with a -, +, e, or E,
svlogd matches the first len characters of each log message against pattern
and acts accordingly:
- -pattern
- the log message is deselected.
- +pattern
- the
log message is selected.
- epattern
- the log message is selected to be printed
to standard error.
- Epattern
- the log message is deselected to be printed
to standard error.
Initially each line is selected to be written to log/current.
Deselected log messages are discarded from log. Initially each line is deselected
to be written to standard err. Log messages selected for standard error
are written to standard error.
svlogd matches a log message
against the string pattern as follows:
pattern is applied to the log message
one character by one, starting with the first. A character not a star (‘‘*’’)
and not a plus (‘‘+’’) matches itself. A plus matches the next character in
pattern in the log message one or more times. A star before the end of pattern
matches any string in the log message that does not include the next character
in pattern. A star at the end of pattern matches any string.
Timestamps optionally
added by svlogd are not considered part of the log message.
An svlogd pattern
is not a regular expression. For example consider a log message like this
2005-12-18_09:13:50.97618 tcpsvd: info: pid 1977 from 10.4.1.14
The following pattern doesn’t match
-*pid*
because the first star matches up to the first p in tcpsvd, and then the
match fails because i is not s. To match this log message, you can use a
pattern like this instead
-*: *: pid *
- -t
- timestamp. Prefix each selected line with a precise timestamp
(see the daemontools’ tai64n program) when writing to log or to standard
error.
- -tt
- timestamp. Prefix each selected line with a human readable, sortable
UTC timestamp of the form YYYY-MM-DD_HH:MM:SS.xxxxx when writing to log or
to standard error.
- -ttt
- timestamp. Prefix each selected line with a human
readable, sortable UTC timestamp of the form YYYY-MM-DDTHH:MM:SS.xxxxx when
writing to log or to standard error.
- -r c
- replace. c must be a single character.
Replace non-printable characters in log messages with c. Characters are replaced
before pattern matching is applied.
- -R xyz
- replace charset. Additionally to
non-printable characters, replace all characters found in xyz with c (default
‘‘_’’).
- -l len
- line length. Pattern matching applies to the first len characters
of a log message only. Default is 1000.
- -b buflen
- buffer size. Set the size
of the buffer svlogd uses when reading from standard input and writing
to logs to buflen. Default is 1024. buflen must be greater than len. For svlogd
instances that process a lot of data in short time, the buffer size should
be increased to improve performance.
- -v
- verbose. Print verbose messages to
standard error.
If svlogd is sent a HUP signal, it closes and reopens
all logs, and updates their configuration according to log/config. If svlogd
has trouble opening a log directory, it prints a warning, and discards
this log directory. If svlogd is unable to open all log directories given
at the command line, it exits with an error.
If svlogd is sent a TERM signal,
or if it sees end-of-file on standard input, it stops reading standard input,
processes the data in the buffer, waits for all processor subprocesses
to finish if any, and exits 0 as soon as possible.
If svlogd is sent an
ALRM signal, it forces log file rotation for all logs with a non empty
current log file.
sv(8), runsv(8), chpst(8), runit(8), runit-init(8),
runsvdir(8), runsvchdir(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/replaceinit.html 0000644 0000000 0000000 00000022234 14675400254 016406 0 ustar root root
runit - replacing init
G. Pape
runit
runit - replacing init
How to replace sysvinit on GNU/Linux
How to replace init on *BSD
How to replace init on MacOSX
How to replace init on Solaris
Replacing sysvinit (GNU/Linux)
Follow these steps to migrate from sysvinit to runit on
Debian GNU/Linux (woody).
The /sbin/init binary is not replaced until step 6, runit is
the default Unix process no 1 after step 7.
If you have installed the precompiled Debian package, start at step 3.
Step 1: The three stages
runit looks for the three stages implementing the system's
booting, running and shutdown in /etc/runit/1,
/etc/runit/2 and /etc/runit/3, create the files now:
# mkdir -p /etc/runit
# cp -p /package/admin/runit/etc/debian/[123] /etc/runit/
Create also a getty service directory:
# mkdir -p /etc/sv/getty-5
# cp -p /package/admin/runit/etc/debian/getty-tty5/run /etc/sv/getty-5/
# cp -p /package/admin/runit/etc/debian/getty-tty5/finish /etc/sv/getty-5/
If you want runit to handle the ctrl-alt-del keyboard request, do:
# cp -p /package/admin/runit/etc/debian/ctrlaltdel /etc/runit/
Step 2: The runit programs
The runit programs must reside on the root partition, copy them to
/sbin:
# cp -p /package/admin/runit/command/runit* /sbin/
Step 3: The getties
At least one getty must run in stage 2 so that you are able to login.
Choose a free tty, say tty5, where sysvinit is not
running any getty (edit /etc/inittab and kill -HUP 1 if
needed), and tell runsvdir about the getty-5
service:
# mkdir -p /service
# ln -s /etc/sv/getty-5 /service/
Start runit's stage 2 for testing:
# /etc/runit/2 &
And check that the getty is running.
Step 4: Reboot into runit for testing
Boot your system with runit for the first time.
This does not change the default boot behavior of your system, lilo
will be told to use runit just once:
- reboot the system
- enter the following on the lilo prompt:
init=/sbin/runit-init
- watch the console output while runit boots up the system
- switch to tty5 when stage 2 is reached, a getty
should run there, you are able to login.
If you are not using lilo as boot loader, refer to the documentation
of your boot loader on how to pass init=/sbin/runit-init to the
kernel.
Step 5: Service migration
The goal is to migrate all services from sysvinit scheme to the
runit service supervision design; take a look at these
run scripts for popular services.
The migration can be done smoothly.
For those services that are not migrated to use run scripts yet,
add the corresponding init-script startup to /etc/runit/1,
e.g.:
#!/bin/sh
# one time tasks
/etc/init.d/kerneld start
/etc/init.d/rmnologin
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
It is possible to just add /etc/init.d/rc 2 for having all services
from the former runlevel 2 started as one time tasks, but keep the goal above
in mind, supervising services has great advantages.
To migrate a service,
create a service directory, disable the service
if it is running, disable the service in /etc/rc.conf or remove the
service startup from the /etc/rc.* scripts and
tell runsvdir about the new service.
Repeat step 4 and 5, using /sbin/runit-init 6 to reboot the
system, until you are satisfied with your services startup.
If anything goes wrong, reboot the system into the default sysvinit
/sbin/init and repair the runit stages, then start again at
step 4.
Step 6: Replace /sbin/init
Now it is time to replace the sysvinit /sbin/init binary:
# mv /sbin/init /sbin/init.sysv
# ln -s runit-init /sbin/init
Step 7: Final reboot
The last step is to do the final reboot to boot the system with the new
default Unix process no 1 runit.
# init 6
To report success:
# ( uname -a ; cat /etc/runit/[123] ) |mail pape-runit-2.2.0@xxiv.smarden.org
Replacing init (*BSD)
Follow these steps to migrate from init to runit on
OpenBSD 2.9 or
FreeBSD 4.4.
The /sbin/init binary is not replaced until step 4.
Step 1: The three stages
runit looks for the three stages implementing the system's
booting, running and shutdown in /etc/runit/1,
/etc/runit/2 and /etc/runit/3 respectively.
Create the scripts now:
# mkdir -p /etc/runit
OpenBSD 2.9:
# cp -p /package/admin/runit/etc/openbsd/[123] /etc/runit/
FreeBSD 4.4:
# cp -p /package/admin/runit/etc/freebsd/[123] /etc/runit/
Remove the svscanboot startup from /etc/rc.local by
deleting the line csh -cf '/command/svscanboot &' (this normally
is the last one); runit will start
runsvdir in stage 2 after running
rc.local in stage 1.
# vi /etc/rc.local
Step 2: The runit programs
The runit programs must reside on the root partition, install them
into /sbin:
# install -m0500 /package/admin/runit/command/runit* /sbin/
Step 3: The getties
At least one getty must run in stage 2 so that you are able to login.
To have it run on the virtual console no 5, create the getty-5 service
directory:
# mkdir -p /etc/sv/getty-5
OpenBSD 2.9:
# cp -p /package/admin/runit/etc/openbsd/getty-ttyC4/run /etc/sv/getty-5/
# cp -p /package/admin/runit/etc/openbsd/getty-ttyC4/finish /etc/sv/getty-5/
FreeBSD 4.4:
# cp -p /package/admin/runit/etc/freebsd/getty-ttyv4/run /etc/sv/getty-5/
# cp -p /package/admin/runit/etc/freebsd/getty-ttyv4/finish /etc/sv/getty-5/
and tell runsvdir about the getty-5
service:
# mkdir -p /service
# ln -s /etc/sv/getty-5 /service/
Start runit's stage 2 for testing:
# /etc/runit/2 &
And check that the getty is running.
Step 4: Replace the /sbin/init binary
Before replacing the init binary, make sure that you are able
to boot your system alternatively, e.g. with a boot floppy, to restore the
former /sbin/init if anything goes wrong.
Make a backup copy of the current /sbin/init program and replace
it with /sbin/runit-init:
# cp -p /sbin/init /sbin/init.bsd
# install /sbin/runit-init /sbin/init
Boot your system with runit for the first time:
# reboot
Watch the console output while runit boots up the system.
Switch to the virtual console 5 (CTRL-ALT-F5) when stage 2 is reached, a
getty should run there, you are able to login.
Use init 6 to reboot and init 0 to halt a system that runs
runit.
This will cause runit to enter stage 3 which runs
/sbin/reboot or /sbin/halt as last command.
To report success:
# ( uname -a ; cat /etc/runit/[123] ) |mail pape-runit-2.2.0@xxiv.smarden.org
Step 5: Service migration
The goal is to migrate all services from /etc/rc.* scheme to the
runit service supervision design; take a look at these
run scripts for popular services.
The migration can be done smoothly.
By default runit runs the /etc/rc scripts in stage 1 as a
one time task, so the services are started automatically:
#!/bin/sh
# system one time tasks
/bin/sh /etc/rc autoboot
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
To migrate a service,
create a service directory, disable the service
if it is running, disable the service in /etc/rc.conf or remove the
service startup from the /etc/rc.* scripts and
tell runsvdir about the new service.
Replacing init on MacOSX
Replacing init on MacOSX is not yet supported.
Please refer to the instructions on how to use
runit service supervision with the MacOSX init scheme.
Replacing init on Solaris
Replacing init on Solaris is not yet supported.
Please refer to the instructions on how to use
runit service supervision with the Solaris sysvinit scheme.
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/runlevels.html 0000644 0000000 0000000 00000007375 14675400254 016137 0 ustar root root
runit - runlevels
G. Pape
runit
runit - runlevels
Prepare runit for using runlevels
Switching runlevels
Creating runlevels
Prepare runit
If not yet done, configure your system to use
runit as process no 1 by following the
instructions.
Create the following directories and symbolic links:
# mkdir -p /etc/runit/runsvdir/default
# mkdir -p /etc/runit/runsvdir/single
# ln -s /etc/sv/getty-5 /etc/runit/runsvdir/single/
# ln -s default /etc/runit/runsvdir/current
Copy the contents of /service/ to
/etc/runit/runsvdir/current/ and replace /service/
with a symbolic link:
# cp -pR /service/* /etc/runit/runsvdir/current/
# mv -f /service /service.old && \
ln -s /etc/runit/runsvdir/current /service
You have now created two runlevels: default and single.
The current runlevel is default.
It is safe to remove /service.old/ if you don't need it anymore.
Finally edit /etc/runit/2 to set the default runlevel when
stage 2 starts:
$ cat /etc/runit/2
#!/bin/sh
PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
runsvchdir default >/dev/null
exec env - PATH=$PATH \
runsvdir /service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'
Switching runlevels
Switching runlevels with runit is done by switching the directory the
runsvdir program is running in.
This is done by the runsvchdir program, e.g.
to switch to the single user runlevel, do:
# runsvchdir single
To switch back to the default runlevel, do:
# runsvchdir default
See the runsvdir program for a description of
what happens when runsvdir sees the directory changed.
Note that there is no guarantee that all services from the previous
runlevel will stop, the runsv processes have sent
the service daemons a SIGTERM and wait for them to terminate.
You can check the status of the previous runlevel through
/etc/runit/runsvdir/previous/.
Creating new runlevels
To create a new runlevel, simply create a new directory in
/etc/runit/runsvdir/.
The name of the directory is the name of the new runlevel.
The name must not start with a dot and must not be current,
current.new, or previous, e.g.:
# mkdir /etc/runit/runsvdir/maintenance
Add the services you want to run in the runlevel maintenance to the
newly created directory, e.g.:
# ln -s /etc/sv/getty-5 /etc/runit/runsvdir/maintenance/
# ln -s /etc/sv/ssh /etc/runit/runsvdir/maintenance/
# ln -s /etc/sv/dnscache /etc/runit/runsvdir/maintenance/
If you want to switch to the runlevel maintenance, do:
# runsvchdir maintenance
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/useinit.html 0000644 0000000 0000000 00000006035 14675400254 015570 0 ustar root root
runit - use with traditional init
G. Pape
runit
runit - use with traditional init
It's possible to use runit's service supervision without replacing
the init scheme of the system.
Simply run the stage 2 of runit as a service with your
current init.
Normally this is done by either adding an entry for
/sbin/runsvdir-start to /etc/inittab, or by adding
/sbin/runsvdir-start as command to /etc/rc.local, or by
adding /sbin/runsvdir-start to the system's StartupItems.
In any case, you first need to copy the stage 2 script to
/sbin/runsvdir-start, and create the services directory
/service/:
# install -m0750 /package/admin/runit/etc/2 /sbin/runsvdir-start
# mkdir -p /service
How to use with sysvinit and inittab
How to use with sysvinit and upstart
How to use with *BSD init
How to use with MacOSX init
Using with sysvinit and inittab
If your system uses a sysvinit alike init scheme with a /etc/inittab
file, do:
# cat >>/etc/inittab <<EOT
SV:123456:respawn:/sbin/runsvdir-start
EOT
and tell init to re-read its configuration, e.g.:
# init q
Using with sysvinit and upstart
If your system uses a sysvinit alike init scheme that utilizes upstart
instead of inittab, and which has start and stop scripts located in
/etc/init/, do:
# cat >/etc/init/runsvdir.conf <<\EOT
# for runit - manage /usr/sbin/runsvdir-start
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn
exec /usr/sbin/runsvdir-start
EOT
and tell init to start the new service, e.g.:
# start runsvdir
Using with *BSD init
If your system uses a BSD alike init scheme with a /etc/rc.local
script, do:
# cat >>/etc/rc.local <<EOT
csh -cf '/sbin/runsvdir-start &'
EOT
and reboot your system.
Using with MacOSX init
On MacOSX 10.2 create an entry for runit in
/System/Library/StartupItems/:
# cd /System/Library/StartupItems
# mkdir -p runit
# cp -p /package/admin/runit/etc/macosx/StartupItems/* runit/
and reboot your system.
On MacOSX 10.4 create an entry for runit in
/Library/LaunchDaemons/, and tell launchd to start the new
service:
# cp /package/admin/runit/etc/macosx/org.smarden.runit.plist \
/Library/LaunchDaemons/
# launchctl load /Library/LaunchDaemons/org.smarden.runit.plist
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/runit.8.html 0000644 0000000 0000000 00000006321 14675400254 015415 0 ustar root root
runit(8) manual page
G. Pape
runit
runit - a UNIX process no 1
runit
runit must be run
as Unix process no 1. It performs the system’s booting, running, and shutdown
in three stages:
runit runs /etc/runit/1 and waits for it to terminate.
The system’s one time tasks are done here. /etc/runit/1 has full control
of /dev/console to be able to start an emergency shell if the one time
initialization tasks fail. If /etc/runit/1 crashes, or exits 100, runit
will skip stage 2 and enter stage 3.
runit runs /etc/runit/2, which
should not return until system shutdown; if it crashes, or exits 111, it
will be restarted. Normally /etc/runit/2 starts runsvdir(8). runit is able
to handle the ctrl-alt-del keyboard request in stage 2, see below.
If
runit is told to shutdown the system, or stage 2 returns, it terminates
stage 2 if it is running, and runs /etc/runit/3. The systems tasks to shutdown
and possibly halt or reboot the system are done here. If stage 3 returns,
runit checks if the file /etc/runit/reboot exists and has the execute by
owner permission set. If so, the system is rebooted, it’s halted otherwise.
If /etc/runit/nosync exists, runit doesn’t invoke
sync(). This is useful in vservers.
If runit receives the ctrl-alt-del keyboard request and the file
/etc/runit/ctrlaltdel exists and has the execute by owner permission set,
runit runs /etc/runit/ctrlaltdel, waits for it to terminate, and then sends
itself a CONT signal.
runit only accepts signals in stage 2.
If runit
receives a CONT signal and the file /etc/runit/stopit exists and has the
execute by owner permission set, runit is told to shutdown the system.
if
runit receives an INT signal, a ctrl-alt-del keyboard request is triggered.
runit-init(8), runsvdir(8), runsvchdir(8), sv(8), runsv(8), chpst(8),
utmpset(8), svlogd(8)
http://smarden.org/runit/
Gerrit Pape <pape@smarden.org>
Table of Contents
admin/runit-2.2.0/doc/dependencies.html 0000644 0000000 0000000 00000002546 14675400254 016541 0 ustar root root
runit -service dependencies
G. Pape
runit
runit - service dependencies
runit's service supervision resolves dependencies for service daemons
designed to be run by a supervisor process automatically.
The service daemon (or the corresponding run scripts) should behave
as follows:
- before providing the service, check if all services it depends on are
available.
If not, exit with an error, the supervisor will then try again.
- write all logs through runit's logging facility.
The runsv program takes care that all logs for
the service are written safely to disk.
Therefore there's no need to depend on a system logging service.
- optionally when the service is told to become down, take down other
services that depend on this one after disabling the service.
If you want to run service daemons that do not support service supervision
as described above, please refer to
this page
about service dependencies I wrote some time ago.
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/doc/usedietlibc.html 0000644 0000000 0000000 00000001625 14675400254 016404 0 ustar root root
runit - use dietlibc
G. Pape
runit
runit - use dietlibc
To recompile the runit programs with the
diet libc, check that you have
the recent version of
dietlibc installed.
Change to the package directory of runit
# cd /package/admin/runit/
Change the conf-cc and conf-ld to use diet
# echo 'diet -Os gcc -O2 -Wall' >src/conf-cc
# echo 'diet -Os gcc -s -Os -pipe' >src/conf-ld
Rebuild and install the runit programs
# package/install
Gerrit Pape <pape@smarden.org>
admin/runit-2.2.0/package/ 0000755 0000000 0000000 00000000000 14675400254 014044 5 ustar root root admin/runit-2.2.0/package/THANKS 0000644 0000000 0000000 00000000174 14675400254 014761 0 ustar root root Thanks to D. J. Bernstein for his daemontools package and for putting the
daemontools' library code into the public domain.
admin/runit-2.2.0/package/versions 0000644 0000000 0000000 00000000522 14675400254 015636 0 ustar root root 0.4.0
0.4.1
0.5.0
0.5.3
0.6.0
0.7.0
0.7.1
0.7.2
0.8.0
0.8.1
0.8.4
0.9.0
0.9.1
0.9.2
0.9.3
0.9.4
0.9.5
0.10.0
0.11.0
0.11.1
0.11.2
0.12.0
0.12.1
0.13.0
0.13.1
1.0.0
1.0.1
1.0.2
1.0.3
1.0.4
1.0.5
1.1.0
1.2.0
1.2.1
1.2.2
1.2.3
1.3.0
1.3.1
1.3.2
1.3.3
1.4.0
1.4.1
1.5.0
1.5.1
1.6.0
1.7.0
1.7.1
1.7.2
1.8.0
1.9.0
2.0.0
2.1.0
2.1.1
2.1.2
2.2.0
admin/runit-2.2.0/package/upgrade 0000755 0000000 0000000 00000001370 14675400254 015422 0 ustar root root #!/bin/sh
set -e
umask 022
test -d package || sh -cx '! : Wrong working directory.'
test -d src || sh -cx '! : Wrong working directory.'
here=`env - PATH=$PATH pwd`
parent=`dirname $here`
echo 'Creating symlink runit -> runit-2.2.0...'
rm -f runit
ln -s runit-2.2.0 runit
mv -f runit ..
echo 'Making command links in /command...'
mkdir -p /command
for i in `cat package/commands`; do
rm -f /command/$i'{new}'
ln -s $parent/runit/command/$i /command/$i'{new}'
mv -f /command/$i'{new}' /command/$i
done
echo 'Making compatibility links in /usr/local/bin...'
mkdir -p /usr/local/bin
for i in `cat package/commands`; do
rm -f /usr/local/bin/$i'{new}'
ln -s /command/$i /usr/local/bin/$i'{new}'
mv -f /usr/local/bin/$i'{new}' /usr/local/bin/$i
done
admin/runit-2.2.0/package/CHANGES 0000644 0000000 0000000 00000074177 14675400254 015057 0 ustar root root 2.2.0
Fri, 27 Sep 2024 00:38:25 +0000
* chpst.dist, sv.dist, svlogd.dist, utmpset.dist: adapt.
* chpst.c, man/chpst.8: add -C option to change working directory (thx
Andrew J. Hesford, void linux).
* doc/install.html: add link to sha256sum.
* doc/install.html, doc/replaceinit.html: change mail address.
* package/TODO: remove.
* package/README,COPYING: Copyright date.
* chpst.c: fix compilation warning(s): -Wunsequenced (thx Dmitry
Bogatov, Z. Liu).
* svlogd.c: Initialize all fields of sockaddr_in (thx Érico Rolim).
* sv.c: add sleep_microseconds to encapsulate (u|nano)sleep (thx Z.
Liu).
* chpst.c, chpst.dist, man/chpst.8: add options -t and -V to chpst man
page and usage (thx Lorenzo Puliti, Z. Liu).
* man/runsv.8: log service's ./finish script is actually not invoked
(thx Jamie Heilman, Dmitry Bogatov, Z. Liu).
* man/runsv.8: clarify how signal override works with control/d and x
(thx Andras Korn, Lorenzo Puliti, Z. Liu).
* runit.c, runit.h, man/runit.8: support /etc/runit/nosync file to make
sync on shutdown/reboot optional (thx Andras Korn).
* prot.c, prot.h, chkshsgr.c, tryshsgr.c: remove; obsolete.
* Makefile, TARGETS: no longer check for "shortsetgroups" (thx Leah
Neukirchen).
* chpst.c: replace prot_uid() with setuid().
* utmpset.c: don't pass int32_t to time() (thx Lorenzo Beretta).
* chpst.c, pathexec.h, pathexec_env.c, pathexec_run.c, runsvdir.c,
sgetopt.c, sgetopt.h, subgetopt.c, subgetopt.h, sv.c, svlogd.c,
utmpset.c: fix compilation warning(s): -Wincompatible-pointer-types-
discards-qualifiers (thx Z. Liu, Debian, and others).
* x86cpuid.c: fix error: call to undeclared library function '...'; ISO
C99 and later do not support implicit function declarations
[-Wimplicit-function-declaration] (thx Z. Liu, Debian, and others).
* chpst.c, pathexec_run.c, prot.c, seek_set.c: fix error: call to
undeclared function '...'; ISO C99 and later do not support implicit
function declarations [-Wimplicit-function-declaration] (thx Z. Liu).
* tryflock.c, trysgact.c, trysgprm.c, trywaitp.c: fix error: type
specifier missing, defaults to 'int'; ISO C99 and later do not support
implicit int [-Wimplicit-int] (thx Z. Liu and others).
* chkshsgr.c, trycpp.c, trypoll.c, tryshsgr.c, tryulong64.c: fix error:
call to undeclared function '...'; ISO C99 and later do not support
implicit function declarations [-Wimplicit-function-declaration] (thx
Z. Liu and others).
2.1.2
Sun, 10 Aug 2014 18:01:54 +0000
* doc/index.html: reorder, cleanup links to distributions; add Linux
from Scratch, Finnix, VServer.
* sv.c: properly format status command's output on failure cases.
* sv.c: support optional LSB init script actions reload and
try-restart.
* man/sv.8: "sv exit" does not send a TERM signal to the log service
(thx Jonathan Nieder).
* fmt_ptime.c: 64 bits time_t fix for svlogd (tnx Jérémie
Courrèges-Anglas).
* sv.c: fix typo that may lead to wrong output from sv when reporting
status of multiple service directories.
* doc/index.html: add deepOfix Mail Server to list of distributions
that include runit (thx Debayan Banerjee).
* doc/useinit.html: update description on how to use with upstart
(thx Gabriel de Perthuis).
* doc/index.html: add Dragora GNU/Linux to list of distributions that
use runit as default init scheme (thx Matias A. Fonzo).
* doc/index.html: add ArchLinux to list of distributions that include
runit (thx Kevin Berry).
2.1.1
Sun, 04 Oct 2009 20:28:38 +0000
* doc/upgrade.html: fix typo.
* sv.c: on 'down', send runsv the 'down' command properly if not yet
done (e.g. when taken up with 'once').
2.1.0
Thu, 24 Sep 2009 22:49:33 +0000
* pathexec_env.c, pathexec.h: add function pathexec_env_run().
* chpst.c, man/chpst.8: new option -b argv0: run prog with different
0th argument.
* sv.c: fix exit code of status command in lsb mode (thx Mathieu
Poumeyrol)
* chpst.c, svwaitdown.c, svwaitup.c: fix checks for return value of
open_* functions (thx David Reiss).
* runsv.c: exit with error if [log/]supervise/control exists, but is
not a fifo (thx Charlie Brady).
* man/sv.8: clarify which return values apply to the LSB init script
interface.
2.0.0
Sun, 15 Jun 2008 15:31:05 +0000
1.9.0
Mon, 05 May 2008 22:00:13 +0000
* doc/upgrade.html: typo.
* sv.c: service name is also relative to the current directory if it
ends with a slash.
* change default directory for services from /var/service/ to /service/.
* runsv.c: create temporary new status files for log/supervise/ actually
in log/supervise/.
* doc/benefits.html: minor additions.
1.8.0
Fri, 21 Sep 2007 00:33:56 +0000
* man/svlogd.8: add hint on how to manually remove log files after the
number of log files svlogd should maintain has been reduced; add hint
about increasing the buffer size if lots of data is to be processed
in short time.
* chpst.c, uidgid.c: improve error reporting if getpwnam() or getgrnam()
fails; cleanup.
* svlogd.c: don't statically bind local udp socket, but request new
source port for each log message sent through udp.
* runit.c: fix typo in error messages (thx Matthew R. Dempsky); minor
rewording.
* doc/useinit.html: add instructions on how to use with upstart (thx
Lloyd Zusman).
* chpst.c: add explicit braces to avoid ambiguous 'else'.
* uw_tmp.h1: fallback to UTMP_FILE if _PATH_UTMP is not defined as seen
on AIX 5.2 ML1, AIX 5.3 ML5 (thx Daniel Clark).
* sv.c: fix race on check for down if pid is 0 and state is run or finish.
* runit.c: speed up collecting zombies.
* runit.c: force check for zombies after a 14 second timeout without
signals (CHLD, CONT, INT).
* doc/index.html: typo.
* doc/*.html: remove $Id$.
1.7.2
Tue, 21 Nov 2006 15:13:47 +0000
* doc/index.html: add list of distributions that are known to include
or package runit; some reordering.
* doc/replaceinit.html: point to faq.html#create, faq.html#tell (thx
David Kaufman).
* doc/runscripts.html: point to faq.html#createlog.
* runit.c: fix arguments to wait_pid() after fork for reboot_system()
(thx Jan Kampe).
* man/runsv.8: suggest printf t instead of echo -n t.
* runsv.c: really don't act on commands in state finish; minor.
1.7.1
Sat, 04 Nov 2006 19:23:29 +0000
* chpst.c, uidgid.c, uidgid.h: support numerical uid gid through
chpst -[u|U] :uid:gid...
* man/chpst.8: adapt; clarify that users and groups are looked up in
/etc/passwd and /etc/group only.
* sv.c: properly wait for a service to be restarted on 'restart';
support checks through -v for pause, cont, kill.
* doc/runscripts.html: add contributed run scripts (thx Kevin, marlowe,
ed neville, xavier dutoit).
1.7.0
Sat, 07 Oct 2006 18:24:17 +0000
* svlogd.c, fmt_ptime.*, man/svlogd.8: new option -ttt: prefix log
messages with sortable UTC timestamp YYYY-MM-DDTHH:MM:SS.xxxxx.
* runsv.c, runsv.8: give two arguments to ./finish: exit code and exit
status of ./run (mostly copied from pipe-tools' npt-supervise, thx
Laurent Bercot).
* runit.c: don't make console the controlling terminal for process 1,
but for stage 1 only; fork before initiating system halt or reboot,
the linux kernel calls do_exit(0) in kernel/sys.c (thx Jan Kampe).
1.6.0
Thu, 29 Jun 2006 07:52:35 +0000
* svlogd.c: cleanup *.t files possibly leftover by processor when
interrupted by signal, also on startup (thx Andras Korn,
http://bugs.debian.org/369840); 1st rename .t to .s, then remove .u.
* man/svlogd.8: adapt.
* svlogd.c: prepend optional timestamp to log messages sent through UDP,
as done for messages written to dir and to stderr.
* uidgid.c: properly fixup user/group argument on getpwnam() error.
* doc/benefits.html: typo; wording.
1.5.1
Wed, 10 May 2006 20:55:35 +0000
* runsv.c: delay restart of log service at least 1 sec, just as the main
service.
* runsvdir.c: don't double-copy filedescriptor.
* package/README, package/COPYING: 2006.
* man/runsvctrl.8, man/runsvstat.8, man/svwaitup.8, man/svwaitdown.8,
doc/runsvctrl.html, doc/runsvstat.html, doc/svwaitdown.html,
doc/svwaitup.html: remove; obsolete.
1.5.0
Sun, 16 Apr 2006 12:26:50 +0000
* man/runsvdir.8: document that the services directory is re-scanned if
the time of last modification, the inode, or the device has changed.
* sv.c: don't report success on 'sv start' if the service is in state
finish (thx Matthew R. Dempsky).
* svlogd.c: new config line p: optionally prefix each line written to
logs, stderr, or through udp; no longer skip empty lines (just
containing '\n'), old behavior can be restored with '-' in config.
* man/svlogd.8: document new p config line; adapt.
1.4.1
Mon, 20 Mar 2006 18:54:41 +0000
* doc/faq.html: typos; add usercontrol, userservices; minor.
* src/uidgid.h: use uid_t, git_t (fix setting of multiple groups with
dietlibc, thx Tino Keitel, http://bugs.debian.org/356016)
runit 1.4.0
Mon, 06 Mar 2006 12:45:08 +0000
* doc/faq.html: new.
* doc/benefits.html: use sv program instead of runsvstat, runsvctrl;
minor.
* doc/replaceinit.html, doc/runlevels.html: put getty service directory
into /etc/sv/.
* doc/runscripts.html: use sv program instead of svwaitup.
* etc/*/3, etc/macosx/StartupItems/runit: use sv program instead of
svwaitdown.
* man/runsv.8: use sv program instead of runsvctrl.
* man/sv.8: minor.
* Makefile, package/commands: no longer build/install runsvctrl,
runsvstat, svwaitdown, svwaitup.
* man/runsvctrl.8, man/runsvstat.8, man/svwaitdown.8, man/svwaitup.8:
remove; obsolete.
* doc/index.html: add faq; remove runsvctrl, runsvstat, svwaitdown,
svwaitup.
* sv: fix usage output.
* chpst: new option -d, limit data segment per process; don't use nested
functions.
runit 1.3.3
Mon, 02 Jan 2006 20:35:34 +0000
* chpst.c: adjust nice value and set limits before dropping permissions.
* sv.c: new additional command 'check'; with -v check for CONT through
./check if service is up.
* man/sv.8: adapt.
runit 1.3.2
Sun, 18 Dec 2005 11:22:04 +0000
* svlogd.c: don't print extra newlines to the log if additionally writing
to the network through udp (thx Andras Korn,
http://bugs.debian.org/339030).
* runsvdir.c: also process svdir changes if mtime of svdir has changed into
the past (thx Martin Dickopp).
* doc/index.html: update description; Please contact this list and not me
privately.
* doc/replaceinit.html, doc/runscripts.html: minor.
* man/chpst.8: -U doesn't support a list of groups.
* man/svlogd.8: update PATTERN MATCHING section, add example (based on
sugesstions from Joshua N Pritikin).
* man/*8: update SEE ALSO sections: runsvctrl, runsvstat, svwaitdown,
svwaitup will become obsolete; remove references to man pages for
programs from the daemontools package.
runit 1.3.1
Wed, 24 Aug 2005 20:14:17 +0000
* doc/runscripts.html: typo; openssh needs absolute path (thx Kevin Berry);
exec into dhcpcd.
* uidgid.c, uidgid.h, chpst.c: support colon-separated list of groups.
* sv.c: utilize optional ./check script in service directory to check for
availablity of service.
* runsv.c: wait_pid() might be interupted.
* man/chpst.8, man/sv.8: adapt.
runit 1.3.0
Sun, 24 Jul 2005 16:50:55 +0000
* man/runsv.8: typo; no longer document the e control character; clarify
custom control on d and x.
* doc/useinit.html: how to use runit with macosx 10.4 (thx Lars Uffmann).
* etc/macosx/org.smarden.runit.plist: new; launchd plist file for
runsvdir-start (thx Lars Uffmann).
* doc/runscripts.html: don't use absolute pathnames for programs in $PATH;
add contributed run scripts (thx Sascha Huedepohl); typos.
* runsvchdir.c, runsvstat.c: optimize output buffer handling.
* runsvctrl.c: write x control character to runsv on e.
* svlogd.c: write to log dir after possibly writing through udp (fixes
line break issue).
* runsv.c, runsv.check: optimize output buffer handling; porperly run
custom t, d, x, k, when stopping service; no longer support e control
character.
* sv.c: new sv program to control services, optionally can be linked to
/etc/init.d/ as lsb "init script" command line interface.
* Makefile, TARGETS: adapt.
* chpst.c: fix pointer types.
* man/sv.8: new.
* package/TODO: new.
runit 1.2.3
Mon, 18 Apr 2005 17:08:35 +0000
* doc/runscripts.html: add contributed run scripts (thx Kevin Berry);
remove mysql run scripts.
* svlogd.dist, svwaitdown.dist, svwaitup.dist: fix program selftest's
false alarms (thx Ian Stokes-Rees).
runit 1.2.2
Sun, 03 Apr 2005 09:21:52 +0000
* doc/index.html, doc/replaceinit.html: no longer refer to sysvinit's
shutdown program.
* man/svlogd.8: svlogd doesn't decrease the number of log files in a log
directory; with n0 don't remove any log files.
* svlogd.c: properly prefix log messages written to standard error with
optional timestamp.
* runsvctrl.c, svwaitdown.c, svwaitup.c: supervise not running -> runsv
not running.
* package/README: 2005.
runit 1.2.1
Sat, 15 Jan 2005 11:57:46 +0000
* chpst.c: typo.
* svwaitdown.c: minimum timeout is 1 second; service directories no longer
must start with /.
* svwaitup.c: minimum uptime of services is 1 second; service directories
no longer must start with /; print number of seconds a service is up if
verbose.
* man/svwaitdown.8, man/svwaitup.8: adapt.
* doc/runscripts.html: add contributed run scripts (thx Stefan Karrmann,
Kevin Berry, Karl Chen).
* runsv.c: typos; bugfix: run optional control/x when receiving SIGTERM
(thx Vladimir Smelhaus); minor.
* man/runsvctrl.8: minor.
* package/COPYING: adapt, 2005.
runit 1.2.0
Fri, 17 Dec 2004 21:08:50 +0000
* doc/upgrade.html: typo.
* runsv.c: support custom control commands through control/ directory,
optionally switch off sending signal; don't update timestamp in status
when running ./finish; only sleep for a second if ./run has been
restarted within a second, and after updating status to down, normally
up, want up.
* man/runsv.8: document custom control commands.
* runsv.check, runsv.dist: check custom control commands.
* doc/runscripts.html: add contributed run scripts (thx Stefan Karrmann,
Kevin Berry).
runit 1.1.0
Sat, 06 Nov 2004 17:21:11 +0000
* svlogd.c: new config option t timeout (thx Enrico Scholz); config
options e and E select and deselect lines for stderr respectively (thx
Vladimir Smelhaus); new config option N.
* man/svlogd.8: adapt.
* runsv.c: on commands down and exit send CONT after TERM.
* man/runsv.8: adapt.
* etc/2: use -P option to runsvdir.
* src/svlogd.check: add check for t config option.
* chpst.c: new option -n: adjust nice level.
* man/chpst.8: adapt.
runit 1.0.5
Tue, 21 Sep 2004 18:18:14 +0000
* svlogd.c: fix line buffer handling for pattern matching (thx Enrico
Scholz); properly retry writing to current on error; minor.
* doc/index.html: wording; add link to useinit.html; remove link to runit
on linuxfromscratch.
* doc/runscripts.html: add hint, some getties need to be run in a new
session/process group (thx Dan Melomedman).
* man/svlogd.8: minor fixes.
* man/svwaitdown.8: remove hint about -x option.
* package/check, package/compile, package/install, package/install-man,
package/upgrade: use set -e instead of #!/bin/sh -e.
* runsvdir.c: new option -P, run each runsv process in a new session and
process group (thx Charlie Brady).
* man/runsvdir.8: adapt; typo.
runit 1.0.4
Sun, 01 Aug 2004 18:29:36 +0000
* doc/runlevels.html, doc/upgrade.html, doc/useinit.html, man/runsvdir.8,
man/runsvchdir.8: minor changes in wording, notations.
* runsvdir.c: check services dir again after one second until it's
unchanged (thx Eric Lammerts); sleep one second before scanning if
services dir mtime is now; loop while chdir to starting dir fails;
rename log, loglen to rplog, rploglen.
* etc/macosx/StartupItems/runit: use -x option to svwaitdown; timeout 14.
runit 1.0.3
Sat, 26 Jun 2004 14:50:41 +0000
* chpst.c, man/chpst.8: new option -/ chroot.
* runit.c, man/runit.8: if stage 1 crashes or exits 100, stage 2 will be
skipped; if stage 2 crashes or exits 111, it will be restarted.
* package/check, package/compile, package/install-man, package/upgrade:
minor cleanup.
* doc/runscripts.html: add, adapt various run scripts (thx).
runit 1.0.2
Mon, 29 Mar 2004 17:52:50 +0000
* man/svlogd.8: timestamps are not considered when matching patterns (thx
Andras KORN).
* runsv.c: on exit run the finish scripts when taking the service down
(thx X.).
* runsv.c, runsvctrl.c: handle sig_quit (thx Wayne Marshall).
* svlogd.c: don't crash on zero byte long config file (thx Alex Efros).
* man/*: minor cleanup.
* doc/index.html: add link to runit on linuxfromscratch doc (thx Richard
A Downing FBCS).
runit 1.0.1
Sun, 07 Mar 2004 10:40:40 +0000
* doc/usedietlibc.html: minor.
* fmt_ptime.c: create timestamps in UTC, not localtime.
* chpst.c: -e dir: silently ignore directories, print warning if verbose.
* runsv.c: allow also log/supervise to be a dangling symlink; more
meaningful error message if opening lock or locking fails.
* check-diff, check-dist, check-local, package/check: new; run checks on
programs.
* package/install: run package/check.
* chpst.check, runit-init.check, runit.check, runsv.check,
runsvchdir.check, runsvctrl.check, runsvdir.check, runsvstat.check,
svlogd.check, svwaitdown.check, svwaitup.check, utmpset.check: new;
check program.
* chpst.dist, runit-init.dist, runit.dist, runsv.dist, runsvchdir.dist,
runsvctrl.dist, runsvdir.dist, runsvstat.dist, svlogd.dist,
svwaitdown.dist, svwaitup.dist, utmpset.dist: new; dist check program
output.
runit 1.0.0
Tue, 10 Feb 2004 13:37:28 +0000
* doc/benefits.html, doc/dependencies.html, doc/index.html,
doc/replaceinit.html, doc/runlevels.html, doc/upgrade.html,
doc/useinit.html: cleanup; minor.
* man/utmpset.8: run utmpset in finish script, not run script.
* man/runsvdir.8: minor.
runit 0.13.1
Mon, 19 Jan 2004 18:32:58 +0000
* doc/upgrade.html: typo.
* svlogd.c: bugfix: properly print new-line character to the log on end
of line (thx Pawel Chmielowski).
* trysocketlib.c: new; check for libraries needed for socket() on some
systems (fixes link failure on solaris, thx Uffe Jakobsen).
* Makefile: adapt.
* print-cc.sh, print-ld.sh: head -1 -> head -n1.
runit 0.13.0
Mon, 12 Jan 2004 14:39:38 +0000
* doc/runscripts.html: use html named entities (thx Taj Khattra); add
more contributed run scripts (thx Marek Bartnikowski, Thomas Schwinge).
* svlogd.c: support sending log entries to remote host through udp,
configurable through u and U lines in log dir config file; minor.
* man/svlogd.8: adapt; document -tt option.
* package/compile, package/install-man, package/upgrade: exit 1 on
sub-shell failures.
* man/runsv.8: fix typos (thx Christian Hammers).
runit 0.12.1
Tue, 18 Nov 2003 15:42:44 +0000
* doc/runscripts: add pppd run script (with chpst) next to the ppp one.
* man/chpst.8: typo.
* etc/debian/3: test -r -> test -x (thx Alejandro Mery).
* runsv.c: don't start new processes while collecting children.
runit 0.12.0
Wed, 29 Oct 2003 18:27:48 +0000
* runsv.c: don't use EOVERFLOW as it is not standard (thx Christoph
Scheurer).
* reboot_system.h1, reboot_system.h2, tryreboot.c: new; test if reboot()
function takes one or two arguments (solaris).
* runit.c: fallthrough stage 3: re-get stderr; sync() before reboot().
* uw_tmp.h1, uw_tmp.h2, tryuwtmp.c, tryuwtmpx.c: new; test for utmpx or
utmp support.
* utmpset.c: support systems with utmp or utmpx (solaris).
* Makefile: adapt.
* supports the solaris platform (thx Uffe Jakobsen).
* doc/benefits.html, doc/index.html, doc/replaceinit.html,
doc/runlevels.html, doc/useinit.html: default service directory is
/var/service; minor.
* etc/2, etc/debian/3, etc/freebsd/3, etc/macosx/StartupItems/runit,
etc/openbsd/3, man/runsv.8, man/runsvchdir.8, man/runsvdir.8: default
service directory is /var/service.
* doc/runscripts.html: add more contributed run scripts (thx Tomasz
Nidecki).
runit 0.11.2
Tue, 23 Sep 2003 10:15:32 +0200
* doc/useinit.html, etc/macosx/StartupItems/runit: don't use /etc/runit/2
when using runit service supervision with traditional init, use
/sbin/runsvdir-start instead.
* fmt_ptime.c: calculate UTC localtime correctly.
* runsv.c: support ./supervise as symbolic link, on dangling symlink create
link target.
runit 0.11.1
Thu, 4 Sep 2003 11:51:02 +0200
* src/Makefile: add dependency to sysdeps to target fmt_ptime.o (thx Thomas
Schwinge).
* svlogd.c: barf if all log directories given at the command line fail.
* man/svlogd.8: adapt.
* doc/runscripts.html: adaptions (thx Erich Schubert, Lang Martin).
runit 0.11.0
Fri, 08 Aug 2003 12:37:14 +0200
* uidgid.c, uidgid.h: new; get uid/gid by name.
* chpst: new; run program with a changed process state (includes envdir,
envuidgid, pgrphack, setlock, setuidgid, softlimit functionality).
* setuidgid.c: remove; obsolete (replaced by chpst).
runit 0.10.0
Sun, 22 Jun 2003 20:44:58 +0200
* doc/index.html, doc/install.html, doc/replaceinit.html, doc/useinit.html:
how to install and configure runit on MacOSX.
* svlogd.c: typo; fix incorrect handling of processor's state file; minor
code cleanup; correctly calculate size for all types of timestamps.
* runit-init.c: exit 0 on wrong usage.
* package/versions: new.
runit 0.9.5
Tue, 17 Jun 2003 10:48:10 +0200
* runit.c: use select() on systems that don't provide poll().
* svlogd.c: reset match flag in lineflush() in all cases.
* Makefile: build setuidgid in default target.
* doc/useinit.html: add instruction to create /etc/runit/2 first.
* doc/install.html: minor.
runit 0.9.4
Wed, 04 Jun 2003 13:56:33 +0200
* svlogd.c: default log file size is 1M; print verbose message only if
-v is set.
* man/svlogd.8: document -v option; minor.
* etc/freebsd/3, etc/openbsd/3: check if magic files in /etc/runit/ are
executable, not readable.
* etc/*/getty-tty*/run: remove utmpset from script.
* etc/*/getty-tty*/finish: new: run utmpset.
* doc/replaceinit.html: adapt.
* setuidgid.c: new: daemontools' setuidgid drop in replacement (not
installed by default).
* Makefile: build setuidgid.
* doc/index.html: update.
runit 0.9.3
Sun, 04 May 2003 11:30:58 +0200
* Makefile: actually build runsvstat, runsvctrl before installing them,
fixes build failure (thx Lukas Beeler).
* runsvctrl.c, runsvstat.c: use _exit().
runit 0.9.2
Sat, 03 May 2003 17:40:23 +0200
* doc/runscripts.html: changes from Jesse Cablek.
* doc/dependencies.html, doc/useinit.html: new.
* doc/index.html: adapt; reorder programs; runsvstat, runsvctrl installed
by default.
* doc/install.html: remove dependency on daemontools; create /package.
* doc/replaceinit.html, man/runsv.8: typos.
* man/svwaitdown.8, man/svwaitup.8: refer to runit and supervise.
* svlogd.c: fix counter var namespace.
* package/commands: add runsvctrl, runsvstat.
runit 0.9.1
Wed, 30 Apr 2003 22:10:57 +0200
* svlogd.c: reset match flag on deselection, fixes pattern matching.
runit 0.9.0
Fri, 25 Apr 2003 09:22:03 +0200
* runsvdir.c: don't propagate sig_term to runsv processes when receiving
sig_term; send sig_term to all runsv processes and exit 111 when
receiving sig_hangup.
* runit.c: print warning for each state that exits non-zero; restart
stage 2 if it exits non-zero.
* svlogd.c: code cleanup.
* svwaitdown.c: send command 'd' (and 'x' if -x is set) to each service if
it's not in state 'want down'.
* svwaitup.c: minor code cleanup.
* man/runsvdir.8, man/svwaitdown.8: adapt.
* doc/runscripts.html: add contributed run scripts (thx!).
* doc/upgrade.html, doc/index.html: adapt.
runit 0.8.4
Sun, 20 Apr 2003 19:31:24 +0200
* svlogd.c: new; runit's service logging daemon.
* fmt_ptime.h, fmt_ptime.c, pmatch.h, pmatch.c: new.
* man/svlogd.8, doc/svlogd.8.html: new.
* man/runsv.8, man/runsvstat.8, man/utmpset.8: minor cleanup.
runit 0.8.1
Wed, 12 Mar 2003 15:10:04 +0100
* runsvdir.c, runsv.c: close-on-exec file descriptors of current dir and
lock files (thx Lukas Beeler).
* doc/runscripts.html: add contributed run scripts (thx Robin S. Socha,
Claus Alboege, Paul Jarc, clemens fischer, Jesse Cablek).
runit 0.8.0
Tue, 25 Feb 2003 16:17:34 +0100
* doc/benefits.html: new.
* doc/index.html, doc/upgrade.html: adapt.
* etc/*/1, etc/*/3, etc/*/ctrlaltdel: set permissions on the magic files
instead of creating and removing them (can make them symbolic links
now); set PATH.
* runit.h: new; centralize runit's compiled in magic file names.
* runit.c: check permissions of magic files instead of sole existence;
conditionally call reboot(RB_AUTOBOOT), reboot(RB_POWER_OFF),
reboot(RB_HALT_SYSTEM) if possible; code cleanup.
* runit-init.c: set permissions on magic files instead of creating or
removing them; code cleanup.
* runsvdir.c: detect and tolerate system time warp; code cleanup.
* runsv.c, runsvchdir.c, runsvctrl.c, runsvstat.c, svwaitdown.c,
svwaitup.c, utmpset.c: code cleanup.
* man/runit.8, man/runit-init.8: adapt.
runit 0.7.2
Fri, 10 Jan 2003 21:34:13 +0100
* runsv.c: close finish script file descriptor.
* runsv.c: close logpipe[] instead of sending sigterm to logservice when
told to exit, loggers should exit when they see EOF on stdin (thx Paul
Jarc).
* etc/*/1, etc/*/3: remove explicit 'exit'.
* error.h: include (upcoming glibc changes).
runit 0.7.1
Wed, 23 Oct 2002 11:40:24 +0200
* man/runsv.8, doc/runlevels.html: typos.
* runsvctrl.c, runsvstat.c: exit 111 on error.
* runsvdir.c: continue reading directory when stat() on entry fails.
* doc/runsvstat.8.html,doc/runsvctrl.8.html: new.
* runsvstat, runsvctrl: new; optional svc, svstat replacements.
* doc/index.html: adapt; new example.
runit 0.7.0
Mon, 07 Oct 2002 11:26:27 +0200
* runsvdir.c: check service directory's inode and device in addition
to mtime; sleep at least 1 second before restarting runsv processes.
* runsv.c: use status[19] for state information; control pipe supports e.
* runsvstat.c: new option -l: only show log service if -l is given; use
status[19] for state.
* runsvchdir: new; change directory runsvdir is running in (switch
runlevels).
* man/runsvchdir.8, doc/runsvchdir.8.html: new.
* svwaitdown.c: -k option: only kill service that still are up on timeout.
runit 0.6.0
Fri, 27 Sep 2002 16:34:57 +0200
* man/runsv.8, man/runsvdir.8: new.
* doc: use runsvdir/runsv instead of svscanboot/supervise.
* svwaitdown.c, svwaitup.c, man/svwaitdown.8, man/svwaitup.8: services
must start with slash.
* svwaitdown: new option -x: wait for runsv to exit instead for the
service to be down; new option -k: SIGKILL still running services if
timeout is reached.
* stage 3: use new svwaitdown options.
runit 0.5.3
Mon, 23 Sep 2002 16:25:07 +0200
* runsv, runsvdir: new; svscan/supervise replacement.
* etc/runit/2: use runsvdir instead of svscanboot.
* runsvstat.c: new; svstat for runsv.
* runsvctrl.c: new; svc for runsv.
* runsvdir.c, runsv.c: code cleanup.
* utmpset.c: setlock utmp and wtmp file.
runit 0.5.0
Wed, 28 Aug 2002 11:18:28 +0200
* utmpset: avoids libutil; compiles with dietlibc; built by default.
* doc/usedietlibc.html: fix description.
* getty-*/run: add utmpset.
runit 0.4.1
Mon, 24 Jun 2002 15:53:11 +0200
* utmpset.c: new option -w: additionally write wtmp record.
runit 0.4.0
Sun, 19 May 2002 12:28:29 +0200
* src/: include public domain sources to build byte.a, unix.a, time.a:
runit builds without having daemontools' sources installed.
* utmpset.c: new utmpset program.
* doc/utmpset.html: new.
runit 0.3.2
Wed, 13 Feb 2002 10:56:17 +0100
* runit.c: support ctrl-alt-del also on Linux/i386, dietlibc.
* runscripts.html: more samples. (thx Alessandro Bono)
runit 0.3.1
Sun, 3 Feb 2002 16:30:55 +0100
* src: cleanup.
runit 0.3.0
Tue, 29 Jan 2002 19:38:33 +0100
* doc: adapted.
* runit.8: changes documented.
* runscripts.html: more examples.
runit 0.2.9
Thu, 17 Jan 2002 19:00:44 +0100
* reportedly runs on FreeBSD 4.3 (thx clemensF)
* svwaitdown: max timeout is 6000, really. (thx ska)
* runit.c: stage 1 gets no new session and full control of console; an
emergency shell or login program (if present) can be executed.
* openbsd, freebsd: support for 'single user' emergency shell in stage 1
* runit.c: skip stage 2 if stage 1 crashes.
runit 0.2.7
Tue, 1 Jan 2002 16:20:14 +0100
* tested on fresh freebsd 4.4 installation in vmware
* new etc/freebsd: stages and getty service
* doc: replaceinit: how to replace bsd init (freebsd)
* svwaitup: minor code cleanup
* doc: /service/getty-5/ as default getty service.
* doc: index: related links added.
* package: install-man added for installing manpages in /usr/local/man/
runit 0.2.6
Sun, 30 Dec 2001 17:29:29 +0100
* runs on openbsd 2.9
* runit: console init and reinit
* runit: sig_pause() on end.
* new: etc/openbsd: stages and getty service
* doc: replaceinit: how to replace bsd init
runit 0.2.3
Thu, 27 Dec 2001 14:41:56 +0100
* doc: runscripts.html integrated
runit 0.2.2
Sun, 23 Dec 2001 18:12:29 +0100
* runit: checks for pid == 1
* new: svwaitdown, svwaitup, svwaitdown.8, svwaitup.8
* stage3: uses svwaitdown
* doc: runscripts.html added
runit 0.2.0
Mon, 26 Nov 2001 12:29:44 +0100
* runit-halt, runit-reboot removed, integrated into runit-init
* tested with dietlibc
* doc: usedietlibs.html added.
* BSD license.
runit 0.1.2
Thu, 22 Nov 2001 18:29:05 +0100
* collects all terminated children in all stages
* sends sigkill to whole process group if stage2 crashes and waits
5 seconds before restarting
* ctraltdel not automatically shuts down, now respects /etc/runit/stopit
* /etc/runit/ctrlaltdel touches /etc/runit/stopit
* on shutdown request: send sigterm to stage 2, wait max 5 second, send
sigkill if still running, leave stage 2, enter stage 3
runit 0.1.1
Tue, 20 Nov 2001 11:56:58 +0100
* package moved to smarden.org
runit 0.1.0
Fri, 16 Nov 2001 14:01:27 +0100
* documention
* debian package
runit 0.0.4
Sun, 11 Nov 2001 19:07:49 +0100
* initial release
admin/runit-2.2.0/package/sharing 0000644 0000000 0000000 00000000043 14675400254 015417 0 ustar root root command:syst
package:dist
src:dist
admin/runit-2.2.0/package/compile 0000755 0000000 0000000 00000001237 14675400254 015425 0 ustar root root #!/bin/sh
set -e
umask 022
test -d package || sh -cx '! : Wrong working directory.'
test -d src || sh -cx '! : Wrong working directory.'
here=`env - PATH=$PATH pwd`
mkdir -p compile command
test -r compile/home || echo $here >compile/home
test -h compile/src || ln -s $here/src compile/src
echo 'Linking ./src/* into ./compile...'
for i in `ls src`; do
test -h compile/$i || ln -s src/$i compile/$i
done
echo 'Compiling everything in ./compile...'
sh -cxe 'cd compile; exec make'
echo 'Copying commands into ./command...'
for i in `cat package/commands`; do
rm -f command/$i'{new}'
cp -p compile/$i command/$i'{new}'
mv -f command/$i'{new}' command/$i
done
admin/runit-2.2.0/package/install 0000755 0000000 0000000 00000000100 14675400254 015427 0 ustar root root #!/bin/sh
set -e
package/compile
package/check
package/upgrade
admin/runit-2.2.0/package/README 0000644 0000000 0000000 00000000066 14675400254 014726 0 ustar root root Copyright 2001-2024
G. Pape
http://smarden.org/runit/
admin/runit-2.2.0/package/check 0000755 0000000 0000000 00000000336 14675400254 015051 0 ustar root root #!/bin/sh
set -e
umask 022
test -d package || sh -cx '! : Wrong working directory.'
test -d compile || sh -cx '! : Wrong working directory.'
echo 'Checking commands in ./command...'
sh -cxe 'cd compile; exec make check'
admin/runit-2.2.0/package/COPYING 0000644 0000000 0000000 00000002612 14675400254 015100 0 ustar root root Copyright (c) 2001-2024, Gerrit Pape
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
admin/runit-2.2.0/package/commands 0000644 0000000 0000000 00000000103 14675400254 015562 0 ustar root root chpst
runit
runit-init
runsv
runsvchdir
runsvdir
sv
svlogd
utmpset
admin/runit-2.2.0/package/install-man 0000755 0000000 0000000 00000001127 14675400254 016212 0 ustar root root #!/bin/sh
set -e
umask 022
test -d package || sh -cx '! : Wrong working directory.'
test -d man || sh -cx '! : Wrong working directory.'
here=`env - PATH=$PATH pwd`
parent=`dirname $here`
echo 'Compressing manpages...'
for i in man/*.[1-8]; do
gzip -c $i >${i}.gz
done
echo 'Making manpage links in /usr/local/man...'
cd man
for i in 8; do
mkdir -p /usr/local/man/man$i
for j in *.$i; do
rm -f /usr/local/man/man$i/$j.gz'{new}'
ln -s $parent/runit/man/$j.gz /usr/local/man/man$i/$j.gz'{new}'
mv -f /usr/local/man/man$i/$j.gz'{new}' /usr/local/man/man$i/$j.gz
done
done
cd ..
admin/runit-2.2.0/src/ 0000755 0000000 0000000 00000000000 14675400254 013240 5 ustar root root admin/runit-2.2.0/src/svlogd.check 0000755 0000000 0000000 00000000636 14675400254 015545 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
svlogd
echo $?
svlogd -V
echo $?
mkdir "${ctmp}"
echo foo |svlogd "${ctmp}"
echo $?
cat "${ctmp}"/current
( echo bar; echo baz ) |svlogd "${ctmp}"
echo $?
cat "${ctmp}"/current
( echo foo; echo bar; echo baz ) |svlogd -r: -R fb "${ctmp}"
echo $?
cat "${ctmp}"/current
echo t2 >"${ctmp}"/config
( echo foo; sleep 3 ) |svlogd "${ctmp}"
echo $?
cat "${ctmp}"/current
rm -rf "${ctmp}"
admin/runit-2.2.0/src/tryreboot.c 0000644 0000000 0000000 00000000125 14675400254 015433 0 ustar root root #include
#include
int main(void) {
return(reboot(0));
}
admin/runit-2.2.0/src/taia_less.c 0000644 0000000 0000000 00000000467 14675400254 015357 0 ustar root root /* Public domain. */
#include "taia.h"
/* XXX: breaks tai encapsulation */
int taia_less(const struct taia *t,const struct taia *u)
{
if (t->sec.x < u->sec.x) return 1;
if (t->sec.x > u->sec.x) return 0;
if (t->nano < u->nano) return 1;
if (t->nano > u->nano) return 0;
return t->atto < u->atto;
}
admin/runit-2.2.0/src/runsvctrl.check 0000755 0000000 0000000 00000000614 14675400254 016305 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
runsvctrl
echo $?
mkdir "${ctmp}"
echo '#!/bin/sh' >"${ctmp}"/run
echo 'echo starting' >>"${ctmp}"/run
echo 'exec sleep 14' >>"${ctmp}"/run
chmod 700 "${ctmp}"/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
runsvctrl down "${ctmp}"
echo $?
sleep 1
cat "${ctmp}"/supervise/stat
runsvctrl exit "${ctmp}"
echo $?
wait
echo $?
rm -rf "${ctmp}"
admin/runit-2.2.0/src/Makefile 0000644 0000000 0000000 00000030373 14675400254 014706 0 ustar root root IT=chpst runit runit-init runsv runsvchdir runsvdir sv svlogd utmpset
default: sysdeps $(IT)
check: $(IT)
./check-local $(IT)
runit: load runit.o unix.a byte.a
./load runit unix.a byte.a -static
runit-init: load runit-init.o unix.a byte.a
./load runit-init unix.a byte.a -static
runsv: load runsv.o unix.a byte.a time.a
./load runsv unix.a byte.a time.a
runsvdir: load runsvdir.o unix.a byte.a time.a
./load runsvdir unix.a byte.a time.a
runsvstat: load runsvstat.o unix.a byte.a time.a
./load runsvstat unix.a byte.a time.a
runsvctrl: load runsvctrl.o unix.a byte.a
./load runsvctrl unix.a byte.a
sv: load sv.o unix.a byte.a time.a
./load sv unix.a byte.a time.a
svwaitup: load svwaitup.o unix.a byte.a time.a
./load svwaitup unix.a byte.a time.a
svwaitdown: load svwaitdown.o unix.a byte.a time.a
./load svwaitdown unix.a byte.a time.a
utmpset: load utmpset.o unix.a byte.a
./load utmpset unix.a byte.a
runsvchdir: load runsvchdir.o unix.a byte.a
./load runsvchdir unix.a byte.a
svlogd: load svlogd.o pmatch.o fmt_ptime.o unix.a byte.a time.a socket.lib
./load svlogd pmatch.o fmt_ptime.o unix.a byte.a time.a \
`cat socket.lib`
chpst: load chpst.o uidgid.o unix.a byte.a
./load chpst uidgid.o unix.a byte.a
runit.o: compile sysdeps runit.c
./compile runit.c
runit-init.o: compile runit-init.c
./compile runit-init.c
runsv.o: compile sysdeps runsv.c
./compile runsv.c
runsvdir.o: compile sysdeps runsvdir.c
./compile runsvdir.c
runsvstat.o: compile sysdeps runsvstat.c
./compile runsvstat.c
runsvctrl.o: compile runsvctrl.c
./compile runsvctrl.c
sv.o: compile sysdeps sv.c
./compile sv.c
svwaitup.o: compile sysdeps svwaitup.c
./compile svwaitup.c
svwaitdown.o: compile sysdeps svwaitdown.c
./compile svwaitdown.c
utmpset.o: compile sysdeps utmpset.c
./compile utmpset.c
runsvchdir.o: compile runsvchdir.c
./compile runsvchdir.c
svlogd.o: compile sysdeps svlogd.c
./compile svlogd.c
chpst.o: compile sysdeps chpst.c
./compile chpst.c
uidgid.o: compile uidgid.c uidgid.h
./compile uidgid.c
pmatch.o: compile pmatch.c
./compile pmatch.c
fmt_ptime.o: compile sysdeps fmt_ptime.c
./compile fmt_ptime.c
reboot_system.h: choose compile reboot_system.h1 reboot_system.h2
./choose c tryreboot reboot_system.h1 reboot_system.h2 > \
reboot_system.h
uw_tmp.h: compile uw_tmp.h1 uw_tmp.h2
( ./compile tryuwtmpx.c 2>/dev/null && cat uw_tmp.h2 >uw_tmp.h ) || \
( ./compile tryuwtmp.c 2>/dev/null && cat uw_tmp.h1 >uw_tmp.h )
rm -f tryuwtmp.o tryuwtmpx.o
socket.lib: compile load trysocketlib.c
./compile trysocketlib.c
( ./load trysocketlib >/dev/null 2>&1 || \
( ./load trysocketlib -lxnet >/dev/null 2>&1 && echo '-lxnet' ) || \
( ./load trysocketlib -lsocket -lnsl >/dev/null 2>&1 && \
echo '-lsocket -lnsl' ) \
) >socket.lib
rm -f trysocketlib.o trysocketlib
clean:
find . -name \*~ -exec rm -f {} \;
find . -name .??*~ -exec rm -f {} \;
find . -name \#?* -exec rm -f {} \;
rm -f `cat TARGETS`
alloc.o: alloc.c alloc.h compile error.h
./compile alloc.c
alloc_re.o: alloc.h alloc_re.c byte.h compile
./compile alloc_re.c
buffer.o: buffer.c buffer.h compile
./compile buffer.c
buffer_0.o: buffer.h buffer_0.c compile
./compile buffer_0.c
buffer_1.o: buffer.h buffer_1.c compile
./compile buffer_1.c
buffer_2.o: buffer.h buffer_2.c compile
./compile buffer_2.c
buffer_get.o: buffer.h buffer_get.c byte.h compile error.h
./compile buffer_get.c
buffer_put.o: buffer.h buffer_put.c byte.h compile error.h str.h
./compile buffer_put.c
buffer_read.o: buffer.h buffer_read.c compile
./compile buffer_read.c
buffer_write.o: buffer.h buffer_write.c compile
./compile buffer_write.c
byte.a: byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_rchr.o \
fmt_uint.o fmt_uint0.o fmt_ulong.o makelib scan_ulong.o str_chr.o \
str_diff.o str_len.o str_start.o
./makelib byte.a byte_chr.o byte_copy.o byte_cr.o byte_diff.o \
byte_rchr.o fmt_uint.o fmt_uint0.o fmt_ulong.o scan_ulong.o str_chr.o \
str_diff.o str_len.o str_start.o
byte_chr.o: byte.h byte_chr.c compile
./compile byte_chr.c
byte_copy.o: byte.h byte_copy.c compile
./compile byte_copy.c
byte_cr.o: byte.h byte_cr.c compile
./compile byte_cr.c
byte_diff.o: byte.h byte_diff.c compile
./compile byte_diff.c
byte_rchr.o: byte.h byte_rchr.c compile
./compile byte_rchr.c
choose: choose.sh warn-auto.sh
rm -f choose
cat warn-auto.sh choose.sh \
> choose
chmod 555 choose
coe.o: coe.c coe.h compile
./compile coe.c
compile: conf-cc print-cc.sh systype warn-auto.sh
rm -f compile
sh print-cc.sh > compile
chmod 555 compile
direntry.h: choose compile direntry.h1 direntry.h2 trydrent.c
./choose c trydrent direntry.h1 direntry.h2 > direntry.h
env.o: compile env.c env.h str.h
./compile env.c
error.o: compile error.c error.h
./compile error.c
error_str.o: compile error.h error_str.c
./compile error_str.c
fd_copy.o: compile fd.h fd_copy.c
./compile fd_copy.c
fd_move.o: compile fd.h fd_move.c
./compile fd_move.c
fifo.o: compile fifo.c fifo.h hasmkffo.h
./compile fifo.c
fmt_uint.o: compile fmt.h fmt_uint.c
./compile fmt_uint.c
fmt_uint0.o: compile fmt.h fmt_uint0.c
./compile fmt_uint0.c
fmt_ulong.o: compile fmt.h fmt_ulong.c
./compile fmt_ulong.c
hasflock.h: choose compile hasflock.h1 hasflock.h2 load tryflock.c
./choose cl tryflock hasflock.h1 hasflock.h2 > hasflock.h
hasmkffo.h: choose compile hasmkffo.h1 hasmkffo.h2 load trymkffo.c
./choose cl trymkffo hasmkffo.h1 hasmkffo.h2 > hasmkffo.h
hassgact.h: choose compile hassgact.h1 hassgact.h2 load trysgact.c
./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h
hassgprm.h: choose compile hassgprm.h1 hassgprm.h2 load trysgprm.c
./choose cl trysgprm hassgprm.h1 hassgprm.h2 > hassgprm.h
haswaitp.h: choose compile haswaitp.h1 haswaitp.h2 load trywaitp.c
./choose cl trywaitp haswaitp.h1 haswaitp.h2 > haswaitp.h
iopause.h: choose compile iopause.h1 iopause.h2 load trypoll.c
./choose clr trypoll iopause.h1 iopause.h2 > iopause.h
iopause.o: compile iopause.c iopause.h select.h tai.h taia.h uint64.h
./compile iopause.c
load: conf-ld print-ld.sh systype warn-auto.sh
rm -f load
sh print-ld.sh > load
chmod 555 load
lock_ex.o: compile hasflock.h lock.h lock_ex.c
./compile lock_ex.c
lock_exnb.o: compile hasflock.h lock.h lock_exnb.c
./compile lock_exnb.c
makelib: print-ar.sh systype warn-auto.sh
rm -f makelib
sh print-ar.sh > makelib
chmod 555 makelib
ndelay_off.o: compile ndelay.h ndelay_off.c
./compile ndelay_off.c
ndelay_on.o: compile ndelay.h ndelay_on.c
./compile ndelay_on.c
open_append.o: compile open.h open_append.c
./compile open_append.c
open_read.o: compile open.h open_read.c
./compile open_read.c
open_trunc.o: compile open.h open_trunc.c
./compile open_trunc.c
open_write.o: compile open.h open_write.c
./compile open_write.c
openreadclose.o: compile error.h gen_alloc.h open.h openreadclose.c \
openreadclose.h readclose.h stralloc.h
./compile openreadclose.c
pathexec_env.o: alloc.h byte.h compile env.h gen_alloc.h pathexec.h \
pathexec_env.c str.h stralloc.h
./compile pathexec_env.c
pathexec_run.o: compile env.h error.h gen_alloc.h pathexec.h \
pathexec_run.c str.h stralloc.h
./compile pathexec_run.c
readclose.o: compile error.h gen_alloc.h readclose.c readclose.h \
stralloc.h
./compile readclose.c
scan_ulong.o: compile scan.h scan_ulong.c
./compile scan_ulong.c
seek_set.o: compile seek.h seek_set.c
./compile seek_set.c
select.h: choose compile select.h1 select.h2 trysysel.c
./choose c trysysel select.h1 select.h2 > select.h
sgetopt.o: buffer.h compile sgetopt.c sgetopt.h subgetopt.h
./compile sgetopt.c
sig.o: compile sig.c sig.h
./compile sig.c
sig_block.o: compile hassgprm.h sig.h sig_block.c
./compile sig_block.c
sig_catch.o: compile hassgact.h sig.h sig_catch.c
./compile sig_catch.c
sig_pause.o: compile hassgprm.h sig.h sig_pause.c
./compile sig_pause.c
str_chr.o: compile str.h str_chr.c
./compile str_chr.c
str_diff.o: compile str.h str_diff.c
./compile str_diff.c
str_len.o: compile str.h str_len.c
./compile str_len.c
str_start.o: compile str.h str_start.c
./compile str_start.c
stralloc_cat.o: byte.h compile gen_alloc.h stralloc.h stralloc_cat.c
./compile stralloc_cat.c
stralloc_catb.o: byte.h compile gen_alloc.h stralloc.h \
stralloc_catb.c
./compile stralloc_catb.c
stralloc_cats.o: byte.h compile gen_alloc.h str.h stralloc.h \
stralloc_cats.c
./compile stralloc_cats.c
stralloc_eady.o: alloc.h compile gen_alloc.h gen_allocdefs.h \
stralloc.h stralloc_eady.c
./compile stralloc_eady.c
stralloc_opyb.o: byte.h compile gen_alloc.h stralloc.h \
stralloc_opyb.c
./compile stralloc_opyb.c
stralloc_opys.o: byte.h compile gen_alloc.h str.h stralloc.h \
stralloc_opys.c
./compile stralloc_opys.c
stralloc_pend.o: alloc.h compile gen_alloc.h gen_allocdefs.h \
stralloc.h stralloc_pend.c
./compile stralloc_pend.c
strerr_die.o: buffer.h compile strerr.h strerr_die.c
./compile strerr_die.c
strerr_sys.o: compile error.h strerr.h strerr_sys.c
./compile strerr_sys.c
subgetopt.o: compile subgetopt.c subgetopt.h
./compile subgetopt.c
sysdeps: compile direntry.h hasflock.h hasmkffo.h hassgact.h \
hassgprm.h haswaitp.h iopause.h load select.h systype \
uint64.h reboot_system.h uw_tmp.h socket.lib
rm -f sysdeps
cat systype compile load socket.lib >>sysdeps
grep sysdep direntry.h >>sysdeps
grep sysdep haswaitp.h >>sysdeps
grep sysdep hassgact.h >>sysdeps
grep sysdep hassgprm.h >>sysdeps
grep sysdep select.h >>sysdeps
grep sysdep uint64.h >>sysdeps
grep sysdep iopause.h >>sysdeps
grep sysdep hasmkffo.h >>sysdeps
grep sysdep hasflock.h >>sysdeps
grep sysdep reboot_system.h >>sysdeps
grep sysdep uw_tmp.h >>sysdeps
cat sysdeps
systype: find-systype.sh trycpp.c x86cpuid.c
sh find-systype.sh > systype
tai_now.o: compile tai.h tai_now.c uint64.h
./compile tai_now.c
tai_pack.o: compile tai.h tai_pack.c uint64.h
./compile tai_pack.c
tai_sub.o: compile tai.h tai_sub.c uint64.h
./compile tai_sub.c
tai_unpack.o: compile tai.h tai_unpack.c uint64.h
./compile tai_unpack.c
taia_add.o: compile tai.h taia.h taia_add.c uint64.h
./compile taia_add.c
taia_approx.o: compile tai.h taia.h taia_approx.c uint64.h
./compile taia_approx.c
taia_frac.o: compile tai.h taia.h taia_frac.c uint64.h
./compile taia_frac.c
taia_less.o: compile tai.h taia.h taia_less.c uint64.h
./compile taia_less.c
taia_now.o: compile tai.h taia.h taia_now.c uint64.h
./compile taia_now.c
taia_pack.o: compile tai.h taia.h taia_pack.c uint64.h
./compile taia_pack.c
taia_sub.o: compile tai.h taia.h taia_sub.c uint64.h
./compile taia_sub.c
taia_uint.o: compile tai.h taia.h taia_uint.c uint64.h
./compile taia_uint.c
time.a: iopause.o makelib tai_now.o tai_pack.o tai_sub.o tai_unpack.o \
taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o \
taia_pack.o taia_sub.o taia_uint.o
./makelib time.a iopause.o tai_now.o tai_pack.o tai_sub.o \
tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o \
taia_now.o taia_pack.o taia_sub.o taia_uint.o
uint64.h: choose compile load tryulong64.c uint64.h1 uint64.h2
./choose clr tryulong64 uint64.h1 uint64.h2 > uint64.h
unix.a: alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o buffer_2.o \
buffer_get.o buffer_put.o buffer_read.o buffer_write.o coe.o env.o \
error.o error_str.o fd_copy.o fd_move.o fifo.o lock_ex.o lock_exnb.o \
makelib ndelay_off.o ndelay_on.o open_append.o open_read.o \
open_trunc.o open_write.o openreadclose.o pathexec_env.o \
pathexec_run.o readclose.o seek_set.o sgetopt.o sig.o \
sig_block.o sig_catch.o sig_pause.o stralloc_cat.o stralloc_catb.o \
stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \
stralloc_pend.o strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o \
wait_pid.o
./makelib unix.a alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o \
buffer_2.o buffer_get.o buffer_put.o buffer_read.o buffer_write.o \
coe.o env.o error.o error_str.o fd_copy.o fd_move.o fifo.o lock_ex.o \
lock_exnb.o ndelay_off.o ndelay_on.o open_append.o open_read.o \
open_trunc.o open_write.o openreadclose.o pathexec_env.o \
pathexec_run.o readclose.o seek_set.o sgetopt.o sig.o \
sig_block.o sig_catch.o sig_pause.o stralloc_cat.o stralloc_catb.o \
stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \
stralloc_pend.o strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o \
wait_pid.o
wait_nohang.o: compile haswaitp.h wait_nohang.c
./compile wait_nohang.c
wait_pid.o: compile error.h haswaitp.h wait_pid.c
./compile wait_pid.c
admin/runit-2.2.0/src/byte_rchr.c 0000644 0000000 0000000 00000000707 14675400254 015371 0 ustar root root /* Public domain. */
#include "byte.h"
unsigned int byte_rchr(s,n,c)
char *s;
register unsigned int n;
int c;
{
register char ch;
register char *t;
register char *u;
ch = c;
t = s;
u = 0;
for (;;) {
if (!n) break; if (*t == ch) u = t; ++t; --n;
if (!n) break; if (*t == ch) u = t; ++t; --n;
if (!n) break; if (*t == ch) u = t; ++t; --n;
if (!n) break; if (*t == ch) u = t; ++t; --n;
}
if (!u) u = t;
return u - s;
}
admin/runit-2.2.0/src/taia_approx.c 0000644 0000000 0000000 00000000203 14675400254 015706 0 ustar root root /* Public domain. */
#include "taia.h"
double taia_approx(const struct taia *t)
{
return tai_approx(&t->sec) + taia_frac(t);
}
admin/runit-2.2.0/src/str_len.c 0000644 0000000 0000000 00000000405 14675400254 015051 0 ustar root root /* Public domain. */
#include "str.h"
unsigned int str_len(const char *s)
{
register const char *t;
t = s;
for (;;) {
if (!*t) return t - s; ++t;
if (!*t) return t - s; ++t;
if (!*t) return t - s; ++t;
if (!*t) return t - s; ++t;
}
}
admin/runit-2.2.0/src/stralloc_opys.c 0000644 0000000 0000000 00000000255 14675400254 016303 0 ustar root root /* Public domain. */
#include "byte.h"
#include "str.h"
#include "stralloc.h"
int stralloc_copys(stralloc *sa,const char *s)
{
return stralloc_copyb(sa,s,str_len(s));
}
admin/runit-2.2.0/src/sig_block.c 0000644 0000000 0000000 00000001223 14675400254 015336 0 ustar root root /* Public domain. */
#include
#include "sig.h"
#include "hassgprm.h"
void sig_block(int sig)
{
#ifdef HASSIGPROCMASK
sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss,sig);
sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0);
#else
sigblock(1 << (sig - 1));
#endif
}
void sig_unblock(int sig)
{
#ifdef HASSIGPROCMASK
sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss,sig);
sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0);
#else
sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1)));
#endif
}
void sig_blocknone(void)
{
#ifdef HASSIGPROCMASK
sigset_t ss;
sigemptyset(&ss);
sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
#else
sigsetmask(0);
#endif
}
admin/runit-2.2.0/src/open.h 0000644 0000000 0000000 00000000365 14675400254 014356 0 ustar root root /* Public domain. */
#ifndef OPEN_H
#define OPEN_H
extern int open_read(const char *);
extern int open_excl(const char *);
extern int open_append(const char *);
extern int open_trunc(const char *);
extern int open_write(const char *);
#endif
admin/runit-2.2.0/src/hasmkffo.h2 0000644 0000000 0000000 00000000100 14675400254 015260 0 ustar root root /* Public domain. */
/* sysdep: +mkfifo */
#define HASMKFIFO 1
admin/runit-2.2.0/src/conf-ld 0000644 0000000 0000000 00000000077 14675400254 014511 0 ustar root root gcc -s
This will be used to link .o files into an executable.
admin/runit-2.2.0/src/runit.c 0000644 0000000 0000000 00000021533 14675400254 014551 0 ustar root root #include
#include
#include
#include
#include
#include
#include
#include "runit.h"
#include "sig.h"
#include "strerr.h"
#include "error.h"
#include "iopause.h"
#include "coe.h"
#include "ndelay.h"
#include "wait.h"
#include "open.h"
#include "reboot_system.h"
/* #define DEBUG */
#define INFO "- runit: "
#define WARNING "- runit: warning: "
#define FATAL "- runit: fatal: "
const char * const stage[3] ={
"/etc/runit/1",
"/etc/runit/2",
"/etc/runit/3" };
int selfpipe[2];
int sigc =0;
int sigi =0;
void sig_cont_handler (void) {
sigc++;
write(selfpipe[1], "", 1);
}
void sig_int_handler (void) {
sigi++;
write(selfpipe[1], "", 1);
}
void sig_child_handler (void) { write(selfpipe[1], "", 1); }
void sync_if_needed() {
struct stat s;
if (stat(NOSYNC, &s) == -1) sync();
}
int main (int argc, const char * const *argv, char * const *envp) {
const char * prog[2];
int pid, pid2;
int wstat;
int st;
iopause_fd x;
#ifndef IOPAUSE_POLL
fd_set rfds;
struct timeval t;
#endif
char ch;
int ttyfd;
struct stat s;
if (getpid() != 1) strerr_die2x(111, FATAL, "must be run as process no 1.");
setsid();
sig_block(sig_alarm);
sig_block(sig_child);
sig_catch(sig_child, sig_child_handler);
sig_block(sig_cont);
sig_catch(sig_cont, sig_cont_handler);
sig_block(sig_hangup);
sig_block(sig_int);
sig_catch(sig_int, sig_int_handler);
sig_block(sig_pipe);
sig_block(sig_term);
/* console */
if ((ttyfd =open_write("/dev/console")) != -1) {
dup2(ttyfd, 0); dup2(ttyfd, 1); dup2(ttyfd, 2);
if (ttyfd > 2) close(ttyfd);
}
/* create selfpipe */
while (pipe(selfpipe) == -1) {
strerr_warn2(FATAL, "unable to create selfpipe, pausing: ", &strerr_sys);
sleep(5);
}
coe(selfpipe[0]);
coe(selfpipe[1]);
ndelay_on(selfpipe[0]);
ndelay_on(selfpipe[1]);
#ifdef RB_DISABLE_CAD
/* activate ctrlaltdel handling, glibc, dietlibc */
if (RB_DISABLE_CAD == 0) reboot_system(0);
#endif
strerr_warn3(INFO, "$Id: c6c9cea989d36a913fe8ed121272c01625813eb4 $",
": booting.", 0);
/* runit */
for (st =0; st < 3; st++) {
/* if (st == 2) logwtmp("~", "reboot", ""); */
while ((pid =fork()) == -1) {
strerr_warn4(FATAL, "unable to fork for \"", stage[st], "\" pausing: ",
&strerr_sys);
sleep(5);
}
if (!pid) {
/* child */
prog[0] =stage[st];
prog[1] =0;
/* stage 1 gets full control of console */
if (st == 0) {
if ((ttyfd =open("/dev/console", O_RDWR)) != -1) {
#ifdef TIOCSCTTY
ioctl(ttyfd, TIOCSCTTY, (char *)0);
#endif
dup2(ttyfd, 0);
if (ttyfd > 2) close(ttyfd);
}
else
strerr_warn2(WARNING, "unable to open /dev/console: ", &strerr_sys);
}
else
setsid();
sig_unblock(sig_alarm);
sig_unblock(sig_child);
sig_uncatch(sig_child);
sig_unblock(sig_cont);
sig_ignore(sig_cont);
sig_unblock(sig_hangup);
sig_unblock(sig_int);
sig_uncatch(sig_int);
sig_unblock(sig_pipe);
sig_unblock(sig_term);
strerr_warn3(INFO, "enter stage: ", stage[st], 0);
execve(*prog, (char *const *)prog, envp);
strerr_die4sys(0, FATAL, "unable to start child: ", stage[st], ": ");
}
x.fd =selfpipe[0];
x.events =IOPAUSE_READ;
for (;;) {
int child;
sig_unblock(sig_child);
sig_unblock(sig_cont);
sig_unblock(sig_int);
#ifdef IOPAUSE_POLL
poll(&x, 1, 14000);
#else
t.tv_sec =14; t.tv_usec =0;
FD_ZERO(&rfds);
FD_SET(x.fd, &rfds);
select(x.fd +1, &rfds, (fd_set*)0, (fd_set*)0, &t);
#endif
sig_block(sig_cont);
sig_block(sig_child);
sig_block(sig_int);
while (read(selfpipe[0], &ch, 1) == 1) {}
while ((child =wait_nohang(&wstat)) > 0)
if (child == pid) break;
if (child == -1) {
strerr_warn2(WARNING, "wait_nohang, pausing: ", &strerr_sys);
sleep(5);
}
/* reget stderr */
if ((ttyfd =open_write("/dev/console")) != -1) {
dup2(ttyfd, 2);
if (ttyfd > 2) close(ttyfd);
}
if (child == pid) {
if (wait_exitcode(wstat) != 0) {
if (wait_crashed(wstat))
strerr_warn3(WARNING, "child crashed: ", stage[st], 0);
else
strerr_warn3(WARNING, "child failed: ", stage[st], 0);
if (st == 0)
/* this is stage 1 */
if (wait_crashed(wstat) || (wait_exitcode(wstat) == 100)) {
strerr_warn3(INFO, "leave stage: ", stage[st], 0);
strerr_warn2(WARNING, "skipping stage 2...", 0);
st++;
break;
}
if (st == 1)
/* this is stage 2 */
if (wait_crashed(wstat) || (wait_exitcode(wstat) == 111)) {
strerr_warn2(WARNING, "killing all processes in stage 2...", 0);
kill(-pid, 9);
sleep(5);
strerr_warn2(WARNING, "restarting.", 0);
st--;
break;
}
}
strerr_warn3(INFO, "leave stage: ", stage[st], 0);
break;
}
if (child != 0) {
/* collect terminated children */
write(selfpipe[1], "", 1);
continue;
}
/* sig? */
if (!sigc && !sigi) {
#ifdef DEBUG
strerr_warn2(WARNING, "poll: ", &strerr_sys);
#endif
continue;
}
if (st != 1) {
strerr_warn2(WARNING, "signals only work in stage 2.", 0);
sigc =sigi =0;
continue;
}
if (sigi && (stat(CTRLALTDEL, &s) != -1) && (s.st_mode & S_IXUSR)) {
strerr_warn2(INFO, "ctrl-alt-del request...", 0);
prog[0] =CTRLALTDEL; prog[1] =0;
while ((pid2 =fork()) == -1) {
strerr_warn4(FATAL, "unable to fork for \"", CTRLALTDEL,
"\" pausing: ", &strerr_sys);
sleep(5);
}
if (!pid2) {
/* child */
strerr_warn3(INFO, "enter stage: ", prog[0], 0);
execve(*prog, (char *const *) prog, envp);
strerr_die4sys(0, FATAL, "unable to start child: ", prog[0], ": ");
}
if (wait_pid(&wstat, pid2) == -1)
strerr_warn2(FATAL, "wait_pid: ", &strerr_sys);
if (wait_crashed(wstat))
strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0);
strerr_warn3(INFO, "leave stage: ", prog[0], 0);
sigi =0;
sigc++;
}
if (sigc && (stat(STOPIT, &s) != -1) && (s.st_mode & S_IXUSR)) {
int i;
/* unlink(STOPIT); */
chmod(STOPIT, 0);
/* kill stage 2 */
#ifdef DEBUG
strerr_warn2(WARNING, "sending sigterm...", 0);
#endif
kill(pid, sig_term);
i =0;
while (i < 5) {
if ((child =wait_nohang(&wstat)) == pid) {
#ifdef DEBUG
strerr_warn2(WARNING, "stage 2 terminated.", 0);
#endif
pid =0;
break;
}
if (child) continue;
if (child == -1)
strerr_warn2(WARNING, "wait_nohang: ", &strerr_sys);
#ifdef DEBUG
strerr_warn2(WARNING, "waiting...", 0);
#endif
sleep(1);
i++;
}
if (pid) {
/* still there */
strerr_warn2(WARNING,
"stage 2 not terminated, sending sigkill...", 0);
kill(pid, 9);
if (wait_pid(&wstat, pid) == -1)
strerr_warn2(WARNING, "wait_pid: ", &strerr_sys);
}
sigc =0;
strerr_warn3(INFO, "leave stage: ", stage[st], 0);
/* enter stage 3 */
break;
}
sigc =sigi =0;
#ifdef DEBUG
strerr_warn2(WARNING, "no request.", 0);
#endif
}
}
/* reget stderr */
if ((ttyfd =open_write("/dev/console")) != -1) {
dup2(ttyfd, 2);
if (ttyfd > 2) close(ttyfd);
}
#ifdef RB_AUTOBOOT
/* fallthrough stage 3 */
strerr_warn2(INFO, "sending KILL signal to all processes...", 0);
kill(-1, SIGKILL);
pid =fork();
switch (pid) {
case 0:
case -1:
if ((stat(REBOOT, &s) != -1) && (s.st_mode & S_IXUSR)) {
strerr_warn2(INFO, "system reboot.", 0);
sync_if_needed();
reboot_system(RB_AUTOBOOT);
}
else {
#ifdef RB_POWER_OFF
strerr_warn2(INFO, "power off...", 0);
sync_if_needed();
reboot_system(RB_POWER_OFF);
sleep(2);
#endif
#ifdef RB_HALT_SYSTEM
strerr_warn2(INFO, "system halt.", 0);
sync_if_needed();
reboot_system(RB_HALT_SYSTEM);
#else
#ifdef RB_HALT
strerr_warn2(INFO, "system halt.", 0);
sync_if_needed();
reboot_system(RB_HALT);
#else
strerr_warn2(INFO, "system reboot.", 0);
sync_if_needed();
reboot_system(RB_AUTOBOOT);
#endif
#endif
}
if (pid == 0) _exit(0);
break;
default:
sig_unblock(sig_child);
while (wait_pid(0, pid) == -1);
}
#endif
for (;;) sig_pause();
/* not reached */
strerr_die2x(0, INFO, "exit.");
return(0);
}
admin/runit-2.2.0/src/trymkffo.c 0000644 0000000 0000000 00000000161 14675400254 015243 0 ustar root root /* Public domain. */
#include
#include
void main()
{
mkfifo("temp-trymkffo",0);
}
admin/runit-2.2.0/src/select.h2 0000644 0000000 0000000 00000000265 14675400254 014755 0 ustar root root /* Public domain. */
#ifndef SELECT_H
#define SELECT_H
/* sysdep: +sysselect */
#include
#include
#include
extern int select();
#endif
admin/runit-2.2.0/src/ndelay_off.c 0000644 0000000 0000000 00000000345 14675400254 015514 0 ustar root root /* Public domain. */
#include
#include
#include "ndelay.h"
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
int ndelay_off(int fd)
{
return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK);
}
admin/runit-2.2.0/src/sv.check 0000755 0000000 0000000 00000000560 14675400254 014673 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
trap 'rm -rf "${ctmp}"' EXIT
sv
echo $?
sv -V
echo $?
mkdir "${ctmp}"
cat >"${ctmp}"/run <<-\EOT
#!/bin/sh
echo starting
exec sleep 14
EOT
chmod 700 "${ctmp}"/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
sv down "${ctmp}"
echo $?
sleep 1
cat "${ctmp}"/supervise/stat
sv exit "${ctmp}"
echo $?
wait
echo $?
admin/runit-2.2.0/src/hassgact.h2 0000644 0000000 0000000 00000000106 14675400254 015265 0 ustar root root /* Public domain. */
/* sysdep: +sigaction */
#define HASSIGACTION 1
admin/runit-2.2.0/src/runsvchdir.c 0000644 0000000 0000000 00000004235 14675400254 015577 0 ustar root root #include
#include
#include
#include
#include "strerr.h"
#include "error.h"
#include "buffer.h"
#define USAGE " dir"
#define SVDIR "/etc/runit/runsvdir"
#define VERSION "$Id: 9bf17f77e33c6b961e060aacffa3c8abd38fc64a $"
char *progname;
char *new;
void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
void fatal(char *m1, char *m2) {
strerr_die5sys(111, progname, ": fatal: ", m1, m2, ": ");
}
void fatalx(char *m1, char *m2) {
strerr_die4x(111, progname, ": fatal: ", m1, m2);
}
void warn(char *m1, char *m2) {
strerr_warn5(progname, ": fatal: ", m1, m2, ": ", &strerr_sys);
}
int main (int argc, char **argv) {
struct stat s;
int dev;
int ino;
progname =*argv++;
if (! argv || ! *argv) usage();
new =*argv;
if (new[0] == '.') fatalx(new, ": must not start with a dot.");
if (chdir(SVDIR) == -1) fatal("unable to chdir: ", SVDIR);
if (stat(new, &s) == -1) {
if (errno == error_noent) fatal(new, 0);
fatal("unable to stat: ", new);
}
if (! S_ISDIR(s.st_mode)) fatalx(new, "not a directory.");
ino =s.st_ino;
dev =s.st_dev;
if (stat("current", &s) == -1) fatal("unable to stat: ", "current");
if ((s.st_ino == ino) && (s.st_dev == dev)) {
buffer_puts(buffer_1, "runsvchdir: ");
buffer_puts(buffer_1, new);
buffer_puts(buffer_1, ": current.\n");
buffer_flush(buffer_1);
_exit(0);
}
if (unlink("current.new") == -1)
if (errno != error_noent) fatal("unable to unlink: ", "current.new");
if (symlink(new, "current.new") == -1)
fatal("unable to create: current.new -> ", new);
if (unlink("previous") == -1)
if (errno != error_noent) fatal("unable to unlink: ", "previous");
if (rename("current", "previous") == -1)
fatal("unable to copy: current to ", "previous");
if (rename("current.new", "current") == -1) {
warn("unable to move: current.new to ", "current");
if (rename("previous", "current") == -1)
fatal("unable to move previous back to ", "current");
_exit(111);
}
buffer_puts(buffer_1, "runsvchdir: ");
buffer_puts(buffer_1, new);
buffer_puts(buffer_1, ": now current.\n");
buffer_flush(buffer_1);
_exit(0);
}
admin/runit-2.2.0/src/trysgprm.c 0000644 0000000 0000000 00000000250 14675400254 015270 0 ustar root root /* Public domain. */
#include
int main()
{
sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss,SIGCHLD);
sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
}
admin/runit-2.2.0/src/taia_now.c 0000644 0000000 0000000 00000000441 14675400254 015204 0 ustar root root /* Public domain. */
#include
#include
#include
#include "taia.h"
void taia_now(struct taia *t)
{
struct timeval now;
gettimeofday(&now,(struct timezone *) 0);
tai_unix(&t->sec,now.tv_sec);
t->nano = 1000 * now.tv_usec + 500;
t->atto = 0;
}
admin/runit-2.2.0/src/haswaitp.h2 0000644 0000000 0000000 00000000102 14675400254 015304 0 ustar root root /* Public domain. */
/* sysdep: +waitpid */
#define HASWAITPID 1
admin/runit-2.2.0/src/lock_ex.c 0000644 0000000 0000000 00000000374 14675400254 015034 0 ustar root root /* Public domain. */
#include
#include
#include
#include "hasflock.h"
#include "lock.h"
#ifdef HASFLOCK
int lock_ex(int fd) { return flock(fd,LOCK_EX); }
#else
int lock_ex(int fd) { return lockf(fd,1,0); }
#endif
admin/runit-2.2.0/src/scan.h 0000644 0000000 0000000 00000002605 14675400254 014340 0 ustar root root /* Public domain. */
#ifndef SCAN_H
#define SCAN_H
extern unsigned int scan_uint(const char *,unsigned int *);
extern unsigned int scan_xint(const char *,unsigned int *);
extern unsigned int scan_nbbint(const char *,unsigned int,unsigned int,unsigned int,unsigned int *);
extern unsigned int scan_ushort(const char *,unsigned short *);
extern unsigned int scan_xshort(const char *,unsigned short *);
extern unsigned int scan_nbbshort(const char *,unsigned int,unsigned int,unsigned int,unsigned short *);
extern unsigned int scan_ulong(const char *,unsigned long *);
extern unsigned int scan_xlong(const char *,unsigned long *);
extern unsigned int scan_nbblong(const char *,unsigned int,unsigned int,unsigned int,unsigned long *);
extern unsigned int scan_plusminus(const char *,int *);
extern unsigned int scan_0x(const char *,unsigned int *);
extern unsigned int scan_whitenskip(const char *,unsigned int);
extern unsigned int scan_nonwhitenskip(const char *,unsigned int);
extern unsigned int scan_charsetnskip(const char *,const char *,unsigned int);
extern unsigned int scan_noncharsetnskip(const char *,const char *,unsigned int);
extern unsigned int scan_strncmp(const char *,const char *,unsigned int);
extern unsigned int scan_memcmp(const char *,const char *,unsigned int);
extern unsigned int scan_long(const char *,long *);
extern unsigned int scan_8long(const char *,unsigned long *);
#endif
admin/runit-2.2.0/src/fmt_ulong.c 0000644 0000000 0000000 00000000520 14675400254 015373 0 ustar root root /* Public domain. */
#include "fmt.h"
unsigned int fmt_ulong(register char *s,register unsigned long u)
{
register unsigned int len; register unsigned long q;
len = 1; q = u;
while (q > 9) { ++len; q /= 10; }
if (s) {
s += len;
do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
}
return len;
}
admin/runit-2.2.0/src/seek_set.c 0000644 0000000 0000000 00000000316 14675400254 015206 0 ustar root root /* Public domain. */
#include
#include
#include "seek.h"
#define SET 0 /* sigh */
int seek_set(int fd,seek_pos pos)
{ if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; }
admin/runit-2.2.0/src/runsvctrl.dist 0000644 0000000 0000000 00000000122 14675400254 016162 0 ustar root root usage: runsvctrl u|d|o|p|c|h|a|i|q|1|2|t|k|x|e service ...
1
starting
0
down
0
0
admin/runit-2.2.0/src/open_trunc.c 0000644 0000000 0000000 00000000264 14675400254 015562 0 ustar root root /* Public domain. */
#include
#include
#include "open.h"
int open_trunc(const char *fn)
{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); }
admin/runit-2.2.0/src/wait_pid.c 0000644 0000000 0000000 00000001333 14675400254 015204 0 ustar root root /* Public domain. */
#include
#include
#include "error.h"
#include "haswaitp.h"
#ifdef HASWAITPID
int wait_pid(wstat,pid) int *wstat; int pid;
{
int r;
do
r = waitpid(pid,wstat,0);
while ((r == -1) && (errno == error_intr));
return r;
}
#else
/* XXX untested */
/* XXX breaks down with more than two children */
static int oldpid = 0;
static int oldwstat; /* defined if(oldpid) */
int wait_pid(wstat,pid) int *wstat; int pid;
{
int r;
if (pid == oldpid) { *wstat = oldwstat; oldpid = 0; return pid; }
do {
r = wait(wstat);
if ((r != pid) && (r != -1)) { oldwstat = *wstat; oldpid = r; continue; }
}
while ((r == -1) && (errno == error_intr));
return r;
}
#endif
admin/runit-2.2.0/src/trysocketlib.c 0000644 0000000 0000000 00000000312 14675400254 016116 0 ustar root root #include
#include
#include
#include
#include
int main(void) {
int s;
s =socket(AF_INET, SOCK_STREAM, 0);
return(close(s));
}
admin/runit-2.2.0/src/TARGETS 0000644 0000000 0000000 00000003040 14675400254 014271 0 ustar root root runit
runit.o
runit-init
runit-init.o
runsv
runsv.o
runsvdir
runsvdir.o
runsvstat
runsvstat.o
runsvctrl
runsvctrl.o
sv
sv.o
svwaitdown
svwaitdown.o
svwaitup
svwaitup.o
utmpset
utmpset.o
runsvchdir
runsvchdir.o
svlogd
svlogd.o
chpst
chpst.o
pmatch.o
fmt_ptime.o
uidgid.o
reboot_system.h
uw_tmp.h
socket.lib
trysocketlib
trysocketlib.o
check
alloc.o
alloc_re.o
buffer.o
buffer_0.o
buffer_1.o
buffer_2.o
buffer_get.o
buffer_put.o
buffer_read.o
buffer_write.o
byte.a
byte_chr.o
byte_copy.o
byte_cr.o
byte_diff.o
byte_rchr.o
choose
coe.o
compile
direntry.h
env.o
error.o
error_str.o
fd_copy.o
fd_move.o
fifo.o
fmt_uint.o
fmt_uint0.o
fmt_ulong.o
hasflock.h
hasmkffo.h
hassgact.h
hassgprm.h
hasshsgr.h
haswaitp.h
iopause.h
iopause.o
load
lock_ex.o
lock_exnb.o
makelib
ndelay_off.o
ndelay_on.o
open_append.o
open_read.o
open_trunc.o
open_write.o
openreadclose.o
pathexec_env.o
pathexec_run.o
prot.o
readclose.o
scan_ulong.o
seek_set.o
select.h
sgetopt.o
sig.o
sig_block.o
sig_catch.o
sig_pause.o
str_chr.o
str_diff.o
str_len.o
str_start.o
stralloc_cat.o
stralloc_catb.o
stralloc_cats.o
stralloc_eady.o
stralloc_opyb.o
stralloc_opys.o
stralloc_pend.o
strerr_die.o
strerr_sys.o
subgetopt.o
sysdeps
systype
tai_now.o
tai_pack.o
tai_sub.o
tai_unpack.o
taia_add.o
taia_approx.o
taia_frac.o
taia_less.o
taia_now.o
taia_pack.o
taia_sub.o
taia_uint.o
time.a
uint64.h
unix.a
wait_nohang.o
wait_pid.o
chpst.local
runit-init.local
runit.local
runsv.local
runsvchdir.local
runsvctrl.local
runsvdir.local
runsvstat.local
sv.local
svlogd.local
svwaitdown.local
svwaitup.local
utmpset.local
admin/runit-2.2.0/src/fd_move.c 0000644 0000000 0000000 00000000274 14675400254 015026 0 ustar root root /* Public domain. */
#include
#include "fd.h"
int fd_move(int to,int from)
{
if (to == from) return 0;
if (fd_copy(to,from) == -1) return -1;
close(from);
return 0;
}
admin/runit-2.2.0/src/buffer_read.c 0000644 0000000 0000000 00000000225 14675400254 015647 0 ustar root root /* Public domain. */
#include
#include "buffer.h"
int buffer_unixread(int fd,char *buf,unsigned int len)
{
return read(fd,buf,len);
}
admin/runit-2.2.0/src/ndelay.h 0000644 0000000 0000000 00000000170 14675400254 014663 0 ustar root root /* Public domain. */
#ifndef NDELAY_H
#define NDELAY_H
extern int ndelay_on(int);
extern int ndelay_off(int);
#endif
admin/runit-2.2.0/src/pmatch.c 0000644 0000000 0000000 00000001353 14675400254 014662 0 ustar root root
int pmatch(const char *p, const char *s, unsigned int len) {
for (;;) {
char c =*p++;
if (! c) return(! len);
switch(c) {
case '*':
if (! (c =*p)) return(1);
for (;;) {
if (! len) return(0);
if (*s == c) break;
++s; --len;
}
continue;
case '+':
if ((c =*p++) != *s) return(0);
for (;;) {
if (! len) return(1);
if (*s != c) break;
++s; --len;
}
continue;
/*
case '?':
if (*p == '?') {
if (*s != '?') return(0);
++p;
}
++s; --len;
continue;
*/
default:
if (! len) return(0);
if (*s != c) return(0);
++s; --len;
continue;
}
}
return(0);
}
admin/runit-2.2.0/src/svwaitdown.c 0000644 0000000 0000000 00000011235 14675400254 015613 0 ustar root root #include
#include "strerr.h"
#include "error.h"
#include "sgetopt.h"
#include "scan.h"
#include "open.h"
#include "tai.h"
#include "buffer.h"
#define FATAL "svwaitdown: fatal: "
#define WARN "svwaitdown: warning: "
#define INFO "svwaitdown: "
#define USAGE " [-v] [-t 1..6000] service ..."
#define VERSION "$Id: 6cd3efc2e15e5e3d2fa60cd0c028e60958676ec7 $"
const char *progname;
const char * const *dir;
unsigned int rc =0;
void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
void warn(const char *s1, const char *s2, struct strerr *e) {
dir++; rc++;
strerr_warn3(WARN, s1, s2, e);
}
void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
int main(int argc, const char * const *argv) {
int opt;
unsigned long sec =600;
int verbose =0;
int doexit =0;
int dokill =0;
int wdir;
int fd;
char status[20];
int r;
unsigned long pid;
struct tai start;
struct tai now;
progname =*argv;
while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) {
switch(opt) {
case 't':
scan_ulong(optarg, &sec);
if ((sec < 1) || (sec > 6000)) usage();
break;
case 'x':
doexit =1;
break;
case 'k':
dokill =1;
break;
case 'v':
verbose =1;
break;
case 'V':
strerr_warn1(VERSION, 0);
case '?':
usage();
}
}
argv +=optind;
if (! argv || ! *argv) usage();
if ((wdir =open_read(".")) == -1)
fatal("unable to open current working directory");
for (dir =argv; *dir; ++dir) {
if (dir != argv)
if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
if (chdir(*dir) == -1) continue; /* bummer */
if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */
if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
close(fd); continue; /* bummer */
}
close(fd);
}
dir =argv;
tai_now(&start);
while (*dir) {
if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
if (chdir(*dir) == -1) {
warn(*dir, ": unable to change directory: ", &strerr_sys);
continue;
}
if ((fd =open_write("supervise/ok")) == -1) {
if (errno == error_nodevice) {
if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0);
dir++;
}
else
warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
continue;
}
close(fd);
if ((fd =open_read("supervise/status")) == -1) {
warn(*dir, "unable to open supervise/status: ", &strerr_sys);
continue;
}
r =buffer_unixread(fd, status, 20);
close(fd);
if ((r < 18) || (r == 19)) { /* supervise compatibility */
if (r == -1)
warn(*dir, "unable to read supervise/status: ", &strerr_sys);
else
warn(*dir, ": unable to read supervise/status: bad format.", 0);
continue;
}
pid =(unsigned char)status[15];
pid <<=8; pid +=(unsigned char)status[14];
pid <<=8; pid +=(unsigned char)status[13];
pid <<=8; pid +=(unsigned char)status[12];
if (! doexit && ! pid) {
/* ok, service is down */
if (verbose) strerr_warn3(INFO, *dir, ": down.", 0);
dir++;
continue;
}
if (status[17] != 'd') { /* catch previous failures */
if ((fd =open_write("supervise/control")) == -1) {
warn(*dir, ": unable to open supervise/control: ", &strerr_sys);
continue;
}
if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
warn(*dir, ": unable to write to supervise/control: ", &strerr_sys);
close(fd);
continue;
}
close(fd);
}
tai_now(&now);
tai_sub(&now, &now, &start);
if (tai_approx(&now) >= sec) {
/* timeout */
if (verbose) strerr_warn2(INFO, "timeout.", 0);
if (dokill) {
if (chdir(*dir) == -1) {
warn(*dir, ": unable to change directory: ", &strerr_sys);
continue;
}
if ((fd =open_write("supervise/control")) == -1) {
if (errno == error_nodevice) {
if (verbose)
strerr_warn3(INFO, *dir, ": runsv not running.", 0);
dir++;
}
else
warn(*argv, ": unable to open supervise/control: ", &strerr_sys);
continue;
}
if (write(fd, "k", 1) != 1)
warn(*argv, ": unable to write to supervise/control: ", &strerr_sys);
else
strerr_warn3(INFO, *dir, ": killed.", 0);
close(fd);
dir++;
if (! *dir) _exit(111);
continue;
}
_exit(111);
}
sleep(1);
}
if (fchdir(wdir) == -1)
strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
close(wdir);
if (rc > 100) rc =100;
_exit(rc);
}
admin/runit-2.2.0/src/ndelay_on.c 0000644 0000000 0000000 00000000343 14675400254 015354 0 ustar root root /* Public domain. */
#include
#include
#include "ndelay.h"
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
int ndelay_on(int fd)
{
return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK);
}
admin/runit-2.2.0/src/sig_pause.c 0000644 0000000 0000000 00000000323 14675400254 015361 0 ustar root root /* Public domain. */
#include
#include "sig.h"
#include "hassgprm.h"
void sig_pause(void)
{
#ifdef HASSIGPROCMASK
sigset_t ss;
sigemptyset(&ss);
sigsuspend(&ss);
#else
sigpause(0);
#endif
}
admin/runit-2.2.0/src/uidgid.h 0000644 0000000 0000000 00000000441 14675400254 014655 0 ustar root root #ifndef UIDGID_H
#define UIDGID_H
#include
struct uidgid {
uid_t uid;
gid_t gid[61];
int gids;
};
/* user */
extern unsigned int uidgid_get(struct uidgid *, char *);
/* [:]user[:group[:group]...] */
extern unsigned int uidgids_get(struct uidgid *, char *);
#endif
admin/runit-2.2.0/src/haswaitp.h1 0000644 0000000 0000000 00000000055 14675400254 015312 0 ustar root root /* Public domain. */
/* sysdep: -waitpid */
admin/runit-2.2.0/src/error_str.c 0000644 0000000 0000000 00000012576 14675400254 015440 0 ustar root root /* Public domain. */
#include
#include "error.h"
#define X(e,s) if (i == e) return s;
const char *error_str(int i)
{
X(0,"no error")
X(error_intr,"interrupted system call")
X(error_nomem,"out of memory")
X(error_noent,"file does not exist")
X(error_txtbsy,"text busy")
X(error_io,"input/output error")
X(error_exist,"file already exists")
X(error_timeout,"timed out")
X(error_inprogress,"operation in progress")
X(error_again,"temporary failure")
X(error_wouldblock,"input/output would block")
X(error_pipe,"broken pipe")
X(error_perm,"permission denied")
X(error_acces,"access denied")
X(error_nodevice,"device not configured")
X(error_proto,"protocol error")
X(error_isdir,"is a directory")
X(error_connrefused,"connection refused")
X(error_notdir,"not a directory")
#ifdef ESRCH
X(ESRCH,"no such process")
#endif
#ifdef E2BIG
X(E2BIG,"argument list too long")
#endif
#ifdef ENOEXEC
X(ENOEXEC,"exec format error")
#endif
#ifdef EBADF
X(EBADF,"file descriptor not open")
#endif
#ifdef ECHILD
X(ECHILD,"no child processes")
#endif
#ifdef EDEADLK
X(EDEADLK,"operation would cause deadlock")
#endif
#ifdef EFAULT
X(EFAULT,"bad address")
#endif
#ifdef ENOTBLK
X(ENOTBLK,"not a block device")
#endif
#ifdef EBUSY
X(EBUSY,"device busy")
#endif
#ifdef EXDEV
X(EXDEV,"cross-device link")
#endif
#ifdef ENODEV
X(ENODEV,"device does not support operation")
#endif
#ifdef EINVAL
X(EINVAL,"invalid argument")
#endif
#ifdef ENFILE
X(ENFILE,"system cannot open more files")
#endif
#ifdef EMFILE
X(EMFILE,"process cannot open more files")
#endif
#ifdef ENOTTY
X(ENOTTY,"not a tty")
#endif
#ifdef EFBIG
X(EFBIG,"file too big")
#endif
#ifdef ENOSPC
X(ENOSPC,"out of disk space")
#endif
#ifdef ESPIPE
X(ESPIPE,"unseekable descriptor")
#endif
#ifdef EROFS
X(EROFS,"read-only file system")
#endif
#ifdef EMLINK
X(EMLINK,"too many links")
#endif
#ifdef EDOM
X(EDOM,"input out of range")
#endif
#ifdef ERANGE
X(ERANGE,"output out of range")
#endif
#ifdef EALREADY
X(EALREADY,"operation already in progress")
#endif
#ifdef ENOTSOCK
X(ENOTSOCK,"not a socket")
#endif
#ifdef EDESTADDRREQ
X(EDESTADDRREQ,"destination address required")
#endif
#ifdef EMSGSIZE
X(EMSGSIZE,"message too long")
#endif
#ifdef EPROTOTYPE
X(EPROTOTYPE,"incorrect protocol type")
#endif
#ifdef ENOPROTOOPT
X(ENOPROTOOPT,"protocol not available")
#endif
#ifdef EPROTONOSUPPORT
X(EPROTONOSUPPORT,"protocol not supported")
#endif
#ifdef ESOCKTNOSUPPORT
X(ESOCKTNOSUPPORT,"socket type not supported")
#endif
#ifdef EOPNOTSUPP
X(EOPNOTSUPP,"operation not supported")
#endif
#ifdef EPFNOSUPPORT
X(EPFNOSUPPORT,"protocol family not supported")
#endif
#ifdef EAFNOSUPPORT
X(EAFNOSUPPORT,"address family not supported")
#endif
#ifdef EADDRINUSE
X(EADDRINUSE,"address already used")
#endif
#ifdef EADDRNOTAVAIL
X(EADDRNOTAVAIL,"address not available")
#endif
#ifdef ENETDOWN
X(ENETDOWN,"network down")
#endif
#ifdef ENETUNREACH
X(ENETUNREACH,"network unreachable")
#endif
#ifdef ENETRESET
X(ENETRESET,"network reset")
#endif
#ifdef ECONNABORTED
X(ECONNABORTED,"connection aborted")
#endif
#ifdef ECONNRESET
X(ECONNRESET,"connection reset")
#endif
#ifdef ENOBUFS
X(ENOBUFS,"out of buffer space")
#endif
#ifdef EISCONN
X(EISCONN,"already connected")
#endif
#ifdef ENOTCONN
X(ENOTCONN,"not connected")
#endif
#ifdef ESHUTDOWN
X(ESHUTDOWN,"socket shut down")
#endif
#ifdef ETOOMANYREFS
X(ETOOMANYREFS,"too many references")
#endif
#ifdef ELOOP
X(ELOOP,"symbolic link loop")
#endif
#ifdef ENAMETOOLONG
X(ENAMETOOLONG,"file name too long")
#endif
#ifdef EHOSTDOWN
X(EHOSTDOWN,"host down")
#endif
#ifdef EHOSTUNREACH
X(EHOSTUNREACH,"host unreachable")
#endif
#ifdef ENOTEMPTY
X(ENOTEMPTY,"directory not empty")
#endif
#ifdef EPROCLIM
X(EPROCLIM,"too many processes")
#endif
#ifdef EUSERS
X(EUSERS,"too many users")
#endif
#ifdef EDQUOT
X(EDQUOT,"disk quota exceeded")
#endif
#ifdef ESTALE
X(ESTALE,"stale NFS file handle")
#endif
#ifdef EREMOTE
X(EREMOTE,"too many levels of remote in path")
#endif
#ifdef EBADRPC
X(EBADRPC,"RPC structure is bad")
#endif
#ifdef ERPCMISMATCH
X(ERPCMISMATCH,"RPC version mismatch")
#endif
#ifdef EPROGUNAVAIL
X(EPROGUNAVAIL,"RPC program unavailable")
#endif
#ifdef EPROGMISMATCH
X(EPROGMISMATCH,"program version mismatch")
#endif
#ifdef EPROCUNAVAIL
X(EPROCUNAVAIL,"bad procedure for program")
#endif
#ifdef ENOLCK
X(ENOLCK,"no locks available")
#endif
#ifdef ENOSYS
X(ENOSYS,"system call not available")
#endif
#ifdef EFTYPE
X(EFTYPE,"bad file type")
#endif
#ifdef EAUTH
X(EAUTH,"authentication error")
#endif
#ifdef ENEEDAUTH
X(ENEEDAUTH,"not authenticated")
#endif
#ifdef ENOSTR
X(ENOSTR,"not a stream device")
#endif
#ifdef ETIME
X(ETIME,"timer expired")
#endif
#ifdef ENOSR
X(ENOSR,"out of stream resources")
#endif
#ifdef ENOMSG
X(ENOMSG,"no message of desired type")
#endif
#ifdef EBADMSG
X(EBADMSG,"bad message type")
#endif
#ifdef EIDRM
X(EIDRM,"identifier removed")
#endif
#ifdef ENONET
X(ENONET,"machine not on network")
#endif
#ifdef ERREMOTE
X(ERREMOTE,"object not local")
#endif
#ifdef ENOLINK
X(ENOLINK,"link severed")
#endif
#ifdef EADV
X(EADV,"advertise error")
#endif
#ifdef ESRMNT
X(ESRMNT,"srmount error")
#endif
#ifdef ECOMM
X(ECOMM,"communication error")
#endif
#ifdef EMULTIHOP
X(EMULTIHOP,"multihop attempted")
#endif
#ifdef EREMCHG
X(EREMCHG,"remote address changed")
#endif
return "unknown error";
}
admin/runit-2.2.0/src/stralloc_cat.c 0000644 0000000 0000000 00000000257 14675400254 016062 0 ustar root root /* Public domain. */
#include "byte.h"
#include "stralloc.h"
int stralloc_cat(stralloc *sato,const stralloc *safrom)
{
return stralloc_catb(sato,safrom->s,safrom->len);
}
admin/runit-2.2.0/src/tai_sub.c 0000644 0000000 0000000 00000000206 14675400254 015030 0 ustar root root /* Public domain. */
#include "tai.h"
void tai_sub(struct tai *t,const struct tai *u,const struct tai *v)
{
t->x = u->x - v->x;
}
admin/runit-2.2.0/src/iopause.h1 0000644 0000000 0000000 00000000462 14675400254 015141 0 ustar root root /* Public domain. */
#ifndef IOPAUSE_H
#define IOPAUSE_H
/* sysdep: -poll */
typedef struct {
int fd;
short events;
short revents;
} iopause_fd;
#define IOPAUSE_READ 1
#define IOPAUSE_WRITE 4
#include "taia.h"
extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *);
#endif
admin/runit-2.2.0/src/pmatch.h 0000644 0000000 0000000 00000000161 14675400254 014663 0 ustar root root #ifndef PMATCH_H
#define PMATCH_H
extern unsigned int pmatch(const char *, const char *, unsigned int);
#endif
admin/runit-2.2.0/src/runsvchdir.dist 0000644 0000000 0000000 00000000031 14675400254 016306 0 ustar root root usage: runsvchdir dir
1
admin/runit-2.2.0/src/strerr_die.c 0000644 0000000 0000000 00000001554 14675400254 015553 0 ustar root root /* Public domain. */
#include
#include "buffer.h"
#include "strerr.h"
void strerr_warn(const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se)
{
strerr_sysinit();
if (x1) buffer_puts(buffer_2,x1);
if (x2) buffer_puts(buffer_2,x2);
if (x3) buffer_puts(buffer_2,x3);
if (x4) buffer_puts(buffer_2,x4);
if (x5) buffer_puts(buffer_2,x5);
if (x6) buffer_puts(buffer_2,x6);
while(se) {
if (se->x) buffer_puts(buffer_2,se->x);
if (se->y) buffer_puts(buffer_2,se->y);
if (se->z) buffer_puts(buffer_2,se->z);
se = se->who;
}
buffer_puts(buffer_2,"\n");
buffer_flush(buffer_2);
}
void strerr_die(int e,const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se)
{
strerr_warn(x1,x2,x3,x4,x5,x6,se);
_exit(e);
}
admin/runit-2.2.0/src/trypoll.c 0000644 0000000 0000000 00000000572 14675400254 015115 0 ustar root root /* Public domain. */
#include
#include
#include
#include
int main()
{
struct pollfd x;
x.fd = open("trypoll.c",O_RDONLY);
if (x.fd == -1) _exit(111);
x.events = POLLIN;
if (poll(&x,1,10) == -1) _exit(1);
if (x.revents != POLLIN) _exit(1);
/* XXX: try to detect and avoid poll() imitation libraries */
_exit(0);
}
admin/runit-2.2.0/src/runsv.dist 0000644 0000000 0000000 00000000143 14675400254 015300 0 ustar root root usage: runsv dir
1
starting
run
term
starting
term
0
0
starting
no interrupt
term
0
starting
term
admin/runit-2.2.0/src/iopause.c 0000644 0000000 0000000 00000003214 14675400254 015051 0 ustar root root /* Public domain. */
#include "taia.h"
#include "select.h"
#include "iopause.h"
void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
{
struct taia t;
int millisecs;
double d;
int i;
if (taia_less(deadline,stamp))
millisecs = 0;
else {
t = *stamp;
taia_sub(&t,deadline,&t);
d = taia_approx(&t);
if (d > 1000.0) d = 1000.0;
millisecs = d * 1000.0 + 20.0;
}
for (i = 0;i < len;++i)
x[i].revents = 0;
#ifdef IOPAUSE_POLL
poll(x,len,millisecs);
/* XXX: some kernels apparently need x[0] even if len is 0 */
/* XXX: how to handle EAGAIN? are kernels really this dumb? */
/* XXX: how to handle EINVAL? when exactly can this happen? */
#else
{
struct timeval tv;
fd_set rfds;
fd_set wfds;
int nfds;
int fd;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
nfds = 1;
for (i = 0;i < len;++i) {
fd = x[i].fd;
if (fd < 0) continue;
if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
if (fd >= nfds) nfds = fd + 1;
if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
}
tv.tv_sec = millisecs / 1000;
tv.tv_usec = 1000 * (millisecs % 1000);
if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0)
return;
/* XXX: for EBADF, could seek out and destroy the bad descriptor */
for (i = 0;i < len;++i) {
fd = x[i].fd;
if (fd < 0) continue;
if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
if (x[i].events & IOPAUSE_READ)
if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
if (x[i].events & IOPAUSE_WRITE)
if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
}
}
#endif
}
admin/runit-2.2.0/src/choose.sh 0000644 0000000 0000000 00000000402 14675400254 015050 0 ustar root root
result="$4"
case "$1" in
*c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;;
esac
case "$1" in
*l*) ./load $2 >/dev/null 2>&1 || result="$3" ;;
esac
case "$1" in
*r*) ./$2 >/dev/null 2>&1 || result="$3" ;;
esac
rm -f $2.o $2
exec cat "$result"
admin/runit-2.2.0/src/subgetopt.h 0000644 0000000 0000000 00000001110 14675400254 015416 0 ustar root root /* Public domain. */
#ifndef SUBGETOPT_H
#define SUBGETOPT_H
#ifndef SUBGETOPTNOSHORT
#define sgopt subgetopt
#define sgoptarg subgetoptarg
#define sgoptind subgetoptind
#define sgoptpos subgetoptpos
#define sgoptproblem subgetoptproblem
#define sgoptprogname subgetoptprogname
#define sgoptdone subgetoptdone
#endif
#define SUBGETOPTDONE -1
extern int subgetopt(int,char *const *,const char *);
extern const char *subgetoptarg;
extern int subgetoptind;
extern int subgetoptpos;
extern int subgetoptproblem;
extern const char *subgetoptprogname;
extern int subgetoptdone;
#endif
admin/runit-2.2.0/src/check-local 0000755 0000000 0000000 00000000350 14675400254 015331 0 ustar root root #!/bin/sh
PATH=`pwd`:$PATH
for i in ${1+"$@"}; do
echo "Checking $i..."
env - PATH="$PATH" ctmp="`pwd`/check-tmp" $i.check 2>&1 |cat -v >$i.local
./check-diff $i || ( cat $i.local; echo "$i failed."; exit 1 ) || exit 1
done
admin/runit-2.2.0/src/sv.c 0000644 0000000 0000000 00000027214 14675400254 014042 0 ustar root root #include
#include
#include
#include
#include "str.h"
#include "strerr.h"
#include "error.h"
#include "sgetopt.h"
#include "open.h"
#include "env.h"
#include "buffer.h"
#include "fmt.h"
#include "scan.h"
#include "tai.h"
#include "taia.h"
#include "wait.h"
#define USAGE " [-v] [-w sec] command service ..."
#define USAGELSB " [-w sec] command"
#define VERSION "$Id: bccdf71babe2596029c67cd0f6cec89bd05844a2 $"
#define FATAL "fatal: "
#define FAIL "fail: "
#define WARN "warning: "
#define OK "ok: "
#define RUN "run: "
#define FINISH "finish: "
#define DOWN "down: "
#define TIMEOUT "timeout: "
#define KILL "kill: "
char *progname;
char *action;
char *acts;
char *varservice ="/service/";
char **service;
char **servicex;
unsigned int services;
unsigned int rc =0;
unsigned int lsb;
unsigned int verbose =0;
unsigned long wait =7;
unsigned int kll =0;
unsigned int islog =0;
struct taia tstart, tnow, tdiff;
struct tai tstatus;
int (*act)(char*) =0;
int (*cbk)(char*) =0;
int curdir, fd, r;
char svstatus[20];
char sulong[FMT_ULONG];
void usage() {
if (!lsb) strerr_die4x(100, "usage: ", progname, USAGE, "\n");
strerr_die4x(2, "usage: ", progname, USAGELSB, "\n");
}
void done(unsigned int e) { if (curdir != -1) fchdir(curdir); _exit(e); }
void fatal(char *m1) {
strerr_warn3(FATAL, m1, ": ", &strerr_sys);
done(lsb ? 151 : 100);
}
void fatal2(char *m1, char *m2) {
strerr_warn4(FATAL, m1, m2, ": ", &strerr_sys);
done(lsb ? 151 : 100);
}
void out(char *p, char *m1) {
buffer_puts(buffer_1, p);
buffer_puts(buffer_1, *service);
if (islog) buffer_puts(buffer_1, "/log");
buffer_puts(buffer_1, ": ");
buffer_puts(buffer_1, m1);
if (errno) {
buffer_puts(buffer_1, ": ");
buffer_puts(buffer_1, error_str(errno));
}
buffer_puts(buffer_1, "\n");
buffer_flush(buffer_1);
}
void fail(char *m1) { ++rc; out(FAIL, m1); }
void failx(char *m1) { errno =0; fail(m1); }
void warn(char *m1) { ++rc; out(WARN, m1); }
void warnx(char *m1) { errno =0; warn(m1); }
void ok(char *m1) { errno =0; out(OK, m1); }
void outs(const char *s) { buffer_puts(buffer_1, s); }
void flush(const char *s) { outs(s); buffer_flush(buffer_1); }
void outs2(const char *s) { buffer_puts(buffer_2, s); }
void flush2(const char *s) { outs2(s); buffer_flush(buffer_2); }
int svstatus_get() {
if ((fd =open_write("supervise/ok")) == -1) {
if (errno == error_nodevice) {
*acts == 'x' ? ok("runsv not running") : failx("runsv not running");
return(0);
}
warn("unable to open supervise/ok");
return(-1);
}
close(fd);
if ((fd =open_read("supervise/status")) == -1) {
warn("unable to open supervise/status");
return(-1);
}
r =read(fd, svstatus, 20);
close(fd);
switch(r) {
case 20: break;
case -1: warn("unable to read supervise/status"); return(-1);
default: warnx("unable to read supervise/status: bad format"); return(-1);
}
return(1);
}
unsigned int svstatus_print(char *m) {
int pid;
int normallyup =0;
struct stat s;
if (stat("down", &s) == -1) {
if (errno != error_noent) {
outs2(WARN); outs2("unable to stat "); outs2(*service); outs2("/down: ");
outs2(error_str(errno)); flush2("\n");
return(0);
}
normallyup =1;
}
pid =(unsigned char) svstatus[15];
pid <<=8; pid +=(unsigned char)svstatus[14];
pid <<=8; pid +=(unsigned char)svstatus[13];
pid <<=8; pid +=(unsigned char)svstatus[12];
tai_unpack(svstatus, &tstatus);
switch (svstatus[19]) {
case 0: outs(DOWN); break;
case 1: outs(RUN); break;
case 2: outs(FINISH); break;
}
outs(m); outs(": ");
if (svstatus[19]) {
outs("(pid "); sulong[fmt_ulong(sulong, pid)] =0;
outs(sulong); outs(") ");
}
buffer_put(buffer_1, sulong,
fmt_ulong(sulong, tnow.sec.x < tstatus.x ? 0 : tnow.sec.x -tstatus.x));
outs("s");
if (pid && !normallyup) outs(", normally down");
if (!pid && normallyup) outs(", normally up");
if (pid && svstatus[16]) outs(", paused");
if (!pid && (svstatus[17] == 'u')) outs(", want up");
if (pid && (svstatus[17] == 'd')) outs(", want down");
if (pid && svstatus[18]) outs(", got TERM");
return(pid ? 1 : 2);
}
int status(char *unused) {
int rc;
rc =svstatus_get();
switch(rc) { case -1: if (lsb) done(4); case 0: return(0); }
rc =svstatus_print(*service);
islog =1;
if (chdir("log") == -1) {
if (errno != error_noent) {
outs("; ");
warn("unable to change directory");
}
else outs("\n");
}
else {
outs("; ");
if (svstatus_get()) { rc =svstatus_print("log"); outs("\n"); }
}
islog =0;
flush("");
if (lsb) switch(rc) { case 1: done(0); case 2: done(3); case 0: done(4); }
return(rc);
}
int checkscript() {
char *prog[2];
struct stat s;
int pid, w;
if (stat("check", &s) == -1) {
if (errno == error_noent) return(1);
outs2(WARN); outs2("unable to stat "); outs2(*service); outs2("/check: ");
outs2(error_str(errno)); flush2("\n");
return(0);
}
/* if (!(s.st_mode & S_IXUSR)) return(1); */
if ((pid =fork()) == -1) {
outs2(WARN); outs2("unable to fork for "); outs2(*service);
outs2("/check: "); outs2(error_str(errno)); flush2("\n");
return(0);
}
if (!pid) {
prog[0] ="./check";
prog[1] =0;
close(1);
execve("check", prog, environ);
outs2(WARN); outs2("unable to run "); outs2(*service); outs2("/check: ");
outs2(error_str(errno)); flush2("\n");
_exit(0);
}
while (wait_pid(&w, pid) == -1) {
if (errno == error_intr) continue;
outs2(WARN); outs2("unable to wait for child "); outs2(*service);
outs2("/check: "); outs2(error_str(errno)); flush2("\n");
return(0);
}
return(!wait_exitcode(w));
}
int check(char *a) {
unsigned int pid;
if ((r =svstatus_get()) == -1) return(-1);
while (*a) {
if (r == 0) { if (*a == 'x') return(1); return(-1); }
pid =(unsigned char)svstatus[15];
pid <<=8; pid +=(unsigned char)svstatus[14];
pid <<=8; pid +=(unsigned char)svstatus[13];
pid <<=8; pid +=(unsigned char)svstatus[12];
switch (*a) {
case 'x': return(0);
case 'u':
if (!pid || svstatus[19] != 1) return(0);
if (!checkscript()) return(0);
break;
case 'd': if (pid || svstatus[19] != 0) return(0); break;
case 'C': if (pid) if (!checkscript()) return(0); break;
case 't':
case 'k':
if (!pid && svstatus[17] == 'd') break;
tai_unpack(svstatus, &tstatus);
if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript())
return(0);
break;
case 'o':
tai_unpack(svstatus, &tstatus);
if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd'))
return(0);
break;
case 'p': if (pid && !svstatus[16]) return(0); break;
case 'c': if (pid && svstatus[16]) return(0); break;
}
++a;
}
outs(OK); svstatus_print(*service); flush("\n");
return(1);
}
int control(char *a) {
if (svstatus_get() <= 0) return(-1);
if (svstatus[17] == *a)
if (*a != 'd' || svstatus[18] == 1) return(0); /* once w/o term */
if ((fd =open_write("supervise/control")) == -1) {
if (errno != error_nodevice)
warn("unable to open supervise/control");
else
*a == 'x' ? ok("runsv not running") : failx("runsv not running");
return(-1);
}
r =write(fd, a, str_len(a));
close(fd);
if (r != str_len(a)) {
warn("unable to write to supervise/control");
return(-1);
}
return(1);
}
void sleep_microseconds(unsigned int microseconds) {
#if _POSIX_C_SOURCE >= 199309L
struct timespec sleeptime;
sleeptime.tv_sec = microseconds / 1000000;
sleeptime.tv_nsec = (microseconds % 1000000) * 1000L;
nanosleep(&sleeptime, NULL);
#else
usleep(microseconds);
#endif
}
int main(int argc, char **argv) {
unsigned int i, done;
char *x;
progname =*argv;
for (i =str_len(*argv); i; --i) if ((*argv)[i -1] == '/') break;
*argv +=i;
optprogname =progname =*argv;
service =argv;
services =1;
lsb =(str_diff(progname, "sv"));
if ((x =env_get("SVDIR"))) varservice =x;
if ((x =env_get("SVWAIT"))) scan_ulong(x, &wait);
while ((i =getopt(argc, (char* const*)argv, "w:vV")) != opteof) {
switch(i) {
case 'w': scan_ulong(optarg, &wait);
case 'v': verbose =1; break;
case 'V': strerr_warn1(VERSION, 0);
case '?': usage();
}
}
argv +=optind; argc -=optind;
if (!(action =*argv++)) usage(); --argc;
if (!lsb) { service =argv; services =argc; }
if (!*service) usage();
taia_now(&tnow); tstart =tnow;
if ((curdir =open_read(".")) == -1)
fatal("unable to open current directory");
act =&control; acts ="s";
if (verbose) cbk =✓
switch (*action) {
case 'x': case 'e':
acts ="x"; break;
case 'X': case 'E':
acts ="x"; kll =1; cbk =✓ break;
case 'D':
acts ="d"; kll =1; cbk =✓ break;
case 'T':
acts ="tc"; kll =1; cbk =✓ break;
case 't':
if (!str_diff(action, "try-restart")) { acts ="tc"; cbk =✓ break; }
case 'c':
if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =✓ break; }
case 'u': case 'd': case 'o': case 'p': case 'h':
case 'a': case 'i': case 'k': case 'q': case '1': case '2':
action[1] =0; acts =action; break;
case 's':
if (!str_diff(action, "shutdown")) { acts ="x"; cbk =✓ break; }
if (!str_diff(action, "start")) { acts ="u"; cbk =✓ break; }
if (!str_diff(action, "stop")) { acts ="d"; cbk =✓ break; }
if (lsb && str_diff(action, "status")) usage();
act =&status; cbk =0; break;
case 'r':
if (!str_diff(action, "restart")) { acts ="tcu"; cbk =✓ break; }
if (!str_diff(action, "reload")) { acts ="h"; cbk =✓ break; }
usage();
case 'f':
if (!str_diff(action, "force-reload"))
{ acts ="tc"; kll =1; cbk =✓ break; }
if (!str_diff(action, "force-restart"))
{ acts ="tcu"; kll =1; cbk =✓ break; }
if (!str_diff(action, "force-shutdown"))
{ acts ="x"; kll =1; cbk =✓ break; }
if (!str_diff(action, "force-stop"))
{ acts ="d"; kll =1; cbk =✓ break; }
default:
usage();
}
servicex =service;
for (i =0; i < services; ++i) {
if ((**service != '/') && (**service != '.') && **service &&
((*service)[str_len(*service) -1] != '/')) {
if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
fail("unable to change to service directory");
*service =0;
}
}
else
if (chdir(*service) == -1) {
fail("unable to change to service directory");
*service =0;
}
if (*service) if (act && (act(acts) == -1)) *service =0;
if (fchdir(curdir) == -1) fatal("unable to change to original directory");
service++;
}
if (*cbk)
for (;;) {
taia_sub(&tdiff, &tnow, &tstart);
service =servicex; done =1;
for (i =0; i < services; ++i, ++service) {
if (!*service) continue;
if ((**service != '/') && (**service != '.')) {
if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
fail("unable to change to service directory");
*service =0;
}
}
else
if (chdir(*service) == -1) {
fail("unable to change to service directory");
*service =0;
}
if (*service) { if (cbk(acts) != 0) *service =0; else done =0; }
if (*service && taia_approx(&tdiff) > wait) {
kll ? outs(KILL) : outs(TIMEOUT);
if (svstatus_get() > 0) { svstatus_print(*service); ++rc; }
flush("\n");
if (kll) control("k");
*service =0;
}
if (fchdir(curdir) == -1)
fatal("unable to change to original directory");
}
if (done) break;
sleep_microseconds(420000);
taia_now(&tnow);
}
return(rc > 99 ? 99 : rc);
}
admin/runit-2.2.0/src/fd.h 0000644 0000000 0000000 00000000163 14675400254 014002 0 ustar root root /* Public domain. */
#ifndef FD_H
#define FD_H
extern int fd_copy(int,int);
extern int fd_move(int,int);
#endif
admin/runit-2.2.0/src/print-ar.sh 0000644 0000000 0000000 00000000371 14675400254 015331 0 ustar root root cat warn-auto.sh
echo 'main="$1"; shift'
echo 'rm -f "$main"'
echo 'ar cr "$main" ${1+"$@"}'
case "`cat systype`" in
sunos-5.*) ;;
unix_sv*) ;;
irix64-*) ;;
irix-*) ;;
dgux-*) ;;
hp-ux-*) ;;
sco*) ;;
*) echo 'ranlib "$main"' ;;
esac
admin/runit-2.2.0/src/fmt.h 0000644 0000000 0000000 00000002124 14675400254 014176 0 ustar root root /* Public domain. */
#ifndef FMT_H
#define FMT_H
#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
#define FMT_LEN ((char *) 0) /* convenient abbreviation */
extern unsigned int fmt_uint(char *,unsigned int);
extern unsigned int fmt_uint0(char *,unsigned int,unsigned int);
extern unsigned int fmt_xint(char *,unsigned int);
extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int);
extern unsigned int fmt_ushort(char *,unsigned short);
extern unsigned int fmt_xshort(char *,unsigned short);
extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short);
extern unsigned int fmt_ulong(char *,unsigned long);
extern unsigned int fmt_xlong(char *,unsigned long);
extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long);
extern unsigned int fmt_plusminus(char *,int);
extern unsigned int fmt_minus(char *,int);
extern unsigned int fmt_0x(char *,int);
extern unsigned int fmt_str(char *,const char *);
extern unsigned int fmt_strn(char *,const char *,unsigned int);
#endif
admin/runit-2.2.0/src/strerr_sys.c 0000644 0000000 0000000 00000000332 14675400254 015621 0 ustar root root /* Public domain. */
#include "error.h"
#include "strerr.h"
struct strerr strerr_sys;
void strerr_sysinit(void)
{
strerr_sys.who = 0;
strerr_sys.x = error_str(errno);
strerr_sys.y = "";
strerr_sys.z = "";
}
admin/runit-2.2.0/src/runsvdir.check 0000755 0000000 0000000 00000000033 14675400254 016112 0 ustar root root #!/bin/sh
runsvdir
echo $?
admin/runit-2.2.0/src/runsvdir.dist 0000644 0000000 0000000 00000000034 14675400254 015776 0 ustar root root usage: runsvdir [-P] dir
1
admin/runit-2.2.0/src/env.c 0000644 0000000 0000000 00000000472 14675400254 014177 0 ustar root root /* Public domain. */
#include "str.h"
#include "env.h"
extern /*@null@*/char *env_get(const char *s)
{
int i;
unsigned int len;
if (!s) return 0;
len = str_len(s);
for (i = 0;environ[i];++i)
if (str_start(environ[i],s) && (environ[i][len] == '='))
return environ[i] + len + 1;
return 0;
}
admin/runit-2.2.0/src/subgetopt.c 0000644 0000000 0000000 00000002605 14675400254 015423 0 ustar root root /* Public domain. */
#define SUBGETOPTNOSHORT
#include "subgetopt.h"
#define sgopt subgetopt
#define optind subgetoptind
#define optpos subgetoptpos
#define optarg subgetoptarg
#define optproblem subgetoptproblem
#define optdone subgetoptdone
int optind = 1;
int optpos = 0;
const char *optarg = 0;
int optproblem = 0;
int optdone = SUBGETOPTDONE;
int sgopt(int argc,char *const *argv,const char *opts)
{
int c;
const char *s;
optarg = 0;
if (!argv || (optind >= argc) || !argv[optind]) return optdone;
if (optpos && !argv[optind][optpos]) {
++optind;
optpos = 0;
if ((optind >= argc) || !argv[optind]) return optdone;
}
if (!optpos) {
if (argv[optind][0] != '-') return optdone;
++optpos;
c = argv[optind][1];
if ((c == '-') || (c == 0)) {
if (c) ++optind;
optpos = 0;
return optdone;
}
/* otherwise c is reassigned below */
}
c = argv[optind][optpos];
++optpos;
s = opts;
while (*s) {
if (c == *s) {
if (s[1] == ':') {
optarg = argv[optind] + optpos;
++optind;
optpos = 0;
if (!*optarg) {
optarg = argv[optind];
if ((optind >= argc) || !optarg) { /* argument past end */
optproblem = c;
return '?';
}
++optind;
}
}
return c;
}
++s;
if (*s == ':') ++s;
}
optproblem = c;
return '?';
}
admin/runit-2.2.0/src/chpst.c 0000644 0000000 0000000 00000032401 14675400254 014525 0 ustar root root #include
#include
#include
#include
#include
#include
#include "sgetopt.h"
#include "error.h"
#include "strerr.h"
#include "str.h"
#include "uidgid.h"
#include "strerr.h"
#include "scan.h"
#include "fmt.h"
#include "lock.h"
#include "pathexec.h"
#include "stralloc.h"
#include "byte.h"
#include "open.h"
#include "openreadclose.h"
#include "direntry.h"
#define USAGE_MAIN " [-vVP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-C pwd] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] [-t n] prog"
#define FATAL "chpst: fatal: "
#define WARNING "chpst: warning: "
const char *progname;
static stralloc sa;
void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
void fatal2(const char *m0, const char *m1) {
strerr_die5sys(111, FATAL, m0, ": ", m1, ": ");
}
void fatalx(const char *m0, const char *m1) {
strerr_die4x(111, FATAL, m0, ": ", m1);
}
void warn(const char *m) { strerr_warn2(WARNING, m, 0); }
void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); }
void usage() { strerr_die4x(100, "usage: ", progname, USAGE_MAIN, "\n"); }
char *set_user =0;
char *env_user =0;
char *argv0 =0;
const char *env_dir =0;
unsigned int verbose =0;
unsigned int pgrp =0;
unsigned int nostdin =0;
unsigned int nostdout =0;
unsigned int nostderr =0;
long limitd =-2;
long limits =-2;
long limitl =-2;
long limita =-2;
long limito =-2;
long limitp =-2;
long limitf =-2;
long limitc =-2;
long limitr =-2;
long limitt =-2;
long nicelvl =0;
const char *lock =0;
const char *root =0;
const char *pwd =0;
unsigned int lockdelay;
void suidgid(char *user, unsigned int ext) {
struct uidgid ugid;
if (ext) {
if (! uidgids_get(&ugid, user)) {
if (*user == ':') fatalx("invalid uid/gids", user +1);
if (errno) fatal("unable to get password/group file entry");
fatalx("unknown user/group", user);
}
}
else
if (! uidgid_get(&ugid, user)) {
if (errno) fatal("unable to get password file entry");
fatalx("unknown account", user);
}
if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to setgroups");
if (setgid(*ugid.gid) == -1) fatal("unable to setgid");
if (setuid(ugid.uid) == -1) fatal("unable to setuid");
}
void euidgid(char *user, unsigned int ext) {
struct uidgid ugid;
char bufnum[FMT_ULONG];
if (ext) {
if (! uidgids_get(&ugid, user)) {
if (*user == ':') fatalx("invalid uid/gids", user +1);
if (errno) fatal("unable to get password/group file entry");
fatalx("unknown user/group", user);
}
}
else
if (! uidgid_get(&ugid, user)) {
if (errno) fatal("unable to get password file entry");
fatalx("unknown account", user);
}
bufnum[fmt_ulong(bufnum, *ugid.gid)] =0;
if (! pathexec_env("GID", bufnum)) die_nomem();
bufnum[fmt_ulong(bufnum, ugid.uid)] =0;
if (! pathexec_env("UID", bufnum)) die_nomem();
}
void edir(const char *dirname) {
int wdir;
DIR *dir;
direntry *d;
int i;
if ((wdir =open_read(".")) == -1)
fatal("unable to open current working directory");
if (chdir(dirname)) fatal2("unable to switch to directory", dirname);
if (! (dir =opendir("."))) fatal2("unable to open directory", dirname);
for (;;) {
errno =0;
d =readdir(dir);
if (! d) {
if (errno) fatal2("unable to read directory", dirname);
break;
}
if (d->d_name[0] == '.') continue;
if (openreadclose(d->d_name, &sa, 256) == -1) {
if ((errno == error_isdir) && env_dir) {
if (verbose)
strerr_warn6(WARNING, "unable to read ", dirname, "/",
d->d_name, ": ", &strerr_sys);
continue;
}
else
strerr_die6sys(111, FATAL, "unable to read ", dirname, "/",
d->d_name, ": ");
}
if (sa.len) {
sa.len =byte_chr(sa.s, sa.len, '\n');
while (sa.len && (sa.s[sa.len -1] == ' ' || sa.s[sa.len -1] == '\t'))
--sa.len;
for (i =0; i < sa.len; ++i) if (! sa.s[i]) sa.s[i] ='\n';
if (! stralloc_0(&sa)) die_nomem();
if (! pathexec_env(d->d_name, sa.s)) die_nomem();
}
else
if (! pathexec_env(d->d_name, 0)) die_nomem();
}
closedir(dir);
if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
close(wdir);
}
void slock_die(const char *m, const char *f, unsigned int x) {
if (! x) fatal2(m, f);
_exit(0);
}
void slock(const char *f, unsigned int d, unsigned int x) {
int fd;
if ((fd =open_append(f)) == -1) slock_die("unable to open lock", f, x);
if (d) {
if (lock_ex(fd) == -1) slock_die("unable to lock", f, x);
return;
}
if (lock_exnb(fd) == -1) slock_die("unable to lock", f, x);
}
void limit(int what, long l) {
struct rlimit r;
if (getrlimit(what, &r) == -1) fatal("unable to getrlimit()");
if ((l < 0) || (l > r.rlim_max))
r.rlim_cur =r.rlim_max;
else
r.rlim_cur =l;
if (setrlimit(what, &r) == -1) fatal("unable to setrlimit()");
}
void slimit() {
if (limitd >= -1) {
#ifdef RLIMIT_DATA
limit(RLIMIT_DATA, limitd);
#else
if (verbose) warn("system does not support RLIMIT_DATA");
#endif
}
if (limits >= -1) {
#ifdef RLIMIT_STACK
limit(RLIMIT_STACK, limits);
#else
if (verbose) warn("system does not support RLIMIT_STACK");
#endif
}
if (limitl >= -1) {
#ifdef RLIMIT_MEMLOCK
limit(RLIMIT_MEMLOCK, limitl);
#else
if (verbose) warn("system does not support RLIMIT_MEMLOCK");
#endif
}
if (limita >= -1) {
#ifdef RLIMIT_VMEM
limit(RLIMIT_VMEM, limita);
#else
#ifdef RLIMIT_AS
limit(RLIMIT_AS, limita);
#else
if (verbose)
warn("system does neither support RLIMIT_VMEM nor RLIMIT_AS");
#endif
#endif
}
if (limito >= -1) {
#ifdef RLIMIT_NOFILE
limit(RLIMIT_NOFILE, limito);
#else
#ifdef RLIMIT_OFILE
limit(RLIMIT_OFILE, limito);
#else
if (verbose)
warn("system does neither support RLIMIT_NOFILE nor RLIMIT_OFILE");
#endif
#endif
}
if (limitp >= -1) {
#ifdef RLIMIT_NPROC
limit(RLIMIT_NPROC, limitp);
#else
if (verbose) warn("system does not support RLIMIT_NPROC");
#endif
}
if (limitf >= -1) {
#ifdef RLIMIT_FSIZE
limit(RLIMIT_FSIZE, limitf);
#else
if (verbose) warn("system does not support RLIMIT_FSIZE");
#endif
}
if (limitc >= -1) {
#ifdef RLIMIT_CORE
limit(RLIMIT_CORE, limitc);
#else
if (verbose) warn("system does not support RLIMIT_CORE");
#endif
}
if (limitr >= -1) {
#ifdef RLIMIT_RSS
limit(RLIMIT_RSS, limitr);
#else
if (verbose) warn("system does not support RLIMIT_RSS");
#endif
}
if (limitt >= -1) {
#ifdef RLIMIT_CPU
limit(RLIMIT_CPU, limitt);
#else
if (verbose) warn("system does not support RLIMIT_CPU");
#endif
}
}
/* argv[0] */
void setuidgid(int, char *const *);
void envuidgid(int, char *const *);
void envdir(int, char *const *);
void pgrphack(int, char *const *);
void setlock(int, char *const *);
void softlimit(int, char *const *);
int main(int argc, char **argv) {
int opt;
int i;
unsigned long ul;
progname =argv[0];
for (i =str_len(progname); i; --i)
if (progname[i -1] == '/') {
progname +=i;
break;
}
if (progname[0] == 'd') ++progname;
/* argv[0] */
if (str_equal(progname, "setuidgid")) setuidgid(argc, argv);
if (str_equal(progname, "envuidgid")) envuidgid(argc, argv);
if (str_equal(progname, "envdir")) envdir(argc, argv);
if (str_equal(progname, "pgrphack")) pgrphack(argc, argv);
if (str_equal(progname, "setlock")) setlock(argc, argv);
if (str_equal(progname, "softlimit")) softlimit(argc, argv);
while ((opt =getopt(argc, argv, "u:U:b:e:m:d:o:p:f:c:r:t:/:C:n:l:L:vP012V"))
!= opteof)
switch(opt) {
case 'u': set_user =(char*)optarg; break;
case 'U': env_user =(char*)optarg; break;
case 'b': argv0 =(char*)optarg; break;
case 'e': env_dir =optarg; break;
case 'm':
if (optarg[scan_ulong(optarg, &ul)]) usage();
limits =limitl =limita =limitd =ul;
break;
case 'd': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitd =ul; break;
case 'o': if (optarg[scan_ulong(optarg, &ul)]) usage(); limito =ul; break;
case 'p': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitp =ul; break;
case 'f': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitf =ul; break;
case 'c': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitc =ul; break;
case 'r': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitr =ul; break;
case 't': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitt =ul; break;
case '/': root =optarg; break;
case 'C': pwd =optarg; break;
case 'n':
switch (*optarg) {
case '-':
++optarg;
if (optarg[scan_ulong(optarg, &ul)]) usage(); nicelvl =ul;
nicelvl *=-1;
break;
case '+': ++optarg;
default:
if (optarg[scan_ulong(optarg, &ul)]) usage(); nicelvl =ul;
break;
}
break;
case 'l': if (lock) usage(); lock =optarg; lockdelay =1; break;
case 'L': if (lock) usage(); lock =optarg; lockdelay =0; break;
case 'v': verbose =1; break;
case 'P': pgrp =1; break;
case '0': nostdin =1; break;
case '1': nostdout =1; break;
case '2': nostderr =1; break;
case 'V': strerr_warn1("$Id: e46a05449578fd7b8ee604f3ea6e81cd77d7d6f8 $", 0);
case '?': usage();
}
argv +=optind;
if (! argv || ! *argv) usage();
if (pgrp) setsid();
if (env_dir) edir(env_dir);
if (root) {
if (chdir(root) == -1) fatal2("unable to change directory", root);
if (chroot(".") == -1) fatal("unable to change root directory");
}
if (pwd) {
if (chdir(pwd) == -1) fatal2("unable to change directory", pwd);
}
if (nicelvl) {
errno =0;
if (nice(nicelvl) == -1) if (errno) fatal("unable to set nice level");
}
if (env_user) euidgid(env_user, 1);
if (set_user) suidgid(set_user, 1);
if (lock) slock(lock, lockdelay, 0);
if (nostdin) if (close(0) == -1) fatal("unable to close stdin");
if (nostdout) if (close(1) == -1) fatal("unable to close stdout");
if (nostderr) if (close(2) == -1) fatal("unable to close stderr");
slimit();
progname =*argv;
if (argv0) *argv =argv0;
pathexec_env_run(progname, argv);
fatal2("unable to run", *argv);
return(0);
}
/* argv[0] */
#define USAGE_SETUIDGID " account child"
#define USAGE_ENVUIDGID " account child"
#define USAGE_ENVDIR " dir child"
#define USAGE_PGRPHACK " child"
#define USAGE_SETLOCK " [ -nNxX ] file program [ arg ... ]"
#define USAGE_SOFTLIMIT " [-a allbytes] [-c corebytes] [-d databytes] [-f filebytes] [-l lockbytes] [-m membytes] [-o openfiles] [-p processes] [-r residentbytes] [-s stackbytes] [-t cpusecs] child"
void setuidgid_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_SETUIDGID, "\n");
}
void setuidgid(int argc, char *const *argv) {
const char *account;
if (! (account =*++argv)) setuidgid_usage();
if (! *++argv) setuidgid_usage();
suidgid((char*)account, 0);
pathexec(argv);
fatal2("unable to run", *argv);
}
void envuidgid_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_ENVUIDGID, "\n");
}
void envuidgid(int argc, char *const *argv) {
const char *account;
if (! (account =*++argv)) envuidgid_usage();
if (! *++argv) envuidgid_usage();
euidgid((char*)account, 0);
pathexec(argv);
fatal2("unable to run", *argv);
}
void envdir_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_ENVDIR, "\n");
}
void envdir(int argc, char *const *argv) {
const char *dir;
if (! (dir =*++argv)) envdir_usage();
if (! *++argv) envdir_usage();
edir(dir);
pathexec(argv);
fatal2("unable to run", *argv);
}
void pgrphack_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_PGRPHACK, "\n");
}
void pgrphack(int argc, char *const *argv) {
if (! *++argv) pgrphack_usage();
setsid();
pathexec(argv);
fatal2("unable to run", *argv);
}
void setlock_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_SETLOCK, "\n");
}
void setlock(int argc, char *const *argv) {
int opt;
unsigned int delay =0;
unsigned int x =0;
const char *fn;
while ((opt =getopt(argc, argv, "nNxX")) != opteof)
switch(opt) {
case 'n': delay =1; break;
case 'N': delay =0; break;
case 'x': x =1; break;
case 'X': x =0; break;
default: setlock_usage();
}
argv +=optind;
if (! (fn =*argv)) setlock_usage();
if (! *++argv) setlock_usage();
slock(fn, delay, x);
pathexec(argv);
if (! x) fatal2("unable to run", *argv);
_exit(0);
}
void softlimit_usage() {
strerr_die4x(100, "usage: ", progname, USAGE_SOFTLIMIT, "\n");
}
void getlarg(long *l) {
unsigned long ul;
if (str_equal(optarg, "=")) { *l =-1; return; }
if (optarg[scan_ulong(optarg, &ul)]) usage();
*l =ul;
}
void softlimit(int argc, char *const *argv) {
int opt;
while ((opt =getopt(argc,argv,"a:c:d:f:l:m:o:p:r:s:t:")) != opteof)
switch(opt) {
case '?': softlimit_usage();
case 'a': getlarg(&limita); break;
case 'c': getlarg(&limitc); break;
case 'd': getlarg(&limitd); break;
case 'f': getlarg(&limitf); break;
case 'l': getlarg(&limitl); break;
case 'm': getlarg(&limitd); limits =limitl =limita =limitd; break;
case 'o': getlarg(&limito); break;
case 'p': getlarg(&limitp); break;
case 'r': getlarg(&limitr); break;
case 's': getlarg(&limits); break;
case 't': getlarg(&limitt); break;
}
argv +=optind;
if (!*argv) softlimit_usage();
slimit();
pathexec(argv);
fatal2("unable to run", *argv);
}
admin/runit-2.2.0/src/reboot_system.h1 0000644 0000000 0000000 00000000213 14675400254 016364 0 ustar root root #include
#include
/* sysdep: -std reboot */
int reboot_system(int what) {
return(reboot(what, (char *)0));
}
admin/runit-2.2.0/src/tai_now.c 0000644 0000000 0000000 00000000174 14675400254 015046 0 ustar root root /* Public domain. */
#include
#include "tai.h"
void tai_now(struct tai *t)
{
tai_unix(t,time((time_t *) 0));
}
admin/runit-2.2.0/src/tai_unpack.c 0000644 0000000 0000000 00000000630 14675400254 015521 0 ustar root root /* Public domain. */
#include "tai.h"
void tai_unpack(const char *s,struct tai *t)
{
uint64 x;
x = (unsigned char) s[0];
x <<= 8; x += (unsigned char) s[1];
x <<= 8; x += (unsigned char) s[2];
x <<= 8; x += (unsigned char) s[3];
x <<= 8; x += (unsigned char) s[4];
x <<= 8; x += (unsigned char) s[5];
x <<= 8; x += (unsigned char) s[6];
x <<= 8; x += (unsigned char) s[7];
t->x = x;
}
admin/runit-2.2.0/src/uint64.h1 0000644 0000000 0000000 00000000174 14675400254 014625 0 ustar root root /* Public domain. */
#ifndef UINT64_H
#define UINT64_H
/* sysdep: -ulong64 */
typedef unsigned long long uint64;
#endif
admin/runit-2.2.0/src/conf-cc 0000644 0000000 0000000 00000000261 14675400254 014472 0 ustar root root gcc -O2 -Wall
gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings
This will be used to compile .c files.
admin/runit-2.2.0/src/taia_sub.c 0000644 0000000 0000000 00000000716 14675400254 015177 0 ustar root root /* Public domain. */
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_sub(struct taia *t,const struct taia *u,const struct taia *v)
{
unsigned long unano = u->nano;
unsigned long uatto = u->atto;
t->sec.x = u->sec.x - v->sec.x;
t->nano = unano - v->nano;
t->atto = uatto - v->atto;
if (t->atto > uatto) {
t->atto += 1000000000UL;
--t->nano;
}
if (t->nano > unano) {
t->nano += 1000000000UL;
--t->sec.x;
}
}
admin/runit-2.2.0/src/svwaitdown.check 0000755 0000000 0000000 00000000626 14675400254 016453 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
svwaitdown
echo $?
svwaitdown -V
echo $?
mkdir "${ctmp}"
echo '#!/bin/sh' >"${ctmp}"/run
echo 'echo starting' >>"${ctmp}"/run
echo 'exec sleep 14' >>"${ctmp}"/run
chmod 700 "${ctmp}"/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
svwaitdown "${ctmp}"
echo $?
svwaitdown -x "${ctmp}"
echo $?
cat "${ctmp}"/supervise/stat
wait
echo $?
rm -rf "${ctmp}"
admin/runit-2.2.0/src/strerr.h 0000644 0000000 0000000 00000005322 14675400254 014734 0 ustar root root /* Public domain. */
#ifndef STRERR_H
#define STRERR_H
struct strerr {
struct strerr *who;
const char *x;
const char *y;
const char *z;
} ;
extern struct strerr strerr_sys;
extern void strerr_sysinit(void);
extern const char *strerr(const struct strerr *);
extern void strerr_warn(const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *);
extern void strerr_die(int,const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *);
#define STRERR(r,se,a) \
{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; }
#define STRERR_SYS(r,se,a) \
{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; }
#define STRERR_SYS3(r,se,a,b,c) \
{ se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; }
#define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \
strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se))
#define strerr_warn5(x1,x2,x3,x4,x5,se) \
strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se))
#define strerr_warn4(x1,x2,x3,x4,se) \
strerr_warn((x1),(x2),(x3),(x4),0,0,(se))
#define strerr_warn3(x1,x2,x3,se) \
strerr_warn((x1),(x2),(x3),0,0,0,(se))
#define strerr_warn2(x1,x2,se) \
strerr_warn((x1),(x2),0,0,0,0,(se))
#define strerr_warn1(x1,se) \
strerr_warn((x1),0,0,0,0,0,(se))
#define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se))
#define strerr_die5(e,x1,x2,x3,x4,x5,se) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se))
#define strerr_die4(e,x1,x2,x3,x4,se) \
strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se))
#define strerr_die3(e,x1,x2,x3,se) \
strerr_die((e),(x1),(x2),(x3),0,0,0,(se))
#define strerr_die2(e,x1,x2,se) \
strerr_die((e),(x1),(x2),0,0,0,0,(se))
#define strerr_die1(e,x1,se) \
strerr_die((e),(x1),0,0,0,0,0,(se))
#define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys)
#define strerr_die5sys(e,x1,x2,x3,x4,x5) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys)
#define strerr_die4sys(e,x1,x2,x3,x4) \
strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys)
#define strerr_die3sys(e,x1,x2,x3) \
strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys)
#define strerr_die2sys(e,x1,x2) \
strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys)
#define strerr_die1sys(e,x1) \
strerr_die((e),(x1),0,0,0,0,0,&strerr_sys)
#define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0)
#define strerr_die5x(e,x1,x2,x3,x4,x5) \
strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0)
#define strerr_die4x(e,x1,x2,x3,x4) \
strerr_die((e),(x1),(x2),(x3),(x4),0,0,0)
#define strerr_die3x(e,x1,x2,x3) \
strerr_die((e),(x1),(x2),(x3),0,0,0,0)
#define strerr_die2x(e,x1,x2) \
strerr_die((e),(x1),(x2),0,0,0,0,0)
#define strerr_die1x(e,x1) \
strerr_die((e),(x1),0,0,0,0,0,0)
#endif
admin/runit-2.2.0/src/lock_exnb.c 0000644 0000000 0000000 00000000412 14675400254 015345 0 ustar root root /* Public domain. */
#include
#include
#include
#include "hasflock.h"
#include "lock.h"
#ifdef HASFLOCK
int lock_exnb(int fd) { return flock(fd,LOCK_EX | LOCK_NB); }
#else
int lock_exnb(int fd) { return lockf(fd,2,0); }
#endif
admin/runit-2.2.0/src/str.h 0000644 0000000 0000000 00000000704 14675400254 014222 0 ustar root root /* Public domain. */
#ifndef STR_H
#define STR_H
extern unsigned int str_copy(char *,const char *);
extern int str_diff(const char *,const char *);
extern int str_diffn(const char *,const char *,unsigned int);
extern unsigned int str_len(const char *);
extern unsigned int str_chr(const char *,int);
extern unsigned int str_rchr(const char *,int);
extern int str_start(const char *,const char *);
#define str_equal(s,t) (!str_diff((s),(t)))
#endif
admin/runit-2.2.0/src/error.c 0000644 0000000 0000000 00000002321 14675400254 014533 0 ustar root root /* Public domain. */
#include
#include "error.h"
/* warning: as coverage improves here, should update error_{str,temp} */
int error_intr =
#ifdef EINTR
EINTR;
#else
-1;
#endif
int error_nomem =
#ifdef ENOMEM
ENOMEM;
#else
-2;
#endif
int error_noent =
#ifdef ENOENT
ENOENT;
#else
-3;
#endif
int error_txtbsy =
#ifdef ETXTBSY
ETXTBSY;
#else
-4;
#endif
int error_io =
#ifdef EIO
EIO;
#else
-5;
#endif
int error_exist =
#ifdef EEXIST
EEXIST;
#else
-6;
#endif
int error_timeout =
#ifdef ETIMEDOUT
ETIMEDOUT;
#else
-7;
#endif
int error_inprogress =
#ifdef EINPROGRESS
EINPROGRESS;
#else
-8;
#endif
int error_wouldblock =
#ifdef EWOULDBLOCK
EWOULDBLOCK;
#else
-9;
#endif
int error_again =
#ifdef EAGAIN
EAGAIN;
#else
-10;
#endif
int error_pipe =
#ifdef EPIPE
EPIPE;
#else
-11;
#endif
int error_perm =
#ifdef EPERM
EPERM;
#else
-12;
#endif
int error_acces =
#ifdef EACCES
EACCES;
#else
-13;
#endif
int error_nodevice =
#ifdef ENXIO
ENXIO;
#else
-14;
#endif
int error_proto =
#ifdef EPROTO
EPROTO;
#else
-15;
#endif
int error_isdir =
#ifdef EISDIR
EISDIR;
#else
-16;
#endif
int error_connrefused =
#ifdef ECONNREFUSED
ECONNREFUSED;
#else
-17;
#endif
int error_notdir =
#ifdef ENOTDIR
ENOTDIR;
#else
-18;
#endif
admin/runit-2.2.0/src/svwaitup.check 0000755 0000000 0000000 00000000755 14675400254 016133 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
svwaitup
echo $?
svwaitup -V
echo $?
mkdir "${ctmp}"
echo '#!/bin/sh' >"${ctmp}"/run
echo 'echo starting' >>"${ctmp}"/run
echo 'exec sleep 14' >>"${ctmp}"/run
chmod 700 "${ctmp}"/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
svwaitup "${ctmp}"
echo $?
cat "${ctmp}"/supervise/stat
svwaitup -s2 "${ctmp}"
echo $?
cat "${ctmp}"/supervise/stat
runsvctrl exit "${ctmp}"
wait
echo $?
chpst -2 svwaitup -s2 "${ctmp}"
echo $?
rm -rf "${ctmp}"
admin/runit-2.2.0/src/str_start.c 0000644 0000000 0000000 00000000562 14675400254 015434 0 ustar root root /* Public domain. */
#include "str.h"
int str_start(register const char *s,register const char *t)
{
register char x;
for (;;) {
x = *t++; if (!x) return 1; if (x != *s++) return 0;
x = *t++; if (!x) return 1; if (x != *s++) return 0;
x = *t++; if (!x) return 1; if (x != *s++) return 0;
x = *t++; if (!x) return 1; if (x != *s++) return 0;
}
}
admin/runit-2.2.0/src/trysgact.c 0000644 0000000 0000000 00000000300 14675400254 015235 0 ustar root root /* Public domain. */
#include
int main()
{
struct sigaction sa;
sa.sa_handler = 0;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(0,&sa,(struct sigaction *) 0);
}
admin/runit-2.2.0/src/svwaitup.dist 0000644 0000000 0000000 00000000176 14675400254 016013 0 ustar root root usage: svwaitup [-v] [-s 1..600] service ...
1
$Id$
usage: svwaitup [-v] [-s 1..600] service ...
1
starting
0
run
0
run
0
1
admin/runit-2.2.0/src/fmt_uint.c 0000644 0000000 0000000 00000000205 14675400254 015226 0 ustar root root /* Public domain. */
#include "fmt.h"
unsigned int fmt_uint(register char *s,register unsigned int u)
{
return fmt_ulong(s,u);
}
admin/runit-2.2.0/src/hasflock.h2 0000644 0000000 0000000 00000000076 14675400254 015270 0 ustar root root /* Public domain. */
/* sysdep: +flock */
#define HASFLOCK 1
admin/runit-2.2.0/src/readclose.h 0000644 0000000 0000000 00000000313 14675400254 015347 0 ustar root root /* Public domain. */
#ifndef READCLOSE_H
#define READCLOSE_H
#include "stralloc.h"
extern int readclose_append(int,stralloc *,unsigned int);
extern int readclose(int,stralloc *,unsigned int);
#endif
admin/runit-2.2.0/src/runsvctrl.c 0000644 0000000 0000000 00000003421 14675400254 015446 0 ustar root root #include
#include "strerr.h"
#include "error.h"
#include "open.h"
#define USAGE " u|d|o|p|c|h|a|i|q|1|2|t|k|x|e service ..."
#define VERSION "$Id: ccf8fc8ee3c340d8de97b5ddd9270b55e0f437cb $"
#define FATAL "runsvctrl: fatal: "
#define WARNING "runsvctrl: warning: "
char *progname;
unsigned int rc =0;
void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
void fatal(char *m1) { strerr_die3sys(111, FATAL, m1, ": "); }
void warn(char *m1, char *m2) {
rc++;
strerr_warn5(WARNING, m1, ": ", m2, ": ", &strerr_sys);
}
void warnx(char *m1, char *m2) {
rc++;
strerr_warn4(WARNING, m1, ": ", m2, 0);
}
int ctrl(char *name, char c) {
int fd;
if ((fd =open_write("supervise/control")) == -1) {
if (errno == error_nodevice)
warnx(name, "runsv not running.");
else
warn(name, "unable to open supervise/control");
return(-1);
}
if (write(fd, &c, 1) != 1) {
warn(name, "unable to write to supervise/control");
return(-1);
}
return(1);
}
int main(int argc, char **argv) {
char **dir;
int curdir;
char c;
progname =*argv++;
if (! argv || ! *argv) usage();
switch ((c =**argv)) {
case 'e': c ='x';
case 'u': case 'd': case 'o': case 'x': case 'p': case 'c': case 'h':
case 'a': case 'i': case 't': case 'k': case 'q': case '1': case '2':
break;
default:
usage();
}
dir =++argv;
if (! dir || ! *dir) usage();
if ((curdir =open_read(".")) == -1) {
rc =100;
fatal("unable to open current directory");
}
for (; dir && *dir; dir++) {
if (chdir(*dir) == -1) {
warn(*dir, "unable to change directory");
continue;
}
ctrl(*dir, c);
if (fchdir(curdir) == -1) {
rc =100;
fatal("unable to change directory");
}
}
if (rc > 100) rc =100;
_exit(rc);
}
admin/runit-2.2.0/src/tryulong64.c 0000644 0000000 0000000 00000000576 14675400254 015451 0 ustar root root /* Public domain. */
#include
int main()
{
unsigned long u;
u = 1;
u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
if (!u) _exit(1);
_exit(0);
}
admin/runit-2.2.0/src/buffer_2.c 0000644 0000000 0000000 00000000266 14675400254 015102 0 ustar root root /* Public domain. */
#include "buffer.h"
char buffer_2_space[256];
static buffer it = BUFFER_INIT(buffer_unixwrite,2,buffer_2_space,sizeof buffer_2_space);
buffer *buffer_2 = ⁢
admin/runit-2.2.0/src/check-dist 0000755 0000000 0000000 00000000265 14675400254 015207 0 ustar root root #!/bin/sh
PATH=`pwd`:$PATH
for i in `cat ../package/commands`; do
echo "Creating new $i.dist..."
env - PATH="$PATH" ctmp="`pwd`/check-tmp" $i.check 2>&1 |cat -v >$i.dist
done
admin/runit-2.2.0/src/coe.h 0000644 0000000 0000000 00000000120 14675400254 014150 0 ustar root root /* Public domain. */
#ifndef COE_H
#define COE_H
extern int coe(int);
#endif
admin/runit-2.2.0/src/tai.h 0000644 0000000 0000000 00000001162 14675400254 014166 0 ustar root root /* Public domain. */
#ifndef TAI_H
#define TAI_H
#include "uint64.h"
struct tai {
uint64 x;
} ;
#define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u)))
extern void tai_now(struct tai *);
#define tai_approx(t) ((double) ((t)->x))
extern void tai_add(struct tai *,const struct tai *,const struct tai *);
extern void tai_sub(struct tai *,const struct tai *,const struct tai *);
#define tai_less(t,u) ((t)->x < (u)->x)
#define TAI_PACK 8
extern void tai_pack(char *,const struct tai *);
extern void tai_unpack(const char *,struct tai *);
extern void tai_uint(struct tai *,unsigned int);
#endif
admin/runit-2.2.0/src/stralloc.h 0000644 0000000 0000000 00000002227 14675400254 015237 0 ustar root root /* Public domain. */
#ifndef STRALLOC_H
#define STRALLOC_H
#include "gen_alloc.h"
GEN_ALLOC_typedef(stralloc,char,s,len,a)
extern int stralloc_ready(stralloc *,unsigned int);
extern int stralloc_readyplus(stralloc *,unsigned int);
extern int stralloc_copy(stralloc *,const stralloc *);
extern int stralloc_cat(stralloc *,const stralloc *);
extern int stralloc_copys(stralloc *,const char *);
extern int stralloc_cats(stralloc *,const char *);
extern int stralloc_copyb(stralloc *,const char *,unsigned int);
extern int stralloc_catb(stralloc *,const char *,unsigned int);
extern int stralloc_append(stralloc *,const char *); /* beware: this takes a pointer to 1 char */
extern int stralloc_starts(stralloc *,const char *);
#define stralloc_0(sa) stralloc_append(sa,"")
extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int);
extern int stralloc_catlong0(stralloc *,long,unsigned int);
#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n)))
#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n)))
#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0))
#endif
admin/runit-2.2.0/src/env.h 0000644 0000000 0000000 00000000201 14675400254 014172 0 ustar root root /* Public domain. */
#ifndef ENV_H
#define ENV_H
extern char **environ;
extern /*@null@*/char *env_get(const char *);
#endif
admin/runit-2.2.0/src/trydrent.c 0000644 0000000 0000000 00000000161 14675400254 015255 0 ustar root root /* Public domain. */
#include
#include
void foo()
{
DIR *dir;
struct dirent *d;
}
admin/runit-2.2.0/src/open_append.c 0000644 0000000 0000000 00000000266 14675400254 015700 0 ustar root root /* Public domain. */
#include
#include
#include "open.h"
int open_append(const char *fn)
{ return open(fn,O_WRONLY | O_NDELAY | O_APPEND | O_CREAT,0600); }
admin/runit-2.2.0/src/sgetopt.c 0000644 0000000 0000000 00000002417 14675400254 015075 0 ustar root root /* Public domain. */
/* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer
D. J. Bernstein, djb@pobox.com.
Depends on subgetopt.h, buffer.h.
No system requirements.
19991219: Switched to buffer.h.
19970208: Cleanups.
931201: Baseline.
No known patent problems.
Documentation in sgetopt.3.
*/
#include "buffer.h"
#define SGETOPTNOSHORT
#include "sgetopt.h"
#define SUBGETOPTNOSHORT
#include "subgetopt.h"
#define getopt sgetoptmine
#define optind subgetoptind
#define opterr sgetopterr
#define optproblem subgetoptproblem
#define optprogname sgetoptprogname
int opterr = 1;
const char *optprogname = 0;
int getopt(int argc,char *const *argv,const char *opts)
{
int c;
const char *s;
if (!optprogname) {
optprogname = *argv;
if (!optprogname) optprogname = "";
for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1;
}
c = subgetopt(argc,argv,opts);
if (opterr)
if (c == '?') {
char chp[2]; chp[0] = optproblem; chp[1] = '\n';
buffer_puts(buffer_2,optprogname);
if (argv[optind] && (optind < argc))
buffer_puts(buffer_2,": illegal option -- ");
else
buffer_puts(buffer_2,": option requires an argument -- ");
buffer_put(buffer_2,chp,2);
buffer_flush(buffer_2);
}
return c;
}
admin/runit-2.2.0/src/error.h 0000644 0000000 0000000 00000001250 14675400254 014540 0 ustar root root /* Public domain. */
#ifndef ERROR_H
#define ERROR_H
/* 20030124: include -upcoming glibc changes */
#include
/* extern int errno; */
extern int error_intr;
extern int error_nomem;
extern int error_noent;
extern int error_txtbsy;
extern int error_io;
extern int error_exist;
extern int error_timeout;
extern int error_inprogress;
extern int error_wouldblock;
extern int error_again;
extern int error_pipe;
extern int error_perm;
extern int error_acces;
extern int error_nodevice;
extern int error_proto;
extern int error_isdir;
extern int error_connrefused;
extern int error_notdir;
extern const char *error_str(int);
extern int error_temp(int);
#endif
admin/runit-2.2.0/src/runsvchdir.check 0000755 0000000 0000000 00000000035 14675400254 016427 0 ustar root root #!/bin/sh
runsvchdir
echo $?
admin/runit-2.2.0/src/hassgprm.h2 0000644 0000000 0000000 00000000112 14675400254 015311 0 ustar root root /* Public domain. */
/* sysdep: +sigprocmask */
#define HASSIGPROCMASK 1
admin/runit-2.2.0/src/tryuwtmpx.c 0000644 0000000 0000000 00000000165 14675400254 015511 0 ustar root root #include
#include
struct futmpx ut;
int main(void) {
char *s =ut.ut_name;
return(0);
}
admin/runit-2.2.0/src/str_diff.c 0000644 0000000 0000000 00000000723 14675400254 015206 0 ustar root root /* Public domain. */
#include "str.h"
int str_diff(register const char *s,register const char *t)
{
register char x;
for (;;) {
x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
}
return ((int)(unsigned int)(unsigned char) x)
- ((int)(unsigned int)(unsigned char) *t);
}
admin/runit-2.2.0/src/sig_catch.c 0000644 0000000 0000000 00000000553 14675400254 015333 0 ustar root root /* Public domain. */
#include
#include "sig.h"
#include "hassgact.h"
void sig_catch(int sig,void (*f)())
{
#ifdef HASSIGACTION
struct sigaction sa;
sa.sa_handler = f;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(sig,&sa,(struct sigaction *) 0);
#else
signal(sig,f); /* won't work under System V, even nowadays---dorks */
#endif
}
admin/runit-2.2.0/src/stralloc_opyb.c 0000644 0000000 0000000 00000000421 14675400254 016255 0 ustar root root /* Public domain. */
#include "stralloc.h"
#include "byte.h"
int stralloc_copyb(stralloc *sa,const char *s,unsigned int n)
{
if (!stralloc_ready(sa,n + 1)) return 0;
byte_copy(sa->s,n,s);
sa->len = n;
sa->s[n] = 'Z'; /* ``offensive programming'' */
return 1;
}
admin/runit-2.2.0/src/uint64.h2 0000644 0000000 0000000 00000000167 14675400254 014630 0 ustar root root /* Public domain. */
#ifndef UINT64_H
#define UINT64_H
/* sysdep: +ulong64 */
typedef unsigned long uint64;
#endif
admin/runit-2.2.0/src/uidgid.c 0000644 0000000 0000000 00000003011 14675400254 014644 0 ustar root root #include
#include
#include
#include "uidgid.h"
#include "str.h"
#include "scan.h"
/* user */
unsigned int uidgid_get(struct uidgid *u, char *ug) {
struct passwd *pwd =0;
if (! (pwd =getpwnam(ug))) return(0);
u->gid[0] =pwd->pw_gid; u->gids =1;
u->uid =pwd->pw_uid;
return(1);
}
/* uid:gid[:gid[:gid]...] */
unsigned int uidgids_set(struct uidgid *u, char *ug) {
unsigned long id;
int i;
if (*(ug +=scan_ulong(ug, &id)) != ':') return(0);
u->uid =(uid_t)id;
++ug;
for (i =0; i < 60; ++i, ++ug) {
ug +=scan_ulong(ug, &id);
u->gid[i] =(gid_t)id;
if (*ug != ':') { ++i; break; }
}
u->gid[i] =0;
u->gids =i;
if (*ug) return(0);
return(1);
}
/* [:]user[:group[:group]...] */
unsigned int uidgids_get(struct uidgid *u, char *ug) {
char *g =0;
struct passwd *pwd =0;
struct group *gr =0;
int i, d =0;
if (*ug == ':') return(uidgids_set(u, ug +1));
if (ug[(d =str_chr(ug, ':'))] == ':') {
ug[d] =0;
g =ug +d +1;
}
if (! (pwd =getpwnam(ug))) { if (g) ug[d] =':'; return(0); }
u->uid =pwd->pw_uid;
if (! g) {
u->gid[0] =pwd->pw_gid;
u->gids =1;
return(1);
}
ug[d] =':';
for (i =0; i < 60; ++i) {
if (g[(d =str_chr(g, ':'))] == ':') {
g[d] =0;
if (! (gr =getgrnam(g))) { g[d] =':'; return(0); }
g[d] =':';
u->gid[i] =gr->gr_gid;
g +=d +1;
}
else {
if (! (gr =getgrnam(g))) return(0);
u->gid[i++] =gr->gr_gid;
break;
}
}
u->gid[i] =0;
u->gids =i;
return(1);
}
admin/runit-2.2.0/src/fmt_ptime.h 0000644 0000000 0000000 00000000453 14675400254 015377 0 ustar root root #ifndef FMT_PTIME_H
#define FMT_PTIME_H
#define FMT_PTIME 30
#include
#include
#include "taia.h"
extern unsigned int fmt_ptime(char *, struct taia *);
extern unsigned int fmt_ptime_iso8601(char *, struct taia *);
extern unsigned int fmt_taia(char *, struct taia *);
#endif
admin/runit-2.2.0/src/open_write.c 0000644 0000000 0000000 00000000233 14675400254 015555 0 ustar root root /* Public domain. */
#include
#include
#include "open.h"
int open_write(const char *fn)
{ return open(fn,O_WRONLY | O_NDELAY); }
admin/runit-2.2.0/src/direntry.h1 0000644 0000000 0000000 00000000247 14675400254 015335 0 ustar root root /* Public domain. */
#ifndef DIRENTRY_H
#define DIRENTRY_H
/* sysdep: -dirent */
#include
#include
#define direntry struct direct
#endif
admin/runit-2.2.0/src/pathexec.h 0000644 0000000 0000000 00000000441 14675400254 015211 0 ustar root root /* Public domain. */
#ifndef PATHEXEC_H
#define PATHEXEC_H
extern void pathexec_run(const char *,char * const *,char * const *);
extern int pathexec_env(const char *,const char *);
extern void pathexec_env_run(const char *, char * const *);
extern void pathexec(char * const *);
#endif
admin/runit-2.2.0/src/sig.c 0000644 0000000 0000000 00000000465 14675400254 014173 0 ustar root root /* Public domain. */
#include
#include "sig.h"
int sig_alarm = SIGALRM;
int sig_child = SIGCHLD;
int sig_cont = SIGCONT;
int sig_hangup = SIGHUP;
int sig_int = SIGINT;
int sig_pipe = SIGPIPE;
int sig_term = SIGTERM;
void (*sig_defaulthandler)() = SIG_DFL;
void (*sig_ignorehandler)() = SIG_IGN;
admin/runit-2.2.0/src/iopause.h2 0000644 0000000 0000000 00000000523 14675400254 015140 0 ustar root root /* Public domain. */
#ifndef IOPAUSE_H
#define IOPAUSE_H
/* sysdep: +poll */
#define IOPAUSE_POLL
#include
#include
typedef struct pollfd iopause_fd;
#define IOPAUSE_READ POLLIN
#define IOPAUSE_WRITE POLLOUT
#include "taia.h"
extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *);
#endif
admin/runit-2.2.0/src/buffer_1.c 0000644 0000000 0000000 00000000301 14675400254 015067 0 ustar root root /* Public domain. */
#include "buffer.h"
char buffer_1_space[BUFFER_OUTSIZE];
static buffer it = BUFFER_INIT(buffer_unixwrite,1,buffer_1_space,sizeof buffer_1_space);
buffer *buffer_1 = ⁢
admin/runit-2.2.0/src/coe.c 0000644 0000000 0000000 00000000155 14675400254 014153 0 ustar root root /* Public domain. */
#include
#include "coe.h"
int coe(int fd)
{
return fcntl(fd,F_SETFD,1);
}
admin/runit-2.2.0/src/x86cpuid.c 0000644 0000000 0000000 00000001320 14675400254 015052 0 ustar root root /* Public domain. */
#include
#include
#include
void nope()
{
exit(1);
}
int main()
{
unsigned long x[4];
unsigned long y[4];
int i;
int j;
char c;
signal(SIGILL,nope);
x[0] = y[0] = 0;
x[1] = y[1] = 0;
x[2] = y[2] = 0;
x[3] = y[3] = 0;
asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) );
if (!x[0]) return 0;
asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) );
for (i = 1;i < 4;++i)
for (j = 0;j < 4;++j) {
c = x[i] >> (8 * j);
if (c < 32) c = 32;
if (c > 126) c = 126;
putchar(c);
}
printf("-%08lx-%08lx\n",y[0],y[3]);
return 0;
}
admin/runit-2.2.0/src/chpst.dist 0000644 0000000 0000000 00000000651 14675400254 015250 0 ustar root root usage: chpst [-vVP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-C pwd] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] [-t n] prog
100
$Id: e46a05449578fd7b8ee604f3ea6e81cd77d7d6f8 $
usage: chpst [-vVP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-C pwd] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] [-t n] prog
100
test=1
0
0
0
0
0
admin/runit-2.2.0/src/runsvdir.c 0000644 0000000 0000000 00000014612 14675400254 015264 0 ustar root root #include
#include
#include
#include
#include "direntry.h"
#include "strerr.h"
#include "error.h"
#include "wait.h"
#include "env.h"
#include "open.h"
#include "pathexec.h"
#include "fd.h"
#include "str.h"
#include "coe.h"
#include "iopause.h"
#include "sig.h"
#include "ndelay.h"
#define USAGE " [-P] dir"
#define VERSION "$Id: 28cb04495cffccf27650de3cf2981942679781cd $"
#define MAXSERVICES 1000
char *progname;
char *svdir;
unsigned long dev =0;
unsigned long ino =0;
struct {
unsigned long dev;
unsigned long ino;
int pid;
int isgone;
} sv[MAXSERVICES];
int svnum =0;
int check =1;
char *rplog =0;
int rploglen;
int logpipe[2];
iopause_fd io[1];
struct taia stamplog;
int exitsoon =0;
int pgrp =0;
void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
void fatal(char *m1, char *m2) {
strerr_die6sys(100, "runsvdir ", svdir, ": fatal: ", m1, m2, ": ");
}
void warn(char *m1, char *m2) {
strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, ": ", &strerr_sys);
}
void warn3x(char *m1, char *m2, char *m3) {
strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, m3, 0);
}
void s_term() { exitsoon =1; }
void s_hangup() { exitsoon =2; }
void runsv(int no, char *name) {
int pid;
if ((pid =fork()) == -1) {
warn("unable to fork for ", name);
return;
}
if (pid == 0) {
/* child */
char *prog[3];
prog[0] ="runsv";
prog[1] =name;
prog[2] =0;
sig_uncatch(sig_hangup);
sig_uncatch(sig_term);
if (pgrp) setsid();
pathexec_run(*prog, prog, (char* const*)environ);
fatal("unable to start runsv ", name);
}
sv[no].pid =pid;
}
void runsvdir() {
DIR *dir;
direntry *d;
int i;
struct stat s;
if (! (dir =opendir("."))) {
warn("unable to open directory ", svdir);
return;
}
for (i =0; i < svnum; i++) sv[i].isgone =1;
errno =0;
while ((d =readdir(dir))) {
if (d->d_name[0] == '.') continue;
if (stat(d->d_name, &s) == -1) {
warn("unable to stat ", d->d_name);
errno =0;
continue;
}
if (! S_ISDIR(s.st_mode)) continue;
for (i =0; i < svnum; i++) {
if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
sv[i].isgone =0;
if (! sv[i].pid) runsv(i, d->d_name);
break;
}
}
if (i == svnum) {
/* new service */
if (svnum >= MAXSERVICES) {
warn3x("unable to start runsv ", d->d_name, ": too many services.");
continue;
}
sv[i].ino =s.st_ino;
sv[i].dev =s.st_dev;
sv[i].pid =0;
sv[i].isgone =0;
svnum++;
runsv(i, d->d_name);
check =1;
}
}
if (errno) {
warn("unable to read directory ", svdir);
closedir(dir);
check =1;
return;
}
closedir(dir);
/* SIGTERM removed runsv's */
for (i =0; i < svnum; i++) {
if (! sv[i].isgone) continue;
if (sv[i].pid) kill(sv[i].pid, SIGTERM);
sv[i] =sv[--svnum];
check =1;
}
}
int setup_log() {
if ((rploglen =str_len(rplog)) < 7) {
warn3x("log must have at least seven characters.", 0, 0);
return(0);
}
if (pipe(logpipe) == -1) {
warn3x("unable to create pipe for log.", 0, 0);
return(-1);
}
coe(logpipe[1]);
coe(logpipe[0]);
ndelay_on(logpipe[0]);
ndelay_on(logpipe[1]);
if (fd_copy(2, logpipe[1]) == -1) {
warn3x("unable to set filedescriptor for log.", 0, 0);
return(-1);
}
io[0].fd =logpipe[0];
io[0].events =IOPAUSE_READ;
taia_now(&stamplog);
return(1);
}
int main(int argc, char **argv) {
struct stat s;
time_t mtime =0;
int wstat;
int curdir;
int pid;
struct taia deadline;
struct taia now;
struct taia stampcheck;
char ch;
int i;
progname =*argv++;
if (! argv || ! *argv) usage();
if (**argv == '-') {
switch (*(*argv +1)) {
case 'P': pgrp =1;
case '-': ++argv;
}
if (! argv || ! *argv) usage();
}
sig_catch(sig_term, s_term);
sig_catch(sig_hangup, s_hangup);
svdir =*argv++;
if (argv && *argv) {
rplog =*argv;
if (setup_log() != 1) {
rplog =0;
warn3x("log service disabled.", 0, 0);
}
}
if ((curdir =open_read(".")) == -1)
fatal("unable to open current directory", 0);
coe(curdir);
taia_now(&stampcheck);
for (;;) {
/* collect children */
for (;;) {
if ((pid =wait_nohang(&wstat)) <= 0) break;
for (i =0; i < svnum; i++) {
if (pid == sv[i].pid) {
/* runsv has gone */
sv[i].pid =0;
check =1;
break;
}
}
}
taia_now(&now);
if (now.sec.x < (stampcheck.sec.x -3)) {
/* time warp */
warn3x("time warp: resetting time stamp.", 0, 0);
taia_now(&stampcheck);
taia_now(&now);
if (rplog) taia_now(&stamplog);
}
if (taia_less(&now, &stampcheck) == 0) {
/* wait at least a second */
taia_uint(&deadline, 1);
taia_add(&stampcheck, &now, &deadline);
if (stat(svdir, &s) != -1) {
if (check || \
s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev) {
/* svdir modified */
if (chdir(svdir) != -1) {
mtime =s.st_mtime;
dev =s.st_dev;
ino =s.st_ino;
check =0;
if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime))
sleep(1);
runsvdir();
while (fchdir(curdir) == -1) {
warn("unable to change directory, pausing", 0);
sleep(5);
}
}
else
warn("unable to change directory to ", svdir);
}
}
else
warn("unable to stat ", svdir);
}
if (rplog)
if (taia_less(&now, &stamplog) == 0) {
write(logpipe[1], ".", 1);
taia_uint(&deadline, 900);
taia_add(&stamplog, &now, &deadline);
}
taia_uint(&deadline, check ? 1 : 5);
taia_add(&deadline, &now, &deadline);
sig_block(sig_child);
if (rplog)
iopause(io, 1, &deadline, &now);
else
iopause(0, 0, &deadline, &now);
sig_unblock(sig_child);
if (rplog && (io[0].revents | IOPAUSE_READ))
while (read(logpipe[0], &ch, 1) > 0)
if (ch) {
for (i =6; i < rploglen; i++)
rplog[i -1] =rplog[i];
rplog[rploglen -1] =ch;
}
switch(exitsoon) {
case 1:
_exit(0);
case 2:
for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
_exit(111);
}
}
/* not reached */
_exit(0);
}
admin/runit-2.2.0/src/byte_copy.c 0000644 0000000 0000000 00000000501 14675400254 015375 0 ustar root root /* Public domain. */
#include "byte.h"
void byte_copy(to,n,from)
register char *to;
register unsigned int n;
register char *from;
{
for (;;) {
if (!n) return; *to++ = *from++; --n;
if (!n) return; *to++ = *from++; --n;
if (!n) return; *to++ = *from++; --n;
if (!n) return; *to++ = *from++; --n;
}
}
admin/runit-2.2.0/src/stralloc_cats.c 0000644 0000000 0000000 00000000253 14675400254 016241 0 ustar root root /* Public domain. */
#include "byte.h"
#include "str.h"
#include "stralloc.h"
int stralloc_cats(stralloc *sa,const char *s)
{
return stralloc_catb(sa,s,str_len(s));
}
admin/runit-2.2.0/src/sig.h 0000644 0000000 0000000 00000001113 14675400254 014167 0 ustar root root /* Public domain. */
#ifndef SIG_H
#define SIG_H
extern int sig_alarm;
extern int sig_child;
extern int sig_cont;
extern int sig_hangup;
extern int sig_int;
extern int sig_pipe;
extern int sig_term;
extern void (*sig_defaulthandler)();
extern void (*sig_ignorehandler)();
extern void sig_catch(int,void (*)());
#define sig_ignore(s) (sig_catch((s),sig_ignorehandler))
#define sig_uncatch(s) (sig_catch((s),sig_defaulthandler))
extern void sig_block(int);
extern void sig_unblock(int);
extern void sig_blocknone(void);
extern void sig_pause(void);
extern void sig_dfl(int);
#endif
admin/runit-2.2.0/src/stralloc_eady.c 0000644 0000000 0000000 00000000341 14675400254 016227 0 ustar root root /* Public domain. */
#include "alloc.h"
#include "stralloc.h"
#include "gen_allocdefs.h"
GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready)
GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus)
admin/runit-2.2.0/src/scan_ulong.c 0000644 0000000 0000000 00000000551 14675400254 015535 0 ustar root root /* Public domain. */
#include "scan.h"
unsigned int scan_ulong(register const char *s,register unsigned long *u)
{
register unsigned int pos = 0;
register unsigned long result = 0;
register unsigned long c;
while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) {
result = result * 10 + c;
++pos;
}
*u = result;
return pos;
}
admin/runit-2.2.0/src/runsvstat.c 0000644 0000000 0000000 00000010131 14675400254 015451 0 ustar root root #include
#include
#include
#include "strerr.h"
#include "error.h"
#include "sgetopt.h"
#include "open.h"
#include "buffer.h"
#include "tai.h"
#include "fmt.h"
#define USAGE " [ -l ] service ..."
#define VERSION "$Id: c17bbd3eda6f3c57027dfb47ff676bdd3fefff9f $"
#define FATAL "runsvstat: fatal: "
#define WARNING "runsvstat: warning: "
const char *progname;
unsigned int rc =0;
struct stat s;
int showlog =0;
void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
void fatal(char *m1) { strerr_die3sys(111, FATAL, m1, ": "); }
void warn(char *m1, char *m2) {
rc++;
strerr_warn5(WARNING, m1, ": ", m2, ": ", &strerr_sys);
}
void warnx(char *m1, char *m2) {
rc++;
strerr_warn4(WARNING, m1, ": ", m2, 0);
}
int show_status(char *name) {
char status[20];
int pid;
int fd;
int normallyup =0;
char sulong[FMT_ULONG];
struct tai when;
struct tai now;
if (stat("down", &s) == -1) {
if (errno != error_noent) {
warn(name, "unable to stat down");
return(-1);
}
normallyup = 1;
}
if ((fd =open_write("supervise/ok")) == -1) {
if (errno == error_nodevice)
warnx(name, "runsv not running.");
else
warn(name, "unable to open supervise/ok");
return(-1);
}
close(fd);
if ((fd =open_read("supervise/status")) == -1) {
warn(name, "unable to open supervise/status");
return(-1);
}
switch(read(fd, status, 20)) {
case 20: break;
case -1:
warn(name, "unable to read supervise/status");
return(-1);
default:
warnx(name, "unable to read supervise/status: bad format.");
return(-1);
}
pid =(unsigned char) status[15];
pid <<=8; pid +=(unsigned char)status[14];
pid <<=8; pid +=(unsigned char)status[13];
pid <<=8; pid +=(unsigned char)status[12];
tai_unpack(status,&when);
tai_now(&now);
if (tai_less(&now,&when)) when =now;
tai_sub(&when,&now,&when);
buffer_puts(buffer_1, name);
buffer_puts(buffer_1, ": ");
if (pid) {
switch (status[19]) {
case 1: buffer_puts(buffer_1, "run "); break;
case 2: buffer_puts(buffer_1, "finish "); break;
}
buffer_puts(buffer_1, "(pid ");
buffer_put(buffer_1, sulong, fmt_ulong(sulong, pid));
buffer_puts(buffer_1, ") ");
}
else
buffer_puts(buffer_1, "down ");
buffer_put(buffer_1, sulong, fmt_ulong(sulong, tai_approx(&when)));
buffer_puts(buffer_1, " seconds");
if (pid && !normallyup) buffer_puts(buffer_1,", normally down");
if (!pid && normallyup) buffer_puts(buffer_1,", normally up");
if (pid && status[16]) buffer_puts(buffer_1,", paused");
if (!pid && (status[17] == 'u')) buffer_puts(buffer_1,", want up");
if (pid && (status[17] == 'd')) buffer_puts(buffer_1,", want down");
if (pid && status[18]) buffer_puts(buffer_1, ", got TERM");
/* buffer_putsflush(buffer_1, "\n"); */
return(1);
}
int main(int argc, char **argv) {
int opt;
int curdir;
char **dir;
progname =*argv;
while ((opt =getopt(argc, (const char * const *)argv, "lV")) != opteof) {
switch(opt) {
case 'l':
showlog =1;
break;
case 'V':
strerr_warn1(VERSION, 0);
case '?':
usage();
}
}
argv +=optind;
dir =argv;
if (! dir || ! *dir) usage();
if ((curdir =open_read(".")) == -1) {
rc =100;
fatal("unable to open current directory");
}
for (; dir && *dir; dir++) {
if (chdir(*dir) == -1) {
warn(*dir, "unable to change directory");
continue;
}
if (show_status(*dir) == 1) {
if (showlog) {
if (stat("log", &s) == -1) {
if (errno != error_noent)
warn("unable to stat()", "./log");
}
else {
if (! S_ISDIR(s.st_mode))
warnx("./log", "not a directory.");
else {
if (chdir("log") == -1) {
warn(*dir, "unable to change directory");
continue;
}
show_status("\n log");
}
}
}
buffer_puts(buffer_1, "\n"); buffer_flush(buffer_1);
}
if (fchdir(curdir) == -1) {
rc =100;
fatal("unable to change directory");
}
}
if (rc > 100) rc =100;
_exit(rc);
}
admin/runit-2.2.0/src/sgetopt.h 0000644 0000000 0000000 00000000733 14675400254 015101 0 ustar root root /* Public domain. */
#ifndef SGETOPT_H
#define SGETOPT_H
#ifndef SGETOPTNOSHORT
#define getopt sgetoptmine
#define optarg subgetoptarg
#define optind subgetoptind
#define optpos subgetoptpos
#define opterr sgetopterr
#define optproblem subgetoptproblem
#define optprogname sgetoptprogname
#define opteof subgetoptdone
#endif
#include "subgetopt.h"
extern int sgetoptmine(int,char *const *,const char *);
extern int sgetopterr;
extern const char *sgetoptprogname;
#endif
admin/runit-2.2.0/src/hasshsgr.h2 0000644 0000000 0000000 00000000120 14675400254 015306 0 ustar root root /* Public domain. */
/* sysdep: +shortsetgroups */
#define HASSHORTSETGROUPS 1
admin/runit-2.2.0/src/buffer_0.c 0000644 0000000 0000000 00000000521 14675400254 015072 0 ustar root root /* Public domain. */
#include "buffer.h"
int buffer_0_read(fd,buf,len) int fd; char *buf; int len;
{
if (buffer_flush(buffer_1) == -1) return -1;
return buffer_unixread(fd,buf,len);
}
char buffer_0_space[BUFFER_INSIZE];
static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space);
buffer *buffer_0 = ⁢
admin/runit-2.2.0/src/str_chr.c 0000644 0000000 0000000 00000000572 14675400254 015054 0 ustar root root /* Public domain. */
#include "str.h"
unsigned int str_chr(register const char *s,int c)
{
register char ch;
register const char *t;
ch = c;
t = s;
for (;;) {
if (!*t) break; if (*t == ch) break; ++t;
if (!*t) break; if (*t == ch) break; ++t;
if (!*t) break; if (*t == ch) break; ++t;
if (!*t) break; if (*t == ch) break; ++t;
}
return t - s;
}
admin/runit-2.2.0/src/taia_add.c 0000644 0000000 0000000 00000000631 14675400254 015132 0 ustar root root /* Public domain. */
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
{
t->sec.x = u->sec.x + v->sec.x;
t->nano = u->nano + v->nano;
t->atto = u->atto + v->atto;
if (t->atto > 999999999UL) {
t->atto -= 1000000000UL;
++t->nano;
}
if (t->nano > 999999999UL) {
t->nano -= 1000000000UL;
++t->sec.x;
}
}
admin/runit-2.2.0/src/runit-init.c 0000644 0000000 0000000 00000003550 14675400254 015511 0 ustar root root #include
#include
#include
#include
#include "runit.h"
#include "strerr.h"
#include "sig.h"
#include "open.h"
#include "error.h"
#define USAGE " 0|6"
#define FATAL "init: fatal: "
/* #define WARNING "init: warning: " */
const char *progname;
void usage(void) { strerr_die4x(0, "usage: ", progname, USAGE, "\n"); }
void runit_halt () {
if (open_trunc(STOPIT) == -1)
strerr_die4sys(111, FATAL, "unable to create ", STOPIT, ": ");
if (chmod(STOPIT, 0100) == -1)
strerr_die4sys(111, FATAL, "unable to chmod ", STOPIT, ": ");
if (chmod(REBOOT, 0) == -1)
if (errno != error_noent)
strerr_die4sys(111, FATAL, "unable to chmod ", REBOOT, ": ");
kill(1, sig_cont);
_exit(0);
}
void runit_reboot () {
if (open_trunc(STOPIT) == -1)
strerr_die4sys(111, FATAL, "unable to create ", STOPIT, ": ");
if (chmod(STOPIT, 0100) == -1)
strerr_die4sys(111, FATAL, "unable to chmod ", STOPIT, ": ");
if (open_trunc(REBOOT) == -1)
strerr_die4sys(111, FATAL, "unable to create ", REBOOT, ": ");
if (chmod(REBOOT, 0100) == -1)
strerr_die4sys(111, FATAL, "unable to chmod ", REBOOT, ": ");
kill(1, sig_cont);
_exit(0);
}
int main (int argc, const char * const *argv, char * const *envp) {
const char *prog[2];
progname =*argv++;
if (getpid() == 1) {
prog[1] =0;
prog[0] ="runit";
/* kernel is starting init, runit does the job. */
execve(RUNIT, (char *const *)prog, envp);
/* serious error */
strerr_die4sys(111, FATAL, "unable to start ", prog[0], ": ");
}
if (! *argv || ! **argv) usage();
switch (**argv) {
case '0':
runit_halt();
break;
case '6':
runit_reboot();
break;
case '-':
if ((*argv)[1] == 'V')
strerr_warn1("$Id: f075d98bf7dd17c893021f9572cbb970cdad8dcf $\n", 0);
default:
usage();
}
/* not reached */
_exit(0);
}
admin/runit-2.2.0/src/sv.dist 0000644 0000000 0000000 00000000246 14675400254 014557 0 ustar root root usage: sv [-v] [-w sec] command service ...
100
$Id: bccdf71babe2596029c67cd0f6cec89bd05844a2 $
usage: sv [-v] [-w sec] command service ...
100
starting
0
down
0
0
admin/runit-2.2.0/src/trycpp.c 0000644 0000000 0000000 00000000241 14675400254 014722 0 ustar root root /* Public domain. */
#include
#include
int main()
{
#ifdef NeXT
printf("nextstep\n"); exit(0);
#endif
printf("unknown\n"); exit(0);
}
admin/runit-2.2.0/src/buffer_put.c 0000644 0000000 0000000 00000003415 14675400254 015550 0 ustar root root /* Public domain. */
#include "buffer.h"
#include "str.h"
#include "byte.h"
#include "error.h"
static int allwrite(int (*op)(),int fd,const char *buf,unsigned int len)
{
int w;
while (len) {
w = op(fd,buf,len);
if (w == -1) {
if (errno == error_intr) continue;
return -1; /* note that some data may have been written */
}
if (w == 0) ; /* luser's fault */
buf += w;
len -= w;
}
return 0;
}
int buffer_flush(buffer *s)
{
int p;
p = s->p;
if (!p) return 0;
s->p = 0;
return allwrite(s->op,s->fd,s->x,p);
}
int buffer_putalign(buffer *s,const char *buf,unsigned int len)
{
unsigned int n;
while (len > (n = s->n - s->p)) {
byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
if (buffer_flush(s) == -1) return -1;
}
/* now len <= s->n - s->p */
byte_copy(s->x + s->p,len,buf);
s->p += len;
return 0;
}
int buffer_put(buffer *s,const char *buf,unsigned int len)
{
unsigned int n;
n = s->n;
if (len > n - s->p) {
if (buffer_flush(s) == -1) return -1;
/* now s->p == 0 */
if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE;
while (len > s->n) {
if (n > len) n = len;
if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
buf += n;
len -= n;
}
}
/* now len <= s->n - s->p */
byte_copy(s->x + s->p,len,buf);
s->p += len;
return 0;
}
int buffer_putflush(buffer *s,const char *buf,unsigned int len)
{
if (buffer_flush(s) == -1) return -1;
return allwrite(s->op,s->fd,buf,len);
}
int buffer_putsalign(buffer *s,const char *buf)
{
return buffer_putalign(s,buf,str_len(buf));
}
int buffer_puts(buffer *s,const char *buf)
{
return buffer_put(s,buf,str_len(buf));
}
int buffer_putsflush(buffer *s,const char *buf)
{
return buffer_putflush(s,buf,str_len(buf));
}
admin/runit-2.2.0/src/hasflock.h1 0000644 0000000 0000000 00000000053 14675400254 015262 0 ustar root root /* Public domain. */
/* sysdep: -flock */
admin/runit-2.2.0/src/alloc.c 0000644 0000000 0000000 00000001500 14675400254 014472 0 ustar root root /* Public domain. */
#include
#include "alloc.h"
#include "error.h"
#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
#define SPACE 2048 /* must be multiple of ALIGNMENT */
typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
static aligned realspace[SPACE / ALIGNMENT];
#define space ((char *) realspace)
static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
/*@null@*//*@out@*/char *alloc(n)
unsigned int n;
{
char *x;
n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
if (n <= avail) { avail -= n; return space + avail; }
x = malloc(n);
if (!x) errno = error_nomem;
return x;
}
void alloc_free(x)
char *x;
{
if (x >= space)
if (x < space + SPACE)
return; /* XXX: assuming that pointers are flat */
free(x);
}
admin/runit-2.2.0/src/tryuwtmp.c 0000644 0000000 0000000 00000000162 14675400254 015316 0 ustar root root #include
#include
struct utmp ut;
int main(void) {
char *s =ut.ut_name;
return(0);
}
admin/runit-2.2.0/src/byte_cr.c 0000644 0000000 0000000 00000000532 14675400254 015033 0 ustar root root /* Public domain. */
#include "byte.h"
void byte_copyr(to,n,from)
register char *to;
register unsigned int n;
register char *from;
{
to += n;
from += n;
for (;;) {
if (!n) return; *--to = *--from; --n;
if (!n) return; *--to = *--from; --n;
if (!n) return; *--to = *--from; --n;
if (!n) return; *--to = *--from; --n;
}
}
admin/runit-2.2.0/src/alloc.h 0000644 0000000 0000000 00000000231 14675400254 014477 0 ustar root root /* Public domain. */
#ifndef ALLOC_H
#define ALLOC_H
extern /*@null@*//*@out@*/char *alloc();
extern void alloc_free();
extern int alloc_re();
#endif
admin/runit-2.2.0/src/print-ld.sh 0000644 0000000 0000000 00000000213 14675400254 015321 0 ustar root root ld="`head -n1 conf-ld`"
systype="`cat systype`"
cat warn-auto.sh
echo 'main="$1"; shift'
echo exec "$ld" '-o "$main" "$main".o ${1+"$@"}'
admin/runit-2.2.0/src/pathexec_env.c 0000644 0000000 0000000 00000002661 14675400254 016062 0 ustar root root /* Public domain. */
#include "stralloc.h"
#include "alloc.h"
#include "str.h"
#include "byte.h"
#include "env.h"
#include "pathexec.h"
static stralloc plus;
static stralloc tmp;
int pathexec_env(const char *s,const char *t)
{
if (!s) return 1;
if (!stralloc_copys(&tmp,s)) return 0;
if (t) {
if (!stralloc_cats(&tmp,"=")) return 0;
if (!stralloc_cats(&tmp,t)) return 0;
}
if (!stralloc_0(&tmp)) return 0;
return stralloc_cat(&plus,&tmp);
}
void pathexec_env_run(const char *file, char *const *argv)
{
char **e;
unsigned int elen;
unsigned int i;
unsigned int j;
unsigned int split;
unsigned int t;
if (!stralloc_cats(&plus,"")) return;
elen = 0;
for (i = 0;environ[i];++i)
++elen;
for (i = 0;i < plus.len;++i)
if (!plus.s[i])
++elen;
e = (char **) alloc((elen + 1) * sizeof(char *));
if (!e) return;
elen = 0;
for (i = 0;environ[i];++i)
e[elen++] = environ[i];
j = 0;
for (i = 0;i < plus.len;++i)
if (!plus.s[i]) {
split = str_chr(plus.s + j,'=');
for (t = 0;t < elen;++t)
if (byte_equal(plus.s + j,split,e[t]))
if (e[t][split] == '=') {
--elen;
e[t] = e[elen];
break;
}
if (plus.s[j + split])
e[elen++] = plus.s + j;
j = i + 1;
}
e[elen] = 0;
pathexec_run(file,argv,e);
alloc_free(e);
}
void pathexec(char *const *argv)
{
return pathexec_env_run(*argv, argv);
}
admin/runit-2.2.0/src/fmt_uint0.c 0000644 0000000 0000000 00000000361 14675400254 015311 0 ustar root root /* Public domain. */
#include "fmt.h"
unsigned int fmt_uint0(char *s,unsigned int u,unsigned int n)
{
unsigned int len;
len = fmt_uint(FMT_LEN,u);
while (len < n) { if (s) *s++ = '0'; ++len; }
if (s) fmt_uint(s,u);
return len;
}
admin/runit-2.2.0/src/print-cc.sh 0000644 0000000 0000000 00000000141 14675400254 015307 0 ustar root root cc="`head -n1 conf-cc`"
systype="`cat systype`"
cat warn-auto.sh
echo exec "$cc" '-c ${1+"$@"}'
admin/runit-2.2.0/src/hasmkffo.h1 0000644 0000000 0000000 00000000054 14675400254 015267 0 ustar root root /* Public domain. */
/* sysdep: -mkfifo */
admin/runit-2.2.0/src/tai_pack.c 0000644 0000000 0000000 00000000471 14675400254 015161 0 ustar root root /* Public domain. */
#include "tai.h"
void tai_pack(char *s,const struct tai *t)
{
uint64 x;
x = t->x;
s[7] = x & 255; x >>= 8;
s[6] = x & 255; x >>= 8;
s[5] = x & 255; x >>= 8;
s[4] = x & 255; x >>= 8;
s[3] = x & 255; x >>= 8;
s[2] = x & 255; x >>= 8;
s[1] = x & 255; x >>= 8;
s[0] = x;
}
admin/runit-2.2.0/src/byte_diff.c 0000644 0000000 0000000 00000000733 14675400254 015342 0 ustar root root /* Public domain. */
#include "byte.h"
int byte_diff(s,n,t)
register char *s;
register unsigned int n;
register char *t;
{
for (;;) {
if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
}
return ((int)(unsigned int)(unsigned char) *s)
- ((int)(unsigned int)(unsigned char) *t);
}
admin/runit-2.2.0/src/pathexec_run.c 0000644 0000000 0000000 00000002030 14675400254 016064 0 ustar root root /* Public domain. */
#include
#include "error.h"
#include "stralloc.h"
#include "str.h"
#include "env.h"
#include "pathexec.h"
static stralloc tmp;
void pathexec_run(const char *file,char * const *argv,char * const *envp)
{
const char *path;
unsigned int split;
int savederrno;
if (file[str_chr(file,'/')]) {
execve(file,argv,envp);
return;
}
path = env_get("PATH");
if (!path) path = "/bin:/usr/bin";
savederrno = 0;
for (;;) {
split = str_chr(path,':');
if (!stralloc_copyb(&tmp,path,split)) return;
if (!split)
if (!stralloc_cats(&tmp,".")) return;
if (!stralloc_cats(&tmp,"/")) return;
if (!stralloc_cats(&tmp,file)) return;
if (!stralloc_0(&tmp)) return;
execve(tmp.s,argv,envp);
if (errno != error_noent) {
savederrno = errno;
if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return;
}
if (!path[split]) {
if (savederrno) errno = savederrno;
return;
}
path += split;
path += 1;
}
}
admin/runit-2.2.0/src/gen_allocdefs.h 0000644 0000000 0000000 00000002274 14675400254 016203 0 ustar root root /* Public domain. */
#ifndef GEN_ALLOC_DEFS_H
#define GEN_ALLOC_DEFS_H
#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \
int ta_ready(register ta *x,register unsigned int n) \
{ register unsigned int i; \
if (x->field) { \
i = x->a; \
if (n > i) { \
x->a = base + n + (n >> 3); \
if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
x->a = i; return 0; } \
return 1; } \
x->len = 0; \
return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
#define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \
int ta_rplus(register ta *x,register unsigned int n) \
{ register unsigned int i; \
if (x->field) { \
i = x->a; n += x->len; \
if (n > i) { \
x->a = base + n + (n >> 3); \
if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
x->a = i; return 0; } \
return 1; } \
x->len = 0; \
return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
#define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \
int ta_append(register ta *x,register const type *i) \
{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; }
#endif
admin/runit-2.2.0/src/select.h1 0000644 0000000 0000000 00000000235 14675400254 014751 0 ustar root root /* Public domain. */
#ifndef SELECT_H
#define SELECT_H
/* sysdep: -sysselect */
#include
#include
extern int select();
#endif
admin/runit-2.2.0/src/svlogd.c 0000644 0000000 0000000 00000057731 14675400254 014717 0 ustar root root #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pmatch.h"
#include "fmt_ptime.h"
#include "alloc.h"
#include "stralloc.h"
#include "strerr.h"
#include "buffer.h"
#include "sig.h"
#include "env.h"
#include "fd.h"
#include "wait.h"
#include "error.h"
#include "sgetopt.h"
#include "open.h"
#include "openreadclose.h"
#include "coe.h"
#include "lock.h"
#include "str.h"
#include "byte.h"
#include "scan.h"
#include "direntry.h"
#include "taia.h"
#include "fmt.h"
#include "ndelay.h"
#include "iopause.h"
#define USAGE " [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ..."
#define VERSION "$Id: 66d40067fb843ee6cde160e47c9dee5c73986f6d $"
#define FATAL "svlogd: fatal: "
#define WARNING "svlogd: warning: "
#define PAUSE "svlogd: pausing: "
#define INFO "svlogd: info: "
const char *progname;
unsigned int verbose =0;
unsigned int timestamp =0;
unsigned long linemax =1000;
unsigned long buflen =1024;
unsigned long linelen;
const char *replace ="";
char repl =0;
char **fndir;
int fdwdir;
struct stat st;
stralloc sa;
int wstat;
struct taia now;
struct taia trotate;
char *databuf;
buffer data;
char *line;
char stamp[FMT_PTIME];
unsigned int exitasap =0;
unsigned int rotateasap =0;
unsigned int reopenasap =0;
unsigned int linecomplete =1;
unsigned int tmaxflag =0;
int fdudp =-1;
iopause_fd in;
struct logdir {
int fddir;
char *btmp;
buffer b;
stralloc inst;
unsigned long size;
unsigned long sizemax;
unsigned long nmax;
unsigned long nmin;
unsigned long tmax;
struct taia trotate;
stralloc processor;
int ppid;
char fnsave[FMT_PTIME];
char *name;
int fdcur;
int fdlock;
char match;
char matcherr;
struct sockaddr_in udpaddr;
unsigned int udponly;
stralloc prefix;
} *dir;
unsigned int dirn =0;
void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); }
void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); }
void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); }
void fatalx(char *m0) { strerr_die2x(111, FATAL, m0); }
void fatal2(char *m0, char *m1) {
strerr_die5sys(111, FATAL, m0, ": ", m1, ": ");
}
void warn(char *m0) { strerr_warn3(WARNING, m0, ": ", &strerr_sys); }
void warn2(char *m0, char *m1) {
strerr_warn5(WARNING, m0, ": ", m1, ": ", &strerr_sys);
}
void warnx(char *m0, char *m1) { strerr_warn4(WARNING, m0, ": ", m1, 0); }
void pause_nomem() { strerr_warn2(PAUSE, "out of memory.", 0); sleep(3); }
void pause1(char *m0) { strerr_warn3(PAUSE, m0, ": ", &strerr_sys); sleep(3); }
void pause2(char *m0, char *m1) {
strerr_warn5(PAUSE, m0, ": ", m1, ": ", &strerr_sys);
sleep(3);
}
unsigned int processorstart(struct logdir *ld) {
int pid;
if (! ld->processor.len) return(0);
if (ld->ppid) {
warnx("processor already running", ld->name);
return(0);
}
while ((pid =fork()) == -1)
pause2("unable to fork for processor", ld->name);
if (! pid) {
char *prog[4];
int fd;
/* child */
sig_uncatch(sig_term);
sig_uncatch(sig_alarm);
sig_uncatch(sig_hangup);
sig_unblock(sig_term);
sig_unblock(sig_alarm);
sig_unblock(sig_hangup);
if (verbose)
strerr_warn5(INFO, "processing: ", ld->name, "/", ld->fnsave, 0);
if ((fd =open_read(ld->fnsave)) == -1)
fatal2("unable to open input for processor", ld->name);
if (fd_move(0, fd) == -1)
fatal2("unable to move filedescriptor for processor", ld->name);
ld->fnsave[26] ='t';
if ((fd =open_trunc(ld->fnsave)) == -1)
fatal2("unable to open output for processor", ld->name);
if (fd_move(1, fd) == -1)
fatal2("unable to move filedescriptor for processor", ld->name);
if ((fd =open_read("state")) == -1) {
if (errno == error_noent) {
if ((fd =open_trunc("state")) == -1)
fatal2("unable to create empty state for processor", ld->name);
close(fd);
if ((fd =open_read("state")) == -1)
fatal2("unable to open state for processor", ld->name);
}
else
fatal2("unable to open state for processor", ld->name);
}
if (fd_move(4, fd) == -1)
fatal2("unable to move filedescriptor for processor", ld->name);
if ((fd =open_trunc("newstate")) == -1)
fatal2("unable to open newstate for processor", ld->name);
if (fd_move(5, fd) == -1)
fatal2("unable to move filedescriptor for processor", ld->name);
prog[0] = "sh";
prog[1] = "-c";
prog[2] = ld->processor.s;
prog[3] = 0;
execve("/bin/sh", prog, environ);
fatal2("unable to run processor", ld->name);
}
ld->ppid =pid;
return(1);
}
unsigned int processorstop(struct logdir *ld) {
char f[28];
if (ld->ppid) {
sig_unblock(sig_hangup);
while (wait_pid(&wstat, ld->ppid) == -1)
pause2("error waiting for processor", ld->name);
sig_block(sig_hangup);
ld->ppid =0;
}
if (ld->fddir == -1) return(1);
while (fchdir(ld->fddir) == -1)
pause2("unable to change directory, want processor", ld->name);
if (wait_exitcode(wstat) != 0) {
warnx("processor failed, restart", ld->name);
ld->fnsave[26] ='t';
unlink(ld->fnsave);
ld->fnsave[26] ='u';
processorstart(ld);
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(ld->processor.len ? 0 : 1);
}
ld->fnsave[26] ='t';
byte_copy(f, 26, ld->fnsave);
f[26] ='s'; f[27] =0;
while (rename(ld->fnsave, f) == -1)
pause2("unable to rename processed", ld->name);
while (chmod(f, 0744) == -1)
pause2("unable to set mode of processed", ld->name);
ld->fnsave[26] ='u';
if (unlink(ld->fnsave) == -1)
strerr_warn5(WARNING, "unable to unlink: ", ld->name, "/", ld->fnsave, 0);
while (rename("newstate", "state") == -1)
pause2("unable to rename state", ld->name);
if (verbose) strerr_warn5(INFO, "processed: ", ld->name, "/", f, 0);
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(1);
}
void rmoldest(struct logdir *ld) {
DIR *d;
direntry *f;
char oldest[FMT_PTIME];
int n =0;
oldest[0] ='A'; oldest[1] =oldest[27] =0;
while (! (d =opendir(".")))
pause2("unable to open directory, want rotate", ld->name);
errno =0;
while ((f =readdir(d)))
if ((f->d_name[0] == '@') && (str_len(f->d_name) == 27)) {
if (f->d_name[26] == 't') {
if (unlink(f->d_name) == -1)
warn2("unable to unlink processor leftover", f->d_name);
}
else {
++n;
if (str_diff(f->d_name, oldest) < 0) byte_copy(oldest, 27, f->d_name);
}
errno =0;
}
if (errno) warn2("unable to read directory", ld->name);
closedir(d);
if (ld->nmax && (n > ld->nmax)) {
if (verbose) strerr_warn5(INFO, "delete: ", ld->name, "/", oldest, 0);
if ((*oldest == '@') && (unlink(oldest) == -1))
warn2("unable to unlink oldest logfile", ld->name);
}
}
unsigned int rotate(struct logdir *ld) {
char tmp[FMT_ULONG +1];
if (ld->fddir == -1) { ld->tmax =0; return(0); }
if (ld->ppid) while(! processorstop(ld));
while (fchdir(ld->fddir) == -1)
pause2("unable to change directory, want rotate", ld->name);
/* create new filename */
ld->fnsave[25] ='.';
if (ld->processor.len)
ld->fnsave[26] ='u';
else
ld->fnsave[26] ='s';
ld->fnsave[27] =0;
do {
taia_now(&now);
fmt_taia(ld->fnsave, &now);
errno =0;
} while ((stat(ld->fnsave, &st) != -1) || (errno != error_noent));
if (ld->tmax && taia_less(&ld->trotate, &now)) {
taia_uint(&ld->trotate, ld->tmax);
taia_add(&ld->trotate, &now, &ld->trotate);
if (taia_less(&ld->trotate, &trotate)) trotate =ld->trotate;
}
if (ld->size > 0) {
buffer_flush(&ld->b);
while (fsync(ld->fdcur) == -1)
pause2("unable to fsync current logfile", ld->name);
while (fchmod(ld->fdcur, 0744) == -1)
pause2("unable to set mode of current", ld->name);
close(ld->fdcur);
if (verbose) {
tmp[0] =' '; tmp[fmt_ulong(tmp +1, ld->size) +1] =0;
strerr_warn6(INFO, "rename: ", ld->name, "/current ",
ld->fnsave, tmp, 0);
}
while (rename("current", ld->fnsave) == -1)
pause2("unable to rename current", ld->name);
while ((ld->fdcur =open_append("current")) == -1)
pause2("unable to create new current", ld->name);
coe(ld->fdcur);
ld->size =0;
while (fchmod(ld->fdcur, 0644) == -1)
pause2("unable to set mode of current", ld->name);
rmoldest(ld);
processorstart(ld);
}
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(1);
}
int buffer_pwrite(int n, char *s, unsigned int len) {
int i;
if ((dir +n)->sizemax) {
if ((dir +n)->size >= (dir +n)->sizemax) rotate(dir +n);
if (len > ((dir +n)->sizemax -(dir +n)->size))
len =(dir +n)->sizemax -(dir +n)->size;
}
while ((i =write((dir +n)->fdcur, s, len)) == -1) {
if ((errno == ENOSPC) && ((dir +n)->nmin < (dir +n)->nmax)) {
DIR *d;
direntry *f;
char oldest[FMT_PTIME];
int j =0;
while (fchdir((dir +n)->fddir) == -1)
pause2("unable to change directory, want remove old logfile",
(dir +n)->name);
oldest[0] ='A'; oldest[1] =oldest[27] =0;
while (! (d =opendir(".")))
pause2("unable to open directory, want remove old logfile",
(dir +n)->name);
errno =0;
while ((f =readdir(d)))
if ((f->d_name[0] == '@') && (str_len(f->d_name) == 27)) {
++j;
if (str_diff(f->d_name, oldest) < 0)
byte_copy(oldest, 27, f->d_name);
}
if (errno) warn2("unable to read directory, want remove old logfile",
(dir +n)->name);
closedir(d);
errno =ENOSPC;
if (j > (dir +n)->nmin)
if (*oldest == '@') {
strerr_warn5(WARNING, "out of disk space, delete: ", (dir +n)->name,
"/", oldest, 0);
errno =0;
if (unlink(oldest) == -1) {
warn2("unable to unlink oldest logfile", (dir +n)->name);
errno =ENOSPC;
}
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
}
}
if (errno) pause2("unable to write to current", (dir +n)->name);
}
(dir +n)->size +=i;
if ((dir +n)->sizemax)
if (s[i -1] == '\n')
if ((dir +n)->size >= ((dir +n)->sizemax -linemax)) rotate(dir +n);
return(i);
}
void logdir_close(struct logdir *ld) {
if (ld->fddir == -1) return;
if (verbose) strerr_warn3(INFO, "close: ", ld->name, 0);
close(ld->fddir);
ld->fddir =-1;
if (ld->fdcur == -1) return; /* impossible */
buffer_flush(&ld->b);
while (fsync(ld->fdcur) == -1)
pause2("unable to fsync current logfile", ld->name);
while (fchmod(ld->fdcur, 0744) == -1)
pause2("unable to set mode of current", ld->name);
close(ld->fdcur);
ld->fdcur =-1;
if (ld->fdlock == -1) return; /* impossible */
close(ld->fdlock);
ld->fdlock =-1;
while (! stralloc_copys(&ld->processor, "")) pause_nomem();
}
/* taken from libdjbdns */
unsigned int ip4_scan(const char *s,char ip[4])
{
unsigned int i;
unsigned int len;
unsigned long u;
len = 0;
i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i;
if (*s != '.') return 0; ++s; ++len;
i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i;
if (*s != '.') return 0; ++s; ++len;
i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i;
if (*s != '.') return 0; ++s; ++len;
i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i;
return len;
}
unsigned int logdir_open(struct logdir *ld, const char *fn) {
int i;
if ((ld->fddir =open_read(fn)) == -1) {
warn2("unable to open log directory", (char*)fn);
return(0);
}
coe(ld->fddir);
if (fchdir(ld->fddir) == -1) {
logdir_close(ld);
warn2("unable to change directory", (char*)fn);
return(0);
}
ld->fdlock =open_append("lock");
if ((ld->fdlock == -1) || (lock_exnb(ld->fdlock) == -1)) {
logdir_close(ld);
warn2("unable to lock directory", (char*)fn);
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(0);
}
coe(ld->fdlock);
ld->size =0;
ld->sizemax =1000000;
ld->nmax =ld->nmin =10;
ld->tmax =0;
ld->name =(char*)fn;
ld->ppid =0;
ld->match ='+';
ld->udpaddr.sin_family =AF_INET;
ld->udpaddr.sin_port =0;
ld->udponly =0;
while (! stralloc_copys(&ld->prefix, "")) pause_nomem();
while (! stralloc_copys(&ld->inst, "")) pause_nomem();
while (! stralloc_copys(&ld->processor, "")) pause_nomem();
/* read config */
if ((i =openreadclose("config", &sa, 128)) == -1)
warn2("unable to read config", ld->name);
if (i != 0) {
int len, c;
unsigned long port;
if (verbose) strerr_warn4(INFO, "read: ", ld->name, "/config", 0);
for (i =0; i +1 < sa.len; ++i) {
len =byte_chr(&sa.s[i], sa.len -i, '\n');
sa.s[len +i] =0;
switch(sa.s[i]) {
case '\n':
case '#':
break;
case '+':
case '-':
case 'e':
case 'E':
while (! stralloc_catb(&ld->inst, &sa.s[i], len)) pause_nomem();
while (! stralloc_0(&ld->inst)) pause_nomem();
break;
case 's':
switch (sa.s[scan_ulong(&sa.s[i +1], &ld->sizemax) +i +1]) {
case 'm': ld->sizemax *=1024;
case 'k': ld->sizemax *=1024;
}
break;
case 'n':
scan_ulong(&sa.s[i +1], &ld->nmax);
break;
case 'N':
scan_ulong(&sa.s[i +1], &ld->nmin);
break;
case 't':
switch (sa.s[scan_ulong(&sa.s[i +1], &ld->tmax) +i +1]) {
/* case 'd': ld->tmax *=24; */
case 'h': ld->tmax *=60;
case 'm': ld->tmax *=60;
}
if (ld->tmax) {
taia_uint(&ld->trotate, ld->tmax);
taia_add(&ld->trotate, &now, &ld->trotate);
if (! tmaxflag || taia_less(&ld->trotate, &trotate))
trotate =ld->trotate;
tmaxflag =1;
}
break;
case '!':
if (len > 1) {
while (! stralloc_copys(&ld->processor, &sa.s[i +1])) pause_nomem();
while (! stralloc_0(&ld->processor)) pause_nomem();
}
break;
case 'U':
ld->udponly =1;
case 'u':
if (! (c =ip4_scan(sa.s +i +1, (char *)&ld->udpaddr.sin_addr))) {
warnx("unable to scan ip address", sa.s +i +1);
break;
}
if (sa.s[i +1 +c] == ':') {
scan_ulong(sa.s +i +c +2, &port);
if (port == 0) {
warnx("unable to scan port number", sa.s +i +c +2);
break;
}
}
else
port =514;
ld->udpaddr.sin_port =htons(port);
break;
case 'p':
if (len > 1) {
while (! stralloc_copys(&ld->prefix, &sa.s[i +1])) pause_nomem();
while (! stralloc_0(&ld->prefix)) pause_nomem();
}
break;
}
i +=len;
}
}
/* open current */
if ((i =stat("current", &st)) != -1) {
if (st.st_size && ! (st.st_mode & S_IXUSR)) {
ld->fnsave[25] ='.'; ld->fnsave[26] ='u'; ld->fnsave[27] =0;
do {
taia_now(&now);
fmt_taia(ld->fnsave, &now);
errno =0;
} while ((stat(ld->fnsave, &st) != -1) || (errno != error_noent));
while (rename("current", ld->fnsave) == -1)
pause2("unable to rename current", ld->name);
rmoldest(ld);
i =-1;
}
else
ld->size =st.st_size;
}
else
if (errno != error_noent) {
logdir_close(ld);
warn2("unable to stat current", ld->name);
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(0);
}
while ((ld->fdcur =open_append("current")) == -1)
pause2("unable to open current", ld->name);
coe(ld->fdcur);
while (fchmod(ld->fdcur, 0644) == -1)
pause2("unable to set mode of current", ld->name);
buffer_init(&ld->b, buffer_pwrite, ld -dir, ld->btmp, buflen);
if (verbose) {
if (i == 0) strerr_warn4(INFO, "append: ", ld->name, "/current", 0);
else strerr_warn4(INFO, "new: ", ld->name, "/current", 0);
}
while (fchdir(fdwdir) == -1)
pause1("unable to change to initial working directory");
return(1);
}
void logdirs_reopen(void) {
int l;
int ok =0;
tmaxflag =0;
taia_now(&now);
for (l =0; l < dirn; ++l) {
logdir_close(&dir[l]);
if (logdir_open(&dir[l], fndir[l])) ok =1;
}
if (! ok) fatalx("no functional log directories.");
}
int buffer_pread(int fd, char *s, unsigned int len) {
int i;
for (i =0; i < dirn; ++i) buffer_flush(&dir[i].b);
if (rotateasap) {
for (i =0; i < dirn; ++i) rotate(dir +i);
rotateasap =0;
}
if (exitasap) {
if (linecomplete) return(0);
len =1;
}
if (reopenasap) {
logdirs_reopen();
reopenasap =0;
}
taia_now(&now);
taia_uint(&trotate, 2744);
taia_add(&trotate, &now, &trotate);
for (i =0; i < dirn; ++i)
if ((dir +i)->tmax) {
if (taia_less(&dir[i].trotate, &now)) rotate(dir +i);
if (taia_less(&dir[i].trotate, &trotate)) trotate =dir[i].trotate;
}
sig_unblock(sig_term);
sig_unblock(sig_child);
sig_unblock(sig_alarm);
sig_unblock(sig_hangup);
iopause(&in, 1, &trotate, &now);
sig_block(sig_term);
sig_block(sig_child);
sig_block(sig_alarm);
sig_block(sig_hangup);
i =read(fd, s, len);
if (i == -1) {
if (errno == error_again) errno =error_intr;
if (errno != error_intr) warn("unable to read standard input");
}
if (i > 0) linecomplete =(s[i -1] == '\n');
return(i);
}
void sig_term_handler(void) {
if (verbose) strerr_warn2(INFO, "sigterm received.", 0);
exitasap =1;
}
void sig_child_handler(void) {
int pid, l;
if (verbose) strerr_warn2(INFO, "sigchild received.", 0);
while ((pid =wait_nohang(&wstat)) > 0)
for (l =0; l < dirn; ++l)
if (dir[l].ppid == pid) {
dir[l].ppid =0;
processorstop(&dir[l]);
break;
}
}
void sig_alarm_handler(void) {
if (verbose) strerr_warn2(INFO, "sigalarm received.", 0);
rotateasap =1;
}
void sig_hangup_handler(void) {
if (verbose) strerr_warn2(INFO, "sighangup received.", 0);
reopenasap =1;
}
void logmatch(struct logdir *ld) {
int i;
ld->match ='+';
ld->matcherr ='E';
for (i =0; i < ld->inst.len; ++i) {
switch(ld->inst.s[i]) {
case '+':
case '-':
if (pmatch(&ld->inst.s[i +1], line, linelen))
ld->match =ld->inst.s[i];
break;
case 'e':
case 'E':
if (pmatch(&ld->inst.s[i +1], line, linelen))
ld->matcherr =ld->inst.s[i];
break;
}
i +=byte_chr(&ld->inst.s[i], ld->inst.len -i, 0);
}
}
int main(int argc, char **argv) {
int i;
int opt;
progname =*argv;
while ((opt =getopt(argc, argv, "R:r:l:b:tvV")) != opteof) {
switch(opt) {
case 'R':
replace =optarg;
if (! repl) repl ='_';
break;
case 'r':
repl =*optarg;
if (! repl || *(optarg +1)) usage();
break;
case 'l':
scan_ulong(optarg, &linemax);
if (linemax == 0) linemax =1000;
break;
case 'b':
scan_ulong(optarg, &buflen);
if (buflen == 0) buflen =1024;
break;
case 't':
if (++timestamp > 3) timestamp =3;
break;
case 'v':
++verbose;
break;
case 'V': strerr_warn1(VERSION, 0);
case '?': usage();
}
}
argv +=optind;
dirn =argc -optind;
if (dirn <= 0) usage();
if (buflen <= linemax) usage();
if ((fdwdir =open_read(".")) == -1)
fatal("unable to open current working directory");
coe(fdwdir);
dir =(struct logdir*)alloc(dirn *sizeof(struct logdir));
if (! dir) die_nomem();
for (i =0; i < dirn; ++i) {
dir[i].fddir =-1; dir[i].fdcur =-1;
dir[i].btmp =(char*)alloc(buflen *sizeof(char));
if (! dir[i].btmp) die_nomem();
dir[i].ppid =0;
}
databuf =(char*)alloc(buflen *sizeof(char));
if (! databuf) die_nomem();
buffer_init(&data, buffer_pread, 0, databuf, buflen);
line =(char*)alloc(linemax *sizeof(char));
if (! line) die_nomem();
fndir =argv;
in.fd =0;
in.events =IOPAUSE_READ;
ndelay_on(in.fd);
sig_block(sig_term);
sig_block(sig_child);
sig_block(sig_alarm);
sig_block(sig_hangup);
sig_catch(sig_term, sig_term_handler);
sig_catch(sig_child, sig_child_handler);
sig_catch(sig_alarm, sig_alarm_handler);
sig_catch(sig_hangup, sig_hangup_handler);
logdirs_reopen();
for(;;) {
char ch;
linelen =0;
for (linelen =0; linelen < linemax; ++linelen) {
if (buffer_GETC(&data, &ch) <= 0) {
exitasap =1;
break;
}
if (! linelen && timestamp) {
taia_now(&now);
switch (timestamp) {
case 1: fmt_taia(stamp, &now); break;
case 2: fmt_ptime(stamp, &now); break;
case 3: fmt_ptime_iso8601(stamp, &now); break;
}
stamp[25] =' '; stamp[26] =0;
}
if (ch == '\n') break;
if (repl) {
if ((ch < 32) || (ch > 126))
ch =repl;
else
for (i =0; replace[i]; ++i)
if (ch == replace[i]) {
ch =repl;
break;
}
}
line[linelen] =ch;
}
if (exitasap && ! data.p) break; /* data buffer is empty */
for (i =0; i < dirn; ++i)
if (dir[i].fddir != -1) {
if (dir[i].inst.len) logmatch(&dir[i]);
if (dir[i].matcherr == 'e') {
if (timestamp) buffer_puts(buffer_2, stamp);
if (dir[i].prefix.len) buffer_puts(buffer_2, dir[i].prefix.s);
buffer_put(buffer_2, line, linelen);
if (linelen == linemax) buffer_puts(buffer_2, "...");
buffer_put(buffer_2, "\n", 1); buffer_flush(buffer_2);
}
if (dir[i].match != '+') continue;
if (dir[i].udpaddr.sin_port != 0) {
fdudp =socket(AF_INET, SOCK_DGRAM, 0);
if (fdudp)
if (ndelay_on(fdudp) == -1) {
close(fdudp);
fdudp =-1;
}
if (fdudp == -1) {
buffer_puts(&dir[i].b, "warning: no udp socket available: ");
if (timestamp) buffer_puts(&dir[i].b, stamp);
if (dir[i].prefix.len) buffer_puts(&dir[i].b, dir[i].prefix.s);
buffer_put(&dir[i].b, line, linelen);
buffer_put(&dir[i].b, "\n", 1);
buffer_flush(&dir[i].b);
}
else {
while (! stralloc_copys(&sa, "")) pause_nomem();
if (timestamp)
while (! stralloc_cats(&sa, stamp)) pause_nomem();
if (dir[i].prefix.len)
while (! stralloc_cats(&sa, dir[i].prefix.s)) pause_nomem();
while (! stralloc_catb(&sa, line, linelen)) pause_nomem();
if (linelen == linemax)
while (! stralloc_cats(&sa, "...")) pause_nomem();
while (! stralloc_append(&sa, "\n")) pause_nomem();
if (sendto(fdudp, sa.s, sa.len, 0,
(struct sockaddr *)&dir[i].udpaddr,
sizeof(dir[i].udpaddr)) != sa.len) {
buffer_puts(&dir[i].b, "warning: failure sending through udp: ");
buffer_put(&dir[i].b, sa.s, sa.len);
buffer_flush(&dir[i].b);
}
close(fdudp);
}
}
if (! dir[i].udponly) {
if (timestamp) buffer_puts(&dir[i].b, stamp);
if (dir[i].prefix.len) buffer_puts(&dir[i].b, dir[i].prefix.s);
buffer_put(&dir[i].b, line, linelen);
}
}
if (linelen == linemax)
for (;;) {
if (buffer_GETC(&data, &ch) <= 0) {
exitasap =1;
break;
}
if (ch == '\n') break;
for (i =0; i < dirn; ++i)
if (dir[i].fddir != -1) {
if (dir[i].match != '+') continue;
if (! dir[i].udponly) buffer_PUTC(&dir[i].b, ch);
}
}
for (i =0; i < dirn; ++i)
if (dir[i].fddir != -1) {
if (dir[i].match != '+') continue;
if (! dir[i].udponly) {
ch ='\n';
buffer_PUTC(&dir[i].b, ch);
buffer_flush(&dir[i].b);
}
}
}
for (i =0; i < dirn; ++i) {
if (dir[i].ppid) while (! processorstop(&dir[i]));
logdir_close(&dir[i]);
}
_exit(0);
}
admin/runit-2.2.0/src/wait_nohang.c 0000644 0000000 0000000 00000000367 14675400254 015710 0 ustar root root /* Public domain. */
#include
#include
#include "haswaitp.h"
int wait_nohang(wstat) int *wstat;
{
#ifdef HASWAITPID
return waitpid(-1,wstat,WNOHANG);
#else
return wait3(wstat,WNOHANG,(struct rusage *) 0);
#endif
}
admin/runit-2.2.0/src/wait.h 0000644 0000000 0000000 00000000475 14675400254 014363 0 ustar root root /* Public domain. */
#ifndef WAIT_H
#define WAIT_H
extern int wait_pid();
extern int wait_nohang();
extern int wait_stop();
extern int wait_stopnohang();
#define wait_crashed(w) ((w) & 127)
#define wait_exitcode(w) ((w) >> 8)
#define wait_stopsig(w) ((w) >> 8)
#define wait_stopped(w) (((w) & 127) == 127)
#endif
admin/runit-2.2.0/src/buffer_write.c 0000644 0000000 0000000 00000000235 14675400254 016067 0 ustar root root /* Public domain. */
#include
#include "buffer.h"
int buffer_unixwrite(int fd,const char *buf,unsigned int len)
{
return write(fd,buf,len);
}
admin/runit-2.2.0/src/svwaitup.c 0000644 0000000 0000000 00000006103 14675400254 015266 0 ustar root root #include
#include "strerr.h"
#include "error.h"
#include "sgetopt.h"
#include "scan.h"
#include "open.h"
#include "tai.h"
#include "buffer.h"
#include "fmt.h"
#define FATAL "svwaitup: fatal: "
#define WARN "svwaitup: warning: "
#define INFO "svwaitup: "
#define USAGE " [-v] [-s 1..600] service ..."
const char *progname;
unsigned long sec =2;
unsigned int rc =0;
const char * const *dir;
void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
void warn(const char *s1, const char *s2, struct strerr *e) {
dir++; rc++;
strerr_warn3(WARN, s1, s2, e);
}
void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
int main(int argc, const char * const *argv) {
int opt;
int verbose =0;
char status[18];
int fd;
int is;
int r;
int wdir;
unsigned long pid;
struct tai when;
struct tai now;
char sulong[FMT_ULONG];
progname =*argv;
while ((opt =getopt(argc, argv, "s:vV")) != opteof) {
switch(opt) {
case 's':
scan_ulong(optarg, &sec);
if ((sec < 1) || (sec > 600)) usage();
break;
case 'v':
verbose =1;
break;
case 'V':
strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0);
case '?':
usage();
}
}
argv +=optind;
if (! argv || ! *argv) usage();
if ((wdir =open_read(".")) == -1)
fatal("unable to open current working directory");
dir =argv;
while (*dir) {
if (dir != argv)
if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
if (chdir(*dir) == -1) {
warn(*dir, ": unable to change directory: ", &strerr_sys);
continue;
}
if ((fd =open_write("supervise/ok")) == -1) {
if (errno == error_nodevice)
warn(*dir, ": runsv not running.", 0);
else
warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
continue;
}
close(fd);
if ((fd =open_read("supervise/status")) == -1) {
warn(*dir, "unable to open supervise/status: ", &strerr_sys);
continue;
}
r =buffer_unixread(fd, status, sizeof status);
close(fd);
if (r < sizeof status) {
if (r == -1)
warn(*dir, "unable to read supervise/status: ", &strerr_sys);
else
warn(*dir, ": unable to read supervise/status: bad format.", 0);
continue;
}
pid =(unsigned char)status[15];
pid <<=8; pid +=(unsigned char)status[14];
pid <<=8; pid +=(unsigned char)status[13];
pid <<=8; pid +=(unsigned char)status[12];
if (! pid) {
warn(*dir, ": is down.", 0);
continue;
}
tai_unpack(status, &when);
tai_now(&now);
if (tai_less(&now, &when)) when =now;
tai_sub(&when, &now, &when);
is =tai_approx(&when);
if (is >= sec) {
/* ok */
if (verbose) {
sulong[fmt_ulong(sulong, is)] =0;
strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0);
}
dir++;
continue;
}
sleep(sec -is);
}
if (fchdir(wdir) == -1)
strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
close(wdir);
if (rc > 100) rc =100;
_exit(rc);
}
admin/runit-2.2.0/src/open_read.c 0000644 0000000 0000000 00000000232 14675400254 015335 0 ustar root root /* Public domain. */
#include
#include
#include "open.h"
int open_read(const char *fn)
{ return open(fn,O_RDONLY | O_NDELAY); }
admin/runit-2.2.0/src/taia_pack.c 0000644 0000000 0000000 00000000550 14675400254 015320 0 ustar root root /* Public domain. */
#include "taia.h"
void taia_pack(char *s,const struct taia *t)
{
unsigned long x;
tai_pack(s,&t->sec);
s += 8;
x = t->atto;
s[7] = x & 255; x >>= 8;
s[6] = x & 255; x >>= 8;
s[5] = x & 255; x >>= 8;
s[4] = x;
x = t->nano;
s[3] = x & 255; x >>= 8;
s[2] = x & 255; x >>= 8;
s[1] = x & 255; x >>= 8;
s[0] = x;
}
admin/runit-2.2.0/src/fifo.c 0000644 0000000 0000000 00000000433 14675400254 014327 0 ustar root root /* Public domain. */
#include
#include
#include "hasmkffo.h"
#include "fifo.h"
#ifdef HASMKFIFO
int fifo_make(const char *fn,int mode) { return mkfifo(fn,mode); }
#else
int fifo_make(const char *fn,int mode) { return mknod(fn,S_IFIFO | mode,0); }
#endif
admin/runit-2.2.0/src/runit.check 0000755 0000000 0000000 00000000030 14675400254 015374 0 ustar root root #!/bin/sh
runit
echo $?
admin/runit-2.2.0/src/fmt_ptime.c 0000644 0000000 0000000 00000002131 14675400254 015365 0 ustar root root #include
#include "fmt_ptime.h"
#include "fmt.h"
unsigned int fmt_ptime2(char *s, struct taia *ta, char sep) {
struct tm *t;
time_t u;
if (ta->sec.x < 4611686018427387914ULL) return(0); /* impossible? */
u =ta->sec.x -4611686018427387914ULL;
if (! (t =gmtime((time_t*)&u))) return(0);
fmt_ulong(s, 1900 +t->tm_year);
s[4] ='-'; fmt_uint0(&s[5], t->tm_mon +1, 2);
s[7] ='-'; fmt_uint0(&s[8], t->tm_mday, 2);
s[10] =sep; fmt_uint0(&s[11], t->tm_hour, 2);
s[13] =':'; fmt_uint0(&s[14], t->tm_min, 2);
s[16] =':'; fmt_uint0(&s[17], t->tm_sec, 2);
s[19] ='.'; fmt_uint0(&s[20], ta->nano, 9);
return(25);
}
unsigned int fmt_ptime(char *s, struct taia *ta) {
return(fmt_ptime2(s, ta, '_'));
}
unsigned int fmt_ptime_iso8601(char *s, struct taia *ta) {
return(fmt_ptime2(s, ta, 'T'));
}
unsigned int fmt_taia(char *s, struct taia *t) {
static char hex[16] ="0123456789abcdef";
static char pack[TAIA_PACK];
int i;
taia_pack(pack, t);
s[0] ='@';
for (i =0; i < 12; ++i) {
s[i *2 +1] =hex[(pack[i] >>4) &15];
s[i *2 +2] =hex[pack[i] &15];
}
return(25);
}
admin/runit-2.2.0/src/gen_alloc.h 0000644 0000000 0000000 00000000303 14675400254 015330 0 ustar root root /* Public domain. */
#ifndef GEN_ALLOC_H
#define GEN_ALLOC_H
#define GEN_ALLOC_typedef(ta,type,field,len,a) \
typedef struct ta { type *field; unsigned int len; unsigned int a; } ta;
#endif
admin/runit-2.2.0/src/taia_frac.c 0000644 0000000 0000000 00000000216 14675400254 015314 0 ustar root root /* Public domain. */
#include "taia.h"
double taia_frac(const struct taia *t)
{
return (t->atto * 0.000000001 + t->nano) * 0.000000001;
}
admin/runit-2.2.0/src/buffer.h 0000644 0000000 0000000 00000003150 14675400254 014661 0 ustar root root /* Public domain. */
#ifndef BUFFER_H
#define BUFFER_H
typedef struct buffer {
char *x;
unsigned int p;
unsigned int n;
int fd;
int (*op)();
} buffer;
#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
#define BUFFER_INSIZE 8192
#define BUFFER_OUTSIZE 8192
extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int);
extern int buffer_flush(buffer *);
extern int buffer_put(buffer *,const char *,unsigned int);
extern int buffer_putalign(buffer *,const char *,unsigned int);
extern int buffer_putflush(buffer *,const char *,unsigned int);
extern int buffer_puts(buffer *,const char *);
extern int buffer_putsalign(buffer *,const char *);
extern int buffer_putsflush(buffer *,const char *);
#define buffer_PUTC(s,c) \
( ((s)->n != (s)->p) \
? ( (s)->x[(s)->p++] = (c), 0 ) \
: buffer_put((s),&(c),1) \
)
extern int buffer_get(buffer *,char *,unsigned int);
extern int buffer_bget(buffer *,char *,unsigned int);
extern int buffer_feed(buffer *);
extern char *buffer_peek(buffer *);
extern void buffer_seek(buffer *,unsigned int);
#define buffer_PEEK(s) ( (s)->x + (s)->n )
#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
#define buffer_GETC(s,c) \
( ((s)->p > 0) \
? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \
: buffer_get((s),(c),1) \
)
extern int buffer_copy(buffer *,buffer *);
extern int buffer_unixread(int,char *,unsigned int);
extern int buffer_unixwrite(int,const char *,unsigned int);
extern buffer *buffer_0;
extern buffer *buffer_0small;
extern buffer *buffer_1;
extern buffer *buffer_1small;
extern buffer *buffer_2;
#endif
admin/runit-2.2.0/src/warn-shsgr 0000644 0000000 0000000 00000000313 14675400254 015253 0 ustar root root Oops. Your getgroups() returned 0, and setgroups() failed; this means
that I can't reliably do my shsgr test. Please either ``make'' as root
or ``make'' while you're in one or more supplementary groups.
admin/runit-2.2.0/src/hasshsgr.h1 0000644 0000000 0000000 00000000064 14675400254 015314 0 ustar root root /* Public domain. */
/* sysdep: -shortsetgroups */
admin/runit-2.2.0/src/utmpset.dist 0000644 0000000 0000000 00000000150 14675400254 015622 0 ustar root root usage: utmpset [-w] line
1
$Id: 6ced914b40d54fdfee353c5b5fdaf297031295e9 $
usage: utmpset [-w] line
1
admin/runit-2.2.0/src/buffer.c 0000644 0000000 0000000 00000000275 14675400254 014661 0 ustar root root /* Public domain. */
#include "buffer.h"
void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len)
{
s->x = buf;
s->fd = fd;
s->op = op;
s->p = 0;
s->n = len;
}
admin/runit-2.2.0/src/tryflock.c 0000644 0000000 0000000 00000000216 14675400254 015240 0 ustar root root /* Public domain. */
#include
#include
#include
int main()
{
flock(0,LOCK_EX | LOCK_UN | LOCK_NB);
}
admin/runit-2.2.0/src/lock.h 0000644 0000000 0000000 00000000212 14675400254 014334 0 ustar root root /* Public domain. */
#ifndef LOCK_H
#define LOCK_H
extern int lock_ex(int);
extern int lock_un(int);
extern int lock_exnb(int);
#endif
admin/runit-2.2.0/src/runit.h 0000644 0000000 0000000 00000000260 14675400254 014550 0 ustar root root #define RUNIT "/sbin/runit"
#define STOPIT "/etc/runit/stopit"
#define REBOOT "/etc/runit/reboot"
#define NOSYNC "/etc/runit/nosync"
#define CTRLALTDEL "/etc/runit/ctrlaltdel"
admin/runit-2.2.0/src/runit-init.dist 0000644 0000000 0000000 00000000031 14675400254 016221 0 ustar root root usage: runit-init 0|6
0
admin/runit-2.2.0/src/warn-auto.sh 0000644 0000000 0000000 00000000100 14675400254 015500 0 ustar root root #!/bin/sh
# WARNING: This file was auto-generated. Do not edit!
admin/runit-2.2.0/src/utmpset.c 0000644 0000000 0000000 00000005371 14675400254 015113 0 ustar root root #include
#include
#include
#include
#include
#include
#include "uw_tmp.h"
#include "strerr.h"
#include "sgetopt.h"
#include "seek.h"
#include "str.h"
#include "open.h"
#include "byte.h"
#include "lock.h"
#define USAGE " [-w] line"
#define FATAL "utmpset: fatal: "
#define WARNING "utmpset: warning: "
const char *progname;
void usage(void) { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
int utmp_logout(const char *line) {
int fd;
uw_tmp ut;
time_t t;
int ok =-1;
if ((fd =open(UW_TMP_UFILE, O_RDWR, 0)) < 0)
strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_UFILE, ": ");
if (lock_ex(fd) == -1)
strerr_die4sys(111, FATAL, "unable to lock: ", UW_TMP_UFILE, ": ");
while (read(fd, &ut, sizeof(uw_tmp)) == sizeof(uw_tmp)) {
if (!ut.ut_name[0] || (str_diff(ut.ut_line, line) != 0)) continue;
memset(ut.ut_name, 0, sizeof ut.ut_name);
memset(ut.ut_host, 0, sizeof ut.ut_host);
if (time(&t) == -1) break;
ut.ut_time = t;
#ifdef DEAD_PROCESS
ut.ut_type =DEAD_PROCESS;
#endif
if (lseek(fd, -(off_t)sizeof(uw_tmp), SEEK_CUR) == -1) break;
if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) break;
ok =1;
break;
}
close(fd);
return(ok);
}
int wtmp_logout(const char *line) {
int fd;
int len;
struct stat st;
uw_tmp ut;
time_t t;
if ((fd = open_append(UW_TMP_WFILE)) == -1)
strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_WFILE, ": ");
if (lock_ex(fd) == -1)
strerr_die4sys(111, FATAL, "unable to lock ", UW_TMP_WFILE, ": ");
if (fstat(fd, &st) == -1) {
close(fd);
return(-1);
}
memset(&ut, 0, sizeof(uw_tmp));
if ((len =str_len(line)) > sizeof ut.ut_line) len =sizeof ut.ut_line -2;
byte_copy(ut.ut_line, len, line);
if (time(&t) == -1) {
close(fd);
return(-1);
}
ut.ut_time = t;
#ifdef DEAD_PROCESS
ut.ut_type =DEAD_PROCESS;
#endif
if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) {
ftruncate(fd, st.st_size);
close(fd);
return(-1);
}
close(fd);
return(1);
}
int main (int argc, char * const *argv, const char * const *envp) {
int opt;
int wtmp =0;
progname =*argv;
while ((opt =getopt(argc, argv, "wV")) != opteof) {
switch(opt) {
case 'w':
wtmp =1;
break;
case 'V':
strerr_warn1("$Id: 6ced914b40d54fdfee353c5b5fdaf297031295e9 $", 0);
case '?':
usage();
}
}
argv +=optind;
if (! argv || ! *argv) usage();
if (utmp_logout(*argv) == -1)
strerr_die4x(111, WARNING, "unable to logout line ", *argv,
" in utmp: no such entry");
if (wtmp)
if (wtmp_logout(*argv) == -1)
strerr_die4sys(111, WARNING,
"unable to logout line ", *argv, " in wtmp: ");
_exit(0);
}
admin/runit-2.2.0/src/byte.h 0000644 0000000 0000000 00000000427 14675400254 014357 0 ustar root root /* Public domain. */
#ifndef BYTE_H
#define BYTE_H
extern unsigned int byte_chr();
extern unsigned int byte_rchr();
extern void byte_copy();
extern void byte_copyr();
extern int byte_diff();
extern void byte_zero();
#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
#endif
admin/runit-2.2.0/src/buffer_get.c 0000644 0000000 0000000 00000002367 14675400254 015524 0 ustar root root /* Public domain. */
#include "buffer.h"
#include "byte.h"
#include "error.h"
static int oneread(int (*op)(),int fd,char *buf,unsigned int len)
{
int r;
for (;;) {
r = op(fd,buf,len);
if (r == -1) if (errno == error_intr) continue;
return r;
}
}
static int getthis(buffer *s,char *buf,unsigned int len)
{
if (len > s->p) len = s->p;
s->p -= len;
byte_copy(buf,len,s->x + s->n);
s->n += len;
return len;
}
int buffer_feed(buffer *s)
{
int r;
if (s->p) return s->p;
r = oneread(s->op,s->fd,s->x,s->n);
if (r <= 0) return r;
s->p = r;
s->n -= r;
if (s->n > 0) byte_copyr(s->x + s->n,r,s->x);
return r;
}
int buffer_bget(buffer *s,char *buf,unsigned int len)
{
int r;
if (s->p > 0) return getthis(s,buf,len);
if (s->n <= len) return oneread(s->op,s->fd,buf,s->n);
r = buffer_feed(s); if (r <= 0) return r;
return getthis(s,buf,len);
}
int buffer_get(buffer *s,char *buf,unsigned int len)
{
int r;
if (s->p > 0) return getthis(s,buf,len);
if (s->n <= len) return oneread(s->op,s->fd,buf,len);
r = buffer_feed(s); if (r <= 0) return r;
return getthis(s,buf,len);
}
char *buffer_peek(buffer *s)
{
return s->x + s->n;
}
void buffer_seek(buffer *s,unsigned int len)
{
s->n += len;
s->p -= len;
}
admin/runit-2.2.0/src/chpst.check 0000755 0000000 0000000 00000000536 14675400254 015367 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
chpst
echo $?
chpst -V
echo $?
# -u
# -U
mkdir "${ctmp}"
echo 1 >"${ctmp}"/test
chpst -e"${ctmp}" env |sed -ne '/^test=1$/p'
echo $?
rm -rf "${ctmp}"
chpst -l"${ctmp}" true
echo $?
rm -f "${ctmp}"
chpst -L"${ctmp}" true
echo $?
rm -f "${ctmp}"
# -m
# -o
# -p
# -f
# -c
chpst -P true
echo $?
chpst -012 true
echo $?
admin/runit-2.2.0/src/alloc_re.c 0000644 0000000 0000000 00000000354 14675400254 015166 0 ustar root root /* Public domain. */
#include "alloc.h"
#include "byte.h"
int alloc_re(x,m,n)
char **x;
unsigned int m;
unsigned int n;
{
char *y;
y = alloc(n);
if (!y) return 0;
byte_copy(y,m,*x);
alloc_free(*x);
*x = y;
return 1;
}
admin/runit-2.2.0/src/openreadclose.c 0000644 0000000 0000000 00000000540 14675400254 016226 0 ustar root root /* Public domain. */
#include "error.h"
#include "open.h"
#include "readclose.h"
#include "openreadclose.h"
int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize)
{
int fd;
fd = open_read(fn);
if (fd == -1) {
if (errno == error_noent) return 0;
return -1;
}
if (readclose(fd,sa,bufsize) == -1) return -1;
return 1;
}
admin/runit-2.2.0/src/svlogd.dist 0000644 0000000 0000000 00000000356 14675400254 015427 0 ustar root root usage: svlogd [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ...
111
$Id: 66d40067fb843ee6cde160e47c9dee5c73986f6d $
usage: svlogd [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ...
111
0
foo
0
foo
bar
baz
0
foo
bar
baz
:oo
:ar
:az
0
admin/runit-2.2.0/src/utmpset.check 0000755 0000000 0000000 00000000055 14675400254 015743 0 ustar root root #!/bin/sh
utmpset
echo $?
utmpset -V
echo $?
admin/runit-2.2.0/src/uw_tmp.h1 0000644 0000000 0000000 00000000546 14675400254 015012 0 ustar root root #include
#include
/* sysdep: -utmpx */
#ifdef _PATH_UTMP
#define UW_TMP_UFILE _PATH_UTMP
#define UW_TMP_WFILE _PATH_WTMP
#else
/* AIX only has UTMP_FILE */
#ifdef UTMP_FILE
#define UW_TMP_UFILE UTMP_FILE
#define UW_TMP_WFILE WTMP_FILE
#else
#error neither _PATH_UTMP nor UTMP_FILE defined.
#endif
#endif
typedef struct utmp uw_tmp;
admin/runit-2.2.0/src/readclose.c 0000644 0000000 0000000 00000001055 14675400254 015346 0 ustar root root /* Public domain. */
#include
#include "error.h"
#include "readclose.h"
int readclose_append(int fd,stralloc *sa,unsigned int bufsize)
{
int r;
for (;;) {
if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; }
r = read(fd,sa->s + sa->len,bufsize);
if (r == -1) if (errno == error_intr) continue;
if (r <= 0) { close(fd); return r; }
sa->len += r;
}
}
int readclose(int fd,stralloc *sa,unsigned int bufsize)
{
if (!stralloc_copys(sa,"")) { close(fd); return -1; }
return readclose_append(fd,sa,bufsize);
}
admin/runit-2.2.0/src/runsvstat.check 0000755 0000000 0000000 00000000702 14675400254 016312 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
runsvstat
echo $?
runsvstat -V
echo $?
mkdir "${ctmp}"
echo '#!/bin/sh' >"${ctmp}"/run
echo 'echo starting' >>"${ctmp}"/run
echo 'exec sleep 14' >>"${ctmp}"/run
chmod 700 "${ctmp}"/run
chpst -2 runsvstat "${ctmp}"
echo $?
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
chpst -1 runsvstat "${ctmp}"
echo $?
runsvctrl exit "${ctmp}"
wait
echo $?
chpst -2 runsvstat "${ctmp}"
echo $?
rm -rf "${ctmp}"
admin/runit-2.2.0/src/fifo.h 0000644 0000000 0000000 00000000145 14675400254 014334 0 ustar root root /* Public domain. */
#ifndef FIFO_H
#define FIFO_H
extern int fifo_make(const char *,int);
#endif
admin/runit-2.2.0/src/runit.dist 0000644 0000000 0000000 00000000061 14675400254 015263 0 ustar root root - runit: fatal: must be run as process no 1.
111
admin/runit-2.2.0/src/uw_tmp.h2 0000644 0000000 0000000 00000000327 14675400254 015010 0 ustar root root #include
#include
/* sysdep: +utmpx */
#define UW_TMP_UFILE _UTMPX_FILE
#define UW_TMP_WFILE _WTMPX_FILE
#ifndef ut_time
#define ut_time ut_tv.tv_sec
#endif
typedef struct futmpx uw_tmp;
admin/runit-2.2.0/src/runsv.check 0000755 0000000 0000000 00000002557 14675400254 015430 0 ustar root root #!/bin/sh
rm -rf "${ctmp}"
runsv
echo $?
mkdir "${ctmp}"
echo '#!/bin/sh' >"${ctmp}"/run
echo 'echo starting' >>"${ctmp}"/run
echo 'exec sleep 14' >>"${ctmp}"/run
chmod 700 "${ctmp}"/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
cat "${ctmp}"/supervise/stat
mkdir -p "${ctmp}"/control
echo '#!/bin/sh' >"${ctmp}"/control/t
echo 'echo term' >>"${ctmp}"/control/t
echo 'exit 1' >>"${ctmp}"/control/t
chmod 700 "${ctmp}"/control/t
echo t >"${ctmp}"/supervise/control
sleep 2
echo x >"${ctmp}"/supervise/control
wait
echo $?
mkdir "${ctmp}"/log
echo '#!/bin/sh' >"${ctmp}"/log/run
echo 'exec cat >foo' >>"${ctmp}"/log/run
chmod 700 "${ctmp}"/log/run
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/log/supervise/stat || sleep 2
mkdir -p "${ctmp}"/control
echo '#!/bin/sh' >"${ctmp}"/control/i
echo 'echo no interrupt' >>"${ctmp}"/control/i
echo 'exit 0' >>"${ctmp}"/control/i
chmod 700 "${ctmp}"/control/i
echo i >"${ctmp}"/supervise/control
sleep 1
echo x >"${ctmp}"/supervise/control
wait
echo $?
cat "${ctmp}"/log/foo
rm -rf "${ctmp}"/supervise
rm -rf "${ctmp}"/log/supervise
rm -f "${ctmp}"/log/foo
ln -s foo "${ctmp}"/supervise
ln -s bar "${ctmp}"/log/supervise
runsv "${ctmp}" &
sleep 1
test -r "${ctmp}"/supervise/stat || sleep 2
test -r "${ctmp}"/log/supervise/stat || sleep 2
echo x >"${ctmp}"/foo/control
wait
echo $?
cat "${ctmp}"/log/foo
rm -rf "${ctmp}"
admin/runit-2.2.0/src/check-diff 0000755 0000000 0000000 00000000151 14675400254 015146 0 ustar root root #!/bin/sh
while read i; do
read j 0<&7 || exit 1
test "$i" = "$j" || exit 1
done 7<$1.dist <$1.local
admin/runit-2.2.0/src/seek.h 0000644 0000000 0000000 00000000427 14675400254 014343 0 ustar root root /* Public domain. */
#ifndef SEEK_H
#define SEEK_H
typedef unsigned long seek_pos;
extern seek_pos seek_cur(int);
extern int seek_set(int,seek_pos);
extern int seek_end(int);
extern int seek_trunc(int,seek_pos);
#define seek_begin(fd) (seek_set((fd),(seek_pos) 0))
#endif
admin/runit-2.2.0/src/taia_uint.c 0000644 0000000 0000000 00000000256 14675400254 015364 0 ustar root root /* Public domain. */
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_uint(struct taia *t,unsigned int s)
{
t->sec.x = s;
t->nano = 0;
t->atto = 0;
}
admin/runit-2.2.0/src/svwaitdown.dist 0000644 0000000 0000000 00000000177 14675400254 016337 0 ustar root root usage: svwaitdown [-v] [-t 1..6000] service ...
1
$Id$
usage: svwaitdown [-v] [-t 1..6000] service ...
1
starting
0
0
down
0
admin/runit-2.2.0/src/trysysel.c 0000644 0000000 0000000 00000000226 14675400254 015302 0 ustar root root /* Public domain. */
#include
#include
#include
#include /* SVR4 silliness */
void foo()
{
;
}
admin/runit-2.2.0/src/runsv.c 0000644 0000000 0000000 00000036701 14675400254 014570 0 ustar root root #include
#include
#include
#include
#include
#include "strerr.h"
#include "error.h"
#include "taia.h"
#include "sig.h"
#include "env.h"
#include "coe.h"
#include "ndelay.h"
#include "fifo.h"
#include "open.h"
#include "lock.h"
#include "iopause.h"
#include "wait.h"
#include "fd.h"
#include "buffer.h"
#include "fmt.h"
#include "byte.h"
#define USAGE " dir"
#define VERSION "$Id: ecf467746d7b97ff0fddb88b9d44cca201c74160 $"
char *progname;
int selfpipe[2];
/* state */
#define S_DOWN 0
#define S_RUN 1
#define S_FINISH 2
/* ctrl */
#define C_NOOP 0
#define C_TERM 1
#define C_PAUSE 2
/* want */
#define W_UP 0
#define W_DOWN 1
#define W_EXIT 2
struct svdir {
int pid;
int state;
int ctrl;
int want;
struct taia start;
int wstat;
int fdlock;
int fdcontrol;
int fdcontrolwrite;
int islog;
};
struct svdir svd[2];
int sigterm =0;
int haslog =0;
int pidchanged =1;
int logpipe[2];
char *dir;
void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
void fatal(char *m) {
strerr_die5sys(111, "runsv ", dir, ": fatal: ", m, ": ");
}
void fatal2(char *m1, char *m2) {
strerr_die6sys(111, "runsv ", dir, ": fatal: ", m1, m2, ": ");
}
void fatalx(char *m1, char *m2) {
strerr_die5x(111, "runsv ", dir, ": fatal: ", m1, m2);
}
void warn(char *m) {
strerr_warn5("runsv ", dir, ": warning: ", m, ": ", &strerr_sys);
}
void warn2(char *m1, char *m2) {
strerr_warn6("runsv ", dir, ": warning: ", m1, m2, ": ", &strerr_sys);
}
void warnx(char *m1, char *m2, char *m3) {
strerr_warn6("runsv ", dir, ": warning: ", m1, m2, m3, 0);
}
void stopservice(struct svdir *);
void s_child() { write(selfpipe[1], "", 1); }
void s_term() {
sigterm =1;
write(selfpipe[1], "", 1); /* XXX */
}
void update_status(struct svdir *s) {
unsigned long l;
int fd;
char status[20];
char bspace[64];
buffer b;
char spid[FMT_ULONG];
char *fstatus ="supervise/status";
char *fstatusnew ="supervise/status.new";
char *fstat ="supervise/stat";
char *fstatnew ="supervise/stat.new";
char *fpid ="supervise/pid";
char *fpidnew ="supervise/pid.new";
if (s->islog) {
fstatus ="log/supervise/status";
fstatusnew ="log/supervise/status.new";
fstat ="log/supervise/stat";
fstatnew ="log/supervise/stat.new";
fpid ="log/supervise/pid";
fpidnew ="log/supervise/pid.new";
}
/* pid */
if (pidchanged) {
if ((fd =open_trunc(fpidnew)) == -1) {
warn2("unable to open ", fpidnew);
return;
}
buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace);
spid[fmt_ulong(spid, (unsigned long)s->pid)] =0;
if (s->pid) {
buffer_puts(&b, spid);
buffer_puts(&b, "\n");
buffer_flush(&b);
}
close(fd);
if (rename(fpidnew, fpid) == -1) {
warn2("unable to rename pid.new to ", fpid);
return;
}
pidchanged =0;
}
/* stat */
if ((fd =open_trunc(fstatnew)) == -1) {
warn2("unable to open ", fstatnew);
return;
}
buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace);
switch (s->state) {
case S_DOWN:
buffer_puts(&b, "down");
break;
case S_RUN:
buffer_puts(&b, "run");
break;
case S_FINISH:
buffer_puts(&b, "finish");
break;
}
if (s->ctrl & C_PAUSE) buffer_puts(&b, ", paused");
if (s->ctrl & C_TERM) buffer_puts(&b, ", got TERM");
if (s->state != S_DOWN)
switch(s->want) {
case W_DOWN:
buffer_puts(&b, ", want down");
break;
case W_EXIT:
buffer_puts(&b, ", want exit");
break;
}
buffer_puts(&b, "\n");
buffer_flush(&b);
close(fd);
if (rename(fstatnew, fstat) == -1)
warn2("unable to rename stat.new to ", fstat);
/* supervise compatibility */
taia_pack(status, &s->start);
l =(unsigned long)s->pid;
status[12] =l; l >>=8;
status[13] =l; l >>=8;
status[14] =l; l >>=8;
status[15] =l;
if (s->ctrl & C_PAUSE)
status[16] =1;
else
status[16] =0;
if (s->want == W_UP)
status[17] ='u';
else
status[17] ='d';
if (s->ctrl & C_TERM)
status[18] =1;
else
status[18] =0;
status[19] =s->state;
if ((fd =open_trunc(fstatusnew)) == -1) {
warn2("unable to open ", fstatusnew);
return;
}
if ((l =write(fd, status, sizeof status)) == -1) {
warn2("unable to write ", fstatusnew);
close(fd);
unlink(fstatusnew);
return;
}
close(fd);
if (l < sizeof status) {
warnx("unable to write ", fstatusnew, ": partial write.");
return;
}
if (rename(fstatusnew, fstatus) == -1)
warn2("unable to rename status.new to ", fstatus);
}
unsigned int custom(struct svdir *s, char c) {
int pid;
int w;
char a[10];
struct stat st;
char *prog[2];
if (s->islog) return(0);
byte_copy(a, 10, "control/?");
a[8] =c;
if (stat(a, &st) == 0) {
if (st.st_mode & S_IXUSR) {
if ((pid =fork()) == -1) {
warn2("unable to fork for ", a);
return(0);
}
if (! pid) {
if (haslog && fd_copy(1, logpipe[1]) == -1)
warn2("unable to setup stdout for ", a);
prog[0] =a;
prog[1] =0;
execve(a, prog, environ);
fatal("unable to run control/?");
}
while (wait_pid(&w, pid) == -1) {
if (errno == error_intr) continue;
warn2("unable to wait for child ", a);
return(0);
}
return(! wait_exitcode(w));
}
}
else {
if (errno == error_noent) return(0);
warn2("unable to stat ", a);
}
return(0);
}
void stopservice(struct svdir *s) {
if (s->pid && ! custom(s, 't')) {
kill(s->pid, SIGTERM);
s->ctrl |=C_TERM;
update_status(s);
}
if (s->want == W_DOWN) {
kill(s->pid, SIGCONT);
custom(s, 'd'); return;
}
if (s->want == W_EXIT) {
kill(s->pid, SIGCONT);
custom(s, 'x');
}
}
void startservice(struct svdir *s) {
int p;
char *run[4];
char code[FMT_ULONG];
char stat[FMT_ULONG];
if (s->state == S_FINISH) {
run[0] ="./finish";
code[fmt_ulong(code, wait_exitcode(s->wstat))] =0;
run[1] =wait_crashed(s->wstat) ? "-1" : code;
stat[fmt_ulong(stat, s->wstat & 0xff)] =0;
run[2] =stat;
run[3] =0;
}
else {
run[0] ="./run";
custom(s, 'u');
run[1] =0;
}
if (s->pid != 0) stopservice(s); /* should never happen */
while ((p =fork()) == -1) {
warn("unable to fork, sleeping");
sleep(5);
}
if (p == 0) {
/* child */
if (haslog) {
if (s->islog) {
if (fd_copy(0, logpipe[0]) == -1)
fatal("unable to setup filedescriptor for ./log/run");
close(logpipe[1]);
if (chdir("./log") == -1)
fatal("unable to change directory to ./log");
}
else {
if (fd_copy(1, logpipe[1]) == -1)
fatal("unable to setup filedescriptor for ./run");
close(logpipe[0]);
}
}
sig_uncatch(sig_child);
sig_unblock(sig_child);
sig_uncatch(sig_term);
sig_unblock(sig_term);
execve(*run, run, environ);
if (s->islog)
fatal2("unable to start log/", *run);
else
fatal2("unable to start ", *run);
}
if (s->state != S_FINISH) {
taia_now(&s->start);
s->state =S_RUN;
}
s->pid =p;
pidchanged =1;
s->ctrl =C_NOOP;
update_status(s);
}
int ctrl(struct svdir *s, char c) {
switch(c) {
case 'd': /* down */
s->want =W_DOWN;
update_status(s);
if (s->state == S_RUN) stopservice(s);
break;
case 'u': /* up */
s->want =W_UP;
update_status(s);
if (s->state == S_DOWN) startservice(s);
break;
case 'x': /* exit */
if (s->islog) break;
s->want =W_EXIT;
update_status(s);
if (s->state == S_RUN) stopservice(s);
break;
case 't': /* sig term */
if (s->state == S_RUN) stopservice(s);
break;
case 'k': /* sig kill */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGKILL);
s->state =S_DOWN;
break;
case 'p': /* sig pause */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGSTOP);
s->ctrl |=C_PAUSE;
update_status(s);
break;
case 'c': /* sig cont */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGCONT);
if (s->ctrl & C_PAUSE) s->ctrl &=~C_PAUSE;
update_status(s);
break;
case 'o': /* once */
s->want =W_DOWN;
update_status(s);
if (s->state == S_DOWN) startservice(s);
break;
case 'a': /* sig alarm */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGALRM);
break;
case 'h': /* sig hup */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGHUP);
break;
case 'i': /* sig int */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGINT);
break;
case 'q': /* sig quit */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGQUIT);
break;
case '1': /* sig usr1 */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGUSR1);
break;
case '2': /* sig usr2 */
if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGUSR2);
break;
}
return(1);
}
int main(int argc, char **argv) {
struct stat s;
int fd;
int r;
char buf[256];
progname =argv[0];
if (! argv[1] || argv[2]) usage();
dir =argv[1];
if (pipe(selfpipe) == -1) fatal("unable to create selfpipe");
coe(selfpipe[0]);
coe(selfpipe[1]);
ndelay_on(selfpipe[0]);
ndelay_on(selfpipe[1]);
sig_block(sig_child);
sig_catch(sig_child, s_child);
sig_block(sig_term);
sig_catch(sig_term, s_term);
if (chdir(dir) == -1) fatal("unable to change to directory");
svd[0].pid =0;
svd[0].state =S_DOWN;
svd[0].ctrl =C_NOOP;
svd[0].want =W_UP;
svd[0].islog =0;
svd[1].pid =0;
taia_now(&svd[0].start);
if (stat("down", &s) != -1) svd[0].want =W_DOWN;
if (stat("log", &s) == -1) {
if (errno != error_noent)
warn("unable to stat() ./log: ");
}
else {
if (! S_ISDIR(s.st_mode))
warnx("./log", 0, ": not a directory.");
else {
haslog =1;
svd[1].state =S_DOWN;
svd[1].ctrl =C_NOOP;
svd[1].want =W_UP;
svd[1].islog =1;
taia_now(&svd[1].start);
if (stat("log/down", &s) != -1)
svd[1].want =W_DOWN;
if (pipe(logpipe) == -1)
fatal("unable to create log pipe");
coe(logpipe[0]);
coe(logpipe[1]);
}
}
if (mkdir("supervise", 0700) == -1) {
if ((r =readlink("supervise", buf, 256)) != -1) {
if (r == 256)
fatalx("unable to readlink ./supervise: ", "name too long");
buf[r] =0;
mkdir(buf, 0700);
}
else {
if ((errno != ENOENT) && (errno != EINVAL))
fatal("unable to readlink ./supervise");
}
}
if ((svd[0].fdlock =open_append("supervise/lock")) == -1)
fatal("unable to open supervise/lock");
if (lock_exnb(svd[0].fdlock) == -1) fatal("unable to lock supervise/lock");
coe(svd[0].fdlock);
if (haslog) {
if (mkdir("log/supervise", 0700) == -1) {
if ((r =readlink("log/supervise", buf, 256)) != -1) {
if (r == 256)
fatalx("unable to readlink ./log/supervise: ", "name too long");
buf[r] =0;
if ((fd =open_read(".")) == -1)
fatal("unable to open current directory");
if (chdir("./log") == -1)
fatal("unable to change directory to ./log");
mkdir(buf, 0700);
if (fchdir(fd) == -1)
fatal("unable to change back to service directory");
close(fd);
}
else {
if ((errno != ENOENT) && (errno != EINVAL))
fatal("unable to readlink ./log/supervise");
}
}
if ((svd[1].fdlock =open_append("log/supervise/lock")) == -1)
fatal("unable to open log/supervise/lock");
if (lock_ex(svd[1].fdlock) == -1)
fatal("unable to lock log/supervise/lock");
coe(svd[1].fdlock);
}
fifo_make("supervise/control", 0600);
if (stat("supervise/control", &s) == -1)
fatal("unable to stat supervise/control");
if (!S_ISFIFO(s.st_mode))
fatalx("supervise/control exists but is not a fifo", "");
if ((svd[0].fdcontrol =open_read("supervise/control")) == -1)
fatal("unable to open supervise/control");
coe(svd[0].fdcontrol);
if ((svd[0].fdcontrolwrite =open_write("supervise/control")) == -1)
fatal("unable to open supervise/control");
coe(svd[0].fdcontrolwrite);
update_status(&svd[0]);
if (haslog) {
fifo_make("log/supervise/control", 0600);
if (stat("supervise/control", &s) == -1)
fatal("unable to stat log/supervise/control");
if (!S_ISFIFO(s.st_mode))
fatalx("log/supervise/control exists but is not a fifo", "");
if ((svd[1].fdcontrol =open_read("log/supervise/control")) == -1)
fatal("unable to open log/supervise/control");
coe(svd[1].fdcontrol);
if ((svd[1].fdcontrolwrite =open_write("log/supervise/control")) == -1)
fatal("unable to open log/supervise/control");
coe(svd[1].fdcontrolwrite);
update_status(&svd[1]);
}
fifo_make("supervise/ok",0600);
if ((fd =open_read("supervise/ok")) == -1)
fatal("unable to read supervise/ok");
coe(fd);
if (haslog) {
fifo_make("log/supervise/ok",0600);
if ((fd =open_read("log/supervise/ok")) == -1)
fatal("unable to read log/supervise/ok");
coe(fd);
}
for (;;) {
iopause_fd x[3];
struct taia deadline;
struct taia now;
char ch;
if (haslog)
if (! svd[1].pid && (svd[1].want == W_UP)) startservice(&svd[1]);
if (! svd[0].pid)
if ((svd[0].want == W_UP) || (svd[0].state == S_FINISH))
startservice(&svd[0]);
x[0].fd =selfpipe[0];
x[0].events =IOPAUSE_READ;
x[1].fd =svd[0].fdcontrol;
x[1].events =IOPAUSE_READ;
if (haslog) {
x[2].fd =svd[1].fdcontrol;
x[2].events =IOPAUSE_READ;
}
taia_now(&now);
taia_uint(&deadline, 3600);
taia_add(&deadline, &now, &deadline);
sig_unblock(sig_term);
sig_unblock(sig_child);
iopause(x, 2 +haslog, &deadline, &now);
sig_block(sig_term);
sig_block(sig_child);
while (read(selfpipe[0], &ch, 1) == 1)
;
for (;;) {
int child;
int wstat;
child =wait_nohang(&wstat);
if (!child) break;
if ((child == -1) && (errno != error_intr)) break;
if (child == svd[0].pid) {
svd[0].pid =0;
pidchanged =1;
svd[0].wstat =wstat;
svd[0].ctrl &=~C_TERM;
if (svd[0].state != S_FINISH)
if ((fd =open_read("finish")) != -1) {
close(fd);
svd[0].state =S_FINISH;
update_status(&svd[0]);
continue;
}
svd[0].state =S_DOWN;
taia_uint(&deadline, 1);
taia_add(&deadline, &svd[0].start, &deadline);
taia_now(&svd[0].start);
update_status(&svd[0]);
if (taia_less(&svd[0].start, &deadline)) sleep(1);
}
if (haslog) {
if (child == svd[1].pid) {
svd[1].pid =0;
pidchanged =1;
svd[1].state =S_DOWN;
svd[1].ctrl &=~C_TERM;
taia_uint(&deadline, 1);
taia_add(&deadline, &svd[1].start, &deadline);
taia_now(&svd[1].start);
update_status(&svd[1]);
if (taia_less(&svd[1].start, &deadline)) sleep(1);
}
}
}
if (read(svd[0].fdcontrol, &ch, 1) == 1) ctrl(&svd[0], ch);
if (haslog)
if (read(svd[1].fdcontrol, &ch, 1) == 1) ctrl(&svd[1], ch);
if (sigterm) { ctrl(&svd[0], 'x'); sigterm =0; }
if ((svd[0].want == W_EXIT) && (svd[0].state == S_DOWN)) {
if (svd[1].pid == 0) _exit(0);
if (svd[1].want != W_EXIT) {
svd[1].want =W_EXIT;
/* stopservice(&svd[1]); */
update_status(&svd[1]);
if (close(logpipe[1]) == -1) warn("unable to close logpipe[1]");
if (close(logpipe[0]) == -1) warn("unable to close logpipe[0]");
}
}
}
_exit(0);
}
admin/runit-2.2.0/src/stralloc_pend.c 0000644 0000000 0000000 00000000257 14675400254 016241 0 ustar root root /* Public domain. */
#include "alloc.h"
#include "stralloc.h"
#include "gen_allocdefs.h"
GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)
admin/runit-2.2.0/src/hassgact.h1 0000644 0000000 0000000 00000000057 14675400254 015271 0 ustar root root /* Public domain. */
/* sysdep: -sigaction */
admin/runit-2.2.0/src/trywaitp.c 0000644 0000000 0000000 00000000145 14675400254 015267 0 ustar root root /* Public domain. */
#include
#include
int main()
{
waitpid(0,0,0);
}
admin/runit-2.2.0/src/fd_copy.c 0000644 0000000 0000000 00000000401 14675400254 015022 0 ustar root root /* Public domain. */
#include
#include
#include "fd.h"
int fd_copy(int to,int from)
{
if (to == from) return 0;
if (fcntl(from,F_GETFL,0) == -1) return -1;
close(to);
if (fcntl(from,F_DUPFD,to) == -1) return -1;
return 0;
}
admin/runit-2.2.0/src/openreadclose.h 0000644 0000000 0000000 00000000246 14675400254 016236 0 ustar root root /* Public domain. */
#ifndef OPENREADCLOSE_H
#define OPENREADCLOSE_H
#include "stralloc.h"
extern int openreadclose(const char *,stralloc *,unsigned int);
#endif
admin/runit-2.2.0/src/taia.h 0000644 0000000 0000000 00000001742 14675400254 014333 0 ustar root root /* Public domain. */
#ifndef TAIA_H
#define TAIA_H
#include "tai.h"
struct taia {
struct tai sec;
unsigned long nano; /* 0...999999999 */
unsigned long atto; /* 0...999999999 */
} ;
extern void taia_tai(const struct taia *,struct tai *);
extern void taia_now(struct taia *);
extern double taia_approx(const struct taia *);
extern double taia_frac(const struct taia *);
extern void taia_add(struct taia *,const struct taia *,const struct taia *);
extern void taia_addsec(struct taia *,const struct taia *,int);
extern void taia_sub(struct taia *,const struct taia *,const struct taia *);
extern void taia_half(struct taia *,const struct taia *);
extern int taia_less(const struct taia *,const struct taia *);
#define TAIA_PACK 16
extern void taia_pack(char *,const struct taia *);
extern void taia_unpack(const char *,struct taia *);
#define TAIA_FMTFRAC 19
extern unsigned int taia_fmtfrac(char *,const struct taia *);
extern void taia_uint(struct taia *,unsigned int);
#endif
admin/runit-2.2.0/src/byte_chr.c 0000644 0000000 0000000 00000000630 14675400254 015202 0 ustar root root /* Public domain. */
#include "byte.h"
unsigned int byte_chr(s,n,c)
char *s;
register unsigned int n;
int c;
{
register char ch;
register char *t;
ch = c;
t = s;
for (;;) {
if (!n) break; if (*t == ch) break; ++t; --n;
if (!n) break; if (*t == ch) break; ++t; --n;
if (!n) break; if (*t == ch) break; ++t; --n;
if (!n) break; if (*t == ch) break; ++t; --n;
}
return t - s;
}
admin/runit-2.2.0/src/runsvstat.dist 0000644 0000000 0000000 00000000144 14675400254 016175 0 ustar root root usage: runsvstat [ -l ] service ...
1
$Id$
usage: runsvstat [ -l ] service ...
1
1
starting
0
0
1
admin/runit-2.2.0/src/stralloc_catb.c 0000644 0000000 0000000 00000000522 14675400254 016217 0 ustar root root /* Public domain. */
#include "stralloc.h"
#include "byte.h"
int stralloc_catb(stralloc *sa,const char *s,unsigned int n)
{
if (!sa->s) return stralloc_copyb(sa,s,n);
if (!stralloc_readyplus(sa,n + 1)) return 0;
byte_copy(sa->s + sa->len,n,s);
sa->len += n;
sa->s[sa->len] = 'Z'; /* ``offensive programming'' */
return 1;
}
admin/runit-2.2.0/src/direntry.h2 0000644 0000000 0000000 00000000246 14675400254 015335 0 ustar root root /* Public domain. */
#ifndef DIRENTRY_H
#define DIRENTRY_H
/* sysdep: +dirent */
#include
#include
#define direntry struct dirent
#endif
admin/runit-2.2.0/src/find-systype.sh 0000644 0000000 0000000 00000006404 14675400254 016236 0 ustar root root # oper-:arch-:syst-:chip-:kern-
# oper = operating system type; e.g., sunos-4.1.4
# arch = machine language; e.g., sparc
# syst = which binaries can run; e.g., sun4
# chip = chip model; e.g., micro-2-80
# kern = kernel version; e.g., sun4m
# dependence: arch --- chip
# \ \
# oper --- syst --- kern
# so, for example, syst is interpreted in light of oper, but chip is not.
# anyway, no slashes, no extra colons, no uppercase letters.
# the point of the extra -'s is to ease parsing: can add hierarchies later.
# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium,
# and i386-486 (486s do have more instructions, you know) as well as i386.
# the idea here is to include ALL useful available information.
exec 2>/dev/null
sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`"
if [ x"$sys" != x ]
then
unamer="`uname -r | tr /: ..`"
unamem="`uname -m | tr /: ..`"
unamev="`uname -v | tr /: ..`"
case "$sys" in
bsd.os|freebsd|netbsd|openbsd)
# in bsd 4.4, uname -v does not have useful info.
# in bsd 4.4, uname -m is arch, not chip.
oper="$sys-$unamer"
arch="$unamem"
syst=""
chip="`sysctl -n hw.model`" # hopefully
kern=""
;;
linux)
# as in bsd 4.4, uname -v does not have useful info.
oper="$sys-$unamer"
syst=""
chip="$unamem"
kern=""
case "$chip" in
i386|i486|i586|i686)
arch="i386"
;;
alpha)
arch="alpha"
;;
esac
;;
aix)
# naturally IBM has to get uname -r and uname -v backwards. dorks.
oper="$sys-$unamev-$unamer"
arch="`arch | tr /: ..`"
syst=""
chip="$unamem"
kern=""
;;
sunos)
oper="$sys-$unamer-$unamev"
arch="`(uname -p || mach) | tr /: ..`"
syst="`arch | tr /: ..`"
chip="$unamem" # this is wrong; is there any way to get the real info?
kern="`arch -k | tr /: ..`"
;;
unix_sv)
oper="$sys-$unamer-$unamev"
arch="`uname -m`"
syst=""
chip="$unamem"
kern=""
;;
*)
oper="$sys-$unamer-$unamev"
arch="`arch | tr /: ..`"
syst=""
chip="$unamem"
kern=""
;;
esac
else
gcc -c trycpp.c
gcc -o trycpp trycpp.o
case `./trycpp` in
nextstep)
oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`"
arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`"
syst=""
chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`"
kern=""
;;
*)
oper="unknown"
arch=""
syst=""
chip=""
kern=""
;;
esac
rm -f trycpp.o trycpp
fi
case "$chip" in
80486)
# let's try to be consistent here. (BSD/OS)
chip=i486
;;
i486DX)
# respect the hyphen hierarchy. (FreeBSD)
chip=i486-dx
;;
i486.DX2)
# respect the hyphen hierarchy. (FreeBSD)
chip=i486-dx2
;;
Intel.586)
# no, you nitwits, there is no such chip. (NeXTStep)
chip=pentium
;;
i586)
# no, you nitwits, there is no such chip. (Linux)
chip=pentium
;;
i686)
# STOP SAYING THAT! (Linux)
chip=ppro
esac
if gcc -c x86cpuid.c
then
if gcc -o x86cpuid x86cpuid.o
then
x86cpuid="`./x86cpuid | tr /: ..`"
case "$x86cpuid" in
?*)
chip="$x86cpuid"
;;
esac
fi
fi
rm -f x86cpuid x86cpuid.o
echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]'
admin/runit-2.2.0/src/hassgprm.h1 0000644 0000000 0000000 00000000061 14675400254 015313 0 ustar root root /* Public domain. */
/* sysdep: -sigprocmask */
admin/runit-2.2.0/src/reboot_system.h2 0000644 0000000 0000000 00000000200 14675400254 016361 0 ustar root root #include
#include
/* sysdep: +std reboot */
int reboot_system(int what) {
return(reboot(what));
}
admin/runit-2.2.0/src/runit-init.check 0000755 0000000 0000000 00000000035 14675400254 016342 0 ustar root root #!/bin/sh
runit-init
echo $?
admin/runit-2.2.0/etc/ 0000755 0000000 0000000 00000000000 14675400254 013224 5 ustar root root admin/runit-2.2.0/etc/debian/ 0000755 0000000 0000000 00000000000 14675400254 014446 5 ustar root root admin/runit-2.2.0/etc/debian/3 0000755 0000000 0000000 00000000360 14675400254 014535 0 ustar root root #!/bin/sh
exec 2>&1
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
LAST=0
test -x /etc/runit/reboot && LAST=6
echo 'Waiting for services to stop...'
sv -w196 force-stop /service/*
sv exit /service/*
echo 'Shutdown...'
/etc/init.d/rc $LAST
admin/runit-2.2.0/etc/debian/1 0000755 0000000 0000000 00000000251 14675400254 014532 0 ustar root root #!/bin/sh
# system one time tasks
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
/etc/init.d/rcS
/etc/init.d/rmnologin
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
admin/runit-2.2.0/etc/debian/getty-tty5/ 0000755 0000000 0000000 00000000000 14675400254 016505 5 ustar root root admin/runit-2.2.0/etc/debian/getty-tty5/finish 0000755 0000000 0000000 00000000037 14675400254 017713 0 ustar root root #!/bin/sh
exec utmpset -w tty5
admin/runit-2.2.0/etc/debian/getty-tty5/run 0000755 0000000 0000000 00000000054 14675400254 017236 0 ustar root root #!/bin/sh
exec /sbin/getty 38400 tty5 linux
admin/runit-2.2.0/etc/debian/ctrlaltdel 0000755 0000000 0000000 00000000275 14675400254 016532 0 ustar root root #!/bin/sh
PATH=/bin:/usr/bin
MSG="System is going down in 14 seconds..."
# echo 'disabled.' ; exit
touch /etc/runit/stopit
chmod 100 /etc/runit/stopit && echo "$MSG" | wall
/bin/sleep 14
admin/runit-2.2.0/etc/debian/2 0000777 0000000 0000000 00000000000 14675400254 015026 2../2 ustar root root admin/runit-2.2.0/etc/2 0000755 0000000 0000000 00000001046 14675400254 013314 0 ustar root root #!/bin/sh
PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
exec env - PATH=$PATH \
runsvdir -P /service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'
admin/runit-2.2.0/etc/openbsd/ 0000755 0000000 0000000 00000000000 14675400254 014656 5 ustar root root admin/runit-2.2.0/etc/openbsd/3 0000755 0000000 0000000 00000000364 14675400254 014751 0 ustar root root #!/bin/sh
exec 2>&1
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
echo 'Waiting for services to stop...'
sv -w196 force-stop /service/*
sv exit /service/*
echo 'Shutdown...'
if test -x /etc/runit/reboot; then
exec reboot
else
exec halt
fi
admin/runit-2.2.0/etc/openbsd/1 0000755 0000000 0000000 00000000517 14675400254 014747 0 ustar root root #!/bin/sh
# system one time tasks
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
trap : 2
trap : 3
sh /etc/rc autoboot
if test $? -ne 0; then
# /etc/rc crashed, start emergency shell.
echo '/etc/rc failed. Press for emergency shell...'
read input
sh -l
exec reboot
fi
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
admin/runit-2.2.0/etc/openbsd/ctrlaltdel 0000755 0000000 0000000 00000000275 14675400254 016742 0 ustar root root #!/bin/sh
PATH=/bin:/usr/bin
MSG="System is going down in 14 seconds..."
# echo 'disabled.' ; exit
touch /etc/runit/stopit
chmod 100 /etc/runit/stopit && echo "$MSG" | wall
/bin/sleep 14
admin/runit-2.2.0/etc/openbsd/2 0000777 0000000 0000000 00000000000 14675400254 015236 2../2 ustar root root admin/runit-2.2.0/etc/openbsd/getty-ttyC4/ 0000755 0000000 0000000 00000000000 14675400254 017017 5 ustar root root admin/runit-2.2.0/etc/openbsd/getty-ttyC4/finish 0000755 0000000 0000000 00000000040 14675400254 020217 0 ustar root root #!/bin/sh
exec utmpset -w ttyC4
admin/runit-2.2.0/etc/openbsd/getty-ttyC4/run 0000755 0000000 0000000 00000000053 14675400254 017547 0 ustar root root #!/bin/sh
exec /usr/libexec/getty Pc ttyC4
admin/runit-2.2.0/etc/freebsd/ 0000755 0000000 0000000 00000000000 14675400254 014636 5 ustar root root admin/runit-2.2.0/etc/freebsd/3 0000755 0000000 0000000 00000000364 14675400254 014731 0 ustar root root #!/bin/sh
exec 2>&1
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
echo 'Waiting for services to stop...'
sv -w196 force-stop /service/*
sv exit /service/*
echo 'Shutdown...'
if test -x /etc/runit/reboot; then
exec reboot
else
exec halt
fi
admin/runit-2.2.0/etc/freebsd/1 0000755 0000000 0000000 00000000517 14675400254 014727 0 ustar root root #!/bin/sh
# system one time tasks
PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
trap : 2
trap : 3
sh /etc/rc autoboot
if test $? -ne 0; then
# /etc/rc crashed, start emergency shell.
echo '/etc/rc failed. Press for emergency shell...'
read input
sh -p
exec reboot
fi
touch /etc/runit/stopit
chmod 0 /etc/runit/stopit
admin/runit-2.2.0/etc/freebsd/getty-ttyv4/ 0000755 0000000 0000000 00000000000 14675400254 017062 5 ustar root root admin/runit-2.2.0/etc/freebsd/getty-ttyv4/finish 0000755 0000000 0000000 00000000040 14675400254 020262 0 ustar root root #!/bin/sh
exec utmpset -w ttyv4
admin/runit-2.2.0/etc/freebsd/getty-ttyv4/run 0000755 0000000 0000000 00000000053 14675400254 017612 0 ustar root root #!/bin/sh
exec /usr/libexec/getty Pc ttyv4
admin/runit-2.2.0/etc/freebsd/ctrlaltdel 0000755 0000000 0000000 00000000275 14675400254 016722 0 ustar root root #!/bin/sh
PATH=/bin:/usr/bin
MSG="System is going down in 14 seconds..."
# echo 'disabled.' ; exit
touch /etc/runit/stopit
chmod 100 /etc/runit/stopit && echo "$MSG" | wall
/bin/sleep 14
admin/runit-2.2.0/etc/freebsd/2 0000777 0000000 0000000 00000000000 14675400254 015216 2../2 ustar root root admin/runit-2.2.0/etc/macosx/ 0000755 0000000 0000000 00000000000 14675400254 014516 5 ustar root root admin/runit-2.2.0/etc/macosx/org.smarden.runit.plist 0000644 0000000 0000000 00000001061 14675400254 021150 0 ustar root root
Label
org.smarden.runit
ServiceDescription
runsvdir - starts and monitors a collection of runsv(8) processes
QueueDirectories
/service
OnDemand
ProgramArguments
/sbin/runsvdir-start
admin/runit-2.2.0/etc/macosx/2 0000777 0000000 0000000 00000000000 14675400254 015076 2../2 ustar root root admin/runit-2.2.0/etc/macosx/StartupItems/ 0000755 0000000 0000000 00000000000 14675400254 017162 5 ustar root root admin/runit-2.2.0/etc/macosx/StartupItems/StartupParameters.plist 0000644 0000000 0000000 00000000411 14675400254 023721 0 ustar root root {
Description = "runit service supervision";
Provides = ("runit");
Requires = ("Disks");
OrderPreference = "None";
Messages =
{
start = "Starting runit service supervision";
stop = "Stopping runit service supervision";
};
}
admin/runit-2.2.0/etc/macosx/StartupItems/runit 0000755 0000000 0000000 00000000514 14675400254 020251 0 ustar root root #!/bin/sh
##
# runit
##
. /etc/rc.common
StartService() {
ConsoleMessage "Starting runit service supervision"
/bin/csh -cf '/sbin/runsvdir-start &'
}
StopService() {
ConsoleMessage "Stopping runit service supervision"
sv -w196 force-stop /service/*
sv exit /service/*
}
RestartService() {
return 0
}
RunService "$1"
admin/runit-2.2.0/man/ 0000755 0000000 0000000 00000000000 14675400254 013224 5 ustar root root admin/runit-2.2.0/man/utmpset.8 0000644 0000000 0000000 00000002073 14675400254 015020 0 ustar root root .TH utmpset 8
.SH NAME
utmpset \- logout a line from utmp and wtmp file
.SH SYNOPSIS
.B utmpset
[
.B \-w
]
.I line
.SH DESCRIPTION
The
.B utmpset
program modifies the user accounting database
.BR utmp (5)
and optionally
.BR wtmp (5)
to indicate that the user on the terminal
.I line
has logged out.
.P
Ordinary
.BR init (8)
processes handle utmp file records for local login accounting.
The
.BR runit (8)
program doesn't include code to update the utmp file, the
.BR getty (8)
processes are handled the same as all other services.
.P
To enable local login accounting, add
.B utmpset
to the
.BR getty (8)
.I finish
scripts, e.g.:
.P
$ cat /service/getty-5/finish
#!/bin/sh
exec utmpset \-w tty5
$
.SH OPTIONS
.TP
.B \-w
wtmp. Additionally to the utmp file, write an empty record for
.I line
to the wtmp file.
.SH EXIT CODES
.B utmpset
returns 111 on error, 1 on wrong usage, 0 in all other cases.
.SH SEE ALSO
sv(8),
runsv(8),
runit(8),
runit-init(8)
runsvdir(8),
runsvchdir(8),
chpst(8),
svlogd(8),
getty(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/runsvdir.8 0000644 0000000 0000000 00000004006 14675400254 015171 0 ustar root root .TH runsvdir 8
.SH NAME
runsvdir \- starts and monitors a collection of runsv(8) processes
.SH SYNOPSIS
.B runsvdir
[\-P]
.I dir
[
.I log
]
.SH DESCRIPTION
.I dir
must be a directory.
.I log
is a space holder for a readproctitle log, and must be at least seven
characters long or absent.
.P
.B runsvdir
starts a
.BR runsv (8)
process for each subdirectory, or symlink to a directory, in the services
directory
.IR dir ,
up to a limit of 1000 subdirectories,
and restarts a
.BR runsv (8)
process if it terminates.
.B runsvdir
skips subdirectory names starting with dots.
.BR runsv (8)
must be in
.BR runsvdir 's
PATH.
.P
At least every five seconds
.B runsvdir
checks whether the time of last modification, the inode, or the device, of
the services directory
.I dir
has changed.
If so, it re-scans the service directory, and if it sees a new subdirectory,
or new symlink to a directory, in
.IR dir ,
it starts a new
.BR runsv (8)
process;
if
.B runsvdir
sees a subdirectory being removed that was previously there, it sends the
corresponding
.BR runsv (8)
process a TERM signal, stops monitoring this process, and so does not
restart the
.BR runsv (8)
process if it exits.
.P
If the
.I log
argument is given to
.BR runsvdir ,
all output to standard error is redirected to this
.IR log ,
which is similar to the daemontools'
.B readproctitle
log.
To see the most recent error messages, use a process-listing tool such as
.BR ps (1).
.B runsvdir
writes a dot to the readproctitle log every 15 minutes so that old error
messages expire.
.SH OPTIONS
.TP
.B \-P
use
.BR setsid (2)
to run each
.BR runsv (8)
process in a new session and separate process group.
.SH SIGNALS
If
.B runsvdir
receives a TERM signal, it exits with 0 immediately.
.P
If
.B runsvdir
receives a HUP signal, it sends a TERM signal to each
.BR runsv (8)
process it is monitoring and then exits with 111.
.SH SEE ALSO
sv(8),
runsv(8),
runsvchdir(8),
runit(8),
runit-init(8),
chpst(8),
svlogd(8),
utmpset(8),
setsid(2)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/runsv.8 0000644 0000000 0000000 00000012562 14675400254 014500 0 ustar root root .TH runsv 8
.SH NAME
runsv \- starts and monitors a service and optionally an appendant log
service
.SH SYNOPSIS
.B runsv
.I service
.SH DESCRIPTION
.I service
must be a directory.
.P
.B runsv
switches to the directory
.I service
and starts ./run.
If ./run exits and ./finish exists,
.B runsv
starts ./finish.
If ./finish doesn't exist or ./finish exits,
.B runsv
restarts ./run.
.P
If ./run or ./finish exit immediately,
.B runsv
waits a second before starting ./finish or restarting ./run.
.P
Two arguments are given to ./finish.
The first one is ./run's exit code, or -1 if ./run didn't exit normally.
The second one is the least significant byte of the exit status as
determined by
.BR waitpid (2);
for instance it is 0 if ./run exited normally, and the signal number
if ./run was terminated by a signal.
If
.B runsv
cannot start ./run for some reason, the exit code is 111 and the status is 0.
.P
If the file
.IR service /down
exists,
.B runsv
does not start ./run immediately.
The control interface (see below) can be used to start the service and to
give other commands to
.BR runsv .
.P
If the directory
.IR service /log
exists,
.B runsv
creates a pipe, redirects
.IR service /run's
and
.IR service /finish's
standard output to the pipe, switches to the directory
.IR service /log
and starts ./run script. The standard input of the log service
is redirected to read from the pipe.
.P
.B runsv
maintains status information in a binary format (compatible to the
daemontools'
.B supervise
program) in
.IR service /supervise/status
and
.IR service /log/supervise/status,
and in a human-readable format in
.IR service /supervise/stat,
.IR service /log/supervise/stat,
.IR service /supervise/pid,
.IR service /log/supervise/pid.
.SH CONTROL
The named pipes
.IR service /supervise/control,
and (optionally)
.IR service /log/supervise/control
are provided to give commands to
.BR runsv .
You can use
.BR sv (8)
to control the service or just write one of the following characters to
the named pipe:
.TP
.B u
Up.
If the service is not running, start it.
If the service stops, restart it.
.TP
.B d
Down.
If the service is running, send it a TERM signal, and then a CONT signal.
If ./run exits, start ./finish if it exists.
After it stops, do not restart service.
.TP
.B o
Once.
If the service is not running, start it.
Do not restart it if it stops.
.TP
.B p
Pause.
If the service is running, send it a STOP signal.
.TP
.B c
Continue.
If the service is running, send it a CONT signal.
.TP
.B h
Hangup.
If the service is running, send it a HUP signal.
.TP
.B a
Alarm.
If the service is running, send it a ALRM signal.
.TP
.B i
Interrupt.
If the service is running, send it a INT signal.
.TP
.B q
Quit.
If the service is running, send it a QUIT signal.
.TP
.B 1
User-defined 1.
If the service is running, send it a USR1 signal.
.TP
.B 2
User-defined 2.
If the service is running, send it a USR2 signal.
.TP
.B t
Terminate.
If the service is running, send it a TERM signal.
.TP
.B k
Kill.
If the service is running, send it a KILL signal.
.TP
.B x
Exit.
If the service is running, send it a TERM signal, and then a CONT signal.
Do not restart the service.
If the service is down, and no log service exists,
.B runsv
exits.
If the service is down and a log service exists,
.B runsv
closes the standard input of the log service, and waits for it to terminate.
If the log service is down,
.B runsv
exits.
This command is ignored if it is given to
.IR service /log/supervise/control.
.P
Example: to send a TERM signal to the socklog-unix service, either do
# sv term /service/socklog-unix
or
# printf t >/service/socklog-unix/supervise/control
.P
.BR printf (1)
usually blocks if no
.B runsv
process is running in the service directory.
.SH CUSTOMIZE CONTROL
For each control character
.I c
except "d" and "x" sent to the control pipe,
.B runsv
first checks if
.I service\fR/control/\fIc
exists and is executable.
If so, it starts
.I service\fR/control/\fIc
and waits for it to terminate, before interpreting the command.
If the program exits with return code 0,
.B runsv
refrains from sending the service the corresponding signal.
The command
.I o
is always considered as command
.IR u .
On command
.I d
first
.I service\fR/control/t
is checked, and then
.I service\fR/control/d.
On command
.I x
first
.I service\fR/control/t
is checked, and then
.I service\fR/control/x.
Specifically:
.P
If the service is running or paused, control characters "d" and "x" are handled as follows:
.TP
.B 1.
.B runsv
checks whether
.I service\fR/control/t
exists and is executable and runs it if yes.
.TP
.B 2.
If
.I service\fR/control/t
exits nonzero, or is not executable or doesn't exist,
.B runsv
sends the service a TERM signal.
.TP
.B 3.
.B runsv
sends the service a CONT signal, disregarding
.I service\fR/control/c
even if it exists and is executable.
.TP
.B 4.
.B runsv
checks whether
.I service\fR/control/d (or control/x)
exists and is executable and runs it if yes. Its exit status is ignored.
.P
The control of the optional log service cannot be customized.
.SH SIGNALS
If
.B runsv
receives a TERM signal, it acts as if the character x was written to the
control pipe.
.SH EXIT CODES
.B runsv
exits 111 on an error on startup or if another
.B runsv
is running in
.IR service .
.P
.B runsv
exits 0 if it was told to exit.
.SH SEE ALSO
sv(8),
chpst(8),
svlogd(8),
runit(8),
runit-init(8),
runsvdir(8),
runsvchdir(8),
utmpset(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/sv.8 0000644 0000000 0000000 00000014217 14675400254 013752 0 ustar root root .TH sv 8
.SH NAME
sv \- control and manage services monitored by
.BR runsv (8)
.SH SYNOPSIS
.B sv
[\-v] [\-w
.I sec\fR]
.I command
.I services
.P
.BI /etc/init.d/ service
[\-w
.I sec\fR]
.I command
.SH DESCRIPTION
The
.B sv
program reports the current status and controls the state of services
monitored by the
.BR runsv (8)
supervisor.
.P
.I services
consists of one or more arguments, each argument naming a directory
.I service
used by
.BR runsv (8).
If
.I service
doesn't start with a dot or slash and doesn't end with a slash, it is
searched in the default services directory
.IR /service/ ,
otherwise relative to the current directory.
.P
.I command
is one of up, down, status, once, pause, cont, hup, alarm, interrupt, 1, 2,
term, kill, or exit, or start, stop, restart, shutdown, force-stop,
force-reload, force-restart, force-shutdown.
.P
The
.B sv
program can be sym-linked to
.I /etc/init.d/
to provide an LSB init script interface.
The
.I service
to be controlled then is specified by the base name of the ``init script''.
.SH COMMANDS
.TP
.B status
Report the current status of the service, and the appendant log service if
available, to standard output.
.TP
.B up
If the service is not running, start it.
If the service stops, restart it.
.TP
.B down
If the service is running, send it the TERM signal, and the CONT signal.
If ./run exits, start ./finish if it exists.
After it stops, do not restart service.
.TP
.B once
If the service is not running, start it.
Do not restart it if it stops.
.TP
.B pause cont hup alarm interrupt quit 1 2 term kill
If the service is running, send it the STOP, CONT, HUP, ALRM, INT, QUIT,
USR1, USR2, TERM, or KILL signal respectively.
.TP
.B exit
If the service is running, send it the TERM signal, and the CONT signal.
Do not restart the service.
If the service is down, and no log service exists,
.BR runsv (8)
exits.
If the service is down and a log service exists,
.BR runsv (8)
closes the standard input of the log service and waits for it to terminate.
If the log service is down,
.BR runsv (8)
exits.
This command is ignored if it is given to an appendant log service.
.P
.BR sv
actually looks only at the first character of these
.IR command s.
.SS Commands compatible to LSB init script actions
.TP
.B status
Same as
.IR status .
.TP
.B start
Same as
.IR up ,
but wait up to 7 seconds for the command to take effect.
Then report the status or timeout.
If the script
.I ./check
exists in the service directory,
.B sv
runs this script to check whether the service is up and available;
it's considered to be available if
.I ./check
exits with 0.
.TP
.B stop
Same as
.IR down ,
but wait up to 7 seconds for the service to become down.
Then report the status or timeout.
.TP
.B reload
Same as
.IR hup ,
and additionally report the status afterwards.
.TP
.B restart
Send the commands
.IR term ,
.IR cont ,
and
.I up
to the service, and wait up to 7 seconds for the service to restart.
Then report the status or timeout.
If the script
.I ./check
exists in the service directory,
.B sv
runs this script to check whether the service is up and available again;
it's considered to be available if
.I ./check
exits with 0.
.TP
.B shutdown
Same as
.IR exit ,
but wait up to 7 seconds for the
.BR runsv (8)
process to terminate.
Then report the status or timeout.
.TP
.B force-stop
Same as
.IR down ,
but wait up to 7 seconds for the service to become down.
Then report the status, and on timeout send the service the
.I kill
command.
.TP
.B force-reload
Send the service the
.I term
and
.I cont
commands, and wait up to 7 seconds for the service to restart.
Then report the status, and on timeout send the service the
.I kill
command.
.TP
.B force-restart
Send the service the
.IR term ,
.I cont
and
.I up
commands, and wait up to 7 seconds for the service to restart.
Then report the status, and on timeout send the service the
.I kill
command.
If the script
.I ./check
exists in the service directory,
.B sv
runs this script to check whether the service is up and available again;
it's considered to be available if
.I ./check
exits with 0.
.TP
.B force-shutdown
Same as
.IR exit ,
but wait up to 7 seconds for the
.BR runsv (8)
process to terminate.
Then report the status, and on timeout send the service the
.I kill
command.
.TP
.B try-restart
if the service is running, send it the
.I term
and
.I cont
commands, and wait up to 7 seconds for the service to restart.
Then report the status or timeout.
.SS Additional Commands
.TP
.B check
Check for the service to be in the state that's been requested.
Wait up to 7 seconds for the service to reach the requested state, then
report the status or timeout.
If the requested state of the service is
.IR up ,
and the script
.I ./check
exists in the service directory,
.B sv
runs this script to check whether the service is up and running; it's
considered to be up if
.I ./check
exits with 0.
.SH OPTIONS
.TP
.B \-v
If the
.I command
is up, down, term, once, cont, or exit, then wait up to 7 seconds for the
command to take effect.
Then report the status or timeout.
.TP
.B \-w \fIsec
Override the default timeout of 7 seconds with
.I sec
seconds.
This option implies
.IR \-v .
.SH ENVIRONMENT
.TP
.B SVDIR
The environment variable $SVDIR overrides the default services directory
.IR /service/ .
.TP
.B SVWAIT
The environment variable $SVWAIT overrides the default 7 seconds to wait
for a command to take effect.
It is overridden by the \-w option.
.SH EXIT CODES
.B sv
exits 0, if the
.I command
was successfully sent to all
.IR services ,
and, if it was told to wait, the
.I command
has taken effect to all services.
.P
For each
.I service
that caused an error (e.g. the directory is not controlled by a
.BR runsv (8)
process, or
.B sv
timed out while waiting),
.B sv
increases the exit code by one and exits non zero.
The maximum is 99.
.B sv
exits 100 on error.
.P
If
.B sv
is called with a base name other than
.BR sv :
it exits 1 on timeout or trouble sending the command; if the
.I command
is
.BR status ,
it exits 3 if the service is down, and 4 if the status is unknown;
it exits 2 on wrong usage, and 151 on error.
.SH SEE ALSO
runsv(8),
chpst(8),
svlogd(8),
runsvdir(8),
runsvchdir(8),
runit(8),
runit-init(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/svlogd.8 0000644 0000000 0000000 00000022545 14675400254 014623 0 ustar root root .TH svlogd 8
.SH NAME
svlogd \- runit's service logging daemon
.SH SYNOPSIS
.B svlogd
[\-tttv] [\-r
.I c\fR] [\-R
.I xyz\fR] [\-l
.I len\fR] [\-b
.I buflen\fR]
.I logs
.SH DESCRIPTION
.I logs
consists of one or more arguments, each specifying a directory.
.P
.B svlogd
continuously reads log data from its standard input, optionally filters log
messages, and writes the data to one or more automatically rotated
.IR logs .
.P
Recent log files can automatically be processed by an arbitrary processor
program when they are rotated, and
.B svlogd
can be told to alert selected log messages to standard error, and through
udp.
.P
.B svlogd
runs until it sees end-of-file on standard input or is sent a TERM signal,
see below.
.SS LOG DIRECTORY
A log directory
.I log
contains some number of old log files, and the current log file
.IR current .
Old log files have a file name starting with
.I @
followed by a precise timestamp (see the daemontools'
.B tai64n
program), indicating when
.I current
was rotated and renamed to this file.
.P
A log directory additionally contains the lock file
.IR lock ,
maybe
.I state
and
.IR newstate ,
and optionally the file
.IR config .
.B svlogd
creates necessary files if they don't exist.
.P
If
.B svlogd
has trouble opening a log directory, it prints a warning, and ignores this
log directory.
If
.B svlogd
is unable to open all log directories given at the command line, it exits
with an error.
This can happen on start-up or after receiving a HUP signal.
.SS LOG FILE ROTATION
.B svlogd
appends selected log messages to the
.I current
log file.
If
.I current
has
.I size
bytes or more (or there is a new-line within the last
.I len
of
.I size
bytes), or is older than a specified amount of
.IR time ,
.I current
is rotated:
.P
.B svlogd
closes
.IR current ,
changes permission of
.I current
to 0755, renames
.I current
to
.RI @ timestamp\fR.s,
and starts with a new empty
.IR current .
If
.B svlogd
sees
.I num
or more old log files in the log directory, it removes the oldest one.
Note that this doesn't decrease the number of log files if there are
already more than
.I num
log files, this must be done manually, e.g. for keeping 10 log files:
.P
ls \-1 \\@* |sort |sed \-ne '10,$p' |xargs rm
.SS PROCESSOR
If
.B svlogd
is told to process recent log files, it saves
.I current
to
.RI @ timestamp\fR.u,
feeds
.RI @ timestamp\fR.u
through ``sh \-c "\fIprocessor\fR"''
and writes the output to
.RI @ timestamp\fR.t.
If the
.I processor
finishes successfully,
.RI @ timestamp\fR.t
is renamed to
.RI @ timestamp\fR.s,
and
.RI @ timestamp\fR.u
is deleted; otherwise
.RI @ timestamp\fR.t
is deleted and the
.I processor
is started again.
.B svlogd
also saves any output that the
.I processor
writes to file descriptor 5, and makes that output available on file
descriptor 4 when running
.I processor
on the next log file rotation.
.P
A
.I processor
is run in the background.
If
.B svlogd
sees a previously started
.I processor
still running when trying to start a new one for the same
.IR log ,
it blocks until the currently running
.I processor
has finished successfully.
Only the HUP signal works in that situation.
Note that this may block any program feeding its log data to
.BR svlogd.
.SS CONFIG
On startup, and after receiving a HUP signal,
.B svlogd
checks for each log directory
.I log
if the configuration file
.I log/config
exists, and if so, reads the file line by line and adjusts configuration for
.I log
as follows:
.P
If the line is empty, or starts with a ``#'', it is ignored.
A line of the form
.TP
.RI s size
sets the maximum file size of
.I current
when
.B svlogd
should rotate the current log file to
.I size
bytes.
Default is 1000000.
If
.I size
is zero,
.B svlogd
doesn't rotate log files.
You should set
.I size
to at least (2 *
.IR len ).
.TP
.RI n num
sets the number of old log files
.B svlogd
should maintain to
.IR num .
If
.B svlogd
sees more that
.I num
old log files in
.I log
after log file rotation, it deletes the oldest one.
Default is 10.
If
.I num
is zero,
.B svlogd
doesn't remove old log files.
.TP
.RI N min
sets the minimum number of old log files
.B svlogd
should maintain to
.IR min .
.I min
must be less than
.IR num .
If
.I min
is set, and
.B svlogd
cannot write to
.I current
because the filesystem is full, and it sees more than
.I min
old log files, it deletes the oldest one.
.TP
.RI t timeout
sets the maximum age of the
.I current
log file when
.B svlogd
should rotate the current log file to
.I timeout
seconds.
If
.I current
is
.I timeout
seconds old, and is not empty,
.B svlogd
forces log file rotation.
.TP
.RI ! processor
tells
.B svlogd
to feed each recent log file through
.I processor
(see above) on log file rotation.
By default log files are not processed.
.TP
.RI u a.b.c.d[:port]
tells
.B svlogd
to transmit the first
.I len
characters of selected log messages to the IP address
.IR a.b.c.d ,
port number
.IR port .
If
.I port
isn't set, the default port for syslog is used (514).
.I len
can be set through the \-l option, see below.
If
.B svlogd
has trouble sending udp packets, it writes error messages to the log
directory.
Attention:
logging through udp is unreliable, and should be used in private networks
only.
.TP
.RI U a.b.c.d[:port]
is the same as the
.I u
line above, but the log messages are no longer written to the log directory,
but transmitted through udp only.
Error messages from
.B svlogd
concerning sending udp packages still go to the log directory.
.TP
.RI p prefix
tells
.B svlogd
to prefix each line to be written to the log directory, to standard error,
or through UDP, with
.IR prefix .
.P
If a line starts with a
.IR \- ,
.IR + ,
.IR e ,
or
.IR E ,
.B svlogd
matches the first
.I len
characters of each log message against
.I pattern
and acts accordingly:
.TP
.RI \- pattern
the log message is deselected.
.TP
.RI + pattern
the log message is selected.
.TP
.RI e pattern
the log message is selected to be printed to standard error.
.TP
.RI E pattern
the log message is deselected to be printed to standard error.
.P
Initially each line is selected to be written to
.IR log/current .
Deselected log messages are discarded from
.IR log .
Initially each line is deselected to be written to standard err.
Log messages selected for standard error are written to standard error.
.SH PATTERN MATCHING
.B svlogd
matches a log message against the string
.I pattern
as follows:
.P
.I pattern
is applied to the log message one character by one, starting with the first.
A character not a star (``*'') and not a plus (``+'') matches itself.
A plus matches the next character in
.I pattern
in the log message one or more times.
A star before the end of
.I pattern
matches any string in the log message that does not include the next
character in
.IR pattern .
A star at the end of
.I pattern
matches any string.
.P
Timestamps optionally added by
.B svlogd
are not considered part of the log message.
.P
An
.B svlogd
pattern is not a regular expression.
For example consider a log message like this
.P
2005-12-18_09:13:50.97618 tcpsvd: info: pid 1977 from 10.4.1.14
.P
The following pattern doesn't match
.P
-*pid*
.P
because the first star matches up to the first p in tcpsvd, and then the
match fails because i is not s.
To match this log message, you can use a pattern like this instead
.P
-*: *: pid *
.SH OPTIONS
.TP
.B \-t
timestamp.
Prefix each selected line with a precise timestamp (see the daemontools'
.B tai64n
program) when writing to
.I log
or to standard error.
.TP
.B \-tt
timestamp.
Prefix each selected line with a human readable, sortable UTC timestamp of
the form YYYY-MM-DD_HH:MM:SS.xxxxx when writing to
.I log
or to standard error.
.TP
.B \-ttt
timestamp.
Prefix each selected line with a human readable, sortable UTC timestamp of
the form YYYY-MM-DDTHH:MM:SS.xxxxx when writing to
.I log
or to standard error.
.TP
.B \-r \fIc
replace.
.I c
must be a single character.
Replace non-printable characters in log messages with
.IR c .
Characters are replaced before pattern matching is applied.
.TP
.B \-R \fIxyz
replace charset.
Additionally to non-printable characters, replace all characters found in
.I xyz
with
.I c
(default ``_'').
.TP
.B \-l \fIlen
line length.
Pattern matching applies to the first
.I len
characters of a log message only.
Default is 1000.
.TP
.B \-b \fIbuflen
buffer size.
Set the size of the buffer
.B svlogd
uses when reading from standard input and writing to
.I logs
to
.IR buflen .
Default is 1024.
.I buflen
must be greater than
.IR len .
For
.B svlogd
instances that process a lot of data in short time, the buffer size should
be increased to improve performance.
.TP
.B \-v
verbose.
Print verbose messages to standard error.
.SH SIGNALS
If
.B svlogd
is sent a HUP signal, it closes and reopens all
.IR logs ,
and updates their configuration according to
.IR log/config .
If
.B svlogd
has trouble opening a log directory, it prints a warning, and discards this
log directory.
If
.B svlogd
is unable to open all log directories given at the command line, it exits
with an error.
.P
If
.B svlogd
is sent a TERM signal, or if it sees end-of-file on standard input, it stops
reading standard input, processes the data in the buffer, waits for all
.I processor
subprocesses to finish if any, and exits 0 as soon as possible.
.P
If
.B svlogd
is sent an ALRM signal, it forces log file rotation for all
.I logs
with a non empty
.I current
log file.
.SH SEE ALSO
sv(8),
runsv(8),
chpst(8),
runit(8),
runit-init(8),
runsvdir(8),
runsvchdir(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/chpst.8 0000644 0000000 0000000 00000011120 14675400254 014431 0 ustar root root .TH chpst 8
.SH NAME
chpst \- runs a program with a changed process state
.SH SYNOPSIS
.B chpst
[\-vVP012]
[\-u
.IR user ]
[\-U
.IR user ]
[\-b
.IR argv0 ]
[-e
.IR dir ]
[\-/
.IR root ]
[\-C
.IR pwd ]
[\-n
.IR inc ]
[-l|-L
.IR lock ]
[-m
.IR bytes ]
[-d
.IR bytes ]
[-o
.IR n ]
[-p
.IR n ]
[-f
.IR bytes ]
[-c
.IR bytes ]
[-t
.IR seconds ]
.I prog
.SH DESCRIPTION
.I prog
consists of one or more arguments.
.P
.B chpst
changes the process state according to the given options, and runs
.IR prog .
.SH OPTIONS
.TP
.B \-u \fI[:]user[:group]
setuidgid.
Set uid and gid to the
.IR user 's
uid and gid, as found in
.IR /etc/passwd .
If
.I user
is followed by a colon and a
.IR group ,
set the gid to
.IR group 's
gid, as found in
.IR /etc/group ,
instead of
.IR user 's
gid.
If
.I group
consists of a colon-separated list of group names,
.B chpst
sets the group ids of all listed groups.
If
.I user
is prefixed with a colon, the
.I user
and all
.I group
arguments are interpreted as uid and gids respectively, and not looked up in
the password or group file.
All initial supplementary groups are removed.
.TP
.B \-U \fI[:]user[:group]
envuidgid.
Set the environment variables $UID and $GID to the
.IR user 's
uid and gid, as found in
.IR /etc/passwd .
If
.I user
is followed by a colon and a
.IR group ,
set $GID to the
.IR group 's
gid, as found in
.IR /etc/group ,
instead of
.IR user 's
gid.
If
.I user
is prefixed with a colon, the
.I user
and
.I group
arguments are interpreted as uid and gid respectively, and not looked up in
the password or group file.
.TP
.B \-b \fIargv0
argv0.
Run
.I prog
with
.I argv0
as the 0th argument.
.TP
.B \-e \fIdir
envdir.
Set various environment variables as specified by files in the directory
.IR dir :
If
.I dir
contains a file named
.I k
whose first line is
.IR v ,
.B chpst
removes the environment variable
.I k
if it exists, and then adds the environment variable
.I k
with the value
.IR v .
The name
.I k
must not contain =.
Spaces and tabs at the end of
.I v
are removed, and nulls in
.I v
are changed to newlines.
If the file
.I k
is empty (0 bytes long),
.B chpst
removes the environment variable
.I k
if it exists, without adding a new variable.
.TP
.B \-/ \fIroot
chroot.
Change the root directory to
.I root
before starting
.IR prog .
.TP
.B \-C \fIpwd
chdir.
Change the working directory to
.I pwd
before starting
.IR prog .
When combined with \-/, the working directory is changed after the chroot.
.TP
.B \-n \fIinc
nice.
Add
.I inc
to the
.BR nice (2)
value before starting
.IR prog .
.I inc
must be an integer, and may start with a minus or plus.
.TP
.B \-l \fIlock
lock.
Open the file
.I lock
for writing, and obtain an exclusive lock on it.
.I lock
will be created if it does not exist.
If
.I lock
is locked by another process, wait until a new lock can be obtained.
.TP
.B \-L \fIlock
The same as \-l, but fail immediately if
.I lock
is locked by another process.
.TP
.B \-m \fIbytes
limit memory.
Limit the data segment, stack segment, locked physical pages, and total of
all segment per process to
.I bytes
bytes each.
.TP
.B \-d \fIbytes
limit data segment.
Limit the data segment per process to
.I bytes
bytes.
.TP
.B \-o \fIn
limit open files.
Limit the number of open file descriptors per process to
.IR n .
.TP
.B \-p \fIn
limit processes.
Limit the number of processes per uid to
.IR n .
.TP
.B \-f \fIbytes
limit output size.
Limit the output file size to
.I bytes
bytes.
.TP
.B \-c \fIbytes
limit core size.
Limit the core file size to
.I bytes
bytes.
.TP
.B \-t \fIseconds
limit CPU time.
Limit CPU time to
.I seconds
seconds, delivering a SIGXCPU thereafter.
.TP
.B \-v
verbose.
Print verbose messages to standard error.
This includes warnings about limits unsupported by the system.
.TP
.B \-V
version string.
Print a version string to standard error.
.TP
.B \-P
pgrphack.
Run
.I prog
in a new process group.
.TP
.B \-0
Close standard input before starting
.IR prog .
.TP
.B \-1
Close standard output before starting
.IR prog .
.TP
.B \-2
Close standard error before starting
.IR prog .
.SH EXIT CODES
.B chpst
exits 100 when called with wrong options.
It prints an error message and exits 111 if it has trouble changing the
process state.
Otherwise its exit code is the same as that of
.IR prog .
.SH EMULATION
If
.B chpst
is called as
.BR envdir ,
.BR envuidgid ,
.BR pgrphack ,
.BR setlock ,
.BR setuidgid ,
or
.BR softlimit ,
it emulates the functionality of these programs from the daemontools package
respectively.
.SH SEE ALSO
sv(8),
runsv(8),
setsid(2),
runit(8),
runit-init(8),
runsvdir(8),
runsvchdir(8)
.P
http://smarden.org/runit/
http://cr.yp.to/daemontools.html
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/runsvchdir.8 0000644 0000000 0000000 00000001643 14675400254 015510 0 ustar root root .TH runsvchdir 8
.SH NAME
runsvchdir \- change services directory of runsvdir(8)
.SH SYNOPSIS
.B runsvchdir
.I dir
.SH DESCRIPTION
.I dir
is a services directory for the use with
.BR runsvdir (8).
If
.I dir
does not start with a slash, it is searched in /etc/runit/runsvdir/.
.I dir
must not start with a dot.
.P
.B runsvchdir
switches to the directory
.IR /etc/runit/runsvdir/ ,
copies
.I current
to
.IR previous ,
and replaces
.I current
with a symlink pointing to
.IR dir .
.P
Normally
.I /service
is a symlink to
.IR current ,
and
.BR runsvdir (8)
is running
.IR /service/ .
.SH EXIT CODES
.B runsvchdir
prints an error message and exits 111 on error.
.B runsvchdir
exits 0 on success.
.SH FILES
/etc/runit/runsvdir/previous
/etc/runit/runsvdir/current
/etc/runit/runsvdir/current.new
.SH SEE ALSO
runsvdir(8),
runit(8),
runit-init(8),
sv(8),
runsv(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/runit.8 0000644 0000000 0000000 00000004016 14675400254 014457 0 ustar root root .TH runit 8
.SH NAME
runit \- a UNIX process no 1
.SH SYNOPSIS
.B runit
.SH DESCRIPTION
.B runit
must be run as Unix process no 1.
It performs the system's booting, running, and shutdown in three stages:
.SH STAGE 1
.B runit
runs
.I /etc/runit/1
and waits for it to terminate.
The system's one time tasks are done here.
.I /etc/runit/1
has full control of
.I /dev/console
to be able to start an emergency shell if the one time initialization tasks
fail. If
.I /etc/runit/1
crashes, or exits 100,
.B runit
will skip stage 2 and enter stage 3.
.SH STAGE 2
.B runit
runs
.IR /etc/runit/2 ,
which should not return until system shutdown; if it crashes, or exits 111,
it will be restarted.
Normally
.I /etc/runit/2
starts
.BR runsvdir (8).
.B runit
is able to handle the ctrl-alt-del keyboard request in stage 2, see below.
.SH STAGE 3
If
.B runit
is told to shutdown the system, or stage 2 returns, it terminates stage 2 if
it is running, and runs
.IR /etc/runit/3 .
The systems tasks to shutdown and possibly halt or reboot the system are
done here.
If stage 3 returns,
.B runit
checks if the file
.I /etc/runit/reboot
exists and has the execute by owner permission set.
If so, the system is rebooted, it's halted otherwise.
If
.I /etc/runit/nosync
exists,
.B runit
doesn't invoke sync(). This is useful in vservers.
.SH CTRL-ALT-DEL
If
.B runit
receives the ctrl-alt-del keyboard request and the file
.I /etc/runit/ctrlaltdel
exists and has the execute by owner permission set,
.B runit
runs
.IR /etc/runit/ctrlaltdel ,
waits for it to terminate, and then sends itself a CONT signal.
.SH SIGNALS
.B runit
only accepts signals in stage 2.
.P
If
.B runit
receives a CONT signal and the file
.I /etc/runit/stopit
exists and has the execute by owner permission set,
.B runit
is told to shutdown the system.
.P
if
.B runit
receives an INT signal, a ctrl-alt-del keyboard request is triggered.
.SH SEE ALSO
runit-init(8),
runsvdir(8),
runsvchdir(8),
sv(8),
runsv(8),
chpst(8),
utmpset(8),
svlogd(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape
admin/runit-2.2.0/man/runit-init.8 0000644 0000000 0000000 00000002324 14675400254 015420 0 ustar root root .TH runit-init 8
.SH NAME
init \- a UNIX process no 1
.SH SYNOPSIS
.B init
[ 0 | 6 ]
.SH DESCRIPTION
.B runit-init
is the first process the kernel starts.
If
.B runit-init
is started as process no 1, it runs and replaces itself with
.BR runit (8).
.P
If
.B runit-init
is started while the system is up, it must be either called as
.B init 0
or
.B init 6\fR:
.TP
.B init 0
tells the Unix process no 1 to shutdown and halt the system.
To signal
.BR runit (8)
the system halt request,
.B runit-init
removes all permissions of the file
.I /etc/runit/reboot
(chmod 0), and sets the execute by owner permission of the file
.I /etc/runit/stopit
(chmod 100).
Then a CONT signal is sent to
.BR runit (8).
.TP
.B init 6
tells the Unix process no 1 to shutdown and reboot the system.
To signal
.BR runit (8)
the system reboot request,
.B runit-init
sets the execute by owner permission of the files
.I /etc/runit/reboot
and
.I /etc/runit/stopit
(chmod 100). Then a CONT signal is sent to
.BR runit (8).
.SH EXIT CODES
.B runit-init
returns 111 on error, 0 in all other cases.
.SH SEE ALSO
runit(8),
runsvdir(8),
runsvchdir(8),
sv(8),
runsv(8),
chpst(8),
utmpset(8),
svlogd(8)
.P
http://smarden.org/runit/
.SH AUTHOR
Gerrit Pape