From 173359dbe40ac4381088060b0f26e66529fa0f29 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 5 Dec 2009 06:19:01 -0700 Subject: [PATCH] test-dup2: enhance test Ensure that dup2(cloexec_fd, target) returns an inheritable fd. * modules/dup2-tests (Depends-on): Add cloexec. * tests/test-dup2.c (main): Enhance test. Signed-off-by: Eric Blake --- ChangeLog | 4 ++++ modules/dup2-tests | 1 + tests/test-dup2.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0c2abd2b..0c1c87070 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-12-05 Eric Blake + test-dup2: enhance test + * modules/dup2-tests (Depends-on): Add cloexec. + * tests/test-dup2.c (main): Enhance test. + cloexec: add dup_cloexec * lib/cloexec.h (dup_cloexec): New prototype. Add copyright header and comments. diff --git a/modules/dup2-tests b/modules/dup2-tests index f11f13814..0fb913a58 100644 --- a/modules/dup2-tests +++ b/modules/dup2-tests @@ -2,6 +2,7 @@ Files: tests/test-dup2.c Depends-on: +cloexec open configure.ac: diff --git a/tests/test-dup2.c b/tests/test-dup2.c index 32c354d0b..005160fc6 100644 --- a/tests/test-dup2.c +++ b/tests/test-dup2.c @@ -25,6 +25,8 @@ #include #include +#include "cloexec.h" + #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* Get declarations of the Win32 API functions. */ # define WIN32_LEAN_AND_MEAN @@ -32,15 +34,15 @@ #endif #define ASSERT(expr) \ - do \ - { \ - if (!(expr)) \ - { \ + do \ + { \ + if (!(expr)) \ + { \ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ - fflush (stderr); \ - abort (); \ - } \ - } \ + fflush (stderr); \ + abort (); \ + } \ + } \ while (0) /* Return non-zero if FD is open. */ @@ -60,6 +62,28 @@ is_open (int fd) #endif } +/* Return non-zero if FD is open and inheritable across exec/spawn. */ +static int +is_inheritable (int fd) +{ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* On Win32, the initial state of unassigned standard file + descriptors is that they are open but point to an + INVALID_HANDLE_VALUE, and there is no fcntl. */ + HANDLE h = (HANDLE) _get_osfhandle (fd); + DWORD flags; + if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0) + return 0; + return (flags & HANDLE_FLAG_INHERIT) != 0; +#else +# ifndef F_GETFD +# error Please port fcntl to your platform +# endif + int i = fcntl (fd, F_GETFD); + return 0 <= i && (i & FD_CLOEXEC) == 0; +#endif +} + int main (void) { @@ -125,8 +149,18 @@ main (void) ASSERT (read (fd, buffer, 1) == 1); ASSERT (*buffer == '2'); + /* Any new fd created by dup2 must not be cloexec. */ + ASSERT (close (fd + 2) == 0); + ASSERT (dup_cloexec (fd) == fd + 1); + ASSERT (!is_inheritable (fd + 1)); + ASSERT (dup2 (fd + 1, fd + 1) == fd + 1); + ASSERT (!is_inheritable (fd + 1)); + ASSERT (dup2 (fd + 1, fd + 2) == fd + 2); + ASSERT (is_inheritable (fd + 2)); + /* Clean up. */ ASSERT (close (fd + 2) == 0); + ASSERT (close (fd + 1) == 0); ASSERT (close (fd) == 0); ASSERT (unlink (file) == 0); -- 2.11.0