Mercurial > hg > octave-lyh > gnulib-hg
changeset 12058:36183b482b71
readlink: fix cygwin 1.5.x bug with return type
On older systems, readlink returned int instead of ssize_t, making
the use of readlink via function pointer harder.
* m4/readlink.m4 (gl_FUNC_READLINK): Require correct signature.
* lib/unistd.in.h (readlink): Use ssize_t.
* lib/readlink.c (readlink): Likewise.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
* modules/unistd (Makefile.am): Substitute it.
* lib/unistd.in.h (readlink): Declare replacement.
* doc/posix-functions/readlink.texi (readlink): Document this.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Tue, 22 Sep 2009 17:14:23 -0600 |
parents | aee865e7b49f |
children | 6babf16a67dd |
files | ChangeLog doc/posix-functions/readlink.texi lib/readlink.c lib/unistd.in.h m4/readlink.m4 m4/unistd_h.m4 modules/unistd |
diffstat | 7 files changed, 58 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2009-09-23 Eric Blake <ebb9@byu.net> + readlink: fix cygwin 1.5.x bug with return type + * m4/readlink.m4 (gl_FUNC_READLINK): Require correct signature. + * lib/unistd.in.h (readlink): Use ssize_t. + * lib/readlink.c (readlink): Likewise. + * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness. + * modules/unistd (Makefile.am): Substitute it. + * lib/unistd.in.h (readlink): Declare replacement. + * doc/posix-functions/readlink.texi (readlink): Document this. + symlink: use throughout gnulib * m4/symlinkat.m4 (gl_FUNC_SYMLINKAT): Omit symlink check. * lib/symlinkat.c (symlinkat) [!HAVE_SYMLINK]: Document why
--- a/doc/posix-functions/readlink.texi +++ b/doc/posix-functions/readlink.texi @@ -9,6 +9,10 @@ Portability problems fixed by Gnulib: @itemize @item +On some platforms, @code{readlink} returns @code{int} instead of +@code{ssize_t}: +FreeBSD 6.0, OpenBSD 3.8, Cygwin 1.5.x. +@item This function is missing on some platforms: mingw. @end itemize
--- a/lib/readlink.c +++ b/lib/readlink.c @@ -1,5 +1,5 @@ /* Stub for readlink(). - Copyright (C) 2003-2007 Free Software Foundation, Inc. + Copyright (C) 2003-2007, 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 @@ -20,30 +20,39 @@ #include <unistd.h> #include <errno.h> -#include <sys/types.h> +#include <string.h> #include <sys/stat.h> -#include <stddef.h> #if !HAVE_READLINK /* readlink() substitute for systems that don't have a readlink() function, such as DJGPP 2.03 and mingw32. */ -/* The official POSIX return type of readlink() is ssize_t, but since here - we have no declaration in a public header file, we use 'int' as return - type. */ - -int -readlink (const char *path, char *buf, size_t bufsize) +ssize_t +readlink (const char *name, char *buf _UNUSED_PARAMETER_, + size_t bufsize _UNUSED_PARAMETER_) { struct stat statbuf; /* In general we should use lstat() here, not stat(). But on platforms - without symbolic links lstat() - if it exists - would be equivalent to + without symbolic links, lstat() - if it exists - would be equivalent to stat(), therefore we can use stat(). This saves us a configure check. */ - if (stat (path, &statbuf) >= 0) + if (stat (name, &statbuf) >= 0) errno = EINVAL; return -1; } -#endif +#else /* HAVE_READLINK */ + +# undef readlink + +/* readlink() wrapper that uses correct types, for systems like cygwin + 1.5.x where readlink returns int. */ + +ssize_t +rpl_readlink (const char *name, char *buf, size_t bufsize) +{ + return readlink (name, buf, bufsize); +} + +#endif /* HAVE_READLINK */
--- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -41,7 +41,9 @@ /* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */ #include <stdlib.h> -#if @GNULIB_WRITE@ && @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@ +#if ((@GNULIB_WRITE@ && @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@) \ + || (@GNULIB_READLINK@ && (!@HAVE_READLINK@ || @REPLACE_READLINK@)) \ + || (@GNULIB_READLINKAT@ && !@HAVE_READLINKAT@)) /* Get ssize_t. */ # include <sys/types.h> #endif @@ -621,13 +623,16 @@ #if @GNULIB_READLINK@ +# if @REPLACE_READLINK@ +# define readlink rpl_readlink +# endif /* Read the contents of the symbolic link FILE and place the first BUFSIZE bytes of it into BUF. Return the number of bytes placed into BUF if successful, otherwise -1 and errno set. See the POSIX:2001 specification <http://www.opengroup.org/susv3xsh/readlink.html>. */ -# if !@HAVE_READLINK@ -extern int readlink (const char *file, char *buf, size_t bufsize); +# if !@HAVE_READLINK@ || @REPLACE_READLINK@ +extern ssize_t readlink (const char *file, char *buf, size_t bufsize); # endif #elif defined GNULIB_POSIXCHECK # undef readlink
--- a/m4/readlink.m4 +++ b/m4/readlink.m4 @@ -1,4 +1,4 @@ -# readlink.m4 serial 5 +# readlink.m4 serial 6 dnl Copyright (C) 2003, 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, @@ -12,6 +12,19 @@ HAVE_READLINK=0 AC_LIBOBJ([readlink]) gl_PREREQ_READLINK + else + AC_CACHE_CHECK([whether readlink signature is correct], + [gl_cv_decl_readlink_works], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <unistd.h> + /* Cause compilation failure if original declaration has wrong type. */ + ssize_t readlink (const char *, char *, size_t);]])], + [gl_cv_decl_readlink_works=yes], [gl_cv_decl_readlink_works=no])]) + if test "$gl_cv_decl_readlink_works" != yes; then + REPLACE_READLINK=1 + AC_LIBOBJ([readlink]) + fi fi ])
--- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -101,6 +101,7 @@ REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK])
--- a/modules/unistd +++ b/modules/unistd @@ -93,6 +93,7 @@ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \