]> granicus.if.org Git - fcron/commitdiff
Fixed bug in logging to a file and made file closure more robust
authorThibault Godouet <fcron@free.fr>
Sun, 13 Jan 2013 17:31:17 +0000 (17:31 +0000)
committerThibault Godouet <fcron@free.fr>
Sun, 13 Jan 2013 17:31:17 +0000 (17:31 +0000)
- when logging to a file, fcron would log a line to the pid file
- adding helpers functions to close files properly: check for errors, and set FILE* to NULL / fd to -1

18 files changed:
Makefile.in
allow.c
conf.c
convert-fcrontab.c
fcron.c
fcronconf.c
fcrondyn.c
fcronsighup.c
fcrontab.c
filesubs.c [new file with mode: 0644]
filesubs.h [new file with mode: 0644]
getloadavg.c
global.h
job.c
log.c
save.c
socket.c
subs.c

index 8a59dda398a5d593ce0da4c49bf902164a95311e..3936894129f0df9f8f1c67aab0842dc6cd58bd45 100644 (file)
@@ -74,11 +74,11 @@ CFLAGS += $(OPTIM) $(OPTION) $(DEFS) $(CPPFLAGS)
 ifeq ($(FCRONDYN), 1)
 LIBOBJS := socket.o $(LIBOBJS)
 endif
-OBJSD := fcron.o cl.o subs.o mem.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o $(LIBOBJS)
-OBJSTAB := fcrontab.o cl.o subs.o mem.o save.o temp_file.o  log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o
-OBJSDYN := fcrondyn.o subs.o mem.o log.o allow.o read_string.o fcronconf.o
-OBJCONV := convert-fcrontab.o cl.o subs.o mem.o save.o log.o u_list.o env_list.o fcronconf.o
-OBJSIG := fcronsighup.o subs.o mem.o log.o allow.o fcronconf.o
+OBJSD := fcron.o cl.o subs.o mem.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o filesubs.o $(LIBOBJS)
+OBJSTAB := fcrontab.o cl.o subs.o mem.o save.o temp_file.o  log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o filesubs.o
+OBJSDYN := fcrondyn.o subs.o mem.o log.o allow.o read_string.o fcronconf.o filesubs.o
+OBJCONV := convert-fcrontab.o cl.o subs.o mem.o save.o log.o u_list.o env_list.o fcronconf.o filesubs.o
+OBJSIG := fcronsighup.o subs.o mem.o log.o allow.o fcronconf.o filesubs.o
 HEADERSALL := config.h $(SRCDIR)/global.h $(SRCDIR)/cl.h $(SRCDIR)/log.h $(SRCDIR)/subs.h $(SRCDIR)/mem.h $(SRCDIR)/save.h $(SRCDIR)/option.h $(SRCDIR)/dyncom.h
 
 # this is a regular expression :
diff --git a/allow.c b/allow.c
index 7405bb0da26fe651a6234420619d1c7059bdc436..049b4aeadbcb1d80e3530cdef3f98397e461dfcf 100644 (file)
--- a/allow.c
+++ b/allow.c
@@ -56,16 +56,16 @@ in_file(char *str, char *file)
         remove_blanks(start);
 
         if (strcmp(str, start) == 0) {
-            fclose(f);
+            xfclose_check(&f, file);
             return 1;
         }
         if (strcmp(start, "all") == 0) {
-            fclose(f);
+            xfclose_check(&f, file);
             return 2;
         }
     }
 
-    fclose(f);
+    xfclose_check(&f, file);
     /* if execution gets here, string is not in file */
     return 0;
 
@@ -118,7 +118,7 @@ is_allowed(char *user)
         int audit_fd = audit_open();
         audit_log_user_message(audit_fd, AUDIT_USER_START, "fcron deny",
                                NULL, NULL, NULL, 0);
-        close(audit_fd);
+        xclose_check(&audit_fd, "audit");
     }
 #endif
 
diff --git a/conf.c b/conf.c
index 7085270ea4ea466735ccdea9a45cb1c32d18ae05..48f851f40fd470e3633aad06f84e1356d0aab591 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -748,13 +748,13 @@ read_file(const char *file_name, cf_t * cf, int is_system_startup)
         error("file %s is truncated : you should reinstall it with fcrontab",
               file_name);
 
-    fclose(ff);
+    xfclose_check(&ff, file_name);
 
     return OK;
 
  err:
     if (ff != NULL)
-        fclose(ff);
+        xfclose_check(&ff, file_name);
 
     if (cl != NULL && cl->cl_next == NULL) {
         /* line is not yet in the line list of the file : free it */
index 7d846e14e9e5ae922ad85fdf7c3633f56b618d73..1ea5e1bb36a13b7ec4b8b9e3d9b0ec354a0a6712 100644 (file)
@@ -205,7 +205,7 @@ convert_file(char *file_name)
 
     Free_safe(line);
 
-    fclose(f);
+    xfclose(&f);
 
     /* open a temp file in write mode and truncate it */
     strcpy(buf, "tmp_");
diff --git a/fcron.c b/fcron.c
index 59fbab67e10ee2c5fa6fdde90d76e55239a5591f..ca913b82dd9521951c60ff83eda3363de2e94231 100644 (file)
--- a/fcron.c
+++ b/fcron.c
@@ -289,7 +289,7 @@ is_system_startup(void)
     if ((reboot = creat(REBOOT_LOCK, S_IRUSR & S_IWUSR)) < 0)
         error_e("Can't create lock for reboot jobs.");
     else
-        close(reboot);
+       xclose_check(&reboot, REBOOT_LOCK);
 
     /* run @reboot jobs */
     return 1;
@@ -442,28 +442,28 @@ create_spooldir(char *dir)
         die_e("Cannot open dir %s", dir);
 
     if (fstat(dir_fd, &st) != 0) {
-        close(dir_fd);
+        xclose_check(&dir_fd, "spooldir");
         die_e("Cannot fstat %s", dir);
     }
 
     if (!S_ISDIR(st.st_mode)) {
-        close(dir_fd);
+        xclose_check(&dir_fd, "spooldir");
         die("%s exists and is not a directory", dir);
     }
 
     if (fchown(dir_fd, useruid, usergid) != 0) {
-        close(dir_fd);
+        xclose_check(&dir_fd, "spooldir");
         die_e("Cannot fchown dir %s to %s:%s", dir, USERNAME, GROUPNAME);
     }
 
     if (fchmod
         (dir_fd,
          S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP) != 0) {
-        close(dir_fd);
+        xclose_check(&dir_fd, "spooldir");
         die_e("Cannot change dir %s's mode to 770", dir);
     }
 
-    close(dir_fd);
+    xclose_check(&dir_fd, "spooldir");
 
     exit(EXIT_OK);
 
@@ -609,7 +609,7 @@ main(int argc, char **argv)
 #ifndef _HPUX_SOURCE
             ioctl(fd, TIOCNOTTY, 0);
 #endif
-            close(fd);
+            xclose_check(&fd, "/dev/tty");
         }
 
         if (freopen("/dev/null", "w", stdout) == NULL)
@@ -620,6 +620,7 @@ main(int argc, char **argv)
         /* close most other open fds */
         xcloselog();
         for (fd = 3; fd < 250; fd++)
+            /* don't use xclose_check() as we do expect most of them to fail */
             (void)close(fd);
 
         /* finally, create a new session */
index 25479e9d0f871e22575bca178cbc733a9f667d23..c1058969dd5b91767e25fee355d39b80273c0637 100644 (file)
@@ -128,7 +128,7 @@ read_conf(void)
         || st.st_mode & S_IWGRP || st.st_mode & S_IWOTH) {
         error("Conf file (%s) must be owned by root:" GROUPNAME
               " and (no more than) 644 : ignored", fcronconf, GROUPNAME);
-        fclose(f);
+        xfclose_check(&f, fcronconf);
         return;
     }
 
@@ -199,6 +199,6 @@ read_conf(void)
 /*     debug("  sendmail=%s", sendmail); */
     }
 
-    fclose(f);
+    xfclose_check(&f, fcronconf);
 
 }
index fb6bb0c9b216f680e3bb4873be0b07f67178d352..aab4f20a4ae93845791d36ac8db73e6619e0b1df 100644 (file)
@@ -603,7 +603,7 @@ talk_fcron(char *cmd_str, int fd)
         error_e("error in recv()");
 
     if (!existing_connection)
-        close(fd);
+        xclose_check(&fd, "unix socket");
 
     return OK;
 }
@@ -707,7 +707,7 @@ interactive_mode(int fd)
 #endif                          /* HAVE_LIBREADLINE */
 
     if (!existing_connection)
-        close(fd);
+        xclose_check(&fd, "unix socket");
 
     return OK;
 }
index 3c6be2436dfbbb2d5c7cc6ab7b39f764f0d31861..3b79c458b113ea6afec18392b7959bc907238570 100644 (file)
@@ -73,7 +73,7 @@ read_pid(void)
     if ((fp = fopen(pidfile, "r")) != NULL) {
         if (fscanf(fp, "%" ATTR_SIZE_PIDT "d", CAST_PIDT_PTR & pid) < 1)
             error("Unable to read fcron daemon's pid (fscanf(fp,...))");
-        fclose(fp);
+        xfclose_check(&fp, pidfile);
     }
 
     return pid;
@@ -96,6 +96,7 @@ sig_daemon(void)
         char sigfile[PATH_LEN];
         char buf[PATH_LEN];
 
+        sigfile[0] = '\0';
         t = time(NULL);
         tm = localtime(&t);
 
@@ -168,8 +169,8 @@ sig_daemon(void)
 
         sleep(sl);
 
-        fclose(fp);
-        close(fd);
+        xfclose_check(&fp, sigfile);
+        xclose_check(&fd, sigfile);
 
         if (remove(sigfile) < 0)
             error_e("Could not remove %s");
index 10dc5b525d0a9095e86c9276e5a7e773fb6843a6..0f5950816e0a23c59f93c7b2342900622e92a175 100644 (file)
@@ -188,7 +188,7 @@ xexit(int exit_val)
 }
 
 int
-copy_src(int from, char *dest)
+copy_src(int from, const char *dest)
     /* copy src file orig (already opened) to dest */
     /* we first copy the file to a temp file name, and then we rename it,
      * so as to avoid data loss if the filesystem is full. */
@@ -247,7 +247,7 @@ copy_src(int from, char *dest)
             goto exiterr;
         }
 
-    close(to_fd);
+    xclose_check(&to_fd, dest);
     to_fd = -1;
 
     if (rename_as_user(tmp_filename_str, dest, useruid, fcrontab_gid) < 0) {
@@ -260,7 +260,7 @@ copy_src(int from, char *dest)
 
  exiterr:
     if (to_fd != -1)
-        close(to_fd);
+        xclose_check(&to_fd, dest);
     return ERR;
 }
 
@@ -301,7 +301,7 @@ remove_fcrontab(char rm_orig)
     }
     else if (asuid == rootuid && fchown(fd, rootuid, fcrontab_gid) != 0)
         error_e("Could not fchown %s to root", buf);
-    close(fd);
+    xclose_check(&fd, buf);
 
     need_sig = 1;
 
@@ -376,7 +376,7 @@ make_file(char *file, int fd)
 
 
 void
-list_file(char *file)
+list_file(const char *file)
 {
     FILE *f = NULL;
     int c;
@@ -396,19 +396,19 @@ list_file(char *file)
 
     f = fdopen(fd, "r");
     if (f == NULL) {
-        close(fd);
+        xclose_check(&fd, file);
         die_e("User %s could not read file \"%s\"", user, file);
     }
 
     while ((c = getc(f)) != EOF)
         putchar(c);
 
-    fclose(f);
+    xfclose_check(&f, file);
 
 }
 
 void
-edit_file(char *fcron_orig)
+edit_file(const char *fcron_orig)
     /* copy file to a temp file, edit that file, and install it
      * if necessary */
 {
@@ -418,7 +418,7 @@ edit_file(char *fcron_orig)
     int status;
     struct stat st;
     time_t mtime = 0;
-    char *tmp_str;
+    char *tmp_str = NULL;
     FILE *f = NULL, *fi = NULL;
     int file = -1, origfd = -1;
     int c;
@@ -432,7 +432,8 @@ edit_file(char *fcron_orig)
             || strcmp(cureditor, "\0") == 0)
             cureditor = editor;
 
-    file = temp_file(&tmp_str);
+    /* temp_file() dies on error, so tmp_str is always set */
+    file = temp_file(&tmp_str); 
     if ((fi = fdopen(file, "w")) == NULL) {
         error_e("could not fdopen");
         goto exiterr;
@@ -466,8 +467,7 @@ edit_file(char *fcron_orig)
                 goto exiterr;
             }
         }
-        fclose(f);
-        f = NULL;
+        xfclose_check(&f, fcron_orig);
 
         if (ferror(fi))
             error_e("Error while writing new fcrontab to %s");
@@ -496,7 +496,7 @@ edit_file(char *fcron_orig)
         }
 #endif
         /* close the file before the user edits it */
-        close(file);
+        xclose_check(&file, tmp_str);
 
         switch (pid = fork()) {
         case 0:
@@ -618,25 +618,20 @@ edit_file(char *fcron_orig)
     delete_file(user);
 
  end:
-    if (file != -1 && close(file) != 0)
-        error_e("could not close %s", tmp_str);
+    xclose_check(&file, tmp_str);
     if (remove_as_user(tmp_str, useruid, fcrontab_gid) != 0)
         error_e("could not remove %s", tmp_str);
-    free(tmp_str);
+    Free_safe(tmp_str);
     xexit(return_val);
 
  exiterr:
+    xfclose_check(&fi, tmp_str);
+    xclose_check(&file, tmp_str);
     if (remove_as_user(tmp_str, useruid, fcrontab_gid) != 0)
         error_e("could not remove %s", tmp_str);
-    free(tmp_str);
-    if (f != NULL)
-        fclose(f);
-    if (fi != NULL)
-        fclose(fi);
-    if (file != -1)
-        close(file);
+    xfclose_check(&f, fcron_orig);
+    Free_safe(tmp_str);
     xexit(EXIT_ERR);
-
 }
 
 
@@ -700,7 +695,7 @@ reinstall(char *fcron_orig)
 
     close(0);
     dup2(i, 0);
-    close(i);
+    xclose(&i);
 
     xexit(install_stdin());
 
diff --git a/filesubs.c b/filesubs.c
new file mode 100644 (file)
index 0000000..036c227
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * FCRON - periodic command scheduler 
+ *
+ *  Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ *  The GNU General Public License can also be found in the file
+ *  `LICENSE' that comes with the fcron source distribution.
+ */
+
+
+#include "global.h"
+#include "filesubs.h"
+
+/* close() a file, and set the FD to -1.
+ * Returns close()'s return value and leaves errno as is. */
+int
+xclose(int *fd)
+{
+    int retval = -1;
+
+    if (*fd != -1) {
+        retval = close(*fd);
+        *fd = -1;
+    }
+
+    return retval;
+}
+
+/* close() a file, and set the FD to -1. Check for errors and log them.
+ * Returns close()'s return value.
+ * WARNING: do NOT call from log.c to avoid potential infinite loops! */
+int
+xclose_check(int *fd, const char *filedesc)
+{
+    int retval = -1;
+
+    if (*fd != -1) {
+        retval = close(*fd);
+        if (retval != 0) {
+            error_e("Error while closing %s", filedesc);
+        }
+        *fd = -1;
+    }
+
+    return retval;
+}
+
+/* fclose() a file, and set the FILE* to NULL.
+ * Returns fclose()'s return value and leaves errno as is. */
+int
+xfclose(FILE **f)
+{
+    int retval = EOF;
+
+    if (f == NULL) {
+        return retval;
+    }
+
+    if (*f != NULL) {
+        retval = fclose (*f);
+        *f = NULL;
+    }
+
+    return retval;
+}
+
+/* fclose() a file, and set the FILE* to NULL. Check for errors and log them.
+ * Returns fclose()'s return value.
+ * WARNING: do NOT call from log.c to avoid potential infinite loops! */
+int
+xfclose_check(FILE **f, const char *filedesc)
+{
+    int retval = EOF;
+
+    if (f == NULL) {
+        return retval;
+    }
+
+    if (*f != NULL) {
+        retval = fclose (*f);
+        if (retval != 0) {
+            error_e("Error while fclosing %s", filedesc);
+        }
+        *f = NULL;
+    }
+
+    return retval;
+}
+
diff --git a/filesubs.h b/filesubs.h
new file mode 100644 (file)
index 0000000..43e5615
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * FCRON - periodic command scheduler
+ *
+ *  Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  The GNU General Public License can also be found in the file
+ *  `LICENSE' that comes with the fcron source distribution.
+ */
+
+/* filesubs: file related macros and functions.
+ * They are used to make the code safer. */
+
+#ifndef __FILESUBS_H__
+#define __FILESUBS_H__
+
+/* macros */
+
+/* function definitions */
+
+int xclose(int *fd);
+int xclose_check(int *fd, const char *filedesc);
+int xfclose(FILE **f);
+int xfclose_check(FILE **f, const char *filedesc);
+
+#endif                          /* __FILESUBS_H__ */
index e5a8e3362da1bb281317333e34b55d8822b35418..f7c4f8f21ec4e3931201c86668d3ea50653e001f 100644 (file)
@@ -89,13 +89,14 @@ getloadavg(double *result, int n)
 {
     FILE *fp;
     int i;
+    char loadavg_path = PROC "/loadavg";
 
     if (n > 3)
         n = 3;
 
-    if ((fp = fopen(PROC "/loadavg", "r")) == NULL) {
-        error_e("could not open '" PROC "/loadavg'"
-                " (make sure procfs is mounted)");
+    if ((fp = fopen(loadavg_path, "r")) == NULL) {
+        error_e("could not open '%s' (make sure procfs is mounted)",
+                loadavg_path);
         i = -1;
     }
     else {
@@ -106,7 +107,7 @@ getloadavg(double *result, int n)
         }
     }
  end:
-    fclose(fp);
+    xfclose_check(&fp, loadavg_path);
     return (i < 0) ? i : i;
 }
 
index 40be6ce03b1b266c4c568045e6ad79297252e763..8442f109ef89a14347654f5f669d56e327552eb1 100644 (file)
--- a/global.h
+++ b/global.h
@@ -232,6 +232,7 @@ typedef struct job_t {
 #include "log.h"
 /* functions used by fcrontab, fcrondyn, and fcron */
 #include "subs.h"
-
+/* file related helper functions */
+#include "filesubs.h"
 
 #endif                          /* __GLOBAL_H__ */
diff --git a/job.c b/job.c
index 7a5b6b8a32956d8934b84bc67ba9a91e3b8fabd2..c211d82304a76ea1a803c8495f2ee981cc9132bb 100644 (file)
--- a/job.c
+++ b/job.c
@@ -465,10 +465,8 @@ run_job_grand_child_setup_stderr_stdout(cl_t * line, int *pipe_fd)
             die_e("dup2() error");      /* dup2 also clears close-on-exec flag */
         /* we close the pipe_fd[]s : the resources remain, and the pipe will
          * be effectively close when the job stops */
-        if (close(pipe_fd[0]) < 0)
-            error_e("setup_stderr_stdout: could not close(pipe_fd[0])");
-        if (close(pipe_fd[1]) < 0)
-            error_e("setup_stderr_stdout: could not close(pipe_fd[1])");
+        xclose_check(&(pipe_fd[0]), "pipe_fd[0] in setup_stderr_stdout");
+        xclose_check(&(pipe_fd[1]), "pipe_fd[1] in setup_stderr_stdout");
         /* Standard buffering results in unwanted behavior (some messages,
          * at least error from fcron process itself, are lost) */
 #ifdef HAVE_SETLINEBUF
@@ -566,8 +564,7 @@ run_job(struct exe_t *exeent)
                                &curhome, &content_type, &encoding);
 
             /* close unneeded READ fd */
-            if (close(pipe_pid_fd[0]) < 0)
-                error_e("child: could not close(pipe_pid_fd[0])");
+            xclose_check(&(pipe_pid_fd[0]), "child's pipe_pid_fd[0]");
 
             pipe_fd[0] = pipe_fd[1] = -1;
             if (!to_stdout && is_mail(line->cl_option)) {
@@ -600,12 +597,9 @@ run_job(struct exe_t *exeent)
                 error_e("Fork error : could not exec \"%s\"", line->cl_shell);
                 if (write(pipe_pid_fd[1], &pid, sizeof(pid)) < 0)
                     error_e("could not write child pid to pipe_pid_fd[1]");
-                if (pipe_fd[0] != -1 && close(pipe_fd[0]) < 0)
-                    error_e("child: could not close(pipe_fd[0])");
-                if (pipe_fd[1] != -1 && close(pipe_fd[1]) < 0)
-                    error_e("child: could not close(pipe_fd[1])");
-                if (close(pipe_pid_fd[1]) < 0)
-                    error_e("child: could not close(pipe_pid_fd[1])");
+                xclose_check(&(pipe_fd[0]), "child's pipe_fd[0]");
+                xclose_check(&(pipe_fd[1]), "child's pipe_fd[1]");
+                xclose_check(&(pipe_pid_fd[1]), "child's pipe_pid_fd[1]");
                 exit(EXIT_ERR);
                 break;
 
@@ -613,8 +607,7 @@ run_job(struct exe_t *exeent)
                 /* grand child (child of the 2nd fork) */
 
                 /* the grand child does not use this pipe: close remaining fd */
-                if (close(pipe_pid_fd[1]) < 0)
-                    error_e("grand child: could not close(pipe_pid_fd[1])");
+                xclose_check(&(pipe_pid_fd[1]), "grand child's pipe_pid_fd[1]");
 
                 if (!to_stdout)
                     /* note : the following closes the pipe */
@@ -654,8 +647,7 @@ run_job(struct exe_t *exeent)
                 /* child (parent of the 2nd fork) */
 
                 /* close unneeded WRITE pipe and READ pipe */
-                if (pipe_fd[1] != -1 && close(pipe_fd[1]) < 0)
-                    error_e("child: could not close(pipe_fd[1])");
+                xclose_check(&(pipe_fd[1]), "child's pipe_fd[1]");
 
 #ifdef CHECKRUNJOB
                 debug("run_job(): child: pipe_fd[1] and pipe_pid_fd[0] closed"
@@ -696,8 +688,7 @@ run_job(struct exe_t *exeent)
                         if (fputs(mailbuf, mailf) < 0)
                             warn("fputs() failed to write to mail file for job %s (pid %d)", line->cl_shell, pid);
                     /* (closes also pipe_fd[0]): */
-                    if (fclose(pipef) != 0)
-                        error_e("child: Could not fclose(pipef)");
+                    xfclose_check(&pipef, "child's pipef");
                 }
 
                 /* FIXME : FOLLOWING HACK USELESS ? */
@@ -714,8 +705,7 @@ run_job(struct exe_t *exeent)
 #ifdef CHECKRUNJOB
                 debug("run_job(): child: closing pipe with parent");
 #endif                          /* CHECKRUNJOB */
-                if (close(pipe_pid_fd[1]) < 0)
-                    error_e("child: could not close(pipe_pid_fd[1])");
+                xclose_check(&(pipe_pid_fd[1]), "child's pipe_pid_fd[1]");
 
                 /* we use a while because of a possible interruption by a signal */
                 while ((pid = wait3(&status, 0, NULL)) > 0) {
@@ -737,8 +727,7 @@ run_job(struct exe_t *exeent)
         /* parent */
 
         /* close unneeded WRITE fd */
-        if (close(pipe_pid_fd[1]) < 0)
-            error_e("parent: could not close(pipe_pid_fd[1])");
+        xclose_check(&(pipe_pid_fd[1]), "parent's pipe_pid_fd[1]");
 
         exeent->e_ctrl_pid = pid;
 
@@ -760,8 +749,7 @@ run_job(struct exe_t *exeent)
             exeent->e_job_pid = -1;
             break;
         }
-        if (close(pipe_pid_fd[0]) < 0)
-            error_e("parent: could not close(pipe_pid_fd[0])");
+        xclose_check(&(pipe_pid_fd[0]), "parent's pipe_pid_fd[0]");
 
 #ifdef CHECKRUNJOB
         debug
@@ -854,8 +842,7 @@ end_job(cl_t * line, int status, FILE * mailf, short mailpos,
     }
 
     /* if mail is sent, execution doesn't get here : close /dev/null */
-    if (mailf != NULL && fclose(mailf) != 0)
-        die_e("Can't close file mailf");
+    xfclose_check(&mailf, "Can't close file mailf");
 
     exit(0);
 
diff --git a/log.c b/log.c
index a2f0b2ef95daa639d7337a5268bac000488418dc..59e0e933189f866f6db85f6fcb92a4c8b6354a1e 100644 (file)
--- a/log.c
+++ b/log.c
@@ -44,7 +44,7 @@ char *logfile_path = NULL;
 
 char *make_msg(const char *append, char *fmt, va_list args);
 void log_syslog_str(int priority, char *msg);
-void log_file_str(FILE * logfile, int priority, char *msg);
+void log_file_str(int priority, char *msg);
 void log_console_str(int priority, char *msg);
 void log_fd_str(int fd, char *msg);
 static void print_line_prefix(FILE * logfile, int priority);
@@ -64,8 +64,8 @@ static FILE *logfile = NULL;
  * or take no action if logging is suppressed.
  * This function will be called automatically if you attempt to log something,
  * however you may have to call it explicitely as it needs to run before the
- * program becomes a daemon so as it can print any errors on the console.
- */
+ * program becomes a daemon so as it can print an error on the console
+ * if it can't open the logs correctly. */
 void
 xopenlog(void)
 {
@@ -110,7 +110,8 @@ xcloselog()
 
     // check whether we need to close syslog, or a file.
     if (logfile != NULL) {
-        if (fclose(logfile) != 0) {
+        /* we must NOT use xfclose_check() in log.c to avoid infinite loops */
+        if (xfclose(&logfile) != 0) {
             int saved_errno = errno;
 
             syslog(COMPLAIN_LEVEL, "Error while closing log file '%s': %s",
@@ -169,7 +170,7 @@ log_syslog_str(int priority, char *msg)
 
 /* log a simple string to a log file if needed */
 void
-log_file_str(FILE * logfile, int priority, char *msg)
+log_file_str(int priority, char *msg)
 {
     xopenlog();
 
@@ -215,7 +216,7 @@ xlog(int priority, int fd, char *fmt, va_list args)
         return;
 
     log_syslog_str(priority, msg);
-    log_file_str(logfile, priority, msg);
+    log_file_str(priority, msg);
     log_console_str(priority, msg);
     log_fd_str(fd, msg);
 
@@ -236,7 +237,7 @@ xlog_e(int priority, int fd, char *fmt, va_list args)
         return;
 
     log_syslog_str(priority, msg);
-    log_file_str(logfile, priority, msg);
+    log_file_str(priority, msg);
     log_console_str(priority, msg);
     log_fd_str(fd, msg);
 
diff --git a/save.c b/save.c
index 5ce201fda63c9e35b90ac9bd4059ac1e9b3744b1..a61c36204dd791e5c3be5441dec79190361d3f04 100644 (file)
--- a/save.c
+++ b/save.c
@@ -338,22 +338,22 @@ save_one_file(cf_t * file, char *filename, uid_t own_uid, gid_t own_gid,
     if (fchown(fd, own_uid, own_gid) != 0) {
         error_e("Could not fchown %s to uid:%d gid:%d", filename, own_uid,
                 own_gid);
-        if (close(fd) < 0)
-            error_e("save_one_file(%s): could not close(fd)", filename);
+        if (xclose(&fd) < 0)
+            error_e("save_one_file(%s): could not xclose(fd)", filename);
         remove_as_user(filename, own_uid, own_gid);
         return ERR;
     }
 
     /* save file : */
     if (write_file_to_disk(fd, file, save_date) == ERR) {
-        if (close(fd) < 0)
-            error_e("save_one_file(%s): could not close(fd)", filename);
+        if (xclose(&fd) < 0)
+            error_e("save_one_file(%s): could not xclose(fd)", filename);
         remove_as_user(filename, own_uid, own_gid);
         return ERR;
     }
 
-    if (close(fd) < 0)
-        error_e("save_one_file(%s): could not close(fd)", filename);
+    if (xclose(&fd) < 0)
+        error_e("save_one_file(%s): could not xclose(fd)", filename);
 
     return OK;
 }
index 3fdb68db522513e61f6342faf31880b45e4df635..78dbeaaf544f99c8dd8b2e5eeae37e6e1c83ea18 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -870,7 +870,7 @@ remove_connection(struct fcrondyn_cl **client, struct fcrondyn_cl *prev_client)
 and make client points to the next entry */
 {
     shutdown((*client)->fcl_sock_fd, SHUT_RDWR);
-    close((*client)->fcl_sock_fd);
+    xclose_check(&((*client)->fcl_sock_fd), "client fd");
     remove_from_select_set((*client)->fcl_sock_fd, &master_set, &set_max_fd);
     debug("connection closed : fd : %d", (*client)->fcl_sock_fd);
     if (prev_client == NULL) {
@@ -920,7 +920,7 @@ check_socket(int num)
                 error_e
                     ("Could not set fd attribute O_NONBLOCK : connection rejected.");
                 shutdown(fd, SHUT_RDWR);
-                close(fd);
+                xclose_check(&fd, "client fd");
             }
             else {
                 Alloc(client, fcrondyn_cl);
@@ -1017,13 +1017,13 @@ close_socket(void)
 
     if (listen_fd) {
         shutdown(listen_fd, SHUT_RDWR);
-        close(listen_fd);
+        xclose_check(&listen_fd, "listening fd");
         unlink(fifofile);
 
         client = fcrondyn_cl_base;
         while (client != NULL) {
             shutdown(client->fcl_sock_fd, SHUT_RDWR);
-            close(client->fcl_sock_fd);
+            xclose_check(&(client->fcl_sock_fd), "client fd");
 
             client_buf = client->fcl_next;
             Free_safe(client);
diff --git a/subs.c b/subs.c
index b5a29be9bf955d8ee721654cd8c1b5f11e644aa2..512dc14cf10c1391836933a251b9644ee506beee 100644 (file)
--- a/subs.c
+++ b/subs.c
@@ -130,15 +130,15 @@ open_as_user(const char *pathname, uid_t openuid, gid_t opengid, int flags, ...)
         if (fstat(fd, &s) < 0) {
             saved_errno = errno;
             error_e("open_as_user(): could not fstat %s", pathname);
-            if (close(fd) < 0)
-                error_e("open_as_user: could not close() %s", pathname);
+            if (xclose(&fd) < 0)
+                error_e("open_as_user: could not xclose() %s", pathname);
             fd = -1;
         }
 
         if (!S_ISREG(s.st_mode) || s.st_nlink != 1) {
             error_e("open_as_user(): file %s is not a regular file", pathname);
-            if (close(fd) < 0)
-                error_e("open_as_user: could not close() %s", pathname);
+            if (xclose(&fd) < 0)
+                error_e("open_as_user: could not xclose() %s", pathname);
             saved_errno = 0;
             fd = -1;
         }
@@ -254,8 +254,8 @@ open_as_user(const char *pathname, uid_t openuid, gid_t opengid, int flags, ...)
     return fd;
 
  err:
-    if (fd >= 0 && close(fd) < 0)
-        error_e("open_as_user: could not close() %s", pathname);
+    if (fd >= 0 && xclose(&fd) < 0)
+        error_e("open_as_user: could not xclose() %s", pathname);
     errno = saved_errno;
     return -1;
 }