Mercurial > hg > octave-kai > gnulib-hg
changeset 13539:56e31af9a41e
readlinkat: split into its own module
* modules/symlinkat: Split readlinkat...
* modules/readlinkat: ...into separate module.
* m4/symlinkat.m4 (gl_FUNC_SYMLINKAT): Move readlinkat check...
* m4/readlinkat.m4 (gl_FUNC_READLINAT): ...to new file.
* lib/symlinkat.c (readlinkat): Move...
* lib/readlinkat.c: ...into new file.
* modules/symlinkat-tests: Split readlinkat test...
* modules/readlinkat-tests: ...into separate module.
* tests/test-symlinkat.c: Split...
* tests/test-readlinkat.c: ...into new file.
* NEWS: Document the split.
* doc/posix-functions/readlinkat.texi (readlinkat): Likewise.
* lib/unistd.in.h (readlinkat): Likewise.
Suggested by Bruno Haible.
Signed-off-by: Eric Blake <eblake@redhat.com>
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Mon, 09 Aug 2010 11:16:07 -0600 |
parents | f6f9cbfb2ff9 |
children | a4b0494e2b96 |
files | ChangeLog NEWS doc/posix-functions/readlinkat.texi lib/readlinkat.c lib/symlinkat.c lib/unistd.in.h m4/readlinkat.m4 m4/symlinkat.m4 modules/readlinkat modules/readlinkat-tests modules/symlinkat modules/symlinkat-tests tests/test-readlinkat.c tests/test-symlinkat.c |
diffstat | 14 files changed, 250 insertions(+), 84 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-08-09 Eric Blake <eblake@redhat.com> + + readlinkat: split into its own module + * modules/symlinkat: Split readlinkat... + * modules/readlinkat: ...into separate module. + * m4/symlinkat.m4 (gl_FUNC_SYMLINKAT): Move readlinkat check... + * m4/readlinkat.m4 (gl_FUNC_READLINAT): ...to new file. + * lib/symlinkat.c (readlinkat): Move... + * lib/readlinkat.c: ...into new file. + * modules/symlinkat-tests: Split readlinkat test... + * modules/readlinkat-tests: ...into separate module. + * tests/test-symlinkat.c: Split... + * tests/test-readlinkat.c: ...into new file. + * NEWS: Document the split. + * doc/posix-functions/readlinkat.texi (readlinkat): Likewise. + * lib/unistd.in.h (readlinkat): Likewise. + Suggested by Bruno Haible. + 2010-08-08 Bruno Haible <bruno@clisp.org> memxfrm: Speed up.
--- a/NEWS +++ b/NEWS @@ -6,6 +6,9 @@ Date Modules Changes +2010-08-09 symlinkat This module now only provides symlinkat; use the + new module 'readlinkat' if needed. + 2010-07-31 ansi-c++-opt If Autoconf >= 2.66 is used, the 'configure' option is now called --disable-c++ rather than --disable-cxx.
--- a/doc/posix-functions/readlinkat.texi +++ b/doc/posix-functions/readlinkat.texi @@ -4,7 +4,7 @@ POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/readlinkat.html} -Gnulib module: symlinkat +Gnulib module: readlinkat Portability problems fixed by Gnulib: @itemize
new file mode 100644 --- /dev/null +++ b/lib/readlinkat.c @@ -0,0 +1,47 @@ +/* Read a symlink relative to an open directory. + Copyright (C) 2009-2010 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 */ + +#include <config.h> + +#include <unistd.h> + +/* Gnulib provides a readlink stub for mingw; use it for distinction + between EINVAL and ENOENT, rather than always failing with ENOSYS. */ + +/* POSIX 2008 says that unlike readlink, readlinkat returns 0 for + success instead of the buffer length. But this would render + readlinkat worthless since readlink does not guarantee a + NUL-terminated buffer. Assume this was a bug in POSIX. */ + +/* Read the contents of symlink FILE into buffer BUF of size LEN, in the + directory open on descriptor FD. If possible, do it without changing + the working directory. Otherwise, resort to using save_cwd/fchdir, + then readlink/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ + +#define AT_FUNC_NAME readlinkat +#define AT_FUNC_F1 readlink +#define AT_FUNC_POST_FILE_PARAM_DECLS , char *buf, size_t len +#define AT_FUNC_POST_FILE_ARGS , buf, len +#define AT_FUNC_RESULT ssize_t +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS +#undef AT_FUNC_RESULT
--- a/lib/symlinkat.c +++ b/lib/symlinkat.c @@ -74,29 +74,3 @@ } #endif /* HAVE_SYMLINK */ - -/* Gnulib provides a readlink stub for mingw; use it for distinction - between EINVAL and ENOENT, rather than always failing with ENOSYS. */ - -/* POSIX 2008 says that unlike readlink, readlinkat returns 0 for - success instead of the buffer length. But this would render - readlinkat worthless since readlink does not guarantee a - NUL-terminated buffer. Assume this was a bug in POSIX. */ - -/* Read the contents of symlink FILE into buffer BUF of size LEN, in the - directory open on descriptor FD. If possible, do it without changing - the working directory. Otherwise, resort to using save_cwd/fchdir, - then readlink/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ - -#define AT_FUNC_NAME readlinkat -#define AT_FUNC_F1 readlink -#define AT_FUNC_POST_FILE_PARAM_DECLS , char *buf, size_t len -#define AT_FUNC_POST_FILE_ARGS , buf, len -#define AT_FUNC_RESULT ssize_t -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS -#undef AT_FUNC_RESULT
--- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -1097,7 +1097,7 @@ # undef readlinkat # if HAVE_RAW_DECL_READLINKAT _GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " - "use gnulib module symlinkat for portability"); + "use gnulib module readlinkat for portability"); # endif #endif
new file mode 100644 --- /dev/null +++ b/m4/readlinkat.m4 @@ -0,0 +1,21 @@ +# serial 1 +# See if we need to provide readlinkat replacement. + +dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Written by Eric Blake. + +AC_DEFUN([gl_FUNC_READLINKAT], +[ + AC_REQUIRE([gl_FUNC_OPENAT]) + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_FUNCS_ONCE([readlinkat]) + if test $ac_cv_func_readlinkat = no; then + HAVE_READLINKAT=0 + AC_LIBOBJ([readlinkat]) + fi +])
--- a/m4/symlinkat.m4 +++ b/m4/symlinkat.m4 @@ -1,5 +1,5 @@ -# serial 3 -# See if we need to provide symlinkat/readlinkat replacement. +# serial 4 +# See if we need to provide symlinkat replacement. dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -13,11 +13,9 @@ AC_REQUIRE([gl_FUNC_OPENAT]) AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([symlinkat readlinkat]) + AC_CHECK_FUNCS_ONCE([symlinkat]) if test $ac_cv_func_symlinkat = no; then - # No known system has readlinkat but not symlinkat HAVE_SYMLINKAT=0 - HAVE_READLINKAT=0 AC_LIBOBJ([symlinkat]) fi ])
new file mode 100644 --- /dev/null +++ b/modules/readlinkat @@ -0,0 +1,29 @@ +Description: +readlinkat(): read symlinks relative to a directory + +Files: +lib/readlinkat.c +m4/readlinkat.m4 + +Depends-on: +extensions +fcntl-h +openat +readlink +unistd + +configure.ac: +gl_FUNC_READLINKAT +gl_UNISTD_MODULE_INDICATOR([readlinkat]) + +Makefile.am: + +Include: +<fcntl.h> +<unistd.h> + +License: +GPL + +Maintainer: +Jim Meyering, Eric Blake
new file mode 100644 --- /dev/null +++ b/modules/readlinkat-tests @@ -0,0 +1,16 @@ +Files: +tests/test-readlink.h +tests/test-readlinkat.c +tests/signature.h +tests/macros.h + +Depends-on: +ignore-value +symlinkat + +configure.ac: + +Makefile.am: +TESTS += test-readlinkat +check_PROGRAMS += test-readlinkat +test_readlinkat_LDADD = $(LDADD) @LIBINTL@
--- a/modules/symlinkat +++ b/modules/symlinkat @@ -1,5 +1,5 @@ Description: -symlinkat() and readlinkat(): manage symlinks relative to a directory +symlinkat(): create symlinks relative to a directory Files: lib/symlinkat.c @@ -9,14 +9,12 @@ extensions fcntl-h openat -readlink symlink unistd configure.ac: gl_FUNC_SYMLINKAT gl_UNISTD_MODULE_INDICATOR([symlinkat]) -gl_UNISTD_MODULE_INDICATOR([readlinkat]) Makefile.am:
--- a/modules/symlinkat-tests +++ b/modules/symlinkat-tests @@ -1,5 +1,4 @@ Files: -tests/test-readlink.h tests/test-symlink.h tests/test-symlinkat.c tests/signature.h
new file mode 100644 --- /dev/null +++ b/tests/test-readlinkat.c @@ -0,0 +1,108 @@ +/* Tests of readlinkat. + Copyright (C) 2009, 2010 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 <unistd.h> + +#include "signature.h" +SIGNATURE_CHECK (readlinkat, ssize_t, (int, char const *, char *, size_t)); + +#include <fcntl.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#include "ignore-value.h" +#include "macros.h" + +#ifndef HAVE_SYMLINK +# define HAVE_SYMLINK 0 +#endif + +#define BASE "test-readlinkat.t" + +#include "test-readlink.h" + +static int dfd = AT_FDCWD; + +static ssize_t +do_readlink (char const *name, char *buf, size_t len) +{ + return readlinkat (dfd, name, buf, len); +} + +int +main (void) +{ + char buf[80]; + int result; + + /* Remove any leftovers from a previous partial run. */ + ignore_value (system ("rm -rf " BASE "*")); + + /* Perform same checks as counterpart functions. */ + result = test_readlink (do_readlink, false); + dfd = openat (AT_FDCWD, ".", O_RDONLY); + ASSERT (0 <= dfd); + ASSERT (test_readlink (do_readlink, false) == result); + + /* Now perform some cross-directory checks. Skip everything else on + mingw. */ + if (HAVE_SYMLINK) + { + const char *contents = "don't matter!"; + ssize_t exp = strlen (contents); + + /* Create link while cwd is '.', then read it in '..'. */ + ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == 0); + errno = 0; + ASSERT (symlinkat (contents, dfd, BASE "link") == -1); + ASSERT (errno == EEXIST); + ASSERT (chdir ("..") == 0); + errno = 0; + ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == -1); + ASSERT (errno == ENOENT); + ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp); + ASSERT (strncmp (contents, buf, exp) == 0); + ASSERT (unlinkat (dfd, BASE "link", 0) == 0); + + /* Create link while cwd is '..', then read it in '.'. */ + ASSERT (symlinkat (contents, dfd, BASE "link") == 0); + ASSERT (fchdir (dfd) == 0); + errno = 0; + ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == -1); + ASSERT (errno == EEXIST); + buf[0] = '\0'; + ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == exp); + ASSERT (strncmp (contents, buf, exp) == 0); + buf[0] = '\0'; + ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp); + ASSERT (strncmp (contents, buf, exp) == 0); + ASSERT (unlink (BASE "link") == 0); + } + + ASSERT (close (dfd) == 0); + if (result == 77) + fputs ("skipping test: symlinks not supported on this file system\n", + stderr); + return result; +}
--- a/tests/test-symlinkat.c +++ b/tests/test-symlinkat.c @@ -1,4 +1,4 @@ -/* Tests of symlinkat and readlinkat. +/* Tests of symlinkat. Copyright (C) 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -22,7 +22,6 @@ #include "signature.h" SIGNATURE_CHECK (symlinkat, int, (char const *, int, char const *)); -SIGNATURE_CHECK (readlinkat, ssize_t, (int, char const *, char *, size_t)); #include <fcntl.h> #include <errno.h> @@ -41,7 +40,6 @@ #define BASE "test-symlinkat.t" -#include "test-readlink.h" #include "test-symlink.h" static int dfd = AT_FDCWD; @@ -52,12 +50,6 @@ return symlinkat (contents, dfd, name); } -static ssize_t -do_readlink (char const *name, char *buf, size_t len) -{ - return readlinkat (dfd, name, buf, len); -} - int main (void) { @@ -68,48 +60,11 @@ ignore_value (system ("rm -rf " BASE "*")); /* Perform same checks as counterpart functions. */ - result = test_readlink (do_readlink, false); - ASSERT (test_symlink (do_symlink, false) == result); + result = test_symlink (do_symlink, false); dfd = openat (AT_FDCWD, ".", O_RDONLY); ASSERT (0 <= dfd); - ASSERT (test_readlink (do_readlink, false) == result); ASSERT (test_symlink (do_symlink, false) == result); - /* Now perform some cross-directory checks. Skip everything else on - mingw. */ - if (HAVE_SYMLINK) - { - const char *contents = "don't matter!"; - ssize_t exp = strlen (contents); - - /* Create link while cwd is '.', then read it in '..'. */ - ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == 0); - errno = 0; - ASSERT (symlinkat (contents, dfd, BASE "link") == -1); - ASSERT (errno == EEXIST); - ASSERT (chdir ("..") == 0); - errno = 0; - ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == -1); - ASSERT (errno == ENOENT); - ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp); - ASSERT (strncmp (contents, buf, exp) == 0); - ASSERT (unlinkat (dfd, BASE "link", 0) == 0); - - /* Create link while cwd is '..', then read it in '.'. */ - ASSERT (symlinkat (contents, dfd, BASE "link") == 0); - ASSERT (fchdir (dfd) == 0); - errno = 0; - ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == -1); - ASSERT (errno == EEXIST); - buf[0] = '\0'; - ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == exp); - ASSERT (strncmp (contents, buf, exp) == 0); - buf[0] = '\0'; - ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp); - ASSERT (strncmp (contents, buf, exp) == 0); - ASSERT (unlink (BASE "link") == 0); - } - ASSERT (close (dfd) == 0); if (result == 77) fputs ("skipping test: symlinks not supported on this file system\n",