diff --git a/ndhc/arp.c b/ndhc/arp.c index 287b658..272ef51 100644 --- a/ndhc/arp.c +++ b/ndhc/arp.c @@ -43,6 +43,7 @@ #include "state.h" #include "dhcp.h" #include "sys.h" +#include "ndhc.h" #include "ifchange.h" #include "options.h" #include "leasefile.h" @@ -234,7 +235,7 @@ static int arp_open_fd(struct client_state_t *cs) } cs->arpFd = fd; - epoll_add(cs, fd); + epoll_add(cs->epollFd, fd); arpreply_clear(); return 0; out_fd: @@ -274,7 +275,7 @@ static int arp_min_close_fd(struct client_state_t *cs) { if (cs->arpFd == -1) return 0; - epoll_del(cs, cs->arpFd); + epoll_del(cs->epollFd, cs->arpFd); close(cs->arpFd); cs->arpFd = -1; arpState = AS_NONE; @@ -498,7 +499,7 @@ void arp_success(struct client_state_t *cs) if (client_config.quit_after_lease) exit(EXIT_SUCCESS); if (!client_config.foreground) - background(cs); + background(); } static void arp_gw_success(struct client_state_t *cs) diff --git a/ndhc/dhcp.c b/ndhc/dhcp.c index 9d08dfc..bba16f1 100644 --- a/ndhc/dhcp.c +++ b/ndhc/dhcp.c @@ -465,7 +465,7 @@ static void change_listen_mode(struct client_state_t *cs, int new_mode) { cs->listenMode = new_mode; if (cs->listenFd >= 0) { - epoll_del(cs, cs->listenFd); + epoll_del(cs->epollFd, cs->listenFd); close(cs->listenFd); cs->listenFd = -1; } @@ -478,7 +478,7 @@ static void change_listen_mode(struct client_state_t *cs, int new_mode) log_error("FATAL: Couldn't listen on socket: %s.", strerror(errno)); exit(EXIT_FAILURE); } - epoll_add(cs, cs->listenFd); + epoll_add(cs->epollFd, cs->listenFd); } void set_listen_raw(struct client_state_t *cs) diff --git a/ndhc/ifchd.c b/ndhc/ifchd.c index e4ac82e..f219473 100644 --- a/ndhc/ifchd.c +++ b/ndhc/ifchd.c @@ -56,6 +56,7 @@ #include "strl.h" #include "cap.h" #include "io.h" +#include "sys.h" #include "ifset.h" #include "seccomp.h" @@ -81,29 +82,6 @@ static void writeordie(int fd, const char *buf, int len) suicide("write returned error"); } -static void ep_add(int fd) -{ - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; - ev.data.fd = fd; - int r = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); - if (r == -1) - suicide("%s failed: %s", __func__, strerror(errno)); -} - -// XXX: Remove dead code. -#if 0 -static void epoll_del(int fd) -{ - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; - ev.data.fd = fd; - int r = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev); - if (r == -1) - suicide("epoll_del failed %s", strerror(errno)); -} -#endif - /* Writes a new resolv.conf based on the information we have received. */ static void write_resolve_conf(void) { @@ -358,8 +336,8 @@ void do_ifch_work(void) ifchd_client_init(); - ep_add(pToIfchR); - ep_add(signalFd); + epoll_add(epollfd, pToIfchR); + epoll_add(epollfd, signalFd); for (;;) { int r = epoll_wait(epollfd, events, 2, -1); diff --git a/ndhc/ndhc.c b/ndhc/ndhc.c index d0929b7..592a0cc 100644 --- a/ndhc/ndhc.c +++ b/ndhc/ndhc.c @@ -49,6 +49,7 @@ #include #include +#include "ndhc.h" #include "ndhc-defines.h" #include "config.h" #include "state.h" @@ -124,6 +125,27 @@ static void show_usage(void) exit(EXIT_SUCCESS); } +static void setup_signals_ndhc(void) +{ + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + sigaddset(&mask, SIGUSR2); + sigaddset(&mask, SIGCHLD); + sigaddset(&mask, SIGPIPE); + sigaddset(&mask, SIGTERM); + if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) + suicide("sigprocmask failed"); + if (cs.signalFd >= 0) { + epoll_del(cs.epollFd, cs.signalFd); + close(cs.signalFd); + } + cs.signalFd = signalfd(-1, &mask, SFD_NONBLOCK); + if (cs.signalFd < 0) + suicide("signalfd failed"); + epoll_add(cs.epollFd, cs.signalFd); +} + static void signal_dispatch(void) { int t; @@ -203,9 +225,9 @@ static void do_ndhc_work(void) if (enforce_seccomp_ndhc()) log_line("ndhc seccomp filter cannot be installed"); - setup_signals_ndhc(&cs); + setup_signals_ndhc(); - epoll_add(&cs, cs.nlFd); + epoll_add(cs.epollFd, cs.nlFd); set_listen_raw(&cs); nowts = curms(); goto jumpstart; @@ -262,6 +284,7 @@ jumpstart: char chroot_dir[MAX_PATH_LENGTH] = ""; char resolv_conf_d[MAX_PATH_LENGTH] = ""; +static char pidfile[MAX_PATH_LENGTH] = PID_FILE_DEFAULT; static uid_t ndhc_uid = 0; static gid_t ndhc_gid = 0; int pToNdhcR; @@ -317,6 +340,22 @@ static void ndhc_main(void) { do_ndhc_work(); } +void background(void) +{ + static char called; + if (!called) { + called = 1; // Do not fork again. + if (daemon(0, 0) == -1) { + perror("fork"); + exit(EXIT_SUCCESS); + } + } + if (file_exists(pidfile, "w") == -1) { + log_line("Cannot open pidfile for write!"); + } else + write_pid(pidfile); +} + int main(int argc, char **argv) { static const struct option arg_options[] = { diff --git a/ndhc/ndhc.h b/ndhc/ndhc.h index e319500..26a57a4 100644 --- a/ndhc/ndhc.h +++ b/ndhc/ndhc.h @@ -37,4 +37,6 @@ extern int pToNdhcW; extern char chroot_dir[MAX_PATH_LENGTH]; extern char resolv_conf_d[MAX_PATH_LENGTH]; +extern void background(void); + #endif /* NJK_NDHC_NDHC_H_ */ diff --git a/ndhc/state.c b/ndhc/state.c index 1f7eefd..a361b73 100644 --- a/ndhc/state.c +++ b/ndhc/state.c @@ -36,6 +36,7 @@ #include "arp.h" #include "options.h" #include "log.h" +#include "ndhc.h" #include "sys.h" #include "random.h" @@ -299,7 +300,7 @@ static void selecting_timeout(struct client_state_t *cs, long long nowts) if (client_config.background_if_no_lease) { log_line("No lease, going to background."); cs->init = 0; - background(cs); + background(); } else if (client_config.abort_if_no_lease) { log_line("No lease, failing."); exit(EXIT_FAILURE); diff --git a/ndhc/sys.c b/ndhc/sys.c index abf7014..d75b2e7 100644 --- a/ndhc/sys.c +++ b/ndhc/sys.c @@ -31,74 +31,30 @@ #include #include #include -#include #include #include +#include "sys.h" #include "config.h" #include "log.h" -#include "pidfile.h" -#include "sys.h" -char pidfile[MAX_PATH_LENGTH] = PID_FILE_DEFAULT; - -void setup_signals_ndhc(struct client_state_t *cs) -{ - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - sigaddset(&mask, SIGUSR2); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGPIPE); - 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; - if (!called) { - called = 1; // Do not fork again. - if (daemon(0, 0) == -1) { - perror("fork"); - exit(EXIT_SUCCESS); - } - if (cs) - setup_signals_ndhc(cs); - } - if (file_exists(pidfile, "w") == -1) { - log_line("Cannot open pidfile for write!"); - } else - write_pid(pidfile); -} - -void epoll_add(struct client_state_t *cs, int fd) +void epoll_add(int epfd, int fd) { struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; ev.data.fd = fd; - r = epoll_ctl(cs->epollFd, EPOLL_CTL_ADD, fd, &ev); + r = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); if (r == -1) suicide("epoll_add failed %s", strerror(errno)); } -void epoll_del(struct client_state_t *cs, int fd) +void epoll_del(int epfd, int fd) { struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; ev.data.fd = fd; - r = epoll_ctl(cs->epollFd, EPOLL_CTL_DEL, fd, &ev); + r = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev); if (r == -1) suicide("epoll_del failed %s", strerror(errno)); } diff --git a/ndhc/sys.h b/ndhc/sys.h index d145101..714960f 100644 --- a/ndhc/sys.h +++ b/ndhc/sys.h @@ -39,11 +39,7 @@ static inline unsigned long long curms() return ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000ULL; } -extern char pidfile[MAX_PATH_LENGTH]; - -void setup_signals_ndhc(struct client_state_t *cs); -void background(struct client_state_t *cs); -void epoll_add(struct client_state_t *cs, int fd); -void epoll_del(struct client_state_t *cs, int fd); +extern void epoll_add(int epfd, int fd); +extern void epoll_del(int epfd, int fd); #endif /* SYS_H_ */