After fork(), a signalfd-created file descriptor still returns signal info
for the parent. Close and recreate a new signalfd after forking into the background.
This commit is contained in:
parent
03d3cbfdb9
commit
a53a82bbc5
@ -136,7 +136,7 @@ void arp_success(struct client_state_t *cs)
|
|||||||
if (client_config.quit_after_lease)
|
if (client_config.quit_after_lease)
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
if (!client_config.foreground)
|
if (!client_config.foreground)
|
||||||
background();
|
background(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef uint32_t aliased_uint32_t __attribute__((__may_alias__));
|
typedef uint32_t aliased_uint32_t __attribute__((__may_alias__));
|
||||||
|
18
ndhc/ndhc.c
18
ndhc/ndhc.c
@ -181,20 +181,6 @@ static void perform_release(void)
|
|||||||
cs.timeout = -1;
|
cs.timeout = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_signals()
|
|
||||||
{
|
|
||||||
sigset_t mask;
|
|
||||||
sigemptyset(&mask);
|
|
||||||
sigaddset(&mask, SIGUSR1);
|
|
||||||
sigaddset(&mask, SIGUSR2);
|
|
||||||
sigaddset(&mask, SIGTERM);
|
|
||||||
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
|
|
||||||
suicide("sigprocmask failed");
|
|
||||||
cs.signalFd = signalfd(-1, &mask, SFD_NONBLOCK);
|
|
||||||
if (cs.signalFd < 0)
|
|
||||||
suicide("signalfd failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void signal_dispatch()
|
static void signal_dispatch()
|
||||||
{
|
{
|
||||||
int t, off = 0;
|
int t, off = 0;
|
||||||
@ -234,7 +220,7 @@ static void do_work(void)
|
|||||||
cs.epollFd = epoll_create1(0);
|
cs.epollFd = epoll_create1(0);
|
||||||
if (cs.epollFd == -1)
|
if (cs.epollFd == -1)
|
||||||
suicide("epoll_create1 failed");
|
suicide("epoll_create1 failed");
|
||||||
epoll_add(&cs, cs.signalFd);
|
setup_signals(&cs);
|
||||||
change_listen_mode(&cs, LM_RAW);
|
change_listen_mode(&cs, LM_RAW);
|
||||||
handle_timeout(&cs);
|
handle_timeout(&cs);
|
||||||
|
|
||||||
@ -387,8 +373,6 @@ int main(int argc, char **argv)
|
|||||||
memcpy(client_config.clientid + 3, client_config.arp, 6);
|
memcpy(client_config.clientid + 3, client_config.arp, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_signals();
|
|
||||||
|
|
||||||
if (chdir(chroot_dir)) {
|
if (chdir(chroot_dir)) {
|
||||||
printf("Failed to chdir(%s)!\n", chroot_dir);
|
printf("Failed to chdir(%s)!\n", chroot_dir);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
33
ndhc/sys.c
33
ndhc/sys.c
@ -3,7 +3,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pidfile.h"
|
#include "pidfile.h"
|
||||||
@ -11,14 +13,38 @@
|
|||||||
|
|
||||||
char pidfile[MAX_PATH_LENGTH] = PID_FILE_DEFAULT;
|
char pidfile[MAX_PATH_LENGTH] = PID_FILE_DEFAULT;
|
||||||
|
|
||||||
void background(void)
|
void setup_signals(struct client_state_t *cs)
|
||||||
|
{
|
||||||
|
sigset_t mask;
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGUSR1);
|
||||||
|
sigaddset(&mask, SIGUSR2);
|
||||||
|
sigaddset(&mask, SIGTERM);
|
||||||
|
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
|
||||||
|
suicide("sigprocmask failed");
|
||||||
|
if (cs->signalFd >= 0) {
|
||||||
|
epoll_del(cs, cs->signalFd);
|
||||||
|
close(cs->signalFd);
|
||||||
|
}
|
||||||
|
cs->signalFd = signalfd(-1, &mask, SFD_NONBLOCK);
|
||||||
|
if (cs->signalFd < 0)
|
||||||
|
suicide("signalfd failed");
|
||||||
|
epoll_add(cs, cs->signalFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @cs can be NULL
|
||||||
|
void background(struct client_state_t *cs)
|
||||||
{
|
{
|
||||||
static char called;
|
static char called;
|
||||||
if (!called && daemon(0, 0) == -1) {
|
if (!called) {
|
||||||
|
called = 1; /* Do not fork again. */
|
||||||
|
if (daemon(0, 0) == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
called = 1; /* Do not fork again. */
|
if (cs)
|
||||||
|
setup_signals(cs);
|
||||||
|
}
|
||||||
if (file_exists(pidfile, "w") == -1) {
|
if (file_exists(pidfile, "w") == -1) {
|
||||||
log_line("cannot open pidfile for write!");
|
log_line("cannot open pidfile for write!");
|
||||||
} else
|
} else
|
||||||
@ -46,3 +72,4 @@ void epoll_del(struct client_state_t *cs, int fd)
|
|||||||
if (r == -1)
|
if (r == -1)
|
||||||
suicide("epoll_del failed %s", strerror(errno));
|
suicide("epoll_del failed %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "ndhc-defines.h"
|
#include "ndhc-defines.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
static inline unsigned long long curms()
|
static inline unsigned long long curms()
|
||||||
{
|
{
|
||||||
@ -13,7 +14,8 @@ static inline unsigned long long curms()
|
|||||||
|
|
||||||
extern char pidfile[MAX_PATH_LENGTH];
|
extern char pidfile[MAX_PATH_LENGTH];
|
||||||
|
|
||||||
void background(void);
|
void setup_signals(struct client_state_t *cs);
|
||||||
|
void background(struct client_state_t *cs);
|
||||||
void epoll_add(struct client_state_t *cs, int fd);
|
void epoll_add(struct client_state_t *cs, int fd);
|
||||||
void epoll_del(struct client_state_t *cs, int fd);
|
void epoll_del(struct client_state_t *cs, int fd);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ static void init_selecting_timeout(struct client_state_t *cs)
|
|||||||
} else {
|
} else {
|
||||||
if (client_config.background_if_no_lease) {
|
if (client_config.background_if_no_lease) {
|
||||||
log_line("No lease, going to background.");
|
log_line("No lease, going to background.");
|
||||||
background();
|
background(cs);
|
||||||
} else if (client_config.abort_if_no_lease) {
|
} else if (client_config.abort_if_no_lease) {
|
||||||
log_line("No lease, failing.");
|
log_line("No lease, failing.");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user