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