From e7ec1f90db08384cc6acc457b90dd24bd0b2425c Mon Sep 17 00:00:00 2001 From: Thibault Godouet Date: Sun, 13 Jan 2013 17:31:17 +0000 Subject: [PATCH] Fixed bug in logging to a file and made file closure more robust - 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 --- Makefile.in | 10 ++--- allow.c | 8 ++-- conf.c | 4 +- convert-fcrontab.c | 2 +- fcron.c | 15 ++++--- fcronconf.c | 4 +- fcrondyn.c | 4 +- fcronsighup.c | 7 +-- fcrontab.c | 45 +++++++++----------- filesubs.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ filesubs.h | 39 +++++++++++++++++ getloadavg.c | 9 ++-- global.h | 3 +- job.c | 39 ++++++----------- log.c | 15 ++++--- save.c | 12 +++--- socket.c | 8 ++-- subs.c | 12 +++--- 18 files changed, 234 insertions(+), 105 deletions(-) create mode 100644 filesubs.c create mode 100644 filesubs.h diff --git a/Makefile.in b/Makefile.in index 8a59dda..3936894 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 7405bb0..049b4ae 100644 --- 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 7085270..48f851f 100644 --- 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 */ diff --git a/convert-fcrontab.c b/convert-fcrontab.c index 7d846e1..1ea5e1b 100644 --- a/convert-fcrontab.c +++ b/convert-fcrontab.c @@ -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 59fbab6..ca913b8 100644 --- 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 */ diff --git a/fcronconf.c b/fcronconf.c index 25479e9..c105896 100644 --- a/fcronconf.c +++ b/fcronconf.c @@ -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); } diff --git a/fcrondyn.c b/fcrondyn.c index fb6bb0c..aab4f20 100644 --- a/fcrondyn.c +++ b/fcrondyn.c @@ -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; } diff --git a/fcronsighup.c b/fcronsighup.c index 3c6be24..3b79c45 100644 --- a/fcronsighup.c +++ b/fcronsighup.c @@ -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"); diff --git a/fcrontab.c b/fcrontab.c index 10dc5b5..0f59508 100644 --- a/fcrontab.c +++ b/fcrontab.c @@ -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 index 0000000..036c227 --- /dev/null +++ b/filesubs.c @@ -0,0 +1,103 @@ +/* + * FCRON - periodic command scheduler + * + * Copyright 2000-2012 Thibault Godouet + * + * 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 index 0000000..43e5615 --- /dev/null +++ b/filesubs.h @@ -0,0 +1,39 @@ +/* + * FCRON - periodic command scheduler + * + * Copyright 2000-2012 Thibault Godouet + * + * 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__ */ diff --git a/getloadavg.c b/getloadavg.c index e5a8e33..f7c4f8f 100644 --- a/getloadavg.c +++ b/getloadavg.c @@ -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; } diff --git a/global.h b/global.h index 40be6ce..8442f10 100644 --- 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 7a5b6b8..c211d82 100644 --- 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 a2f0b2e..59e0e93 100644 --- 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 5ce201f..a61c362 100644 --- 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; } diff --git a/socket.c b/socket.c index 3fdb68d..78dbeaa 100644 --- 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 b5a29be..512dc14 100644 --- 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; } -- 2.47.3