Mercurial > hg > octave-jordi > gnulib-hg
changeset 11937:ded3ad24a7f4
openat-safer: new module
* modules/openat-safer: New file.
* lib/openat-safer.c: Likewise.
* m4/fcntl-safer.m4 (gl_OPENAT_SAFER): New macro.
* lib/fcntl-safer.h (openat_safer): Declare.
* lib/fcntl--.h (openat): Override.
* MODULES.html.sh (File descriptor based I/O): Mention it.
* lib/openat.h: Add double-inclusion guards.
* lib/openat.c (includes): Only include "fcntl-safer.h", not
"fcntl--.h", so we can implement openat.
* modules/openat-safer-tests: New test.
* tests/test-openat-safer.c: New file.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Wed, 02 Sep 2009 06:07:54 -0600 |
parents | a126d5b22410 |
children | 7cbcde229d97 |
files | ChangeLog MODULES.html.sh lib/fcntl--.h lib/fcntl-safer.h lib/openat-safer.c lib/openat.c lib/openat.h m4/fcntl-safer.m4 modules/openat-safer modules/openat-safer-tests tests/test-openat-safer.c |
diffstat | 11 files changed, 253 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2009-09-02 Eric Blake <ebb9@byu.net> + openat-safer: new module + * modules/openat-safer: New file. + * lib/openat-safer.c: Likewise. + * m4/fcntl-safer.m4 (gl_OPENAT_SAFER): New macro. + * lib/fcntl-safer.h (openat_safer): Declare. + * lib/fcntl--.h (openat): Override. + * MODULES.html.sh (File descriptor based I/O): Mention it. + * lib/openat.h: Add double-inclusion guards. + * lib/openat.c (includes): Only include "fcntl-safer.h", not + "fcntl--.h", so we can implement openat. + * modules/openat-safer-tests: New test. + * tests/test-openat-safer.c: New file. + dirent-safer: new module * modules/dirent-safer: New file. * lib/dirent--.h: Likewise.
--- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2509,6 +2509,7 @@ func_begin_table func_module fcntl-safer + func_module openat-safer func_module safe-read func_module safe-write func_module full-read
--- a/lib/fcntl--.h +++ b/lib/fcntl--.h @@ -1,6 +1,6 @@ /* Like fcntl.h, but redefine some names to avoid glitches. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 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 @@ -25,3 +25,9 @@ #undef creat #define creat creat_safer + +#if GNULIB_OPENAT_SAFER +# include "openat.h" /* FIXME - <fcntl.h> should be sufficient. */ +# undef openat +# define openat openat_safer +#endif
--- a/lib/fcntl-safer.h +++ b/lib/fcntl-safer.h @@ -1,6 +1,6 @@ /* Invoke fcntl-like functions, but avoid some glitches. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 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 @@ -21,3 +21,7 @@ int open_safer (char const *, int, ...); int creat_safer (char const *, mode_t); + +#if GNULIB_OPENAT_SAFER +int openat_safer (int, char const *, int, ...); +#endif
new file mode 100644 --- /dev/null +++ b/lib/openat-safer.c @@ -0,0 +1,47 @@ +/* Invoke openat, but avoid some glitches. + + Copyright (C) 2005, 2006, 2008-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 Paul Eggert for open, ported by Eric Blake for openat. */ + +#include <config.h> + +#include "fcntl-safer.h" + +#include <fcntl.h> +#include "openat.h" /* FIXME - <fcntl.h> should be sufficient. */ +#include <stdarg.h> +#include "unistd-safer.h" + +int +openat_safer (int fd, char const *file, int flags, ...) +{ + mode_t mode = 0; + + if (flags & O_CREAT) + { + va_list ap; + va_start (ap, flags); + + /* 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); + + va_end (ap); + } + + return fd_safer (openat (fd, file, flags, mode)); +}
--- a/lib/openat.c +++ b/lib/openat.c @@ -25,10 +25,16 @@ #include <sys/stat.h> #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -#include "fcntl--.h" #include "openat-priv.h" #include "save-cwd.h" +/* We can't use "fcntl--.h", so that openat_safer does not interfere. */ +#if GNULIB_FCNTL_SAFER +# include "fcntl-safer.h" +# undef open +# define open open_safer +#endif + /* Replacement for Solaris' openat function. <http://www.google.com/search?q=openat+site:docs.sun.com> First, try to simulate it via open ("/proc/self/fd/FD/FILE").
--- a/lib/openat.h +++ b/lib/openat.h @@ -16,6 +16,9 @@ /* written by Jim Meyering */ +#ifndef _GL_HEADER_OPENAT +#define _GL_HEADER_OPENAT + #include <fcntl.h> #include <sys/types.h> @@ -120,3 +123,5 @@ { return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); } + +#endif /* _GL_HEADER_OPENAT */
--- a/m4/fcntl-safer.m4 +++ b/m4/fcntl-safer.m4 @@ -1,4 +1,4 @@ -#serial 6 +#serial 7 dnl Copyright (C) 2005-2007, 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, @@ -11,3 +11,9 @@ # Prerequisites of lib/open-safer.c. AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) ]) + +AC_DEFUN([gl_OPENAT_SAFER], +[ + AC_REQUIRE([gl_FCNTL_SAFER]) + AC_LIBOBJ([openat-safer]) +])
new file mode 100644 --- /dev/null +++ b/modules/openat-safer @@ -0,0 +1,28 @@ +Description: +openat function that avoids clobbering std{in,out,err}. + +Files: +lib/fcntl--.h +lib/fcntl-safer.h +lib/openat-safer.c +m4/fcntl-safer.m4 + +Depends-on: +fcntl-safer +openat +unistd-safer + +configure.ac: +gl_OPENAT_SAFER +gl_MODULE_INDICATOR([openat-safer]) + +Makefile.am: + +Include: +"fcntl-safer.h" + +License: +GPL + +Maintainer: +Eric Blake
new file mode 100644 --- /dev/null +++ b/modules/openat-safer-tests @@ -0,0 +1,11 @@ +Files: +tests/test-openat-safer.c + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-openat-safer +check_PROGRAMS += test-openat-safer +test_openat_safer_LDADD = $(LDADD) @LIBINTL@
new file mode 100644 --- /dev/null +++ b/tests/test-openat-safer.c @@ -0,0 +1,122 @@ +/* Test that openat_safer leave 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 <ebb9@byu.net>, 2009. */ + +#include <config.h> + +#include "fcntl--.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> + +/* 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) + +int +main () +{ + int i; + int j; + int dfd; + int fd; + char buf[2]; + const char *witness = "test-openat-safer.txt"; + + /* 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 handle for future use. */ + dfd = openat (AT_FDCWD, ".", O_RDONLY); + ASSERT (STDERR_FILENO < dfd); + + /* Create file for later checks. */ + remove (witness); + fd = openat (dfd, witness, O_WRONLY | O_CREAT | O_EXCL, 0600); + ASSERT (STDERR_FILENO < fd); + ASSERT (write (fd, "hi", 2) == 2); + ASSERT (close (fd) == 0); + + /* Four iterations, with progressively more standard descriptors + closed. */ + for (i = -1; i <= STDERR_FILENO; i++) + { + ASSERT (fchdir (dfd) == 0); + if (0 <= i) + ASSERT (close (i) == 0); + + /* Execute once in ".", once in "..". */ + for (j = 0; j <= 1; j++) + { + if (j) + ASSERT (chdir ("..") == 0); + + /* Check for error detection. */ + errno = 0; + ASSERT (openat (AT_FDCWD, "", O_RDONLY) == -1); + ASSERT (errno == ENOENT); + errno = 0; + ASSERT (openat (dfd, "", O_RDONLY) == -1); + ASSERT (errno == ENOENT); + + /* Check for trailing slash and /dev/null handling; the + particular errno might be ambiguous. */ + errno = 0; + ASSERT (openat (dfd, "nonexist.ent/", O_CREAT | O_RDONLY, + S_IRUSR | S_IWUSR) == -1); + /* ASSERT (errno == ENOTDIR); */ + errno = 0; + ASSERT (openat (dfd, "/dev/null/", O_RDONLY) == -1); + /* ASSERT (errno == ENOTDIR); */ + fd = openat (dfd, "/dev/null", O_RDONLY); + ASSERT (STDERR_FILENO < fd); + ASSERT (close (fd) == 0); + + /* Check for our witness file. */ + fd = openat (dfd, witness, O_RDONLY | O_NOFOLLOW); + ASSERT (STDERR_FILENO < fd); + ASSERT (read (fd, buf, 2) == 2); + ASSERT (buf[0] == 'h' && buf[1] == 'i'); + ASSERT (close (fd) == 0); + } + } + ASSERT (fchdir (dfd) == 0); + ASSERT (unlink (witness) == 0); + ASSERT (close (dfd) == 0); + + return 0; +}