From 2791749f220602482c2cce772e6520c54218c0dd Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 17 Dec 2019 20:35:28 +0000 Subject: [PATCH] GNU/Hurd: retry EINTR returns from pipe I/O Replaces: a76f64c3d4 --- doc/doc-txt/ChangeLog | 3 +++ src/OS/Makefile-Base | 6 +++-- src/OS/os.c-GNU | 35 +++++++++++++++++++++++++ src/OS/os.h-GNU | 6 ++++- src/src/deliver.c | 60 ++++++++++++++++++++----------------------- src/src/osfunctions.h | 25 +++++++++++++----- src/src/queue.c | 7 ++--- src/src/rda.c | 58 ++++++++++++++++++++--------------------- src/src/transport.c | 36 ++++++++++++++++---------- 9 files changed, 148 insertions(+), 88 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index f4963389e..13468ae46 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -53,6 +53,9 @@ JH/13 Bug 2498: Reset a counter used for ARC verify before handling another the following one did not, a crash could result when adding an Authentication-Results: header. +JH/14 On GNU/Hurd, retry EINTR returns from I/O on pipes, which seem to occur + frequently. + Exim version 4.93 ----------------- diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index 36af8308d..1ab3ac35f 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -644,7 +644,8 @@ HDRS = blob.h \ mytypes.h \ sha_ver.h \ structs.h \ - os.h + os.h \ + osfunctions.h PHDRS = ../config.h \ ../dbfunctions.h \ ../dbstuff.h \ @@ -655,7 +656,8 @@ PHDRS = ../config.h \ ../macros.h \ ../mytypes.h \ ../structs.h \ - ../os.h + ../os.h \ + ../osfunctions.h .SUFFIXES: .o .c .c.o:; @echo "$(CC) $*.c" diff --git a/src/OS/os.c-GNU b/src/OS/os.c-GNU index e5d6ff66c..06226839b 100644 --- a/src/OS/os.c-GNU +++ b/src/OS/os.c-GNU @@ -52,4 +52,39 @@ return -1; } #endif /* OS_LOAD_AVERAGE */ + +ssize_t +os_pipe_read(int fd, void * buf, size_t count) +{ +for (int rc, retries = 10; retries > 0; retries--) + { + if ((rc = read(fd, buf, count) >= 0) break; + if (rc != -1 || errno != EINTR) break; + } +return rc; +} + + +ssize_t +os_pipe_write(int fd, void * buf, size_t count) +{ +for (int rc, retries = 10; retries > 0; retries--) + { + if ((rc = write(fd, buf, count) >= 0) break; + if (rc != -1 || errno != EINTR) break; + } +return rc; +} + +ssize_t +os_pipe_writev(int fd, const struct iovec * iov, int iovcnt +{ +for (int rc, retries = 10; retries > 0; retries--) + { + if ((rc = writev(fd, iov, iovcnt) >= 0) break; + if (rc != -1 || errno != EINTR) break; + } +return rc; +} + /* End of os.c-GNU */ diff --git a/src/OS/os.h-GNU b/src/OS/os.h-GNU index 1de2e3e84..772d278ad 100644 --- a/src/OS/os.h-GNU +++ b/src/OS/os.h-GNU @@ -21,7 +21,11 @@ typedef struct flock flock_t; #define ICONV_ARG2_TYPE const char ** /* setgroups(0, NULL) succeeds, and drops the gid group -as well as any supplementary groups*/ +as well as any supplementary groups */ #define OS_SETGROUPS_ZERO_DROPS_ALL +/* reads and writes on pipes frequently return EINTR. We provide +a routine to retry that */ +#define OS_PIPE_RW_EINTR + /* End */ diff --git a/src/src/deliver.c b/src/src/deliver.c index 733fe6ff5..8c0593448 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -2402,14 +2402,14 @@ if ((pid = fork()) == 0) uschar *s; int ret; - if( (ret = write(pfd[pipe_write], &addr2->transport_return, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], &transport_count, sizeof(transport_count))) != sizeof(transport_count) - || (ret = write(pfd[pipe_write], &addr2->flags, sizeof(addr2->flags))) != sizeof(addr2->flags) - || (ret = write(pfd[pipe_write], &addr2->basic_errno, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], &addr2->more_errno, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], &addr2->delivery_usec, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], &addr2->special_action, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], &addr2->transport, + if( (ret = os_pipe_write(pfd[pipe_write], &addr2->transport_return, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], &transport_count, sizeof(transport_count))) != sizeof(transport_count) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->flags, sizeof(addr2->flags))) != sizeof(addr2->flags) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->basic_errno, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->more_errno, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->delivery_usec, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->special_action, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], &addr2->transport, sizeof(transport_instance *))) != sizeof(transport_instance *) /* For a file delivery, pass back the local part, in case the original @@ -2417,8 +2417,8 @@ if ((pid = fork()) == 0) logging. */ || (testflag(addr2, af_file) - && ( (ret = write(pfd[pipe_write], &local_part_length, sizeof(int))) != sizeof(int) - || (ret = write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length + && ( (ret = os_pipe_write(pfd[pipe_write], &local_part_length, sizeof(int))) != sizeof(int) + || (ret = os_pipe_write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length ) ) ) @@ -2430,8 +2430,8 @@ if ((pid = fork()) == 0) for (i = 0, s = addr2->message; i < 2; i++, s = addr2->user_message) { int message_length = s ? Ustrlen(s) + 1 : 0; - if( (ret = write(pfd[pipe_write], &message_length, sizeof(int))) != sizeof(int) - || message_length > 0 && (ret = write(pfd[pipe_write], s, message_length)) != message_length + if( (ret = os_pipe_write(pfd[pipe_write], &message_length, sizeof(int))) != sizeof(int) + || message_length > 0 && (ret = os_pipe_write(pfd[pipe_write], s, message_length)) != message_length ) log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s", ret == -1 ? strerror(errno) : "short write"); @@ -2464,26 +2464,26 @@ will remain. Afterwards, close the reading end. */ for (addr2 = addr; addr2; addr2 = addr2->next) { - if ((len = read(pfd[pipe_read], &status, sizeof(int))) > 0) + if ((len = os_pipe_read(pfd[pipe_read], &status, sizeof(int))) > 0) { int i; uschar **sptr; addr2->transport_return = status; - len = read(pfd[pipe_read], &transport_count, + len = os_pipe_read(pfd[pipe_read], &transport_count, sizeof(transport_count)); - len = read(pfd[pipe_read], &addr2->flags, sizeof(addr2->flags)); - len = read(pfd[pipe_read], &addr2->basic_errno, sizeof(int)); - len = read(pfd[pipe_read], &addr2->more_errno, sizeof(int)); - len = read(pfd[pipe_read], &addr2->delivery_usec, sizeof(int)); - len = read(pfd[pipe_read], &addr2->special_action, sizeof(int)); - len = read(pfd[pipe_read], &addr2->transport, + len = os_pipe_read(pfd[pipe_read], &addr2->flags, sizeof(addr2->flags)); + len = os_pipe_read(pfd[pipe_read], &addr2->basic_errno, sizeof(int)); + len = os_pipe_read(pfd[pipe_read], &addr2->more_errno, sizeof(int)); + len = os_pipe_read(pfd[pipe_read], &addr2->delivery_usec, sizeof(int)); + len = os_pipe_read(pfd[pipe_read], &addr2->special_action, sizeof(int)); + len = os_pipe_read(pfd[pipe_read], &addr2->transport, sizeof(transport_instance *)); if (testflag(addr2, af_file)) { int llen; - if ( read(pfd[pipe_read], &llen, sizeof(int)) != sizeof(int) + if ( os_pipe_read(pfd[pipe_read], &llen, sizeof(int)) != sizeof(int) || llen > 64*4 /* limit from rfc 5821, times I18N factor */ ) { @@ -2493,7 +2493,7 @@ for (addr2 = addr; addr2; addr2 = addr2->next) } /* sanity-checked llen so disable the Coverity error */ /* coverity[tainted_data] */ - if (read(pfd[pipe_read], big_buffer, llen) != llen) + if (os_pipe_read(pfd[pipe_read], big_buffer, llen) != llen) { log_write(0, LOG_MAIN|LOG_PANIC, "bad local_part read" " from delivery subprocess"); @@ -2506,10 +2506,10 @@ for (addr2 = addr; addr2; addr2 = addr2->next) for (i = 0, sptr = &addr2->message; i < 2; i++, sptr = &addr2->user_message) { int message_length; - len = read(pfd[pipe_read], &message_length, sizeof(int)); + len = os_pipe_read(pfd[pipe_read], &message_length, sizeof(int)); if (message_length > 0) { - len = read(pfd[pipe_read], big_buffer, message_length); + len = os_pipe_read(pfd[pipe_read], big_buffer, message_length); big_buffer[big_buffer_size-1] = '\0'; /* guard byte */ if (len > 0) *sptr = string_copy(big_buffer); } @@ -4147,14 +4147,10 @@ if (PIPE_HEADER_SIZE != snprintf(CS pipe_header, PIPE_HEADER_SIZE+1, "%c%c%05ld" DEBUG(D_deliver) debug_printf("header write id:%c,subid:%c,size:%ld,final:%s\n", id, subid, (long)size, pipe_header); -for (int retries = 10; retries > 0; retries--) - { - if ((ret = writev(fd, iov, 2)) == total_len) return; - if (ret != -1 || errno != EINTR) break; - } -log_write(0, LOG_MAIN|LOG_PANIC_DIE, - "Failed writing transport result to pipe (%ld of %ld bytes): %s", - (long)ret, (long)total_len, ret == -1 ? strerror(errno) : "short write"); +if ((ret = os_pipe_writev(fd, iov, 2)) != total_len) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "Failed writing transport result to pipe (%ld of %ld bytes): %s", + (long)ret, (long)total_len, ret == -1 ? strerror(errno) : "short write"); } /************************************************* diff --git a/src/src/osfunctions.h b/src/src/osfunctions.h index 4e6e9a91c..8b3e14312 100644 --- a/src/src/osfunctions.h +++ b/src/src/osfunctions.h @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2016 */ +/* Copyright (c) The Exim Maintainers 2019 */ /* See the file NOTICE for conditions of use and distribution. */ /* Prototypes for os-specific functions. For utilities, we don't need the one @@ -18,25 +19,35 @@ Notably, strsignal() is not in the Single Unix Specification (v3) and predicting constness is awkward. */ #ifndef os_getloadavg -extern int os_getloadavg(void); + extern int os_getloadavg(void); #endif #ifndef os_restarting_signal -extern void os_restarting_signal(int, void (*)(int)); + extern void os_restarting_signal(int, void (*)(int)); #endif #ifndef os_non_restarting_signal -extern void os_non_restarting_signal(int, void (*)(int)); + extern void os_non_restarting_signal(int, void (*)(int)); #endif #ifndef os_strexit -extern const char *os_strexit(int); /* char to match os_strsignal */ + extern const char *os_strexit(int); /* char to match os_strsignal */ #endif #ifndef os_strsignal -extern const char *os_strsignal(int); /* char to match strsignal in some OS */ + extern const char *os_strsignal(int); /* char to match strsignal in some OS */ #endif #ifndef os_unsetenv -extern int os_unsetenv(const uschar *); + extern int os_unsetenv(const uschar *); #endif #ifndef os_getcwd -extern uschar *os_getcwd(uschar *, size_t); + extern uschar *os_getcwd(uschar *, size_t); +#endif + +#ifdef OS_PIPE_RW_EINTR + extern ssize_t os_pipe_read(int fd, void * buf, size_t count); + extern ssize_t os_pipe_write(int fd, void * buf, size_t count); + extern ssize_t os_pipe_writev(int fd, const struct iovec * iov, int iovcnt); +#else +# define os_pipe_read(fd, buf, count) read(fd, buf, count) +# define os_pipe_write(fd, buf, count) write(fd, buf, count) +# define os_pipe_writev(fd, buf, count) writev(fd, buf, count) #endif /* End of osfunctions.h */ diff --git a/src/src/queue.c b/src/src/queue.c index a57801426..061743323 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -653,9 +653,10 @@ for (int i = queue_run_in_order ? -1 : 0; the mere fact that read() unblocks is enough. */ set_process_info("running queue: waiting for children of %d", pid); - if ((status = read(pfd[pipe_read], buffer, sizeof(buffer))) != 0) - log_write(0, LOG_MAIN|LOG_PANIC, status > 0 ? - "queue run: unexpected data on pipe" : "queue run: error on pipe: %s", + if ((status = os_pipe_read(pfd[pipe_read], buffer, sizeof(buffer))) != 0) + log_write(0, LOG_MAIN|LOG_PANIC, status > 0 + ? "queue run: unexpected data on pipe" + : "queue run: error on pipe read: %s", strerror(errno)); (void)close(pfd[pipe_read]); set_process_info("running queue"); diff --git a/src/src/rda.c b/src/src/rda.c index 42b7b14a5..341979df5 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -439,9 +439,9 @@ Returns: -1 on error, else 0 static int rda_write_string(int fd, const uschar *s) { -int len = (s == NULL)? 0 : Ustrlen(s) + 1; -return ( write(fd, &len, sizeof(int)) != sizeof(int) - || (s != NULL && write(fd, s, len) != len) +int len = s ? Ustrlen(s) + 1 : 0; +return ( os_pipe_write(fd, &len, sizeof(int)) != sizeof(int) + || s && write(fd, s, len) != len ) ? -1 : 0; } @@ -466,14 +466,14 @@ rda_read_string(int fd, uschar **sp) { int len; -if (read(fd, &len, sizeof(int)) != sizeof(int)) return FALSE; +if (os_pipe_read(fd, &len, sizeof(int)) != sizeof(int)) return FALSE; if (len == 0) *sp = NULL; else /* We know we have enough memory so disable the error on "len" */ /* coverity[tainted_data] */ /* We trust the data source, so untainted */ - if (read(fd, *sp = store_get(len, FALSE), len) != len) return FALSE; + if (os_pipe_read(fd, *sp = store_get(len, FALSE), len) != len) return FALSE; return TRUE; } @@ -641,8 +641,8 @@ if ((pid = fork()) == 0) /* Pass back whether it was a filter, and the return code and any overall error text via the pipe. */ - if ( write(fd, filtertype, sizeof(int)) != sizeof(int) - || write(fd, &yield, sizeof(int)) != sizeof(int) + if ( os_pipe_write(fd, filtertype, sizeof(int)) != sizeof(int) + || os_pipe_write(fd, &yield, sizeof(int)) != sizeof(int) || rda_write_string(fd, *error) != 0 ) goto bad; @@ -669,12 +669,12 @@ if ((pid = fork()) == 0) int i = 0; for (header_line * h = header_list; h != waslast->next; i++, h = h->next) if ( h->type == htype_old - && write(fd, &i, sizeof(i)) != sizeof(i) + && os_pipe_write(fd, &i, sizeof(i)) != sizeof(i) ) goto bad; i = -1; - if (write(fd, &i, sizeof(i)) != sizeof(i)) + if (os_pipe_write(fd, &i, sizeof(i)) != sizeof(i)) goto bad; while (waslast != header_last) @@ -682,7 +682,7 @@ if ((pid = fork()) == 0) waslast = waslast->next; if (waslast->type != htype_old) if ( rda_write_string(fd, waslast->text) != 0 - || write(fd, &(waslast->type), sizeof(waslast->type)) + || os_pipe_write(fd, &(waslast->type), sizeof(waslast->type)) != sizeof(waslast->type) ) goto bad; @@ -693,7 +693,7 @@ if ((pid = fork()) == 0) /* Write the contents of the $n variables */ - if (write(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) + if (os_pipe_write(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) goto bad; /* If the result was DELIVERED or NOTDELIVERED, we pass back the generated @@ -711,10 +711,10 @@ if ((pid = fork()) == 0) int ig_err = addr->prop.ignore_error ? 1 : 0; if ( rda_write_string(fd, addr->address) != 0 - || write(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) - || write(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) + || os_pipe_write(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) + || os_pipe_write(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) || rda_write_string(fd, addr->prop.errors_address) != 0 - || write(fd, &ig_err, sizeof(ig_err)) != sizeof(ig_err) + || os_pipe_write(fd, &ig_err, sizeof(ig_err)) != sizeof(ig_err) ) goto bad; @@ -727,7 +727,7 @@ if ((pid = fork()) == 0) if (!addr->reply) { - if (write(fd, &reply_options, sizeof(int)) != sizeof(int)) /* 0 means no reply */ + if (os_pipe_write(fd, &reply_options, sizeof(int)) != sizeof(int)) /* 0 means no reply */ goto bad; } else @@ -735,10 +735,10 @@ if ((pid = fork()) == 0) reply_options |= REPLY_EXISTS; if (addr->reply->file_expand) reply_options |= REPLY_EXPAND; if (addr->reply->return_message) reply_options |= REPLY_RETURN; - if ( write(fd, &reply_options, sizeof(int)) != sizeof(int) - || write(fd, &(addr->reply->expand_forbid), sizeof(int)) + if ( os_pipe_write(fd, &reply_options, sizeof(int)) != sizeof(int) + || os_pipe_write(fd, &(addr->reply->expand_forbid), sizeof(int)) != sizeof(int) - || write(fd, &(addr->reply->once_repeat), sizeof(time_t)) + || os_pipe_write(fd, &(addr->reply->once_repeat), sizeof(time_t)) != sizeof(time_t) || rda_write_string(fd, addr->reply->to) != 0 || rda_write_string(fd, addr->reply->cc) != 0 @@ -787,8 +787,8 @@ empty pipe. Afterwards, close the reading end. */ /* Read initial data, including yield and contents of *error */ fd = pfd[pipe_read]; -if (read(fd, filtertype, sizeof(int)) != sizeof(int) || - read(fd, &yield, sizeof(int)) != sizeof(int) || +if (os_pipe_read(fd, filtertype, sizeof(int)) != sizeof(int) || + os_pipe_read(fd, &yield, sizeof(int)) != sizeof(int) || !rda_read_string(fd, error)) goto DISASTER; /* Read the contents of any syntax error blocks if we have a pointer */ @@ -821,7 +821,7 @@ if (f.system_filtering) for (;;) { int n; - if (read(fd, &n, sizeof(int)) != sizeof(int)) goto DISASTER; + if (os_pipe_read(fd, &n, sizeof(int)) != sizeof(int)) goto DISASTER; if (n < 0) break; while (hn < n) { @@ -837,14 +837,14 @@ if (f.system_filtering) int type; if (!rda_read_string(fd, &s)) goto DISASTER; if (!s) break; - if (read(fd, &type, sizeof(type)) != sizeof(type)) goto DISASTER; + if (os_pipe_read(fd, &type, sizeof(type)) != sizeof(type)) goto DISASTER; header_add(type, "%s", s); } } /* Read the values of the $n variables */ -if (read(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) goto DISASTER; +if (os_pipe_read(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) goto DISASTER; /* If the yield is DELIVERED, NOTDELIVERED, FAIL, or FREEZE there may follow addresses and data to go with them. Keep them in the same order in the @@ -875,10 +875,10 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || /* Next comes the mode and the flags fields */ - if ( read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) - || read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) + if ( os_pipe_read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) + || os_pipe_read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) || !rda_read_string(fd, &addr->prop.errors_address) - || read(fd, &i, sizeof(i)) != sizeof(i) + || os_pipe_read(fd, &i, sizeof(i)) != sizeof(i) ) goto DISASTER; addr->prop.ignore_error = (i != 0); @@ -907,7 +907,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || /* Then an int containing reply options; zero => no reply data. */ - if (read(fd, &reply_options, sizeof(int)) != sizeof(int)) goto DISASTER; + if (os_pipe_read(fd, &reply_options, sizeof(int)) != sizeof(int)) goto DISASTER; if ((reply_options & REPLY_EXISTS) != 0) { addr->reply = store_get(sizeof(reply_item), FALSE); @@ -915,9 +915,9 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || addr->reply->file_expand = (reply_options & REPLY_EXPAND) != 0; addr->reply->return_message = (reply_options & REPLY_RETURN) != 0; - if (read(fd,&(addr->reply->expand_forbid),sizeof(int)) != + if (os_pipe_read(fd,&(addr->reply->expand_forbid),sizeof(int)) != sizeof(int) || - read(fd,&(addr->reply->once_repeat),sizeof(time_t)) != + os_pipe_read(fd,&(addr->reply->once_repeat),sizeof(time_t)) != sizeof(time_t) || !rda_read_string(fd, &(addr->reply->to)) || !rda_read_string(fd, &(addr->reply->cc)) || diff --git a/src/src/transport.c b/src/src/transport.c index 14bd91cdb..c4f374509 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1254,16 +1254,24 @@ if ((write_pid = fork()) == 0) rc = internal_transport_write_message(tctx, size_limit); save_errno = errno; - if ( write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)) - != sizeof(BOOL) - || write(pfd[pipe_write], (void *)&save_errno, sizeof(int)) - != sizeof(int) - || write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int)) - != sizeof(int) - || write(pfd[pipe_write], (void *)&tctx->addr->delivery_usec, sizeof(int)) - != sizeof(int) - ) - rc = FALSE; /* compiler quietening */ + errno = 0; + for (int retries = 10;;) + { + if ( os_pipe_write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)) + != sizeof(BOOL) + || os_pipe_write(pfd[pipe_write], (void *)&save_errno, sizeof(int)) + != sizeof(int) + || os_pipe_write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int)) + != sizeof(int) + || os_pipe_write(pfd[pipe_write], (void *)&tctx->addr->delivery_usec, sizeof(int)) + != sizeof(int) + ) + if (errno == EINTR && --retries > 0) + continue; + else + rc = FALSE; /* compiler quietening */ + break; + } exim_underbar_exit(0); } save_errno = errno; @@ -1376,7 +1384,7 @@ if (write_pid > 0) if (rc == 0) { BOOL ok; - if (read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)) != sizeof(BOOL)) + if (os_pipe_read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)) != sizeof(BOOL)) { DEBUG(D_transport) debug_printf("pipe read from writing process: %s\n", strerror(errno)); @@ -1385,9 +1393,9 @@ if (write_pid > 0) } else if (!ok) { - int dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); - dummy = read(pfd[pipe_read], (void *)&tctx->addr->more_errno, sizeof(int)); - dummy = read(pfd[pipe_read], (void *)&tctx->addr->delivery_usec, sizeof(int)); + int dummy = os_pipe_read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); + dummy = os_pipe_read(pfd[pipe_read], (void *)&tctx->addr->more_errno, sizeof(int)); + dummy = os_pipe_read(pfd[pipe_read], (void *)&tctx->addr->delivery_usec, sizeof(int)); dummy = dummy; /* compiler quietening */ yield = FALSE; } -- 2.25.1