bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: fix mkostemp, add pipe2-safer


From: Eric Blake
Subject: Re: fix mkostemp, add pipe2-safer
Date: Mon, 07 Dec 2009 22:10:53 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Bruno Haible on 12/6/2009 5:18 PM:
>   - The code accesses an undefined variable 'result'.

You caught one, but missed the other.  I noticed some other things while
fixing it.  Pushing these:

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAksd390ACgkQ84KuGfSFAYCczwCgob08TPrWRDlidwiZsXokK6Fj
DFkAn2Ygm8In0/BAn+fGkHnrpEjTjWIM
=yWmr
-----END PGP SIGNATURE-----
From a1afba1b2122388e9a120b6a1f011367e6db1518 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Mon, 7 Dec 2009 10:17:07 -0700
Subject: [PATCH 1/2] unistd-safer: add unit test

Add more unit tests.  Meanwhile, fix compilation error on mingw when
testing unistd-safer and fchdir together; and avoid gcc warning on
platforms without setmode.

* modules/unistd-safer-tests: New file.
* tests/test-dup-safer.c: Likewise.
* tests/test-cloexec.c (setmode): Avoid compiler warning.
* tests/test-dup2.c (setmode): Likewise.
* lib/cloexec.c (dup_cloexec): Fix mingw compile error.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog                  |    7 ++
 lib/cloexec.c              |    2 +-
 modules/unistd-safer-tests |   13 +++
 tests/test-cloexec.c       |    3 +-
 tests/test-dup-safer.c     |  186 ++++++++++++++++++++++++++++++++++++++++++++
 tests/test-dup2.c          |    3 +-
 6 files changed, 211 insertions(+), 3 deletions(-)
 create mode 100644 modules/unistd-safer-tests
 create mode 100644 tests/test-dup-safer.c

diff --git a/ChangeLog b/ChangeLog
index 3cf1bdb..73e6faa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2009-12-07  Eric Blake  <address@hidden>

+       unistd-safer: add unit test
+       * modules/unistd-safer-tests: New file.
+       * tests/test-dup-safer.c: Likewise.
+       * tests/test-cloexec.c (setmode): Avoid compiler warning.
+       * tests/test-dup2.c (setmode): Likewise.
+       * lib/cloexec.c (dup_cloexec): Fix mingw compile error.
+
        cloexec: preserve text vs. binary across dup_cloexec
        * lib/cloexec.c (dup_cloexec) [W32]: Query and use translation
        mode.
diff --git a/lib/cloexec.c b/lib/cloexec.c
index 57e0be5..18985cb 100644
--- a/lib/cloexec.c
+++ b/lib/cloexec.c
@@ -128,7 +128,7 @@ dup_cloexec (int fd)

 #  if REPLACE_FCHDIR
   if (0 <= nfd)
-    result = _gl_register_dup (fd, nfd);
+    nfd = _gl_register_dup (fd, nfd);
 #  endif
   return nfd;

diff --git a/modules/unistd-safer-tests b/modules/unistd-safer-tests
new file mode 100644
index 0000000..17b17a0
--- /dev/null
+++ b/modules/unistd-safer-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-dup-safer.c
+
+Depends-on:
+binary-io
+cloexec
+stdbool
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-dup-safer
+check_PROGRAMS += test-dup-safer
diff --git a/tests/test-cloexec.c b/tests/test-cloexec.c
index a29d1be..1f43014 100644
--- a/tests/test-cloexec.c
+++ b/tests/test-cloexec.c
@@ -69,7 +69,8 @@ is_inheritable (int fd)
 }

 #if !O_BINARY
-# define setmode(f,m) 0
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
 #endif

 /* Return non-zero if FD is open in the given MODE, which is either
diff --git a/tests/test-dup-safer.c b/tests/test-dup-safer.c
new file mode 100644
index 0000000..24cc9e5
--- /dev/null
+++ b/tests/test-dup-safer.c
@@ -0,0 +1,186 @@
+/* Test that dup_safer leaves standard fds alone.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake <address@hidden>, 2009.  */
+
+#include <config.h>
+
+#include "unistd--.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "binary-io.h"
+#include "cloexec.h"
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
+
+/* This test intentionally closes stderr.  So, we arrange to have fd 10
+   (outside the range of interesting fd's during the test) set up to
+   duplicate the original stderr.  */
+
+#define BACKUP_STDERR_FILENO 10
+static FILE *myerr;
+
+#define ASSERT(expr) \
+  do                                                                         \
+    {                                                                        \
+      if (!(expr))                                                           \
+        {                                                                    \
+          fprintf (myerr, "%s:%d: assertion failed\n", __FILE__, __LINE__);  \
+          fflush (myerr);                                                    \
+          abort ();                                                          \
+        }                                                                    \
+    }                                                                        \
+  while (0)
+
+/* Return true if FD is open.  */
+static bool
+is_open (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.  */
+  return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+#  error Please port fcntl to your platform
+# endif
+  return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+/* Return true if FD is open and inheritable across exec/spawn.  */
+static bool
+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
+}
+
+/* Return true if FD is open in the given MODE, which is either
+   O_TEXT or O_BINARY.  */
+static bool
+is_mode (int fd, int mode)
+{
+  int value = setmode (fd, O_BINARY);
+  setmode (fd, value);
+  return mode == value;
+}
+
+#define witness "test-dup-safer.txt"
+
+int
+main (void)
+{
+  int i;
+  int fd;
+
+  /* We close fd 2 later, so save it in fd 10.  */
+  if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
+      || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
+    return 2;
+
+  /* Create file for later checks.  */
+  fd = creat (witness, 0600);
+  ASSERT (STDERR_FILENO < fd);
+
+  /* Four iterations, with progressively more standard descriptors
+     closed.  */
+  for (i = -1; i <= STDERR_FILENO; i++)
+    {
+      if (0 <= i)
+        ASSERT (close (i) == 0);
+
+      /* Detect errors.  */
+      errno = 0;
+      ASSERT (dup (-1) == -1);
+      ASSERT (errno == EBADF);
+      errno = 0;
+      ASSERT (dup (10000000) == -1);
+      ASSERT (errno == EBADF);
+      close (fd + 1);
+      errno = 0;
+      ASSERT (dup (fd + 1) == -1);
+      ASSERT (errno == EBADF);
+
+      /* Preserve text vs. binary.  */
+      setmode (fd, O_BINARY);
+      ASSERT (dup (fd) == fd + 1);
+      ASSERT (is_open (fd + 1));
+      ASSERT (is_inheritable (fd + 1));
+      ASSERT (is_mode (fd + 1, O_BINARY));
+
+      ASSERT (close (fd + 1) == 0);
+      setmode (fd, O_TEXT);
+      ASSERT (dup (fd) == fd + 1);
+      ASSERT (is_open (fd + 1));
+      ASSERT (is_inheritable (fd + 1));
+      ASSERT (is_mode (fd + 1, O_TEXT));
+
+      /* Create cloexec copy.  */
+      ASSERT (close (fd + 1) == 0);
+      ASSERT (fd_safer_flag (dup_cloexec (fd), O_CLOEXEC) == fd + 1);
+      ASSERT (set_cloexec_flag (fd + 1, true) == 0);
+      ASSERT (is_open (fd + 1));
+      ASSERT (!is_inheritable (fd + 1));
+      ASSERT (close (fd) == 0);
+
+      /* dup always creates inheritable copies.  Also, check that
+         earliest slot past std fds is used.  */
+      ASSERT (dup (fd + 1) == fd);
+      ASSERT (is_open (fd));
+      ASSERT (is_inheritable (fd));
+      ASSERT (close (fd + 1) == 0);
+    }
+
+  /* Cleanup.  */
+  ASSERT (close (fd) == 0);
+  ASSERT (unlink (witness) == 0);
+
+  return 0;
+}
diff --git a/tests/test-dup2.c b/tests/test-dup2.c
index e6d3c62..b22d1e6 100644
--- a/tests/test-dup2.c
+++ b/tests/test-dup2.c
@@ -86,7 +86,8 @@ is_inheritable (int fd)
 }

 #if !O_BINARY
-# define setmode(f,m) 0
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
 #endif

 /* Return non-zero if FD is open in the given MODE, which is either
-- 
1.6.5.rc1


From 67ac31ed5b8a602032d034bd91022ba329e6485f Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Mon, 7 Dec 2009 17:15:07 -0700
Subject: [PATCH 2/2] unlink: fix m4 detection

The m4 test failed under -Werror due to implicit declaration.

* m4/unlink.m4 (gl_FUNC_UNLINK): Include correct header.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog    |    3 +++
 m4/unlink.m4 |    4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 73e6faa..7b78dca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2009-12-07  Eric Blake  <address@hidden>

+       unlink: fix m4 detection
+       * m4/unlink.m4 (gl_FUNC_UNLINK): Include correct header.
+
        unistd-safer: add unit test
        * modules/unistd-safer-tests: New file.
        * tests/test-dup-safer.c: Likewise.
diff --git a/m4/unlink.m4 b/m4/unlink.m4
index bed2466..f89261c 100644
--- a/m4/unlink.m4
+++ b/m4/unlink.m4
@@ -1,4 +1,4 @@
-# unlink.m4 serial 2
+# unlink.m4 serial 3
 dnl Copyright (C) 2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,7 +18,7 @@ AC_DEFUN([gl_FUNC_UNLINK],
      fi
      AC_RUN_IFELSE(
        [AC_LANG_PROGRAM(
-         [[#include <stdio.h>
+         [[#include <unistd.h>
            #include <errno.h>
 ]], [[if (!unlink ("conftest.file/") || errno != ENOTDIR) return 1;
 #if HAVE_LSTAT
-- 
1.6.5.rc1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]