Run as a daemon or service: Difference between revisions
(→{{header|C}}: Describe BSDisms. Keep dup2() in program.) |
(→{{libheader|BSD libc}}: doesn't really simplify much: there's freopen anyway) |
||
Line 12: | Line 12: | ||
[[BSD]] provides a convenient [http://netbsd.gw.com/cgi-bin/man-cgi?daemon+3+NetBSD-current daemon(3)] function. [[GNU]] libc also provides [http://www.kernel.org/doc/man-pages/online/pages/man3/daemon.3.html daemon(3)], but [[POSIX]] omits it, so it is not portable. Other BSDisms in this program are __progname and <err.h>. |
[[BSD]] provides a convenient [http://netbsd.gw.com/cgi-bin/man-cgi?daemon+3+NetBSD-current daemon(3)] function. [[GNU]] libc also provides [http://www.kernel.org/doc/man-pages/online/pages/man3/daemon.3.html daemon(3)], but [[POSIX]] omits it, so it is not portable. Other BSDisms in this program are __progname and <err.h>. |
||
The task also wants to redirect stdout. This program does so with [http://netbsd.gw.com/cgi-bin/man-cgi?dup2+2+NetBSD-current dup2(2)]. |
The task also wants to redirect stdout. This program does so with [http://netbsd.gw.com/cgi-bin/man-cgi?dup2+2+NetBSD-current dup2(2)]. Had we wanted to directly write to a file, we could open the file with <code>file = fopen(argv[1], "a")</code>, and write to ''file'' instead of ''stdout''. |
||
<lang c>#include <err.h> |
<lang c>#include <err.h> |
Revision as of 05:07, 19 November 2011
A daemon is a service that runs in the background independent of a users login session.
Demonstrate how a program disconnects from the terminal to run as a daemon in the background.
Write a small program that writes a message roughly once a second to its stdout which should be redirected to a file.
Note that in some language implementations it may not be possible to disconnect from the terminal, and instead the process needs to be started with stdout (and stdin) redirected to files before program start. If that is the case then a helper program to set up this redirection should be written in the language itself. A shell wrapper, as would be the usual solution on Unix systems, is not appropriate.
C
BSD provides a convenient daemon(3) function. GNU libc also provides daemon(3), but POSIX omits it, so it is not portable. Other BSDisms in this program are __progname and <err.h>.
The task also wants to redirect stdout. This program does so with dup2(2). Had we wanted to directly write to a file, we could open the file with file = fopen(argv[1], "a")
, and write to file instead of stdout.
<lang c>#include <err.h>
- include <errno.h>
- include <fcntl.h>
- include <stdlib.h>
- include <stdio.h>
- include <string.h>
- include <syslog.h>
- include <time.h>
- include <unistd.h>
int main(int argc, char **argv) { extern char *__progname; time_t clock; int fd;
if (argc != 2) { fprintf(stderr, "usage: %s file\n", __progname); exit(1); }
/* Open the file before becoming a daemon. */ fd = open(argv[1], O_WRONLY | O_APPEND | O_CREAT, 0666); if (fd < 0) err(1, argv[1]);
/* * Become a daemon. Lose terminal, current working directory, * stdin, stdout, stderr. */ if (daemon(0, 0) < 0) err(1, "daemon");
/* Redirect stdout. */ if (dup2(fd, STDOUT_FILENO) < 0) { syslog(LOG_ERR, "dup2: %s", strerror(errno)); exit(1); } close(fd);
/* Dump clock. */ for (;;) { time(&clock); fputs(ctime(&clock), stdout); fflush(stdout); sleep(1); /* Can wake early or drift late. */ } }</lang>
$ make dumper cc -O2 -pipe -o dumper dumper.c $ ./dumper dump $ tail -f dump Fri Nov 18 13:50:41 2011 Fri Nov 18 13:50:42 2011 Fri Nov 18 13:50:43 2011 Fri Nov 18 13:50:44 2011 Fri Nov 18 13:50:45 2011 ^C $ pkill -x dumper $ rm dump
Pike
__FILE__
is a preprocessor definition that contains the current filename.
if the first argument is "daemon" the program will be restarted with stdout redirected to "foo".
<lang Pike>int main(int argc, array argv) {
if (sizeof(argv)>1 && argv[1] == "daemon") { Stdio.File newout = Stdio.File("foo", "wc"); Process.spawn_pike(({ __FILE__ }), ([ "stdout":newout ])); return 1; }
int i = 100; while(i--) { write(i+"\n"); sleep(0.1); }
}</lang>