diff --git a/usr.sbin/daemon/daemon.8 b/usr.sbin/daemon/daemon.8 --- a/usr.sbin/daemon/daemon.8 +++ b/usr.sbin/daemon/daemon.8 @@ -57,10 +57,10 @@ .Pp The options are as follows: .Bl -tag -width indent -.It Fl c +.It Fl c -change-dir Change the current working directory to the root .Pq Dq Pa / . -.It Fl f +.It Fl f -close-fds Redirect standard input, standard output and standard error to .Pa /dev/null . When this option is used together with any of the options related to file @@ -68,35 +68,35 @@ .Pa /dev/null , then stdout and/or stderr is redirected to a file or to syslog as specified by the other options. -.It Fl H +.It Fl H -sighup Close .Pa output_file and re-open it when signal SIGHUP is received, for interoperability with .Xr newsyslog 1 and similar log rotation / archival mechanisms. If -.Fl o +.Fl -output-file is not specified, this flag is ignored. -.It Fl S +.It Fl S -syslog Enable syslog output. This is implicitly applied if other syslog parameters are provided. The default values are daemon, notice, and daemon for facility, priority, and tag, respectively. -.It Fl o Ar output_file +.It Fl o -output-file Ar output_file Append output from the daemonized process to .Pa output_file . If the file does not exist, it is created with permissions 0600. When this option is used together with options -.Fl c +.Fl -change-dir and -.Fl H +.Fl -sighup the absolute path needs to be provided to ensure .Nm can re-open the file after a SIGHUP. -.It Fl m Ar output_mask +.It Fl m -output-mask Ar output_mask Redirect output from the child process stdout (1), stderr (2), or both (3). This value specifies what is sent to syslog and the log file. The default is 3. -.It Fl p Ar child_pidfile +.It Fl p -child-pidfile Ar child_pidfile Write the ID of the created process into the .Ar child_pidfile using the @@ -112,9 +112,9 @@ owner is the user who runs the .Nm regardless of whether the -.Fl u +.Fl -user option is used or not. -.It Fl P Ar supervisor_pidfile +.It Fl P -supervisor-pidfile Ar supervisor_pidfile Write the ID of the .Nm process into the @@ -132,45 +132,46 @@ owner is the user who runs the .Nm regardless of whether the -.Fl u +.Fl -user option is used or not. -.It Fl r +.It Fl r -restart Supervise and restart the program after a one-second delay if it has been terminated. -.It Fl R Ar restart_delay_seconds +.It Fl R -restart-delay Ar restart_delay_seconds Supervise and restart the program after the specified delay if it has been terminated. -.It Fl t Ar title +.It Fl t -title Ar title Set the title for the daemon process. The default is the daemonized invocation. -.It Fl u Ar user +.It Fl u -user Ar user Login name of the user to execute the program under. Requires adequate superuser privileges. -.It Fl s Ar syslog_priority +.It Fl s -syslog-priority Ar syslog_priority These priorities are accepted: emerg, alert, crit, err, warning, notice, info, and debug. The default is notice. -.It Fl l Ar syslog_facility +.It Fl l -syslog facility Ar syslog_facility These facilities are accepted: auth, authpriv, console, cron, daemon, ftp, kern, lpr, mail, news, ntp, security, syslog, user, uucp, and local0, ..., local7. The default is daemon. -.It Fl T Ar syslog_tag +.It Fl T -syslog tag Ar syslog_tag Set the tag which is appended to all syslog messages. The default is daemon. .El .Pp If any of the options -.Fl p , -.Fl P , -.Fl r , -.Fl o , -.Fl s , -.Fl T , -.Fl m , -.Fl S , +.Fl -child-pidfile , +.Fl -output-mask , +.Fl -restart , +.Fl -restart-delay , +.Fl -supervisor-pidfile , +.Fl -syslog , +.Fl -syslog-facility +.Fl -syslog-priority , +.Fl -syslog-tag , or -.Fl l +.Fl -output , are specified, the program is executed in a spawned child process. The .Nm @@ -187,21 +188,21 @@ .Nm process and written to stdout. The -.Fl f +.Fl -close-fds option may be used to suppress the stdout output completely. .Pp The -.Fl P +.Fl -supervisor-pidfile option is useful combined with the -.Fl r +.Fl -restart option as .Ar supervisor_pidfile contains the ID of the supervisor not the child. This is especially important if you use -.Fl r +.Fl -restart in an rc script as the -.Fl p +.Fl -child-pidfile option will give you the child's ID to signal when you attempt to stop the service, causing .Nm @@ -229,7 +230,7 @@ If the command cannot be executed, an error message is printed to standard error. The exact behavior depends on the logging parameters and the -.Fl f +.Fl -close-fds flag. .Sh SEE ALSO .Xr nohup 1 , diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,58 @@ static volatile sig_atomic_t terminate = 0, child_gone = 0, pid = 0, do_log_reopen = 0; +static char shortopts[] = "+cfHSp:P:ru:o:s:l:t:l:m:R:T:"; + +static struct option longopts[] = { + { "change-dir", no_argument, NULL, 'c' }, + { "close-fds", no_argument, NULL, 'f' }, + { "sighup", no_argument, NULL, 'H' }, + { "syslog", no_argument, NULL, 'S' }, + { "output-file", required_argument, NULL, 'o' }, + { "output-mask", required_argument, NULL, 'm' }, + { "child-pidfile", required_argument, NULL, 'p' }, + { "supervisor-pidfile", required_argument, NULL, 'P' }, + { "restart", no_argument, NULL, 'r' }, + { "restart-delay", required_argument, NULL, 'R' }, + { "title", required_argument, NULL, 't' }, + { "user", required_argument, NULL, 'u' }, + { "syslog-priority", required_argument, NULL, 's' }, + { "syslog-facility", required_argument, NULL, 'l' }, + { "syslog-tag", required_argument, NULL, 'T' }, + { NULL, 0, NULL, 0 } +}; + +static void +usage(void) +{ + (void)fprintf(stderr, + "usage: daemon [-cfHrS] [-p child_pidfile] [-P supervisor_pidfile]\n" + " [-u user] [-o output_file] [-t title]\n" + " [-l syslog_facility] [-s syslog_priority]\n" + " [-T syslog_tag] [-m output_mask] [-R restart_delay_secs]\n" + "command arguments ...\n"); + + (void)fprintf(stderr, + " --change-dir -c Change the current working directory to root\n" + " --close-fds -f Set stdin, stdout, stderr to /dev/null\n" + " --sighup -H Close and re-open output file on SIGHUP\n" + " --syslog -S Send output to syslog\n" + " --output-file -o Append output of the child process to file\n" + " --output-mask -m What to send to syslog/file\n" + " 1=stdout, 2=stderr, 3=both\n" + " --child-pidfile -p Write PID of the child process to file\n" + " --supervisor-pidfile -P Write PID of the supervisor process to file\n" + " --restart -r Restart child if it terminates (1 sec delay)\n" + " --restart-delay -R Restart child if it terminates after N sec\n" + " --title -t Set the title of the supervisor process\n" + " --user -u <user> Drop privileges, run as given user\n" + " --syslog-priority -s <prio> Set syslog priority\n" + " --syslog-facility -l <flty> Set syslog facility\n" + " --syslog-tag -T <tag> Set syslog tag\n" + "see daemon(8) for more details\n"); + exit(1); +} + int main(int argc, char *argv[]) { @@ -106,7 +159,7 @@ log_reopen = 0; outfn = NULL; title = NULL; - while ((ch = getopt(argc, argv, "cfHSp:P:ru:o:s:l:t:l:m:R:T:")) != -1) { + while ((ch = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch (ch) { case 'c': nochdir = 0; @@ -182,7 +235,7 @@ if (outfd == -1) err(7, "open"); } - + if (dosyslog) openlog(logtag, LOG_PID | LOG_NDELAY, logfac); @@ -610,14 +663,3 @@ lpp->outfd = outfd; } -static void -usage(void) -{ - (void)fprintf(stderr, - "usage: daemon [-cfHrS] [-p child_pidfile] [-P supervisor_pidfile]\n" - " [-u user] [-o output_file] [-t title]\n" - " [-l syslog_facility] [-s syslog_priority]\n" - " [-T syslog_tag] [-m output_mask] [-R restart_delay_secs]\n" - "command arguments ...\n"); - exit(1); -}