From: Stephan Bosch Date: Mon, 26 Feb 2018 21:27:40 +0000 (+0100) Subject: lib-program-client: Use event logging. X-Git-Tag: 2.3.9~2074 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=23cfbf2451f7191dee1d9995011c898a7bf32bd4;p=thirdparty%2Fdovecot%2Fcore.git lib-program-client: Use event logging. This also makes the overall log messages better match similar messages produced by other parts of Dovecot. --- diff --git a/src/lib-program-client/program-client-local.c b/src/lib-program-client/program-client-local.c index bb6c067cb0..46b87dc58b 100644 --- a/src/lib-program-client/program-client-local.c +++ b/src/lib-program-client/program-client-local.c @@ -29,6 +29,8 @@ struct program_client_local { struct child_wait *child_wait; struct timeout *to_kill; + char *bin_path; + pid_t pid; int status; bool exited:1; @@ -59,20 +61,22 @@ exec_child(const char *bin_path, const char *const *args, out_fd = dev_null_fd; if (in_fd != STDIN_FILENO && dup2(in_fd, STDIN_FILENO) < 0) - i_fatal("dup2(stdin) failed: %m"); + i_fatal("program %s: dup2(stdin) failed: %m", bin_path); if (out_fd != STDOUT_FILENO && dup2(out_fd, STDOUT_FILENO) < 0) - i_fatal("dup2(stdout) failed: %m"); + i_fatal("program %s: dup2(stdout) failed: %m", bin_path); if (in_fd != STDIN_FILENO && in_fd != dev_null_fd && close(in_fd) < 0) - i_error("close(in_fd) failed: %m"); + i_error("program %s: close(in_fd) failed: %m", bin_path); if (out_fd != STDOUT_FILENO && out_fd != dev_null_fd && (out_fd != in_fd) && close(out_fd) < 0) - i_error("close(out_fd) failed: %m"); + i_error("program %s: close(out_fd) failed: %m", bin_path); /* Drop stderr if requested */ if (drop_stderr) { - if (dup2(dev_null_fd, STDERR_FILENO) < 0) - i_fatal("dup2(stderr) failed: %m"); + if (dup2(dev_null_fd, STDERR_FILENO) < 0) { + i_fatal("program %s: " + "dup2(stderr) failed: %m", bin_path); + } } /* Setup extra fds */ @@ -83,18 +87,22 @@ exec_child(const char *bin_path, const char *const *args, i_assert(efd[1] != STDOUT_FILENO); i_assert(efd[1] != STDERR_FILENO); if (efd[0] != efd[1]) { - if (dup2(efd[0], efd[1]) < 0) - i_fatal("dup2(extra_fd=%d) failed: %m", - efd[1]); + if (dup2(efd[0], efd[1]) < 0) { + i_fatal("program %s" + "dup2(extra_fd=%d) failed: %m", + bin_path, efd[1]); + } } } for(efd = extra_fds; *efd != -1; efd += 2) { if (efd[0] != efd[1] && efd[0] != STDIN_FILENO && efd[0] != STDOUT_FILENO && efd[0] != STDERR_FILENO) { - if (close(efd[0]) < 0) - i_error("close(extra_fd=%d) failed: %m", - efd[1]); + if (close(efd[0]) < 0) { + i_error("program %s" + "close(extra_fd=%d) failed: %m", + bin_path, efd[1]); + } } } } @@ -156,13 +164,13 @@ program_client_local_connect(struct program_client *pclient) /* create normal I/O fds */ if (pclient->input != NULL) { if (pipe(fd_in) < 0) { - i_error("pipe(in) failed: %m"); + e_error(pclient->event, "pipe(in) failed: %m"); return -1; } } if (pclient->output != NULL) { if (pipe(fd_out) < 0) { - i_error("pipe(out) failed: %m"); + e_error(pclient->event, "pipe(out) failed: %m"); return -1; } } @@ -178,7 +186,8 @@ program_client_local_connect(struct program_client *pclient) child_extra_fds = t_new(int, xfd_count * 2 + 1); for(i = 0; i < xfd_count; i++) { if (pipe(extra_fd) < 0) { - i_error("pipe(extra=%d) failed: %m", + e_error(pclient->event, + "pipe(extra=%d) failed: %m", extra_fd[1]); return -1; } @@ -192,28 +201,34 @@ program_client_local_connect(struct program_client *pclient) /* fork child */ if ((plclient->pid = fork()) == (pid_t)-1) { - i_error("fork() failed: %m"); + e_error(pclient->event, "fork() failed: %m"); /* clean up */ if (fd_in[0] >= 0 && close(fd_in[0]) < 0) { - i_error("close(pipe:in:rd) failed: %m"); + e_error(pclient->event, + "close(pipe:in:rd) failed: %m"); } if (fd_in[1] >= 0 && close(fd_in[1]) < 0) { - i_error("close(pipe:in:wr) failed: %m"); + e_error(pclient->event, + "close(pipe:in:wr) failed: %m"); } if (fd_out[0] >= 0 && close(fd_out[0]) < 0) { - i_error("close(pipe:out:rd) failed: %m"); + e_error(pclient->event, + "close(pipe:out:rd) failed: %m"); } if (fd_out[1] >= 0 && close(fd_out[1]) < 0) { - i_error("close(pipe:out:wr) failed: %m"); + e_error(pclient->event, + "close(pipe:out:wr) failed: %m"); } for(i = 0; i < xfd_count; i++) { if (close(child_extra_fds[i * 2]) < 0) { - i_error("close(pipe:extra=%d:wr) failed: %m", + e_error(pclient->event, + "close(pipe:extra=%d:wr) failed: %m", child_extra_fds[i * 2 + 1]); } if (close(parent_extra_fds[i]) < 0) { - i_error("close(pipe:extra=%d:rd) failed: %m", + e_error(pclient->event, + "close(pipe:extra=%d:rd) failed: %m", child_extra_fds[i * 2 + 1]); } } @@ -222,13 +237,18 @@ program_client_local_connect(struct program_client *pclient) if (plclient->pid == 0) { /* child */ - if (fd_in[1] >= 0 && close(fd_in[1]) < 0) - i_error("close(pipe:in:wr) failed: %m"); - if (fd_out[0] >= 0 && close(fd_out[0]) < 0) - i_error("close(pipe:out:rd) failed: %m"); + if (fd_in[1] >= 0 && close(fd_in[1]) < 0) { + e_error(pclient->event, + "close(pipe:in:wr) failed: %m"); + } + if (fd_out[0] >= 0 && close(fd_out[0]) < 0) { + e_error(pclient->event, + "close(pipe:out:rd) failed: %m"); + } for(i = 0; i < xfd_count; i++) { if (close(parent_extra_fds[i]) < 0) { - i_error("close(pipe:extra=%d:rd) failed: %m", + e_error(pclient->event, + "close(pipe:extra=%d:rd) failed: %m", child_extra_fds[i * 2 + 1]); } } @@ -240,17 +260,23 @@ program_client_local_connect(struct program_client *pclient) RESTRICT_ACCESS_FLAG_ALLOW_ROOT : 0), pclient->set.home); - exec_child(pclient->path, pclient->args, &pclient->envs, + exec_child(plclient->bin_path, pclient->args, &pclient->envs, fd_in[0], fd_out[1], child_extra_fds, pclient->set.drop_stderr); i_unreached(); } /* parent */ - if (fd_in[0] >= 0 && close(fd_in[0]) < 0) - i_error("close(pipe:in:rd) failed: %m"); - if (fd_out[1] >= 0 && close(fd_out[1]) < 0) - i_error("close(pipe:out:wr) failed: %m"); + program_client_set_label(pclient, + t_strdup_printf("exec:%s (%d)", plclient->bin_path, + plclient->pid)); + + if (fd_in[0] >= 0 && close(fd_in[0]) < 0) { + e_error(pclient->event, "close(pipe:in:rd) failed: %m"); + } + if (fd_out[1] >= 0 && close(fd_out[1]) < 0) { + e_error(pclient->event, "close(pipe:out:wr) failed: %m"); + } if (fd_in[1] >= 0) { net_set_nonblock(fd_in[1], TRUE); pclient->fd_out = fd_in[1]; @@ -261,7 +287,8 @@ program_client_local_connect(struct program_client *pclient) } for(i = 0; i < xfd_count; i++) { if (close(child_extra_fds[i * 2]) < 0) { - i_error("close(pipe:extra=%d:wr) failed: %m", + e_error(pclient->event, + "close(pipe:extra=%d:wr) failed: %m", child_extra_fds[i * 2 + 1]); } net_set_nonblock(parent_extra_fds[i], TRUE); @@ -287,7 +314,8 @@ program_client_local_close_output(struct program_client *pclient) /* Shutdown output; program stdin will get EOF */ if (fd_out >= 0 && close(fd_out) < 0) { - i_error("close(%s) failed: %m", pclient->path); + e_error(pclient->event, + "close(fd_out) failed: %m"); return -1; } return 1; @@ -312,8 +340,9 @@ program_client_local_exited(struct program_client_local *plclient) int exit_code = WEXITSTATUS(plclient->status); if (exit_code != 0) { - i_info("program `%s' terminated with non-zero exit code %d", - pclient->path, exit_code); + e_info(pclient->event, + "Terminated with non-zero exit code %d", + exit_code); pclient->exit_code = PROGRAM_CLIENT_EXIT_FAILURE; } else { pclient->exit_code = PROGRAM_CLIENT_EXIT_SUCCESS; @@ -321,20 +350,24 @@ program_client_local_exited(struct program_client_local *plclient) } else if (WIFSIGNALED(plclient->status)) { /* Killed with a signal */ if (plclient->sent_term) { - i_error("program `%s' was forcibly terminated with signal %d", - pclient->path, WTERMSIG(plclient->status)); + e_error(pclient->event, + "Forcibly terminated with signal %d", + WTERMSIG(plclient->status)); } else { - i_error("program `%s' terminated abnormally, signal %d", - pclient->path, WTERMSIG(plclient->status)); + e_error(pclient->event, + "Terminated abnormally with signal %d", + WTERMSIG(plclient->status)); } } else if (WIFSTOPPED(plclient->status)) { /* Stopped */ - i_error("program `%s' stopped, signal %d", - pclient->path, WSTOPSIG(plclient->status)); + e_error(pclient->event, + "Stopped with signal %d", + WSTOPSIG(plclient->status)); } else { /* Something else */ - i_error("program `%s' terminated abnormally, return status %d", - pclient->path, plclient->status); + e_error(pclient->event, + "Terminated abnormally with status %d", + plclient->status); } program_client_disconnected(pclient); @@ -343,6 +376,8 @@ program_client_local_exited(struct program_client_local *plclient) static void program_client_local_kill_now(struct program_client_local *plclient) { + struct program_client *pclient = &plclient->client; + if (plclient->child_wait != NULL) { /* no need for this anymore */ child_wait_free(&plclient->child_wait); @@ -353,17 +388,19 @@ program_client_local_kill_now(struct program_client_local *plclient) /* kill it brutally now: it should die right away */ if (kill(plclient->pid, SIGKILL) < 0) { - i_error("failed to send SIGKILL signal to program `%s'", - plclient->client.path); + e_error(pclient->event, + "Failed to send SIGKILL signal to program"); } else if (waitpid(plclient->pid, &plclient->status, 0) < 0) { - i_error("waitpid(%s) failed: %m", - plclient->client.path); + e_error(pclient->event, "waitpid(%d) failed: %m", + plclient->pid); } } static void program_client_local_kill(struct program_client_local *plclient) { + struct program_client *pclient = &plclient->client; + /* time to die */ timeout_remove(&plclient->to_kill); @@ -374,29 +411,27 @@ program_client_local_kill(struct program_client_local *plclient) if (plclient->sent_term) { /* Timed out again */ - if (plclient->client.debug) { - i_debug("program `%s' (%d) did not die after %d milliseconds: " - "sending KILL signal", - plclient->client.path, plclient->pid, KILL_TIMEOUT); - } + e_debug(pclient->event, + "Program did not die after %d milliseconds", + KILL_TIMEOUT); program_client_local_kill_now(plclient); program_client_local_exited(plclient); return; } - if (plclient->client.debug) - i_debug("program `%s'(%d) execution timed out after %u milliseconds: " - "sending TERM signal", plclient->client.path, plclient->pid, - plclient->client.set.input_idle_timeout_msecs); + e_debug(pclient->event, + "Execution timed out after %u milliseconds: " + "Sending TERM signal", + pclient->set.input_idle_timeout_msecs); /* send sigterm, keep on waiting */ plclient->sent_term = TRUE; /* Kill child gently first */ if (kill(plclient->pid, SIGTERM) < 0) { - i_error("failed to send SIGTERM signal to program `%s'", - plclient->client.path); + e_error(pclient->event, + "Failed to send SIGTERM signal to program"); (void)kill(plclient->pid, SIGKILL); program_client_local_exited(plclient); return; @@ -443,10 +478,8 @@ program_client_local_disconnect(struct program_client *pclient, bool force) runtime < pclient->set.input_idle_timeout_msecs) timeout = pclient->set.input_idle_timeout_msecs - runtime; - if (pclient->debug) { - i_debug("waiting for program `%s' to finish after %lu msecs", - pclient->path, runtime); - } + e_debug(pclient->event, + "Waiting for program to finish after %lu msecs", runtime); force = force || (timeout == 0 && pclient->set.input_idle_timeout_msecs > 0); @@ -492,16 +525,20 @@ program_client_local_create(const char *bin_path, const struct program_client_settings *set) { struct program_client_local *plclient; + const char *label; pool_t pool; + label = t_strconcat("exec:", bin_path, NULL); + pool = pool_alloconly_create("program client local", 1024); plclient = p_new(pool, struct program_client_local, 1); - program_client_init(&plclient->client, pool, bin_path, args, set); + program_client_init(&plclient->client, pool, label, args, set); plclient->client.connect = program_client_local_connect; plclient->client.close_output = program_client_local_close_output; plclient->client.switch_ioloop = program_client_local_switch_ioloop; plclient->client.disconnect = program_client_local_disconnect; plclient->client.destroy = program_client_local_destroy; + plclient->bin_path = p_strdup(pool, bin_path); plclient->pid = -1; child_wait_init(); diff --git a/src/lib-program-client/program-client-private.h b/src/lib-program-client/program-client-private.h index ff5750744a..3810422345 100644 --- a/src/lib-program-client/program-client-private.h +++ b/src/lib-program-client/program-client-private.h @@ -32,10 +32,11 @@ struct program_client { pool_t pool; struct program_client_settings set; - char *path; const char **args; ARRAY_TYPE(const_string) envs; + struct event *event; + int fd_in, fd_out; struct io *io; struct timeout *to; @@ -67,8 +68,11 @@ struct program_client { bool destroying:1; }; +void program_client_set_label(struct program_client *pclient, + const char *label); + void program_client_init(struct program_client *pclient, pool_t pool, - const char *path, + const char *initial_label, const char *const *args, const struct program_client_settings *set); diff --git a/src/lib-program-client/program-client-remote.c b/src/lib-program-client/program-client-remote.c index e579c05121..d2c3df01c5 100644 --- a/src/lib-program-client/program-client-remote.c +++ b/src/lib-program-client/program-client-remote.c @@ -206,7 +206,7 @@ program_client_istream_create(struct program_client *program_client, struct program_client_remote { struct program_client client; - const char *hostname; + const char *address; struct dns_lookup_settings dns_set; struct dns_lookup *lookup; unsigned int ips_count; @@ -218,6 +218,7 @@ struct program_client_remote { bool noreply:1; bool resolved:1; + bool have_hostname:1; }; static void @@ -265,7 +266,8 @@ program_client_remote_connected(struct program_client_remote *prclient) if (o_stream_send(pclient->raw_program_output, str_data(str), str_len(str)) < 0) { - i_error("write(%s) failed: %s", + e_error(pclient->event, + "write(%s) failed: %s", o_stream_get_name(pclient->raw_program_output), o_stream_get_error(pclient->raw_program_output)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); @@ -291,25 +293,25 @@ program_client_unix_connect(struct program_client *pclient) (struct program_client_remote *)pclient; int fd; - if (pclient->set.debug) - i_debug("Trying to connect %s", pclient->path); + e_debug(pclient->event, "Trying to connect"); timeout_remove(&prclient->to_retry); - if ((fd = net_connect_unix(pclient->path)) < 0) { + if ((fd = net_connect_unix(prclient->address)) < 0) { switch (errno) { case EACCES: - i_error("%s", + e_error(pclient->event, "%s", eacces_error_get("net_connect_unix", - pclient->path)); + prclient->address)); return -1; case EAGAIN: prclient->to_retry = timeout_add_short(100, program_client_unix_reconnect, prclient); return 0; default: - i_error("net_connect_unix(%s) failed: %m", - pclient->path); + e_error(pclient->event, + "net_connect_unix(%s) failed: %m", + prclient->address); return -1; } } @@ -330,8 +332,8 @@ program_client_net_connect_timeout(struct program_client_remote *prclient) io_remove(&pclient->io); timeout_remove(&pclient->to); - i_error("connect(%s) failed: timeout in %u milliseconds", - pclient->path, + e_error(pclient->event, "connect(%s) failed: " + "Timeout in %u milliseconds", prclient->address, pclient->set.client_connect_timeout_msecs); /* set error to timeout here */ @@ -351,8 +353,8 @@ program_client_net_connected(struct program_client_remote *prclient) io_remove(&pclient->io); if ((errno = net_geterror(pclient->fd_out)) != 0) { - i_error("connect(%s) failed: %m", - pclient->path); + e_error(pclient->event, "connect(%s) failed: %m", + prclient->address); /* disconnect and try again */ i_close_fd(&pclient->fd_out); @@ -368,7 +370,7 @@ static void program_client_net_connect_real(struct program_client_remote *prclient) { struct program_client *pclient = &prclient->client; - const char *str; + const char *address, *label; timeout_remove(&pclient->to); @@ -376,22 +378,20 @@ program_client_net_connect_real(struct program_client_remote *prclient) i_assert(prclient->ips_count > 0); - if (net_ipport2str(prclient->ips, prclient->port, &str) < 0) + if (net_ipport2str(prclient->ips, prclient->port, &address) < 0) i_unreached(); - pclient->path = p_strdup(pclient->pool, str); + label = t_strconcat("tcp:", address, NULL); + program_client_set_label(pclient, label); - if (pclient->debug) { - i_debug("Trying to connect %s (timeout %u msecs)", - pclient->path, - pclient->set.client_connect_timeout_msecs); - } + e_debug(pclient->event, "Trying to connect (timeout %u msecs)", + pclient->set.client_connect_timeout_msecs); /* try to connect */ int fd; if ((fd = net_connect_ip(prclient->ips, prclient->port, (prclient->ips->family == AF_INET ? &net_ip4_any : &net_ip6_any))) < 0) { - i_error("connect(%s) failed: %m", pclient->path); + e_error(pclient->event, "connect(%s) failed: %m", address); prclient->to_retry = timeout_add_short(0, program_client_net_connect_again, prclient); return; @@ -419,10 +419,10 @@ program_client_net_connect_again(struct program_client_remote *prclient) pclient->error = PROGRAM_CLIENT_ERROR_NONE; if (--prclient->ips_left == 0) { - if (prclient->ips_count > 1) - i_error("program-client-net: " - "%s: No addresses left to try", - prclient->hostname); + if (prclient->ips_count > 1) { + e_error(pclient->event, + "No IP addresses left to try"); + } program_client_fail(pclient, error != PROGRAM_CLIENT_ERROR_NONE ? error : @@ -441,9 +441,8 @@ program_client_net_connect_resolved(const struct dns_lookup_result *result, struct program_client *pclient = &prclient->client; if (result->ret != 0) { - i_error("program-client-net: Cannot resolve '%s': %s", - pclient->path, - result->error); + e_error(pclient->event, "Cannot resolve `%s': %s", + prclient->address, result->error); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_OTHER); return; } @@ -475,24 +474,20 @@ program_client_net_connect_init(struct program_client *pclient) struct ip_addr ip; if (prclient->ips != NULL) { - prclient->hostname = p_strdup(pclient->pool, - net_ip2addr(prclient->ips)); - } else if (net_addr2ip(pclient->path, &ip) == 0) { - prclient->hostname = p_strdup(pclient->pool, - net_ip2addr(&ip)); + /* nothing to do */ + } else if (net_addr2ip(prclient->address, &ip) == 0) { prclient->resolved = TRUE; prclient->ips = p_new(pclient->pool, struct ip_addr, 1); *prclient->ips = ip; prclient->ips_count = 1; } else { prclient->resolved = FALSE; - prclient->hostname = p_strdup(pclient->pool, pclient->path); if (pclient->set.dns_client_socket_path != NULL) { prclient->dns_set.dns_client_socket_path = pclient->set.dns_client_socket_path; prclient->dns_set.timeout_msecs = pclient->set.client_connect_timeout_msecs; - dns_lookup(pclient->path, &prclient->dns_set, + dns_lookup(prclient->address, &prclient->dns_set, program_client_net_connect_resolved, prclient, &prclient->lookup); return 0; @@ -501,13 +496,13 @@ program_client_net_connect_init(struct program_client *pclient) unsigned int ips_count; int err; /* guess we do it here then.. */ - if ((err = net_gethostbyname(pclient->path, + if ((err = net_gethostbyname(prclient->address, &ips, &ips_count)) != 0) { - i_error("program-client-remote: " - "Cannot resolve '%s': %s", - pclient->path, + e_error(pclient->event, + "Cannot resolve `%s': %s", + prclient->address, net_gethosterror(err)); - return -1; + return -1; } prclient->ips_count = ips_count; prclient->ips = p_memdup(pclient->pool, @@ -533,8 +528,8 @@ program_client_remote_close_output(struct program_client *pclient) if (fd_in >= 0) { if (shutdown(fd_out, SHUT_WR) < 0 && errno != ENOTCONN) { - i_error("shutdown(%s, SHUT_WR) failed: %m", - pclient->path); + e_error(pclient->event, + "shutdown(fd_out, SHUT_WR) failed: %m"); return -1; } } else { @@ -575,15 +570,19 @@ program_client_unix_create(const char *socket_path, const char *const *args, bool noreply) { struct program_client_remote *prclient; + const char *label; pool_t pool; + label = t_strconcat("unix:", socket_path, NULL); + pool = pool_alloconly_create("program client unix", 1024); prclient = p_new(pool, struct program_client_remote, 1); - program_client_init(&prclient->client, pool, socket_path, args, set); + program_client_init(&prclient->client, pool, label, args, set); prclient->client.connect = program_client_unix_connect; prclient->client.close_output = program_client_remote_close_output; prclient->client.disconnect = program_client_remote_disconnect; prclient->client.switch_ioloop = program_client_remote_switch_ioloop; + prclient->address = p_strdup(pool, socket_path); prclient->noreply = noreply; return &prclient->client; @@ -596,16 +595,21 @@ program_client_net_create(const char *host, in_port_t port, bool noreply) { struct program_client_remote *prclient; + const char *label; pool_t pool; + label = t_strdup_printf("tcp:%s:%u", host, port); + pool = pool_alloconly_create("program client net", 1024); prclient = p_new(pool, struct program_client_remote, 1); - program_client_init(&prclient->client, pool, host, args, set); + program_client_init(&prclient->client, pool, label, args, set); prclient->client.connect = program_client_net_connect_init; prclient->client.close_output = program_client_remote_close_output; prclient->client.disconnect = program_client_remote_disconnect; prclient->client.set.use_dotstream = TRUE; + prclient->address = p_strdup(pool, host); prclient->port = port; + prclient->have_hostname = TRUE; prclient->noreply = noreply; return &prclient->client; } @@ -618,19 +622,24 @@ program_client_net_create_ips(const struct ip_addr *ips, size_t ips_count, bool noreply) { struct program_client_remote *prclient; + const char *label; pool_t pool; i_assert(ips != NULL && ips_count > 0); + if (net_ipport2str(ips, port, &label) < 0) + i_unreached(); + label = t_strconcat("tcp:", label, NULL); + pool = pool_alloconly_create("program client net", 1024); prclient = p_new(pool, struct program_client_remote, 1); - program_client_init(&prclient->client, pool, net_ip2addr(ips), - args, set); + program_client_init(&prclient->client, pool, label, args, set); prclient->client.connect = program_client_net_connect_init; prclient->client.close_output = program_client_remote_close_output; prclient->client.disconnect = program_client_remote_disconnect; prclient->client.switch_ioloop = program_client_remote_switch_ioloop; prclient->client.set.use_dotstream = TRUE; + prclient->address = p_strdup(pool, net_ip2addr(ips)); prclient->ips = p_memdup(pool, ips, sizeof(struct ip_addr)*ips_count); prclient->ips_count = ips_count; diff --git a/src/lib-program-client/program-client.c b/src/lib-program-client/program-client.c index eecba8d99c..0dc0b540c5 100644 --- a/src/lib-program-client/program-client.c +++ b/src/lib-program-client/program-client.c @@ -20,6 +20,13 @@ #define MAX_OUTPUT_BUFFER_SIZE 16384 #define MAX_OUTPUT_MEMORY_BUFFER (1024*128) +void program_client_set_label(struct program_client *pclient, + const char *label) +{ + event_set_append_log_prefix(pclient->event, + t_strconcat("program ", label, ": ", NULL)); +} + static void program_client_callback(struct program_client *pclient, int result, void *context) @@ -35,16 +42,18 @@ program_client_callback(struct program_client *pclient, int result, static void program_client_timeout(struct program_client *pclient) { - i_error("program `%s' execution timed out (> %u msecs)", - pclient->path, pclient->set.input_idle_timeout_msecs); + e_error(pclient->event, + "Execution timed out (> %u msecs)", + pclient->set.input_idle_timeout_msecs); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_RUN_TIMEOUT); } static void program_client_connect_timeout(struct program_client *pclient) { - i_error("program `%s' socket connection timed out (> %u msecs)", - pclient->path, pclient->set.client_connect_timeout_msecs); + e_error(pclient->event, + "Connection timed out (> %u msecs)", + pclient->set.client_connect_timeout_msecs); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_CONNECT_TIMEOUT); } @@ -207,7 +216,8 @@ program_client_output_finish(struct program_client *pclient) /* flush the output */ if ((ret=o_stream_finish(output)) < 0) { - i_error("write(%s) failed: %s", + e_error(pclient->event, + "write(%s) failed: %s", o_stream_get_name(output), o_stream_get_error(output)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); @@ -232,13 +242,15 @@ program_client_output_pump_finished(enum iostream_pump_status status, case IOSTREAM_PUMP_STATUS_INPUT_EOF: break; case IOSTREAM_PUMP_STATUS_INPUT_ERROR: - i_error("read(%s) failed: %s", + e_error(pclient->event, + "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); return; case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR: - i_error("write(%s) failed: %s", + e_error(pclient->event, + "write(%s) failed: %s", o_stream_get_name(output), o_stream_get_error(output)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); @@ -278,7 +290,8 @@ program_client_input_finish(struct program_client *pclient) return; if (ret < 0) { if (input->stream_errno != 0) { - i_error("read(%s) failed: %s", + e_error(pclient->event, + "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); program_client_fail(pclient, @@ -317,13 +330,15 @@ program_client_input_pump_finished(enum iostream_pump_status status, case IOSTREAM_PUMP_STATUS_INPUT_EOF: break; case IOSTREAM_PUMP_STATUS_INPUT_ERROR: - i_error("read(%s) failed: %s", + e_error(pclient->event, + "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); return; case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR: - i_error("write(%s) failed: %s", + e_error(pclient->event, + "write(%s) failed: %s", o_stream_get_name(output), o_stream_get_error(output)); program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO); @@ -428,18 +443,21 @@ void program_client_connected(struct program_client *pclient) } void program_client_init(struct program_client *pclient, pool_t pool, - const char *path, - const char *const *args, + const char *initial_label, const char *const *args, const struct program_client_settings *set) { pclient->pool = pool; - pclient->path = p_strdup(pool, path); if (args != NULL) pclient->args = p_strarray_dup(pool, args); pclient->set = *set; pclient->debug = set->debug; pclient->fd_in = -1; pclient->fd_out = -1; + + pclient->event = event_create(set->event); + if ((set != NULL && set->debug)) + event_set_forced_debug(pclient->event, TRUE); + program_client_set_label(pclient, initial_label); } void program_client_set_input(struct program_client *pclient, @@ -585,6 +603,8 @@ void program_client_destroy(struct program_client **_pclient) if (pclient->destroy != NULL) pclient->destroy(pclient); + event_unref(&pclient->event); + pool_unref(&pclient->pool); } diff --git a/src/lib-program-client/program-client.h b/src/lib-program-client/program-client.h index 53b28c1ce6..2020d13ae7 100644 --- a/src/lib-program-client/program-client.h +++ b/src/lib-program-client/program-client.h @@ -16,6 +16,9 @@ struct program_client_settings { const char *dns_client_socket_path; const char *home; + /* Event to use for the program client. */ + struct event *event; + bool allow_root:1; bool debug:1; bool drop_stderr:1;