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)
{
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;
}
if (writev(fd->fd, iov, iov_len) == -1) {
logerr("%s: write", __func__);
- control_free(fd);
+ control_hangup(fd);
return;
}
{
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
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__);
}
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
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);