[exim-cvs] Check syscall return values.

Page principale
Supprimer ce message
Répondre à ce message
Auteur: Exim Git Commits Mailing List
Date:  
À: exim-cvs
Sujet: [exim-cvs] Check syscall return values.
Gitweb: http://git.exim.org/exim.git/commitdiff/1ac6b2e7857d7b6645dbd09047c4c2ac3b6cef1d
Commit:     1ac6b2e7857d7b6645dbd09047c4c2ac3b6cef1d
Parent:     4328fd3cb019281becab844b6bf560632b1d34b1
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Fri Nov 23 00:52:43 2012 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Fri Nov 23 01:27:59 2012 +0000


    Check syscall return values.


    Mostly just compiler-quietening rather than intelligent error-handling.
    This deals with complaints of "attribute warn_unused_result" during an rpm
    build for SL6 (probably for Fedora also).
---
 src/src/dbfn.c                  |    3 +-
 src/src/deliver.c               |   81 +++++++++++++++++---------
 src/src/directory.c             |    7 ++-
 src/src/dkim.c                  |    7 ++-
 src/src/exim.c                  |   16 ++++--
 src/src/exim_lock.c             |    6 +-
 src/src/log.c                   |    5 +-
 src/src/malware.c               |   14 ++--
 src/src/queue.c                 |    5 +-
 src/src/rda.c                   |  120 ++++++++++++++++++++++++---------------
 src/src/receive.c               |    7 ++-
 src/src/smtp_in.c               |    4 +-
 src/src/spool_in.c              |    4 +-
 src/src/spool_mbox.c            |    6 ++-
 src/src/spool_out.c             |   10 ++-
 src/src/transport.c             |   17 ++++--
 src/src/transports/appendfile.c |   49 ++++++++++++----
 src/src/transports/autoreply.c  |   16 ++++--
 src/src/transports/pipe.c       |   11 +++-
 src/src/transports/tf_maildir.c |    2 +-
 20 files changed, 262 insertions(+), 128 deletions(-)


diff --git a/src/src/dbfn.c b/src/src/dbfn.c
index c74ac9c..4a1c20f 100644
--- a/src/src/dbfn.c
+++ b/src/src/dbfn.c
@@ -208,7 +208,8 @@ if (created && geteuid() == root_uid)
       if (Ustat(buffer, &statbuf) >= 0 && statbuf.st_uid != exim_uid)
         {
         DEBUG(D_hints_lookup) debug_printf("ensuring %s is owned by exim\n", buffer);
-        (void)Uchown(buffer, exim_uid, exim_gid);
+        if (Uchown(buffer, exim_uid, exim_gid))
+          DEBUG(D_hints_lookup) debug_printf("failed setting %s to owned by exim\n", buffer);
         }
       }
     }
diff --git a/src/src/deliver.c b/src/src/deliver.c
index eef9103..34f75fe 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -1904,33 +1904,40 @@ if ((pid = fork()) == 0)
     int i;
     int local_part_length = Ustrlen(addr2->local_part);
     uschar *s;
+    int ret;


-    (void)write(pfd[pipe_write], (void *)&(addr2->transport_return), sizeof(int));
-    (void)write(pfd[pipe_write], (void *)&transport_count, sizeof(transport_count));
-    (void)write(pfd[pipe_write], (void *)&(addr2->flags), sizeof(addr2->flags));
-    (void)write(pfd[pipe_write], (void *)&(addr2->basic_errno), sizeof(int));
-    (void)write(pfd[pipe_write], (void *)&(addr2->more_errno), sizeof(int));
-    (void)write(pfd[pipe_write], (void *)&(addr2->special_action), sizeof(int));
-    (void)write(pfd[pipe_write], (void *)&(addr2->transport),
-      sizeof(transport_instance *));
+    if(  (ret = write(pfd[pipe_write], (void *)&(addr2->transport_return), sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], (void *)&transport_count, sizeof(transport_count))) != sizeof(transport_count)
+      || (ret = write(pfd[pipe_write], (void *)&(addr2->flags), sizeof(addr2->flags))) != sizeof(addr2->flags)
+      || (ret = write(pfd[pipe_write], (void *)&(addr2->basic_errno), sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], (void *)&(addr2->more_errno), sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], (void *)&(addr2->special_action), sizeof(int))) != sizeof(int)
+      || (ret = write(pfd[pipe_write], (void *)&(addr2->transport),
+        sizeof(transport_instance *))) != sizeof(transport_instance *)


     /* For a file delivery, pass back the local part, in case the original
     was only part of the final delivery path. This gives more complete
     logging. */


-    if (testflag(addr2, af_file))
-      {
-      (void)write(pfd[pipe_write], (void *)&local_part_length, sizeof(int));
-      (void)write(pfd[pipe_write], addr2->local_part, local_part_length);
-      }
+      || (testflag(addr2, af_file)
+          && (  (ret = write(pfd[pipe_write], (void *)&local_part_length, sizeof(int))) != sizeof(int)
+             || (ret = write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length
+         )
+     )
+      )
+      log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s\n",
+    ret == -1 ? strerror(errno) : "short write");


     /* Now any messages */


     for (i = 0, s = addr2->message; i < 2; i++, s = addr2->user_message)
       {
       int message_length = (s == NULL)? 0 : Ustrlen(s) + 1;
-      (void)write(pfd[pipe_write], (void *)&message_length, sizeof(int));
-      if (message_length > 0) (void)write(pfd[pipe_write], s, message_length);
+      if(  (ret = write(pfd[pipe_write], (void *)&message_length, sizeof(int))) != sizeof(int)
+        || (message_length > 0  && (ret = write(pfd[pipe_write], s, message_length)) != message_length)
+    )
+        log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s\n",
+      ret == -1 ? strerror(errno) : "short write");
       }
     }


@@ -3449,6 +3456,15 @@ while (parcount > max)



+static void
+rmt_dlv_checked_write(int fd, void * buf, int size)
+{
+int ret = write(fd, buf, size);
+if(ret != size)
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed writing transport result to pipe: %s\n",
+    ret == -1 ? strerror(errno) : "short write");
+}
+
 /*************************************************
 *           Do remote deliveries                 *
 *************************************************/
@@ -3968,7 +3984,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
       {
       if (h->address == NULL || h->status < hstatus_unusable) continue;
       sprintf(CS big_buffer, "H%c%c%s", h->status, h->why, h->address);
-      (void)write(fd, big_buffer, Ustrlen(big_buffer+3) + 4);
+      rmt_dlv_checked_write(fd, big_buffer, Ustrlen(big_buffer+3) + 4);
       }


     /* The number of bytes written. This is the same for each address. Even
@@ -3978,7 +3994,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)


     big_buffer[0] = 'S';
     memcpy(big_buffer+1, &transport_count, sizeof(transport_count));
-    (void)write(fd, big_buffer, sizeof(transport_count) + 1);
+    rmt_dlv_checked_write(fd, big_buffer, sizeof(transport_count) + 1);


     /* Information about what happened to each address. Four item types are
     used: an optional 'X' item first, for TLS information, then an optional "C"
@@ -4007,7 +4023,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
           sprintf(CS ptr, "%.512s", addr->peerdn);
           while(*ptr++);
           }
-        (void)write(fd, big_buffer, ptr - big_buffer);
+        rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
         }
       #endif


@@ -4016,21 +4032,21 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
         ptr = big_buffer;
     sprintf(CS big_buffer, "C1%.64s", client_authenticator);
         while(*ptr++);
-        (void)write(fd, big_buffer, ptr - big_buffer);
+        rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
     }
       if (client_authenticated_id)
         {
         ptr = big_buffer;
     sprintf(CS big_buffer, "C2%.64s", client_authenticated_id);
         while(*ptr++);
-        (void)write(fd, big_buffer, ptr - big_buffer);
+        rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
     }
       if (client_authenticated_sender)
         {
         ptr = big_buffer;
     sprintf(CS big_buffer, "C3%.64s", client_authenticated_sender);
         while(*ptr++);
-        (void)write(fd, big_buffer, ptr - big_buffer);
+        rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
     }


       /* Retry information: for most success cases this will be null. */
@@ -4049,7 +4065,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
           sprintf(CS ptr, "%.512s", r->message);
           while(*ptr++);
           }
-        (void)write(fd, big_buffer, ptr - big_buffer);
+        rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
         }


       /* The rest of the information goes in an 'A' item. */
@@ -4085,7 +4101,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
         memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
         ptr += sizeof(addr->host_used->port);
         }
-      (void)write(fd, big_buffer, ptr - big_buffer);
+      rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
       }


     /* Add termination flag, close the pipe, and that's it. The character
@@ -4095,7 +4111,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)


     big_buffer[0] = 'Z';
     big_buffer[1] = (continue_transport == NULL)? '0' : '1';
-    (void)write(fd, big_buffer, 2);
+    rmt_dlv_checked_write(fd, big_buffer, 2);
     (void)close(fd);
     exit(EXIT_SUCCESS);
     }
@@ -6022,12 +6038,23 @@ if (addr_local != NULL || addr_remote != NULL)
   that the mode is correct - the group setting doesn't always seem to get
   set automatically. */


-  (void)fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC);
-  (void)fchown(journal_fd, exim_uid, exim_gid);
-  (void)fchmod(journal_fd, SPOOL_MODE);
+  if(  fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC)
+    || fchown(journal_fd, exim_uid, exim_gid)
+    || fchmod(journal_fd, SPOOL_MODE)
+    )
+    {
+    int ret = Uunlink(spoolname);
+    log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't set perms on journal file %s: %s",
+      spoolname, strerror(errno));
+    if(ret  &&  errno != ENOENT)
+      log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
+        spoolname, strerror(errno));
+    return DELIVER_NOT_ATTEMPTED;
+    }
   }



+
/* Now we can get down to the business of actually doing deliveries. Local
deliveries are done first, then remote ones. If ever the problems of how to
handle fallback transports are figured out, this section can be put into a loop
diff --git a/src/src/directory.c b/src/src/directory.c
index c6d46aa..5c55a45 100644
--- a/src/src/directory.c
+++ b/src/src/directory.c
@@ -74,7 +74,12 @@ while (c != 0 && *p != 0)

     /* Set the ownership if necessary. */


-    if (use_chown) (void)Uchown(buffer, exim_uid, exim_gid);
+    if (use_chown && Uchown(buffer, exim_uid, exim_gid))
+      {
+      if (!panic) return FALSE;
+      log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+        "Failed to set owner on directory \"%s\": %s\n", buffer, strerror(errno));
+      }


     /* It appears that any mode bits greater than 0777 are ignored by
     mkdir(), at least on some operating systems. Therefore, if the mode
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 05b5fec..cb7fc70 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -504,7 +504,12 @@ uschar *dkim_exim_sign(int dkim_fd,
         rc = NULL;
         goto CLEANUP;
       }
-      (void)read(privkey_fd,big_buffer,(big_buffer_size-2));
+      if (read(privkey_fd,big_buffer,(big_buffer_size-2)) < 0) {
+        log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s",
+      dkim_private_key_expanded);
+        rc = NULL;
+        goto CLEANUP;
+      }
       (void)close(privkey_fd);
       dkim_private_key_expanded = big_buffer;
     }
diff --git a/src/src/exim.c b/src/src/exim.c
index a59cfea..6be3c51 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -222,7 +222,7 @@ to disrupt whatever is going on outside the signal handler. */


if (fd < 0) return;

-(void)write(fd, process_info, process_info_len);
+{int dummy = write(fd, process_info, process_info_len); dummy = dummy; }
(void)close(fd);
}

@@ -3905,8 +3905,9 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
{
int i;
uschar *p = big_buffer;
- Ustrcpy(p, "cwd=");
- (void)getcwd(CS p+4, big_buffer_size - 4);
+ char * dummy;
+ Ustrcpy(p, "cwd= (failed)");
+ dummy = /* quieten compiler */ getcwd(CS p+4, big_buffer_size - 4);
while (*p) p++;
(void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc);
while (*p) p++;
@@ -3949,8 +3950,9 @@ privilege by now. Before the chdir, we try to ensure that the directory exists.

if (Uchdir(spool_directory) != 0)
{
+ int dummy;
(void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE);
- (void)Uchdir(spool_directory);
+ dummy = /* quieten compiler */ Uchdir(spool_directory);
}

 /* Handle calls with the -bi option. This is a sendmail option to rebuild *the*
@@ -5398,7 +5400,11 @@ while (more)
     if (ftest_prefix != NULL) printf("Prefix    = %s\n", ftest_prefix);
     if (ftest_suffix != NULL) printf("Suffix    = %s\n", ftest_suffix);


-    (void)chdir("/");   /* Get away from wherever the user is running this from */
+    if (chdir("/"))   /* Get away from wherever the user is running this from */
+      {
+      DEBUG(D_receive) debug_printf("chdir(\"/\") failed\n");
+      exim_exit(EXIT_FAILURE);
+      }


     /* Now we run either a system filter test, or a user filter test, or both.
     In the latter case, headers added by the system filter will persist and be
diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c
index 0a9dfde..0d34751 100644
--- a/src/src/exim_lock.c
+++ b/src/src/exim_lock.c
@@ -583,12 +583,14 @@ if (restore_times)
   struct stat strestore;
   struct utimbuf ut;
   stat(filename, &strestore);
-  (void)system(command);
+  i = system(command);
   ut.actime = strestore.st_atime;
   ut.modtime = strestore.st_mtime;
   utime(filename, &ut);
   }
-else (void)system(command);
+else i = system(command);
+
+if(i && !quiet) printf("warning: nonzero status %d\n", i);


 /* Remove the locks and exit. Unlink the /tmp file if we can get an exclusive
 lock on the mailbox. This should be a non-blocking lock call, as there is no
diff --git a/src/src/log.c b/src/src/log.c
index 3a91ed2..7af9281 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -1093,7 +1093,10 @@ if ((flags & LOG_PANIC) != 0)
     panic_recurseflag = FALSE;


     if (panic_save_buffer != NULL)
-      (void) write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer));
+      {
+      int i = write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer));
+      i = i;    /* compiler quietening */
+      }


     written_len = write_to_fd_buf(paniclogfd, log_buffer, length);
     if (written_len != length)
diff --git a/src/src/malware.c b/src/src/malware.c
index 7de913f..994c629 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -1214,7 +1214,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
                                           sizeof(sophie_options_buffer))) == NULL) {
         /* no options supplied, use default options */
         sophie_options = sophie_options_default;
-      };
+      }


       /* open the sophie socket */
       sock = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -1249,14 +1249,14 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
       DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n",
           scanner_name, sophie_options);


-      if (write(sock, file_name, Ustrlen(file_name)) < 0) {
+      if (  write(sock, file_name, Ustrlen(file_name)) < 0
+     || write(sock, "\n", 1) != 1
+         ) {
         (void)close(sock);
         log_write(0, LOG_MAIN|LOG_PANIC,
              "malware acl condition: unable to write to sophie UNIX socket (%s)", sophie_options);
         return DEFER;
-      };
-
-      (void)write(sock, "\n", 1);
+      }


       /* wait for result */
       memset(av_buffer, 0, sizeof(av_buffer));
@@ -1265,7 +1265,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
         log_write(0, LOG_MAIN|LOG_PANIC,
              "malware acl condition: unable to read from sophie UNIX socket (%s)", sophie_options);
         return DEFER;
-      };
+      }


       (void)close(sock);


@@ -1283,7 +1283,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
       else {
         /* all ok, no virus */
         malware_name = NULL;
-      };
+      }
     }
     /* ----------------------------------------------------------------------- */


diff --git a/src/src/queue.c b/src/src/queue.c
index b3dbd2c..ff0ae67 100644
--- a/src/src/queue.c
+++ b/src/src/queue.c
@@ -650,7 +650,8 @@ for (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);
-    (void)read(pfd[pipe_read], buffer, sizeof(buffer));
+    if (read(pfd[pipe_read], buffer, sizeof(buffer)) >= 0)
+      log_write(0, LOG_MAIN|LOG_PANIC, "queue run: unexpected data on pipe");
     (void)close(pfd[pipe_read]);
     set_process_info("running queue");


@@ -1018,7 +1019,7 @@ if (action >= MSG_SHOW_BODY)
     }


   while((rc = read(fd, big_buffer, big_buffer_size)) > 0)
-    (void)write(fileno(stdout), big_buffer, rc);
+    rc = write(fileno(stdout), big_buffer, rc);


   (void)close(fd);
   return TRUE;
diff --git a/src/src/rda.c b/src/src/rda.c
index 8774340..f915ce7 100644
--- a/src/src/rda.c
+++ b/src/src/rda.c
@@ -433,22 +433,24 @@ return parse_forward_list(data,
 *         Write string down pipe                 *
 *************************************************/


-/* This function is used for tranferring a string down a pipe between
+/* This function is used for transferring a string down a pipe between
processes. If the pointer is NULL, a length of zero is written.

 Arguments:
   fd         the pipe
   s          the string


-Returns:     nothing
+Returns:     -1 on error, else 0
 */


-static void
+static int
 rda_write_string(int fd, uschar *s)
 {
 int len = (s == NULL)? 0 : Ustrlen(s) + 1;
-(void)write(fd, &len, sizeof(int));
-if (s != NULL) (void)write(fd, s, len);
+return (  write(fd, &len, sizeof(int)) != sizeof(int)
+       || (s != NULL  &&  write(fd, s, len) != len)
+       )
+       ? -1 : 0;
 }



@@ -645,9 +647,11 @@ if ((pid = fork()) == 0)
/* Pass back whether it was a filter, and the return code and any overall
error text via the pipe. */

-  (void)write(fd, filtertype, sizeof(int));
-  (void)write(fd, &yield, sizeof(int));
-  rda_write_string(fd, *error);
+  if (  write(fd, filtertype, sizeof(int)) != sizeof(int)
+     || write(fd, &yield, sizeof(int)) != sizeof(int)
+     || rda_write_string(fd, *error) != 0
+     )
+    goto bad;


/* Pass back the contents of any syntax error blocks if we have a pointer */

@@ -655,11 +659,12 @@ if ((pid = fork()) == 0)
     {
     error_block *ep;
     for (ep = *eblockp; ep != NULL; ep = ep->next)
-      {
-      rda_write_string(fd, ep->text1);
-      rda_write_string(fd, ep->text2);
-      }
-    rda_write_string(fd, NULL);    /* Indicates end of eblocks */
+      if (  rda_write_string(fd, ep->text1) != 0
+         || rda_write_string(fd, ep->text2) != 0
+     )
+    goto bad;
+    if (rda_write_string(fd, NULL) != 0)    /* Indicates end of eblocks */
+      goto bad;
     }


   /* If this is a system filter, we have to pass back the numbers of any
@@ -671,27 +676,33 @@ if ((pid = fork()) == 0)
     int i = 0;
     header_line *h;
     for (h = header_list; h != waslast->next; i++, h = h->next)
-      {
-      if (h->type == htype_old) (void)write(fd, &i, sizeof(i));
-      }
+      if (  h->type == htype_old
+         && write(fd, &i, sizeof(i)) != sizeof(i)
+     )
+    goto bad;
+
     i = -1;
-    (void)write(fd, &i, sizeof(i));
+    if (write(fd, &i, sizeof(i)) != sizeof(i))
+    goto bad;


     while (waslast != header_last)
       {
       waslast = waslast->next;
       if (waslast->type != htype_old)
-        {
-        rda_write_string(fd, waslast->text);
-        (void)write(fd, &(waslast->type), sizeof(waslast->type));
-        }
+    if (  rda_write_string(fd, waslast->text) != 0
+           || write(fd, &(waslast->type), sizeof(waslast->type))
+          != sizeof(waslast->type)
+       )
+      goto bad;
       }
-    rda_write_string(fd, NULL);    /* Indicates end of added headers */
+    if (rda_write_string(fd, NULL) != 0)    /* Indicates end of added headers */
+      goto bad;
     }


/* Write the contents of the $n variables */

-  (void)write(fd, filter_n, sizeof(filter_n));
+  if (write(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n))
+    goto bad;


   /* If the result was DELIVERED or NOTDELIVERED, we pass back the generated
   addresses, and their associated information, through the pipe. This is
@@ -707,52 +718,71 @@ if ((pid = fork()) == 0)
       {
       int reply_options = 0;


-      rda_write_string(fd, addr->address);
-      (void)write(fd, &(addr->mode), sizeof(addr->mode));
-      (void)write(fd, &(addr->flags), sizeof(addr->flags));
-      rda_write_string(fd, addr->p.errors_address);
+      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)
+         || rda_write_string(fd, addr->p.errors_address) != 0
+     )
+    goto bad;


       if (addr->pipe_expandn != NULL)
         {
         uschar **pp;
         for (pp = addr->pipe_expandn; *pp != NULL; pp++)
-          rda_write_string(fd, *pp);
+          if (rda_write_string(fd, *pp) != 0)
+        goto bad;
         }
-      rda_write_string(fd, NULL);
+      if (rda_write_string(fd, NULL) != 0)
+        goto bad;


       if (addr->reply == NULL)
-        (void)write(fd, &reply_options, sizeof(int));    /* 0 means no reply */
+    {
+        if (write(fd, &reply_options, sizeof(int)) != sizeof(int))    /* 0 means no reply */
+      goto bad;
+    }
       else
         {
         reply_options |= REPLY_EXISTS;
         if (addr->reply->file_expand) reply_options |= REPLY_EXPAND;
         if (addr->reply->return_message) reply_options |= REPLY_RETURN;
-        (void)write(fd, &reply_options, sizeof(int));
-        (void)write(fd, &(addr->reply->expand_forbid), sizeof(int));
-        (void)write(fd, &(addr->reply->once_repeat), sizeof(time_t));
-        rda_write_string(fd, addr->reply->to);
-        rda_write_string(fd, addr->reply->cc);
-        rda_write_string(fd, addr->reply->bcc);
-        rda_write_string(fd, addr->reply->from);
-        rda_write_string(fd, addr->reply->reply_to);
-        rda_write_string(fd, addr->reply->subject);
-        rda_write_string(fd, addr->reply->headers);
-        rda_write_string(fd, addr->reply->text);
-        rda_write_string(fd, addr->reply->file);
-        rda_write_string(fd, addr->reply->logfile);
-        rda_write_string(fd, addr->reply->oncelog);
+        if (  write(fd, &reply_options, sizeof(int)) != sizeof(int)
+           || write(fd, &(addr->reply->expand_forbid), sizeof(int))
+          != sizeof(int)
+           || 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
+           || rda_write_string(fd, addr->reply->bcc) != 0
+           || rda_write_string(fd, addr->reply->from) != 0
+           || rda_write_string(fd, addr->reply->reply_to) != 0
+           || rda_write_string(fd, addr->reply->subject) != 0
+           || rda_write_string(fd, addr->reply->headers) != 0
+           || rda_write_string(fd, addr->reply->text) != 0
+           || rda_write_string(fd, addr->reply->file) != 0
+           || rda_write_string(fd, addr->reply->logfile) != 0
+           || rda_write_string(fd, addr->reply->oncelog) != 0
+       )
+      goto bad;
         }
       }


-    rda_write_string(fd, NULL);   /* Marks end of addresses */
+    if (rda_write_string(fd, NULL) != 0)   /* Marks end of addresses */
+      goto bad;
     }


/* OK, this process is now done. Free any cached resources. Must use _exit()
and not exit() !! */

+out:
(void)close(fd);
search_tidyup();
_exit(0);
+
+bad:
+ DEBUG(D_rewrite) debug_printf("rda_interpret: failed write to pipe\n");
+ goto out;
}

/* Back in the main process: panic if the fork did not succeed. */
diff --git a/src/src/receive.c b/src/src/receive.c
index 9b9b717..1943a74 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -2793,7 +2793,10 @@ if (data_fd < 0)
/* Make sure the file's group is the Exim gid, and double-check the mode
because the group setting doesn't always get set automatically. */

-(void)fchown(data_fd, exim_uid, exim_gid);
+if (fchown(data_fd, exim_uid, exim_gid))
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+    "Failed setting ownership on spool file %s: %s",
+    spool_name, strerror(errno));
 (void)fchmod(data_fd, SPOOL_MODE);


 /* We now have data file open. Build a stream for it and lock it. We lock only
@@ -2823,7 +2826,7 @@ if (next != NULL)
   {
   uschar *s = next->text;
   int len = next->slen;
-  (void)fwrite(s, 1, len, data_file);
+  len = fwrite(s, 1, len, data_file);  len = len; /* compiler quietening */
   body_linecount++;                 /* Assumes only 1 line */
   }


diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 5bc331f..243b8f7 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -3192,7 +3192,9 @@ while (done <= 0)
     if (tls_in.active >= 0) (void)tls_write(TRUE, s, ptr); else
     #endif


-    (void)fwrite(s, 1, ptr, smtp_out);
+      {
+      int i = fwrite(s, 1, ptr, smtp_out); i = i; /* compiler quietening */
+      }
     DEBUG(D_receive)
       {
       uschar *cr;
diff --git a/src/src/spool_in.c b/src/src/spool_in.c
index 6747804..a546b65 100644
--- a/src/src/spool_in.c
+++ b/src/src/spool_in.c
@@ -718,8 +718,8 @@ while ((n = fgetc(f)) != EOF)
   int i;


   if (!isdigit(n)) goto SPOOL_FORMAT_ERROR;
-  (void)ungetc(n, f);
-  (void)fscanf(f, "%d%c ", &n, flag);
+  if(ungetc(n, f) == EOF  ||  fscanf(f, "%d%c ", &n, flag) == EOF)
+    goto SPOOL_READ_ERROR;
   if (flag[0] != '*') message_size += n;  /* Omit non-transmitted headers */


   if (read_headers)
diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c
index bdeb2b1..12cf3d4 100644
--- a/src/src/spool_mbox.c
+++ b/src/src/spool_mbox.c
@@ -96,7 +96,11 @@ FILE *spool_mbox(unsigned long *mbox_file_size, uschar *source_file_override) {
     };


     /* End headers */
-    (void)fwrite("\n", 1, 1, mbox_file);
+    if (fwrite("\n", 1, 1, mbox_file) != 1) {
+      log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \
+        message headers to %s", mbox_path);
+      goto OUT;
+    }


     /* copy body file */
     if (source_file_override == NULL) {
diff --git a/src/src/spool_out.c b/src/src/spool_out.c
index 5df2a41..ce25a56 100644
--- a/src/src/spool_out.c
+++ b/src/src/spool_out.c
@@ -93,10 +93,12 @@ double-check the mode because the group setting doesn't always get set
 automatically. */


 if (fd >= 0)
-  {
-  (void)fchown(fd, exim_uid, exim_gid);
-  (void)fchmod(fd, SPOOL_MODE);
-  }
+  if (fchown(fd, exim_uid, exim_gid) || fchmod(fd, SPOOL_MODE))
+    {
+    DEBUG(D_any) debug_printf("failed setting perms on %s\n", temp_name);
+    (void) close(fd); fd = -1;
+    Uunlink(temp_name);
+    }


 return fd;
 }
diff --git a/src/src/transport.c b/src/src/transport.c
index 7c79bb0..160d080 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -1226,9 +1226,14 @@ if ((write_pid = fork()) == 0)
     size_limit, add_headers, remove_headers, NULL, NULL,
     rewrite_rules, rewrite_existflags);
   save_errno = errno;
-  (void)write(pfd[pipe_write], (void *)&rc, sizeof(BOOL));
-  (void)write(pfd[pipe_write], (void *)&save_errno, sizeof(int));
-  (void)write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int));
+  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 *)&(addr->more_errno), sizeof(int))
+        != sizeof(int)
+     )
+    rc = FALSE;    /* compiler quietening */
   _exit(0);
   }
 save_errno = errno;
@@ -1339,11 +1344,11 @@ if (write_pid > 0)
     if (rc == 0)
       {
       BOOL ok;
-      (void)read(pfd[pipe_read], (void *)&ok, sizeof(BOOL));
+      int dummy = read(pfd[pipe_read], (void *)&ok, sizeof(BOOL));
       if (!ok)
         {
-        (void)read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
-        (void)read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
+        dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
+        dummy = read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
         yield = FALSE;
         }
       }
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 11c59bb..db3b5ae 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -1771,8 +1771,14 @@ if (!isdirectory)
       /* We have successfully created and opened the file. Ensure that the group
       and the mode are correct. */


-      (void)Uchown(filename, uid, gid);
-      (void)Uchmod(filename, mode);
+      if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+        {
+        addr->basic_errno = errno;
+        addr->message = string_sprintf("while setting perms on mailbox %s",
+          filename);
+        addr->transport_return = FAIL;
+        goto RETURN;
+        }
       }



@@ -2573,8 +2579,13 @@ else
     /* Why are these here? Put in because they are present in the non-maildir
     directory case above. */


-    (void)Uchown(filename, uid, gid);
-    (void)Uchmod(filename, mode);
+    if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on maildir %s",
+        filename);
+      return FALSE;
+      }
     }


   #endif  /* SUPPORT_MAILDIR */
@@ -2615,8 +2626,13 @@ else
     /* Why are these here? Put in because they are present in the non-maildir
     directory case above. */


-    (void)Uchown(filename, uid, gid);
-    (void)Uchmod(filename, mode);
+    if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on file %s",
+        filename);
+      return FALSE;
+      }


     /* Built a C stream from the open file descriptor. */


@@ -2707,8 +2723,13 @@ else
       Uunlink(filename);
       return FALSE;
       }
-    (void)Uchown(dataname, uid, gid);
-    (void)Uchmod(dataname, mode);
+    if(Uchown(dataname, uid, gid) || Uchmod(dataname, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on file %s",
+        dataname);
+      return FALSE;
+      }
     }


#endif /* SUPPORT_MAILSTORE */
@@ -2717,8 +2738,13 @@ else
/* In all cases of writing to a new file, ensure that the file which is
going to be renamed has the correct ownership and mode. */

-  (void)Uchown(filename, uid, gid);
-  (void)Uchmod(filename, mode);
+  if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+    {
+    addr->basic_errno = errno;
+    addr->message = string_sprintf("while setting perms on file %s",
+      filename);
+    return FALSE;
+    }
   }



@@ -3095,7 +3121,8 @@ if (yield != OK)
investigated so far have ftruncate(), whereas not all have the F_FREESP
fcntl() call (BSDI & FreeBSD do not). */

-  if (!isdirectory) (void)ftruncate(fd, saved_size);
+  if (!isdirectory && ftruncate(fd, saved_size))
+    DEBUG(D_transport) debug_printf("Error restting file size\n");
   }


 /* Handle successful writing - we want the modification time to be now for
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index cce1cd7..4e391b8 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -529,8 +529,10 @@ if (oncelog != NULL && *oncelog != 0 && to != NULL)
       uschar *ptr = log_buffer;
       sprintf(CS ptr, "%s\n  previously sent to %.200s\n", tod_stamp(tod_log), to);
       while(*ptr) ptr++;
-      (void)write(log_fd, log_buffer, ptr - log_buffer);
-      (void)close(log_fd);
+      if(write(log_fd, log_buffer, ptr - log_buffer) != ptr-log_buffer
+        || close(log_fd))
+        DEBUG(D_transport) debug_printf("Problem writing log file %s for %s "
+          "transport\n", logfile, tblock->name);
       }
     goto END_OFF;
     }
@@ -753,7 +755,9 @@ if (cache_fd >= 0)
     }


   memcpy(cache_time, &now, sizeof(time_t));
-  (void)write(cache_fd, from, size);
+  if(write(cache_fd, from, size) != size)
+    DEBUG(D_transport) debug_printf("Problem writing cache file %s for %s "
+      "transport\n", oncelog, tblock->name);
   }


 /* Update DBM file */
@@ -849,8 +853,10 @@ if (logfile != NULL)
         "  %s\n", headers);
       while(*ptr) ptr++;
       }
-    (void)write(log_fd, log_buffer, ptr - log_buffer);
-    (void)close(log_fd);
+    if(write(log_fd, log_buffer, ptr - log_buffer) != ptr-log_buffer
+      || close(log_fd))
+      DEBUG(D_transport) debug_printf("Problem writing log file %s for %s "
+        "transport\n", logfile, tblock->name);
     }
   else DEBUG(D_transport) debug_printf("Failed to open log file %s for %s "
     "transport: %s\n", logfile, tblock->name, strerror(errno));
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index 32a7bfa..fe94e85 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -749,14 +749,19 @@ if (outpid == 0)
   while ((rc = read(fd_out, big_buffer, big_buffer_size)) > 0)
     {
     if (addr->return_file >= 0)
-      write(addr->return_file, big_buffer, rc);
+      if(write(addr->return_file, big_buffer, rc) != rc)
+        DEBUG(D_transport) debug_printf("Problem writing to return_file\n");
     count += rc;
     if (count > ob->max_output)
       {
-      uschar *message = US"\n\n*** Too much output - remainder discarded ***\n";
       DEBUG(D_transport) debug_printf("Too much output from pipe - killed\n");
       if (addr->return_file >= 0)
-        write(addr->return_file, message, Ustrlen(message));
+    {
+        uschar *message = US"\n\n*** Too much output - remainder discarded ***\n";
+        rc = Ustrlen(message);
+        if(write(addr->return_file, message, rc) != rc)
+          DEBUG(D_transport) debug_printf("Problem writing to return_file\n");
+    }
       killpg(pid, SIGKILL);
       break;
       }
diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c
index 7a240b6..cfe7cb2 100644
--- a/src/src/transports/tf_maildir.c
+++ b/src/src/transports/tf_maildir.c
@@ -212,7 +212,7 @@ uschar buffer[256];
 sprintf(CS buffer, "%d 1\n", size);
 len = Ustrlen(buffer);
 (void)lseek(fd, 0, SEEK_END);
-(void)write(fd, buffer, len);
+len = write(fd, buffer, len);
 DEBUG(D_transport)
   debug_printf("added '%.*s' to maildirsize file\n", len-1, buffer);
 }