diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-09-12 11:27:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-09-12 11:27:55 +0000 |
commit | bded53bef9ad75eb7f53268e4a8f397185788588 (patch) | |
tree | 67fb33ef481d5bde92c21d3a088ee609fdb7308e /src | |
parent | Adding upstream version 2.0.3. (diff) | |
download | dnscap-upstream/2.1.0.tar.xz dnscap-upstream/2.1.0.zip |
Adding upstream version 2.1.0.upstream/2.1.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon.c | 52 | ||||
-rw-r--r-- | src/dnscap.1.in | 3 | ||||
-rw-r--r-- | src/options.c | 11 | ||||
-rw-r--r-- | src/options.h | 4 |
4 files changed, 70 insertions, 0 deletions
diff --git a/src/daemon.c b/src/daemon.c index 88ce785..596b863 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -224,6 +224,57 @@ void drop_privileges(void) #endif } +void write_pid_file(void) +{ + FILE* fp; + int fd, flags; + struct flock lock; + + if (!options.pid_file) + return; + + if ((fd = open(options.pid_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { + fprintf(stderr, "unable to open PID file %s: %s", options.pid_file, strerror(errno)); + exit(1); + } + + if ((flags = fcntl(fd, F_GETFD)) == -1) { + fprintf(stderr, "unable to get PID file flags: %s", strerror(errno)); + exit(1); + } + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == 1) { + fprintf(stderr, "unable to set PID file flags: %s", strerror(errno)); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + if (fcntl(fd, F_SETLK, &lock) == -1) { + if (errno == EACCES || errno == EAGAIN) { + fprintf(stderr, "PID file locked by other process"); + exit(1); + } + + fprintf(stderr, "unable to lock PID file: %s", strerror(errno)); + exit(1); + } + + if (ftruncate(fd, 0) == -1) { + fprintf(stderr, "unable to truncate PID file: %s", strerror(errno)); + exit(1); + } + + fp = fdopen(fd, "w"); + if (!fp || fprintf(fp, "%d\n", getpid()) < 1 || fflush(fp)) { + fprintf(stderr, "unable to write to PID file: %s", strerror(errno)); + exit(1); + } +} + void daemonize(void) { pid_t pid; @@ -235,6 +286,7 @@ void daemonize(void) exit(1); } else if (pid > 0) exit(0); + write_pid_file(); openlog("dnscap", 0, LOG_DAEMON); if (setsid() < 0) { logerr("setsid failed: %s", strerror(errno)); diff --git a/src/dnscap.1.in b/src/dnscap.1.in index f33fcfc..58c4b90 100644 --- a/src/dnscap.1.in +++ b/src/dnscap.1.in @@ -163,6 +163,9 @@ functions, unless options .B \-N is given or only reading from files. .TP +.BI "\-o pid_file" =... +Specify the file to write the PID to when running as a daemon (default none). +.TP .BI "\-o user" =... Specify the user to drop privileges to (default nobody). .TP diff --git a/src/options.c b/src/options.c index 29a5dad..8d03c26 100644 --- a/src/options.c +++ b/src/options.c @@ -228,6 +228,13 @@ int option_parse(options_t* options, const char* option) options->bpf_hosts_apply_all = 1; return 0; } + } else if (have("pid_file")) { + if (options->pid_file) { + free(options->pid_file); + } + if ((options->pid_file = strdup(argument))) { + return 0; + } } return 1; @@ -244,5 +251,9 @@ void options_free(options_t* options) free(options->group); options->group = 0; } + if (options->pid_file) { + free(options->pid_file); + options->pid_file = 0; + } } } diff --git a/src/options.h b/src/options.h index 40e0ee8..99acb8d 100644 --- a/src/options.h +++ b/src/options.h @@ -72,6 +72,8 @@ enum dump_format { \ 0, 0, 0, 0, 0, \ \ + 0, \ +\ 0 \ } @@ -113,6 +115,8 @@ struct options { int reassemble_tcp_bfbparsedns; int bpf_hosts_apply_all; + + char* pid_file; }; int option_parse(options_t* options, const char* option); |