Gitweb:
https://git.exim.org/exim.git/commitdiff/8e9fdd6369f0a7a81f0ca195e24edd372f7ca3ef
Commit: 8e9fdd6369f0a7a81f0ca195e24edd372f7ca3ef
Parent: 14bd960fabc9e22ceab77ba69a9d14a4cc2e7b50
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Mar 15 17:34:02 2020 +0000
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sun Mar 15 17:34:02 2020 +0000
labelled-process fork function
---
src/src/child.c | 14 +++++++++-----
src/src/daemon.c | 10 +++++-----
src/src/deliver.c | 14 +++++++-------
src/src/exim.c | 4 ++--
src/src/functions.h | 18 ++++++++++++++++++
src/src/globals.c | 1 +
src/src/globals.h | 1 +
src/src/local_scan.h | 34 +++++++++++++++++++---------------
src/src/log.c | 2 +-
src/src/moan.c | 11 ++++++-----
src/src/queue.c | 4 ++--
src/src/rda.c | 2 +-
src/src/route.c | 2 +-
src/src/sieve.c | 28 +++++++++++-----------------
src/src/smtp_in.c | 5 +++--
src/src/tls.c | 2 +-
src/src/transport.c | 6 +++---
src/src/transports/autoreply.c | 8 +++-----
src/src/transports/pipe.c | 2 +-
src/src/transports/smtp.c | 4 ++--
20 files changed, 97 insertions(+), 75 deletions(-)
diff --git a/src/src/child.c b/src/src/child.c
index c5054b6..f6d44e1 100644
--- a/src/src/child.c
+++ b/src/src/child.c
@@ -185,13 +185,15 @@ to exist, even if all calls from within Exim are changed, because it is
documented for use from local_scan().
Argument: fdptr pointer to int for the stdin fd
+ purpose of the child process, for debug
Returns: pid of the created process or -1 if anything has gone wrong
*/
pid_t
-child_open_exim(int *fdptr)
+child_open_exim_function(int * fdptr, const uschar * purpose)
{
-return child_open_exim2(fdptr, US"<>", bounce_sender_authentication);
+return child_open_exim2_function(fdptr, US"<>", bounce_sender_authentication,
+ purpose);
}
@@ -202,12 +204,14 @@ Arguments:
fdptr pointer to int for the stdin fd
sender for a sender address (data for -f)
sender_authentication authenticated sender address or NULL
+ purpose of the child process, for debug
Returns: pid of the created process or -1 if anything has gone wrong
*/
pid_t
-child_open_exim2(int *fdptr, uschar *sender, uschar *sender_authentication)
+child_open_exim2_function(int * fdptr, uschar * sender,
+ uschar * sender_authentication, const uschar * purpose)
{
int pfd[2];
int save_errno;
@@ -220,7 +224,7 @@ on the wait. */
if (pipe(pfd) != 0) return (pid_t)(-1);
oldsignal = signal(SIGCHLD, SIG_DFL);
-pid = fork();
+pid = exim_fork(purpose);
/* Child process: make the reading end of the pipe into the standard input and
close the writing end. If debugging, pass debug_fd as stderr. Then re-exec
@@ -337,7 +341,7 @@ that the child process can be waited for. We sometimes get here with it set
otherwise. Save the old state for resetting on the wait. */
oldsignal = signal(SIGCHLD, SIG_DFL);
-pid = fork();
+pid = exim_fork(US"queryprogram"); /* queryprogram tpt is sole caller */
/* Handle the child process. First, set the required environment. We must do
this before messing with the pipes, in order to be able to write debugging
diff --git a/src/src/daemon.c b/src/src/daemon.c
index aa36a5d..a1ef1f9 100644
--- a/src/src/daemon.c
+++ b/src/src/daemon.c
@@ -367,7 +367,7 @@ if (LOGGING(smtp_connection))
expansion above did a lookup. */
search_tidyup();
-pid = fork();
+pid = exim_fork(US"daemon accept");
/* Handle the child process */
@@ -663,7 +663,7 @@ if (pid == 0)
mac_smtp_fflush();
- if ((dpid = fork()) == 0)
+ if ((dpid = exim_fork(US"daemon-accept delivery")) == 0)
{
(void)fclose(smtp_in);
(void)fclose(smtp_out);
@@ -981,7 +981,7 @@ if (daemon_notifier_fd >= 0)
if (f.running_in_test_harness || write_pid)
{
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"daemon del pidfile")) == 0)
{
if (override_pid_file_path)
(void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, FALSE, 3,
@@ -1601,7 +1601,7 @@ if (f.background_daemon)
if (getppid() != 1)
{
- pid_t pid = fork();
+ pid_t pid = exim_fork(US"daemon");
if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"fork() failed when starting daemon: %s", strerror(errno));
if (pid > 0) exit(EXIT_SUCCESS); /* in parent process, just exit */
@@ -2130,7 +2130,7 @@ for (;;)
if (queue_interval > 0 &&
(local_queue_run_max <= 0 || queue_run_count < local_queue_run_max))
{
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"queue runner")) == 0)
{
DEBUG(D_any) debug_printf("Starting queue-runner: pid %d\n",
(int)getpid());
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 5c5167b..5d825cd 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -2268,7 +2268,7 @@ a clean slate and doesn't interfere with the parent process. */
search_tidyup();
-if ((pid = fork()) == 0)
+if ((pid = exim_fork(US"delivery (local)")) == 0)
{
BOOL replicate = TRUE;
@@ -2615,7 +2615,7 @@ if (addr->special_action == SPECIAL_WARN && addr->transport->warn_message)
"message for %s transport): %s", addr->transport->warn_message,
addr->transport->name, expand_string_message);
- else if ((pid = child_open_exim(&fd)) > 0)
+ else if ((pid = child_open_exim(&fd, US"warning message")) > 0)
{
FILE *f = fdopen(fd, "wb");
if (errors_reply_to && !contains_header(US"Reply-To", warn_message))
@@ -4647,7 +4647,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
search_tidyup();
DEBUG(D_deliver) debug_printf("forking transport process\n");
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"transport")) == 0)
{
int fd = pfd[pipe_write];
host_item *h;
@@ -7336,7 +7336,7 @@ if (addr_senddsn)
int fd;
/* create exim process to send message */
- pid = child_open_exim(&fd);
+ pid = child_open_exim(&fd, US"DSN");
DEBUG(D_deliver) debug_printf("DSN: child_open_exim returns: %d\n", pid);
@@ -7537,7 +7537,7 @@ while (addr_failed)
/* Make a subprocess to send a message */
- if ((pid = child_open_exim(&fd)) < 0)
+ if ((pid = child_open_exim(&fd, US"bounce message")) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
"create child process to send failure message: %s", getpid(),
getppid(), strerror(errno));
@@ -8195,7 +8195,7 @@ else if (addr_defer != (address_item *)(+1))
{
header_line *h;
int fd;
- pid_t pid = child_open_exim(&fd);
+ pid_t pid = child_open_exim(&fd, US"delay-warning message");
if (pid > 0)
{
@@ -8583,7 +8583,7 @@ if (cutthrough.cctx.sock >= 0 && cutthrough.callout_hold_only)
goto fail;
where = US"fork";
- if ((pid = fork()) < 0)
+ if ((pid = exim_fork(US"tls-proxy interproc")) < 0)
goto fail;
else if (pid == 0) /* child: fork again to totally disconnect */
diff --git a/src/src/exim.c b/src/src/exim.c
index 4e4b6bb..6bde8fd 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -4608,7 +4608,7 @@ if (msg_action_arg > 0 && msg_action != MSG_LOAD)
pid_t pid;
if (i == argc - 1)
(void)deliver_message(argv[i], forced_delivery, deliver_give_up);
- else if ((pid = fork()) == 0)
+ else if ((pid = exim_fork(US"cmdline-delivery")) == 0)
{
(void)deliver_message(argv[i], forced_delivery, deliver_give_up);
exim_underbar_exit(EXIT_SUCCESS, US"cmdline-delivery");
@@ -5694,7 +5694,7 @@ while (more)
pid_t pid;
search_tidyup();
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"local-accept delivery")) == 0)
{
int rc;
close_unwanted(); /* Close unwanted file descriptors and TLS */
diff --git a/src/src/functions.h b/src/src/functions.h
index 042006f..9e71d0c 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -150,6 +150,9 @@ extern void bits_set(unsigned int *, size_t, int *);
extern void cancel_cutthrough_connection(BOOL, const uschar *);
extern int check_host(void *, const uschar *, const uschar **, uschar **);
extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
+extern pid_t child_open_exim_function(int *, const uschar *);
+extern pid_t child_open_exim2_function(int *, uschar *, uschar *,
+ const uschar *);
extern pid_t child_open_uid(const uschar **, const uschar **, int,
uid_t *, gid_t *, int *, int *, uschar *, BOOL);
extern BOOL cleanup_environment(void);
@@ -1108,6 +1111,21 @@ errno = EACCES;
return NULL;
}
+/******************************************************************************/
+/* Process manipulation */
+
+static inline pid_t
+exim_fork(const unsigned char * purpose)
+{
+pid_t pid = fork();
+if (pid == 0) process_purpose = purpose;
+return pid;
+}
+
+#define child_open_exim(p, r) child_open_exim_function((p), (r))
+#define child_open_exim2(p, s, a, r) child_open_exim2_function((p), (s), (a), (r))
+
+/******************************************************************************/
#endif /* !MACRO_PREDEF */
#endif /* _FUNCTIONS_H_ */
diff --git a/src/src/globals.c b/src/src/globals.c
index a771f11..28e78d4 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1188,6 +1188,7 @@ uschar *primary_hostname = NULL;
uschar *process_info;
int process_info_len = 0;
uschar *process_log_path = NULL;
+const uschar *process_purpose = US"fresh exec";
#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
uschar *hosts_proxy = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index 28d170c..c922274 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -771,6 +771,7 @@ extern BOOL print_topbitchars; /* Topbit chars are printing chars */
extern uschar *process_info; /* For SIGUSR1 output */
extern int process_info_len;
extern uschar *process_log_path; /* Alternate path */
+extern const uschar *process_purpose; /* for debug output */
extern BOOL prod_requires_admin; /* TRUE if prodding requires admin */
#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
diff --git a/src/src/local_scan.h b/src/src/local_scan.h
index 206a843..bb131d3 100644
--- a/src/src/local_scan.h
+++ b/src/src/local_scan.h
@@ -31,6 +31,21 @@ settings, and the store functions. */
#include "store.h"
+/* Some people (Marc Merlin et al) are maintaining a patch that allows for
+dynamic local_scan() libraries. This code is not yet in Exim proper, but it
+helps the maintainers if we keep their ABI version numbers here. This may
+mutate into more general support later. The major number is increased when the
+ABI is changed in a non backward compatible way. The minor number is increased
+each time a new feature is added (in a way that doesn't break backward
+compatibility). */
+
+#define LOCAL_SCAN_ABI_VERSION_MAJOR 4
+#define LOCAL_SCAN_ABI_VERSION_MINOR 1
+#define LOCAL_SCAN_ABI_VERSION \
+ LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR
+
+
+
/* The function and its return codes. */
extern int local_scan(int, uschar **);
@@ -99,19 +114,6 @@ the name of the data file to be present in the first line. */
#define SPOOL_DATA_START_OFFSET (MESSAGE_ID_LENGTH+3)
-/* Some people (Marc Merlin et al) are maintaining a patch that allows for
-dynamic local_scan() libraries. This code is not yet in Exim proper, but it
-helps the maintainers if we keep their ABI version numbers here. This may
-mutate into more general support later. The major number is increased when the
-ABI is changed in a non backward compatible way. The minor number is increased
-each time a new feature is added (in a way that doesn't break backward
-compatibility). */
-
-#define LOCAL_SCAN_ABI_VERSION_MAJOR 4
-#define LOCAL_SCAN_ABI_VERSION_MINOR 0
-#define LOCAL_SCAN_ABI_VERSION \
- LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR
-
/* Structure definitions that are documented as visible in the function. */
typedef struct header_line {
@@ -180,8 +182,6 @@ extern BOOL smtp_input; /* TRUE if input is via SMTP */
extern int child_close(pid_t, int);
extern pid_t child_open(uschar **, uschar **, int, int *, int *, BOOL);
-extern pid_t child_open_exim(int *);
-extern pid_t child_open_exim2(int *, uschar *, uschar *);
extern void debug_printf(const char *, ...) PRINTF_FUNCTION(1,2);
extern uschar *expand_string(uschar *);
extern void header_add(int, const char *, ...);
@@ -223,10 +223,14 @@ with the original name. */
# define string_copy(s) string_copy_function(s)
# define string_copyn(s, n) string_copyn_function((s), (n))
# define string_copy_taint(s, t) string_copy_taint_function((s), (t))
+# define child_open_exim(p) child_open_exim_function((p), US"from local_scan")
+# define child_open_exim2(p, s, a) child_open_exim2_function((p), (s), (a), US"from local_scan")
extern uschar * string_copy_function(const uschar *);
extern uschar * string_copyn_function(const uschar *, int n);
extern uschar * string_copy_taint_function(const uschar *, BOOL tainted);
+extern pid_t child_open_exim_function(int *, const uschar *);
+extern pid_t child_open_exim2_function(int *, uschar *, uschar *, const uschar *);
#endif
/* End of local_scan.h */
diff --git a/src/src/log.c b/src/src/log.c
index e2543a7..e80c177 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -313,7 +313,7 @@ Returns: a file descriptor, or < 0 on failure (errno set)
int
log_create_as_exim(uschar *name)
{
-pid_t pid = fork();
+pid_t pid = exim_fork(US"logfile create");
int status = 1;
int fd = -1;
diff --git a/src/src/moan.c b/src/src/moan.c
index 31d033c..51f5da5 100644
--- a/src/src/moan.c
+++ b/src/src/moan.c
@@ -160,15 +160,16 @@ if ( ident == ERRMESS_DMARC_FORENSIC
&& (s2 = expand_string(string_sprintf("${address:%s}", s)))
&& *s2
)
- pid = child_open_exim2(&fd, s2, bounce_sender_authentication);
+ pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
+ US"moan_send_message");
else
{
s = NULL;
- pid = child_open_exim(&fd);
+ pid = child_open_exim(&fd, US"moan_send_message");
}
#else
-pid = child_open_exim(&fd);
+pid = child_open_exim(&fd, US"moan_send_message");
#endif
if (pid < 0)
@@ -584,7 +585,7 @@ moan_tell_someone(uschar *who, address_item *addr,
FILE *f;
va_list ap;
int fd;
-int pid = child_open_exim(&fd);
+int pid = child_open_exim(&fd, US"moan_tell_someone");
if (pid < 0)
{
@@ -820,7 +821,7 @@ if (!(s = expand_string(syntax_errors_to)))
/* If we can't create a process to send the message, just forget about
it. */
-pid = child_open_exim(&fd);
+pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
if (pid < 0)
{
diff --git a/src/src/queue.c b/src/src/queue.c
index c9ac84b..2b64f52 100644
--- a/src/src/queue.c
+++ b/src/src/queue.c
@@ -497,7 +497,7 @@ for (int i = queue_run_in_order ? -1 : 0;
else
for (i = 0; qpid[i]; ) i++;
DEBUG(D_queue_run) debug_printf("q2stage forking\n");
- if ((qpid[i] = fork()))
+ if ((qpid[i] = exim_fork(US"qrun phase one")))
continue; /* parent loops around */
DEBUG(D_queue_run) debug_printf("q2stage child\n");
}
@@ -651,7 +651,7 @@ for (int i = queue_run_in_order ? -1 : 0;
#endif
single_item_retry:
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"qrun delivery")) == 0)
{
int rc;
testharness_pause_ms(100);
diff --git a/src/src/rda.c b/src/src/rda.c
index 547a8bf..85791c2 100644
--- a/src/src/rda.c
+++ b/src/src/rda.c
@@ -615,7 +615,7 @@ with the parent process. */
oldsignal = signal(SIGCHLD, SIG_DFL);
search_tidyup();
-if ((pid = fork()) == 0)
+if ((pid = exim_fork(US"router interpret")) == 0)
{
header_line *waslast = header_last; /* Save last header */
diff --git a/src/src/route.c b/src/src/route.c
index fd3cb3e..6226b06 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -736,7 +736,7 @@ while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
otherwise. Save the old state for resetting on the wait. */
oldsignal = signal(SIGCHLD, SIG_DFL);
- pid = fork();
+ pid = exim_fork(US"require-files");
/* If fork() fails, reinstate the original error and behave as if
this block of code were not present. This is the same behaviour as happens
diff --git a/src/src/sieve.c b/src/src/sieve.c
index 5e8d1e6..e07b7da 100644
--- a/src/src/sieve.c
+++ b/src/src/sieve.c
@@ -3084,7 +3084,8 @@ while (*filter->pc)
{
int pid, fd;
- if ((pid = child_open_exim2(&fd,envelope_from,envelope_from))>=1)
+ if ((pid = child_open_exim2(&fd, envelope_from, envelope_from,
+ US"sieve-notify")) >= 1)
{
FILE *f;
uschar *buffer;
@@ -3092,7 +3093,8 @@ while (*filter->pc)
f = fdopen(fd, "wb");
fprintf(f,"From: %s\n", from.length == -1
- ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain") : from.character);
+ ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain")
+ : from.character);
for (string_item * p = recipient; p; p=p->next)
fprintf(f,"To: %s\n",p->text);
fprintf(f,"Auto-Submitted: auto-notified; %s\n",filter->enotify_mailto_owner);
@@ -3103,9 +3105,11 @@ while (*filter->pc)
message.length=Ustrlen(message.character);
}
/* Allocation is larger than necessary, but enough even for split MIME words */
- buffer_capacity=32+4*message.length;
+ buffer_capacity = 32 + 4*message.length;
buffer=store_get(buffer_capacity, TRUE);
- if (message.length!=-1) fprintf(f,"Subject: %s\n",parse_quote_2047(message.character, message.length, US"utf-8", buffer, buffer_capacity, TRUE));
+ if (message.length != -1)
+ fprintf(f, "Subject: %s\n", parse_quote_2047(message.character,
+ message.length, US"utf-8", buffer, buffer_capacity, TRUE));
fprintf(f,"\n");
if (body.length>0) fprintf(f,"%s\n",body.character);
fflush(f);
@@ -3113,27 +3117,17 @@ while (*filter->pc)
(void)child_close(pid, 0);
}
}
- if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
- {
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || debug_selector & D_filter)
debug_printf("Notification to `%s': '%s'.\n",method.character,message.length!=-1 ? message.character : CUS "");
- }
#endif
}
else
- {
- if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
- {
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || debug_selector & D_filter)
debug_printf("Repeated notification to `%s' ignored.\n",method.character);
- }
- }
}
else
- {
- if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
- {
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || debug_selector & D_filter)
debug_printf("Ignoring notification, triggering message contains Auto-submitted: field.\n");
- }
- }
}
}
#endif
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 66f752d..b5f44f5 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -5759,7 +5759,7 @@ while (done <= 0)
oldsignal = signal(SIGCHLD, SIG_IGN);
- if ((pid = fork()) == 0)
+ if ((pid = exim_fork(US"etrn command")) == 0)
{
smtp_input = FALSE; /* This process is not associated with the */
(void)fclose(smtp_in); /* SMTP call any more. */
@@ -5770,7 +5770,8 @@ while (done <= 0)
/* If not serializing, do the exec right away. Otherwise, fork down
into another process. */
- if (!smtp_etrn_serialize || (pid = fork()) == 0)
+ if ( !smtp_etrn_serialize
+ || (pid = exim_fork(US"etrn serialised command")) == 0)
{
DEBUG(D_exec) debug_print_argv(argv);
exim_nullstd(); /* Ensure std{in,out,err} exist */
diff --git a/src/src/tls.c b/src/src/tls.c
index a0cfcbf..2f9faa3 100644
--- a/src/src/tls.c
+++ b/src/src/tls.c
@@ -441,7 +441,7 @@ else if (!nowarn && !tls_certificate)
oldsignal = signal(SIGCHLD, SIG_DFL);
fflush(NULL);
-if ((pid = fork()) < 0)
+if ((pid = exim_fork(US"cipher validate")) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
if (pid == 0)
diff --git a/src/src/transport.c b/src/src/transport.c
index 3eb1c80..d92ad4c 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -1248,7 +1248,7 @@ via a(nother) pipe. While writing to the filter, we do not do the CRLF,
smtp dots, or check string processing. */
if (pipe(pfd) != 0) goto TIDY_UP; /* errno set */
-if ((write_pid = fork()) == 0)
+if ((write_pid = exim_fork(US"transport filter")) == 0)
{
BOOL rc;
(void)close(fd_read);
@@ -1954,14 +1954,14 @@ int status;
DEBUG(D_transport) debug_printf("transport_pass_socket entered\n");
-if ((pid = fork()) == 0)
+if ((pid = exim_fork(US"continued-transport interproc")) == 0)
{
/* Disconnect entirely from the parent process. If we are running in the
test harness, wait for a bit to allow the previous process time to finish,
write the log, etc., so that the output is always in the same order for
automatic comparison. */
- if ((pid = fork()) != 0)
+ if ((pid = exim_fork(US"continued-transport")) != 0)
{
DEBUG(D_transport) debug_printf("transport_pass_socket succeeded (final-pid %d)\n", pid);
_exit(EXIT_SUCCESS);
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index 4b5ef8e..2b487b4 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -567,12 +567,10 @@ if (file)
/* Make a subprocess to send the message */
-pid = child_open_exim(&fd);
-
-/* Creation of child failed; defer this delivery. */
-
-if (pid < 0)
+if ((pid = child_open_exim(&fd, US"autoreply")) < 0)
{
+ /* Creation of child failed; defer this delivery. */
+
addr->transport_return = DEFER;
addr->basic_errno = errno;
addr->message = string_sprintf("Failed to create child process to send "
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index ca22f26..83272d8 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -737,7 +737,7 @@ tctx.u.fd = fd_in;
/* Now fork a process to handle the output that comes down the pipe. */
-if ((outpid = fork()) < 0)
+if ((outpid = exim_fork(US"pipe-transport output")) < 0)
{
addr->basic_errno = errno;
addr->transport_return = DEFER;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 6f99909..459110b 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -3284,7 +3284,7 @@ int max_fd = MAX(pfd[0], tls_out.active.sock) + 1;
int rc, i;
close(pfd[1]);
-if ((rc = fork()))
+if ((rc = exim_fork(US"tls proxy")))
{
DEBUG(D_transport) debug_printf("proxy-proc final-pid %d\n", rc);
_exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
@@ -4279,7 +4279,7 @@ propagate it from the initial
#ifndef DISABLE_TLS
if (tls_out.active.sock >= 0)
{
- int pid = fork();
+ int pid = exim_fork(US"tls proxy interproc");
if (pid == 0) /* child; fork again to disconnect totally */
{
testharness_pause_ms(100); /* let parent debug out */