forked from ElementsProject/lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Rusty Russell <[email protected]>
- Loading branch information
1 parent
ccd0e5d
commit c5cc5c5
Showing
6 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../licenses/BSD-MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#include "config.h" | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
/** | ||
* daemonize - routine to turn a process into a well-behaved daemon. | ||
* | ||
* Daemons should detach themselves thoroughly from the process which launched | ||
* them, and not prevent any filesystems from being unmounted. daemonize() | ||
* helps with the process. | ||
* | ||
* Example: | ||
* #include <ccan/daemonize/daemonize.h> | ||
* #include <ccan/str/str.h> | ||
* #include <err.h> | ||
* #include <unistd.h> | ||
* #include <stdlib.h> | ||
* | ||
* static void usage(const char *name) | ||
* { | ||
* errx(1, "Usage: %s [--daemonize]\n", name); | ||
* } | ||
* | ||
* // Wait for a minute, possibly as a daemon. | ||
* int main(int argc, char *argv[]) | ||
* { | ||
* if (argc != 1) { | ||
* if (argc == 2 && streq(argv[1], "--daemonize")) { | ||
* if (!daemonize()) | ||
* err(1, "Failed to become daemon"); | ||
* } else | ||
* usage(argv[1]); | ||
* } | ||
* sleep(60); | ||
* exit(0); | ||
* } | ||
* | ||
* License: BSD-MIT | ||
*/ | ||
int main(int argc, char *argv[]) | ||
{ | ||
if (argc != 2) | ||
return 1; | ||
|
||
if (strcmp(argv[1], "depends") == 0) { | ||
return 0; | ||
} | ||
|
||
if (strcmp(argv[1], "libs") == 0) { | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* Licensed under BSD-MIT - see LICENSE file for details */ | ||
#include <ccan/daemonize/daemonize.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <fcntl.h> | ||
|
||
/* This code is based on Stevens Advanced Programming in the UNIX | ||
* Environment. */ | ||
bool daemonize(void) | ||
{ | ||
pid_t pid; | ||
|
||
/* Separate from our parent via fork, so init inherits us. */ | ||
if ((pid = fork()) < 0) | ||
return false; | ||
/* use _exit() to avoid triggering atexit() processing */ | ||
if (pid != 0) | ||
_exit(0); | ||
|
||
/* Don't hold files open. */ | ||
close(STDIN_FILENO); | ||
close(STDOUT_FILENO); | ||
close(STDERR_FILENO); | ||
|
||
/* Many routines write to stderr; that can cause chaos if used | ||
* for something else, so set it here. */ | ||
if (open("/dev/null", O_WRONLY) != 0) | ||
return false; | ||
if (dup2(0, STDERR_FILENO) != STDERR_FILENO) | ||
return false; | ||
close(0); | ||
|
||
/* Session leader so ^C doesn't whack us. */ | ||
if (setsid() == (pid_t)-1) | ||
return false; | ||
/* Move off any mount points we might be in. */ | ||
if (chdir("/") != 0) | ||
return false; | ||
|
||
/* Discard our parent's old-fashioned umask prejudices. */ | ||
umask(0); | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* Licensed under BSD-MIT - see LICENSE file for details */ | ||
#ifndef CCAN_DAEMONIZE_H | ||
#define CCAN_DAEMONIZE_H | ||
#include <stdbool.h> | ||
|
||
/** | ||
* daemonize - turn this process into a daemon. | ||
* | ||
* This routine forks us off to become a daemon. It returns false on failure | ||
* (eg. fork(), chdir or open failed) and sets errno. | ||
* | ||
* Side effects for programmers to be aware of: | ||
* - PID changes (our parent exits, we become child of init) | ||
* - stdin and stdout file descriptors are closed | ||
* - stderr is reopened to /dev/null so you don't reuse it | ||
* - Current working directory changes to / | ||
* - Umask is set to 0. | ||
*/ | ||
bool daemonize(void); | ||
|
||
#endif /* CCAN_DAEMONIZE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <ccan/daemonize/daemonize.h> | ||
#include <ccan/daemonize/daemonize.c> | ||
#include <ccan/tap/tap.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <err.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
struct child_data { | ||
pid_t pid; | ||
pid_t ppid; | ||
bool in_root_dir; | ||
int read_from_stdin, write_to_stdout, write_to_stderr; | ||
}; | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
int fds[2]; | ||
struct child_data daemonized; | ||
pid_t pid; | ||
|
||
plan_tests(5); | ||
|
||
if (pipe(fds) != 0) | ||
err(1, "Failed pipe"); | ||
|
||
/* Since daemonize forks and parent exits, we need to fork | ||
* that parent. */ | ||
pid = fork(); | ||
if (pid == -1) | ||
err(1, "Failed fork"); | ||
|
||
if (pid == 0) { | ||
char buffer[2]; | ||
pid = getpid(); | ||
daemonize(); | ||
/* Keep valgrind happy about uninitialized bytes. */ | ||
memset(&daemonized, 0, sizeof(daemonized)); | ||
daemonized.pid = getpid(); | ||
daemonized.in_root_dir = (getcwd(buffer, 2) != NULL); | ||
daemonized.read_from_stdin | ||
= read(STDIN_FILENO, buffer, 1) == -1 ? errno : 0; | ||
daemonized.write_to_stdout | ||
= write(STDOUT_FILENO, buffer, 1) == -1 ? errno : 0; | ||
if (write(STDERR_FILENO, buffer, 1) != 1) { | ||
daemonized.write_to_stderr = errno; | ||
if (daemonized.write_to_stderr == 0) | ||
daemonized.write_to_stderr = -1; | ||
} else | ||
daemonized.write_to_stderr = 0; | ||
|
||
/* Make sure parent exits. */ | ||
while (getppid() == pid) | ||
sleep(1); | ||
daemonized.ppid = getppid(); | ||
if (write(fds[1], &daemonized, sizeof(daemonized)) | ||
!= sizeof(daemonized)) | ||
exit(1); | ||
exit(0); | ||
} | ||
|
||
if (read(fds[0], &daemonized, sizeof(daemonized)) != sizeof(daemonized)) | ||
err(1, "Failed read"); | ||
|
||
ok1(daemonized.pid != pid); | ||
#if 0 /* Believe it or not, this fails under Ubuntu 13.10 (Upstart) */ | ||
ok1(daemonized.ppid == 1); | ||
#endif | ||
ok1(daemonized.in_root_dir); | ||
ok1(daemonized.read_from_stdin == EBADF); | ||
ok1(daemonized.write_to_stdout == EBADF); | ||
ok1(daemonized.write_to_stderr == 0); | ||
|
||
return exit_status(); | ||
} |