From 4968d14544e0dc1a0519d3bbdefbcf8027f5c3ab Mon Sep 17 00:00:00 2001 From: James Youngman Date: Tue, 30 Mar 2010 20:34:13 +0100 Subject: [PATCH] Support O_CREAT in open_cloexec. To: address@hidden * lib/fdleak.c: Include and "cloexec.h". (open_cloexec): Support O_CREAT. Use O_CLOEXEC if it is available. (O_CLOEXEC): #define to 0 if not already #defined. * import-gnulib.config (modules): Import modules open (for PROMOTED_MODE_T) and stdbool (for 'true'). * lib/fdleak.h: Update prototype of open_cloexec to allow mode to be passed. Signed-off-by: James Youngman --- ChangeLog | 19 +++++++++++++++---- configure.ac | 3 +++ import-gnulib.config | 2 ++ lib/fdleak.c | 38 ++++++++++++++++++++++++-------------- lib/fdleak.h | 2 +- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38498ba..7f27bb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,26 @@ 2010-03-30 James Youngman + Support O_CREAT in open_cloexec. + * lib/fdleak.c: Include and "cloexec.h". + (open_cloexec): Support O_CREAT. Use O_CLOEXEC if it is available. + (O_CLOEXEC): #define to 0 if not already #defined. + * lib/fdleak.h: Update prototype of open_cloexec to allow mode to + be passed. + + * import-gnulib.config (modules): Import modules open (for + PROMOTED_MODE_T) and stdbool (for 'true'). + + Tolerate the absence of getrusage. * configure.ac: Check for and the getrusage function. * lib/fdleak.c: Don't #include if we don't have it. (get_max_fd): If neither /proc/self/fd not getrusage is available, return _POSIX_OPEN_MAX. - (remember_non_cloexec_fds): Also check for leaks in file - descriptors 0, 1, 2, just in case the caller closed them. + + Detect leaks in file descriptors 0, 1, 2. + * lib/fdleak.c: (remember_non_cloexec_fds): Also check for leaks + in file descriptors 0, 1, 2, just in case the caller closed them. (find_first_leaked_fd): Likewise. - (open_cloexec): Make sure we are not creating a file (for some odd - system where O_CREAT is 0). 2009-08-16 James Youngman diff --git a/configure.ac b/configure.ac index 7647934..1de0328 100644 --- a/configure.ac +++ b/configure.ac @@ -145,6 +145,9 @@ AC_TYPE_MODE_T AC_STRUCT_ST_BLOCKS AC_CHECK_MEMBERS([struct stat.st_rdev]) +dnl fdleak.c uses PROMOTED_MODE_T, which is defined by gnulib. +gl_PROMOTED_TYPE_MODE_T + AC_MSG_CHECKING([whether we should use struct dirent.d_type, if available]) if test x$ac_cv_d_type = xno; then AC_MSG_RESULT([no]) diff --git a/import-gnulib.config b/import-gnulib.config index 833a9e6..b8288f1 100644 --- a/import-gnulib.config +++ b/import-gnulib.config @@ -60,6 +60,7 @@ mbsstr mktime modechange mountlist +open pathmax progname quotearg @@ -70,6 +71,7 @@ savedir selinux-at stat-macros stat-time +stdbool stdint stpcpy strcasestr diff --git a/lib/fdleak.c b/lib/fdleak.c index 992ecfd..243c2ed 100644 --- a/lib/fdleak.c +++ b/lib/fdleak.c @@ -25,10 +25,13 @@ #include #include #include +#include #include +#include #include "dirent-safer.h" #include "extendbuf.h" +#include "cloexec.h" #include "fdleak.h" #include "error.h" @@ -54,6 +57,9 @@ static int *non_cloexec_fds; static size_t num_cloexec_fds; +#if !defined(O_CLOEXEC) +#define O_CLOEXEC 0 +#endif /* Determine the value of the largest open fd, on systems that * offer /proc/self/fd. */ @@ -296,25 +302,29 @@ find_first_leaked_fd (const int* prev_non_cloexec_fds, size_t n) } int -open_cloexec (const char *path, int flags) +open_cloexec (const char *path, int flags, ...) { int fd; + mode_t mode = 0; - /* Make sure we don't accidentally create a file, since we - * aren't passing a mode argument. */ - assert ((flags & O_CREAT) == 0); + if (flags & O_CREAT) + { + /* this code is copied from gnulib's open-safer.c. */ + va_list ap; + va_start (ap, flags); - fd = open (path, flags -#if defined O_CLOEXEC - |O_CLOEXEC -#endif - ); - if (fd < 0) - return fd; + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (ap, PROMOTED_MODE_T); -#if !defined O_CLOEXEC - make_fd_cloexec (fd); -#endif + va_end (ap); + } + + fd = open (path, flags|O_CLOEXEC, mode); + if ((fd >= 0) && !O_CLOEXEC) + { + set_cloexec_flag (fd, true); + } return fd; } diff --git a/lib/fdleak.h b/lib/fdleak.h index 47b01cb..0bb6d51 100644 --- a/lib/fdleak.h +++ b/lib/fdleak.h @@ -19,5 +19,5 @@ void remember_non_cloexec_fds (void); void forget_non_cloexec_fds (void); void complain_about_leaky_fds (void); -int open_cloexec(const char *path, int flags); +int open_cloexec(const char *path, int flags, ...); -- 1.5.6.5