From: Roy Marples Date: Wed, 17 May 2023 02:08:45 +0000 (+0100) Subject: control: deal with hangup better X-Git-Tag: v10.0.2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41084f34629d4da5937dc44e0b68677b11eb65a3;p=thirdparty%2Fdhcpcd.git control: deal with hangup better Maybe fix #205 --- diff --git a/src/control.c b/src/control.c index 0b7133e2..ecd6d47f 100644 --- a/src/control.c +++ b/src/control.c @@ -93,6 +93,19 @@ control_free(struct fd_list *fd) free(fd); } +static void +control_hangup(struct fd_list *fd) +{ + +#ifdef PRIVSEP + if (IN_PRIVSEP(fd->ctx)) { + if (ps_ctl_sendeof(fd) == -1) + logerr(__func__); + } +#endif + control_free(fd); +} + static void control_handle_read(struct fd_list *fd) { @@ -100,16 +113,9 @@ control_handle_read(struct fd_list *fd) ssize_t bytes; bytes = read(fd->fd, buffer, sizeof(buffer) - 1); - if (bytes == -1) + if (bytes == -1) { logerr(__func__); - if (bytes == -1 || bytes == 0) { -#ifdef PRIVSEP - if (IN_PRIVSEP(fd->ctx)) { - if (ps_ctl_sendeof(fd) == -1) - logerr(__func__); - } -#endif - control_free(fd); + control_hangup(fd); return; } @@ -159,7 +165,7 @@ control_handle_write(struct fd_list *fd) if (writev(fd->fd, iov, iov_len) == -1) { logerr("%s: write", __func__); - control_free(fd); + control_hangup(fd); return; } @@ -194,13 +200,15 @@ control_handle_data(void *arg, unsigned short events) { struct fd_list *fd = arg; - if (!(events & (ELE_READ | ELE_WRITE))) + if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP))) logerrx("%s: unexpected event 0x%04x", __func__, events); if (events & ELE_WRITE && !(events & ELE_HANGUP)) control_handle_write(fd); if (events & ELE_READ) control_handle_read(fd); + if (events & ELE_HANGUP) + control_hangup(fd); } void diff --git a/src/privsep-control.c b/src/privsep-control.c index abea5024..38f18c4e 100644 --- a/src/privsep-control.c +++ b/src/privsep-control.c @@ -64,27 +64,13 @@ ps_ctl_startcb(struct ps_process *psp) ctx->options & DHCPCD_MANAGER ? NULL : *ctx->ifv, af); } -static ssize_t -ps_ctl_recvmsgcb(void *arg, struct ps_msghdr *psm, __unused struct msghdr *msg) -{ - struct dhcpcd_ctx *ctx = arg; - - if (psm->ps_cmd != PS_CTL_EOF) { - errno = ENOTSUP; - return -1; - } - - ctx->ps_control_client = NULL; - return 0; -} - static void ps_ctl_recvmsg(void *arg, unsigned short events) { struct ps_process *psp = arg; if (ps_recvpsmsg(psp->psp_ctx, psp->psp_fd, events, - ps_ctl_recvmsgcb, psp->psp_ctx) == -1) + NULL, psp->psp_ctx) == -1) logerr(__func__); } @@ -175,22 +161,26 @@ ps_ctl_recv(void *arg, unsigned short events) char buf[BUFSIZ]; ssize_t len; - if (!(events & ELE_READ)) + if (!(events & (ELE_READ | ELE_HANGUP))) logerrx("%s: unexpected event 0x%04x", __func__, events); - len = read(ctx->ps_ctl->psp_work_fd, buf, sizeof(buf)); - if (len == 0) - return; - if (len == -1) { - logerr("%s: read", __func__); - eloop_exit(ctx->eloop, EXIT_FAILURE); - return; + if (events & ELE_READ) { + len = read(ctx->ps_ctl->psp_work_fd, buf, sizeof(buf)); + if (len == -1) + logerr("%s: read", __func__); + else if (len == 0) + // FIXME: Why does this happen? + ; + else if (ctx->ps_control_client == NULL) + logerrx("%s: clientfd #%d disconnected (len=%zd)", + __func__, ctx->ps_ctl->psp_work_fd, len); + else { + errno = 0; + if (control_queue(ctx->ps_control_client, + buf, (size_t)len) == -1) + logerr("%s: control_queue", __func__); + } } - if (ctx->ps_control_client == NULL) /* client disconnected */ - return; - errno = 0; - if (control_queue(ctx->ps_control_client, buf, (size_t)len) == -1) - logerr("%s: control_queue", __func__); } static void @@ -205,8 +195,6 @@ ps_ctl_listen(void *arg, unsigned short events) logerrx("%s: unexpected event 0x%04x", __func__, events); len = read(ctx->ps_control->fd, buf, sizeof(buf)); - if (len == 0) - return; if (len == -1) { logerr("%s: read", __func__); eloop_exit(ctx->eloop, EXIT_FAILURE);