summaryrefslogtreecommitdiff
path: root/relay/dhcrelay.c
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2016-10-01 01:35:37 +0200
committerFrancis Dupont <fdupont@isc.org>2016-10-01 01:35:37 +0200
commit29b23207c05a7a0ec1a90d42dc4e49d47f9b1a7f (patch)
tree502b9cbff8cdce72054798e5a6699624640c499e /relay/dhcrelay.c
parenta1372bbec77052d550678db54ee2c10721480177 (diff)
downloadisc-dhcp-29b23207c05a7a0ec1a90d42dc4e49d47f9b1a7f.tar.gz
Daemonize sooner (code from bind9/named) (rebased)
Diffstat (limited to 'relay/dhcrelay.c')
-rw-r--r--relay/dhcrelay.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 344cee78..fd838be5 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -77,6 +77,9 @@ int missing_circuit_id = 0; /* Circuit ID option in matching RAI option
was missing. */
int max_hop_count = 10; /* Maximum hop count */
+int no_daemon = 0;
+int dfd[2] = { -1, -1 };
+
#ifdef DHCPv6
/* Force use of DHCPv6 interface-id option. */
isc_boolean_t use_if_id = ISC_FALSE;
@@ -223,7 +226,7 @@ main(int argc, char **argv) {
struct server_list *sp = NULL;
char *service_local = NULL, *service_remote = NULL;
u_int16_t port_local = 0, port_remote = 0;
- int no_daemon = 0, quiet = 0;
+ int quiet = 0;
int fd;
int i;
#ifdef DHCPv6
@@ -256,6 +259,50 @@ main(int argc, char **argv) {
setlogmask(LOG_UPTO(LOG_INFO));
#endif
+ /* Parse arguments changing no_daemon */
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-d")) {
+ no_daemon = 1;
+ } else if (!strcmp(argv[i], "--version")) {
+ log_info("isc-dhcrelay-%s", PACKAGE_VERSION);
+ exit(0);
+ } else if (!strcmp(argv[i], "--help") ||
+ !strcmp(argv[i], "-h")) {
+ log_info(DHCRELAY_USAGE,
+#ifdef DHCPv6
+ isc_file_basename(progname),
+#endif
+ isc_file_basename(progname));
+ exit(0);
+ }
+ }
+ /* When not forbidden prepare to become a daemon */
+ if (!no_daemon) {
+ int pid;
+
+ if (pipe(dfd) == -1)
+ log_fatal("Can't get pipe: %m");
+ if ((pid = fork ()) < 0)
+ log_fatal("Can't fork daemon: %m");
+ if (pid != 0) {
+ /* Parent: wait for the child to start */
+ int n;
+
+ (void) close(dfd[1]);
+ do {
+ char buf;
+
+ n = read(dfd[0], &buf, 1);
+ if (n == 1)
+ _exit(0);
+ } while (n == -1 && errno == EINTR);
+ _exit(1);
+ }
+ /* Child */
+ (void) close(dfd[0]);
+ }
+
+
/* Set up the isc and dns library managers */
status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
NULL, NULL);
@@ -288,7 +335,7 @@ main(int argc, char **argv) {
local_family = AF_INET6;
#endif
} else if (!strcmp(argv[i], "-d")) {
- no_daemon = 1;
+ /* no_daemon = 1; */
} else if (!strcmp(argv[i], "-q")) {
quiet = 1;
quiet_interface_discovery = 1;
@@ -481,17 +528,6 @@ main(int argc, char **argv) {
no_dhcrelay_pid = ISC_TRUE;
} else if (!strcmp(argv[i], "--no-pid")) {
no_pid_file = ISC_TRUE;
- } else if (!strcmp(argv[i], "--version")) {
- log_info("isc-dhcrelay-%s", PACKAGE_VERSION);
- exit(0);
- } else if (!strcmp(argv[i], "--help") ||
- !strcmp(argv[i], "-h")) {
- log_info(DHCRELAY_USAGE,
-#ifdef DHCPv6
- isc_file_basename(progname),
-#endif
- isc_file_basename(progname));
- exit(0);
} else if (argv[i][0] == '-') {
usage("Unknown command: %s", argv[i]);
} else {
@@ -647,17 +683,21 @@ main(int argc, char **argv) {
/* Become a daemon... */
if (!no_daemon) {
- int pid;
+ char buf = 0;
FILE *pf;
int pfdesc;
log_perror = 0;
- if ((pid = fork()) < 0)
- log_fatal("Can't fork daemon: %m");
- else if (pid)
- exit(0);
+ /* Signal parent we started successfully. */
+ if (dfd[0] != -1 && dfd[1] != -1) {
+ if (write(dfd[1], &buf, 1) != 1)
+ log_fatal("write to parent: %m");
+ (void) close(dfd[1]);
+ dfd[0] = dfd[1] = -1;
+ }
+ /* Create the pid file. */
if (no_pid_file == ISC_FALSE) {
pfdesc = open(path_dhcrelay_pid,
O_CREAT | O_TRUNC | O_WRONLY, 0644);
@@ -1865,12 +1905,19 @@ parse_allow_deny(struct option_cache **oc, struct parse *p, int i) {
isc_result_t
dhcp_set_control_state(control_object_state_t oldstate,
control_object_state_t newstate) {
+ char buf = 0;
+
if (newstate != server_shutdown)
return ISC_R_SUCCESS;
if (no_pid_file == ISC_FALSE)
(void) unlink(path_dhcrelay_pid);
+ if (!no_daemon && dfd[0] != -1 && dfd[1] != -1) {
+ IGNORE_RET(write(dfd[1], &buf, 1));
+ (void) close(dfd[1]);
+ dfd[0] = dfd[1] = -1;
+ }
exit(0);
}