X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/0a49a7a4f1090b6f1ce1d0f9d969804c9226b53e..6d7c6175eda3aaa316d1960a89170a285510ad40:/src/src/transports/pipe.c diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 35048258e..32a7bfa7c 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -1,5 +1,3 @@ -/* $Cambridge: exim/src/src/transports/pipe.c,v 1.14 2009/11/16 19:50:39 nm4 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ @@ -41,6 +39,8 @@ optionlist pipe_transport_options[] = { (void *)offsetof(pipe_transport_options_block, escape_string) }, { "freeze_exec_fail", opt_bool, (void *)offsetof(pipe_transport_options_block, freeze_exec_fail) }, + { "freeze_signal", opt_bool, + (void *)offsetof(pipe_transport_options_block, freeze_signal) }, { "ignore_status", opt_bool, (void *)offsetof(pipe_transport_options_block, ignore_status) }, { "log_defer_output", opt_bool | opt_public, @@ -57,6 +57,8 @@ optionlist pipe_transport_options[] = { (void *)offsetof(pipe_transport_options_block, message_suffix) }, { "path", opt_stringptr, (void *)offsetof(pipe_transport_options_block, path) }, + { "permit_coredump", opt_bool, + (void *)offsetof(pipe_transport_options_block, permit_coredump) }, { "pipe_as_creator", opt_bool | opt_public, (void *)offsetof(transport_instance, deliver_as_creator) }, { "restrict_to_path", opt_bool, @@ -109,7 +111,9 @@ pipe_transport_options_block pipe_transport_option_defaults = { 60*60, /* timeout */ 0, /* options */ FALSE, /* freeze_exec_fail */ + FALSE, /* freeze_signal */ FALSE, /* ignore_status */ + FALSE, /* permit_coredump */ FALSE, /* restrict_to_path */ FALSE, /* timeout_defer */ FALSE, /* use_shell */ @@ -127,7 +131,7 @@ pipe_transport_options_block pipe_transport_option_defaults = { /* Called for each delivery in the privileged state, just before the uid/gid are changed and the main entry point is called. In a system that supports the login_cap facilities, this function is used to set the class resource limits -for the user. +for the user. It may also re-enable coredumps. Arguments: tblock points to the transport instance @@ -170,6 +174,24 @@ if (ob->use_classresources) } #endif +#ifdef RLIMIT_CORE +if (ob->permit_coredump) + { + struct rlimit rl; + rl.rlim_cur = RLIM_INFINITY; + rl.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &rl) < 0) + { +#ifdef SETRLIMIT_NOT_SUPPORTED + if (errno != ENOSYS && errno != ENOTSUP) +#endif + log_write(0, LOG_MAIN, + "delivery setrlimit(RLIMIT_CORE, RLIM_INFINITY) failed: %s", + strerror(errno)); + } + } +#endif + return OK; } @@ -939,11 +961,20 @@ if ((rc = child_close(pid, timeout)) != 0) /* Either the process completed, but yielded a non-zero (necessarily positive) status, or the process was terminated by a signal (rc will contain the negation of the signal number). Treat killing by signal as failure unless - status is being ignored. */ + status is being ignored. By default, the message is bounced back, unless + freeze_signal is set, in which case it is frozen instead. */ else if (rc < 0) { - if (!ob->ignore_status) + if (ob->freeze_signal) + { + addr->transport_return = DEFER; + addr->special_action = SPECIAL_FREEZE; + addr->message = string_sprintf("Child process of %s transport (running " + "command \"%s\") was terminated by signal %d (%s)%s", tblock->name, cmd, + -rc, os_strsignal(-rc), tmsg); + } + else if (!ob->ignore_status) { addr->transport_return = FAIL; addr->message = string_sprintf("Child process of %s transport (running "