diff options
Diffstat (limited to 'gl')
-rw-r--r-- | gl/fseeko.c | 116 | ||||
-rw-r--r-- | gl/getpass.c | 233 | ||||
-rw-r--r-- | gl/getpass.h | 31 | ||||
-rw-r--r-- | gl/gnulib.mk | 122 | ||||
-rw-r--r-- | gl/lseek.c | 62 | ||||
-rw-r--r-- | gl/m4/fseeko.m4 | 30 | ||||
-rw-r--r-- | gl/m4/getpass.m4 | 47 | ||||
-rw-r--r-- | gl/m4/gnulib-cache.m4 | 4 | ||||
-rw-r--r-- | gl/m4/gnulib-comp.m4 | 19 | ||||
-rw-r--r-- | gl/m4/lseek.m4 | 50 |
10 files changed, 711 insertions, 3 deletions
diff --git a/gl/fseeko.c b/gl/fseeko.c new file mode 100644 index 0000000000..209ce9c690 --- /dev/null +++ b/gl/fseeko.c @@ -0,0 +1,116 @@ +/* An fseeko() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <stdio.h> + +/* Get off_t and lseek. */ +#include <unistd.h> + +#undef fseeko +#if !HAVE_FSEEKO +# undef fseek +# define fseeko fseek +#endif + +int +rpl_fseeko (FILE *fp, off_t offset, int whence) +{ +#if LSEEK_PIPE_BROKEN + /* mingw gives bogus answers rather than failure on non-seekable files. */ + if (lseek (fileno (fp), 0, SEEK_CUR) == -1) + return EOF; +#endif + + /* These tests are based on fpurge.c. */ +#if defined _IO_ferror_unlocked /* GNU libc, BeOS */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +#elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ +# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */ + /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> + and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */ +# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub +# else /* FreeBSD, MacOS X, Cygwin */ +# define fp_ub fp->_ub +# endif +# if defined __SL64 && defined __SCLE /* Cygwin */ + if ((fp->_flags & __SL64) == 0) + { + /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit + mode; but has an fseeko that requires 64-bit mode. */ + FILE *tmp = fopen ("/dev/null", "r"); + if (!tmp) + return -1; + fp->_flags |= __SL64; + fp->_seek64 = tmp->_seek64; + fclose (tmp); + } +# endif + if (fp->_p == fp->_bf._base + && fp->_r == 0 + && fp->_w == ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ + ? fp->_bf._size + : 0) + && fp_ub._base == NULL) +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ +# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ +# define fp_ ((struct { unsigned char *_ptr; \ + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + int _file; \ + unsigned int _flag; \ + } *) fp) + if (fp_->_ptr == fp_->_base + && (fp_->_ptr == NULL || fp_->_cnt == 0)) +# else + if (fp->_ptr == fp->_base + && (fp->_ptr == NULL || fp->_cnt == 0)) +# endif +#elif defined __UCLIBC__ /* uClibc */ + if (((fp->__modeflags & __FLAG_WRITING) == 0 + || fp->__bufpos == fp->__bufstart) + && ((fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) == 0 + || fp->__bufpos == fp->__bufread)) +#else + #error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib." +#endif + { + off_t pos = lseek (fileno (fp), offset, whence); + if (pos == -1) + { +#if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ + fp->_flags &= ~__SOFF; +#endif + return -1; + } + else + { +#if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ + fp->_offset = pos; + fp->_flags |= __SOFF; +#endif + return 0; + } + } + else + return fseeko (fp, offset, whence); +} diff --git a/gl/getpass.c b/gl/getpass.c new file mode 100644 index 0000000000..4ae233305d --- /dev/null +++ b/gl/getpass.c @@ -0,0 +1,233 @@ +/* Copyright (C) 1992-2001, 2003, 2004, 2005, 2006, 2007 Free Software + Foundation, Inc. + + This file is part of the GNU C Library. + + 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LIBC +# include <config.h> +#endif + +#include "getpass.h" + +#include <stdio.h> + +#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) + +#include <stdbool.h> + +#if HAVE_DECL___FSETLOCKING && HAVE___FSETLOCKING +# if HAVE_STDIO_EXT_H +# include <stdio_ext.h> +# endif +#else +# define __fsetlocking(stream, type) /* empty */ +#endif + +#if HAVE_TERMIOS_H +# include <termios.h> +#endif + +#include "getline.h" + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#else +# if !HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush_unlocked +# define fflush_unlocked(x) fflush (x) +# endif +# if !HAVE_DECL_FLOCKFILE +# undef flockfile +# define flockfile(x) ((void) 0) +# endif +# if !HAVE_DECL_FUNLOCKFILE +# undef funlockfile +# define funlockfile(x) ((void) 0) +# endif +# if !HAVE_DECL_FPUTS_UNLOCKED +# undef fputs_unlocked +# define fputs_unlocked(str,stream) fputs (str, stream) +# endif +# if !HAVE_DECL_PUTC_UNLOCKED +# undef putc_unlocked +# define putc_unlocked(c,stream) putc (c, stream) +# endif +#endif + +/* It is desirable to use this bit on systems that have it. + The only bit of terminal state we want to twiddle is echoing, which is + done in software; there is no need to change the state of the terminal + hardware. */ + +#ifndef TCSASOFT +# define TCSASOFT 0 +#endif + +static void +call_fclose (void *arg) +{ + if (arg != NULL) + fclose (arg); +} + +char * +getpass (const char *prompt) +{ + FILE *tty; + FILE *in, *out; + struct termios s, t; + bool tty_changed = false; + static char *buf; + static size_t bufsize; + ssize_t nread; + + /* Try to write to and read from the terminal if we can. + If we can't open the terminal, use stderr and stdin. */ + + tty = fopen ("/dev/tty", "w+"); + if (tty == NULL) + { + in = stdin; + out = stderr; + } + else + { + /* We do the locking ourselves. */ + __fsetlocking (tty, FSETLOCKING_BYCALLER); + + out = in = tty; + } + + flockfile (out); + + /* Turn echoing off if it is on now. */ +#if HAVE_TCGETATTR + if (tcgetattr (fileno (in), &t) == 0) + { + /* Save the old one. */ + s = t; + /* Tricky, tricky. */ + t.c_lflag &= ~(ECHO | ISIG); + tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0); + } +#endif + + /* Write the prompt. */ + fputs_unlocked (prompt, out); + fflush_unlocked (out); + + /* Read the password. */ + nread = getline (&buf, &bufsize, in); + + /* According to the C standard, input may not be followed by output + on the same stream without an intervening call to a file + positioning function. Suppose in == out; then without this fseek + call, on Solaris, HP-UX, AIX, OSF/1, the previous input gets + echoed, whereas on IRIX, the following newline is not output as + it should be. POSIX imposes similar restrictions if fileno (in) + == fileno (out). The POSIX restrictions are tricky and change + from POSIX version to POSIX version, so play it safe and invoke + fseek even if in != out. */ + fseeko (out, 0, SEEK_CUR); + + if (buf != NULL) + { + if (nread < 0) + buf[0] = '\0'; + else if (buf[nread - 1] == '\n') + { + /* Remove the newline. */ + buf[nread - 1] = '\0'; + if (tty_changed) + { + /* Write the newline that was not echoed. */ + putc_unlocked ('\n', out); + } + } + } + + /* Restore the original setting. */ +#if HAVE_TCSETATTR + if (tty_changed) + tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s); +#endif + + funlockfile (out); + + call_fclose (tty); + + return buf; +} + +#else /* W32 native */ + +/* Windows implementation by Martin Lambers <marlam@marlam.de>, + improved by Simon Josefsson. */ + +/* For PASS_MAX. */ +#include <limits.h> +/* For _getch(). */ +#include <conio.h> +/* For strdup(). */ +#include <string.h> + +#ifndef PASS_MAX +# define PASS_MAX 512 +#endif + +char * +getpass (const char *prompt) +{ + char getpassbuf[PASS_MAX + 1]; + size_t i = 0; + int c; + + if (prompt) + { + fputs (prompt, stderr); + fflush (stderr); + } + + for (;;) + { + c = _getch (); + if (c == '\r') + { + getpassbuf[i] = '\0'; + break; + } + else if (i < PASS_MAX) + { + getpassbuf[i++] = c; + } + + if (i >= PASS_MAX) + { + getpassbuf[i] = '\0'; + break; + } + } + + if (prompt) + { + fputs ("\r\n", stderr); + fflush (stderr); + } + + return strdup (getpassbuf); +} +#endif diff --git a/gl/getpass.h b/gl/getpass.h new file mode 100644 index 0000000000..bdff8754d4 --- /dev/null +++ b/gl/getpass.h @@ -0,0 +1,31 @@ +/* getpass.h -- Read a password of arbitrary length from /dev/tty or stdin. + Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by Simon Josefsson <jas@extundo.com>, 2004. + + 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef GETPASS_H +# define GETPASS_H + +/* Get getpass declaration, if available. */ +# include <unistd.h> + +# if defined HAVE_DECL_GETPASS && !HAVE_DECL_GETPASS +/* Read a password of arbitrary length from /dev/tty or stdin. */ +char *getpass (const char *prompt); + +# endif + +#endif /* GETPASS_H */ diff --git a/gl/gnulib.mk b/gl/gnulib.mk index 147965707b..55b8118a7c 100644 --- a/gl/gnulib.mk +++ b/gl/gnulib.mk @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --aux-dir=build-aux --avoid=snprintf --avoid=vasnprintf --makefile-name=gnulib.mk --libtool --macro-prefix=gl arpa_inet error fdl gendocs getaddrinfo getline gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf +# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --aux-dir=build-aux --avoid=snprintf --avoid=vasnprintf --makefile-name=gnulib.mk --libtool --macro-prefix=gl arpa_inet error fdl gendocs getaddrinfo getline getpass gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf MOSTLYCLEANFILES += core *.stackdump @@ -49,6 +49,15 @@ EXTRA_libgnu_la_SOURCES += error.c ## end gnulib module error +## begin gnulib module fseeko + + +EXTRA_DIST += fseeko.c + +EXTRA_libgnu_la_SOURCES += fseeko.c + +## end gnulib module fseeko + ## begin gnulib module gendocs @@ -83,6 +92,15 @@ EXTRA_libgnu_la_SOURCES += getline.c ## end gnulib module getline +## begin gnulib module getpass + + +EXTRA_DIST += getpass.c getpass.h + +EXTRA_libgnu_la_SOURCES += getpass.c + +## end gnulib module getpass + ## begin gnulib module gettext-h libgnu_la_SOURCES += gettext.h @@ -122,6 +140,15 @@ EXTRA_DIST += $(top_srcdir)/build-aux/link-warning.h ## end gnulib module link-warning +## begin gnulib module lseek + + +EXTRA_DIST += lseek.c + +EXTRA_libgnu_la_SOURCES += lseek.c + +## end gnulib module lseek + ## begin gnulib module maintainer-makefile EXTRA_DIST += $(top_srcdir)/build-aux/GNUmakefile $(top_srcdir)/build-aux/maint.mk @@ -184,6 +211,58 @@ EXTRA_DIST += stdbool_.h ## end gnulib module stdbool +## begin gnulib module stdio + +BUILT_SOURCES += stdio.h + +# We need the following in order to create <stdio.h> when the system +# doesn't have one that works with the given compiler. +stdio.h: stdio_.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ + -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ + -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ + -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ + -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ + -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ + -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ + -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ + -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ + -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ + -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ + -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ + -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ + -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ + -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ + -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ + -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ + -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ + -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ + -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ + -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ + < $(srcdir)/stdio_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += stdio.h stdio.h-t + +EXTRA_DIST += stdio_.h + +## end gnulib module stdio + ## begin gnulib module strdup @@ -281,6 +360,47 @@ EXTRA_DIST += sys_socket_.h ## end gnulib module sys_socket +## begin gnulib module unistd + +BUILT_SOURCES += unistd.h + +# We need the following in order to create an empty placeholder for +# <unistd.h> when the system doesn't have one. +unistd.h: unistd_.h + rm -f $@-t $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ + -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ + -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ + -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ + -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ + -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ + -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ + -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ + -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ + -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ + -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ + -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ + -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ + -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ + -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ + -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ + -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ + -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ + -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ + -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ + -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ + -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + < $(srcdir)/unistd_.h; \ + } > $@-t + mv $@-t $@ +MOSTLYCLEANFILES += unistd.h unistd.h-t + +EXTRA_DIST += unistd_.h + +## end gnulib module unistd + ## begin gnulib module version-etc libgnu_la_SOURCES += version-etc.h version-etc.c diff --git a/gl/lseek.c b/gl/lseek.c new file mode 100644 index 0000000000..db8dbfb3e9 --- /dev/null +++ b/gl/lseek.c @@ -0,0 +1,62 @@ +/* An lseek() function that detects pipes. + Copyright (C) 2007 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Windows platforms. */ +/* Get GetFileType. */ +# include <windows.h> +#else +# include <sys/stat.h> +#endif +#include <errno.h> + +#undef lseek + +off_t +rpl_lseek (int fd, off_t offset, int whence) +{ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals. */ + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + if (GetFileType (h) != FILE_TYPE_DISK) + { + errno = ESPIPE; + return -1; + } +#else + /* BeOS lseek mistakenly succeeds on pipes... */ + struct stat statbuf; + if (fstat (fd, &statbuf) < 0) + return -1; + if (!S_ISREG (statbuf.st_mode)) + { + errno = ESPIPE; + return -1; + } +#endif + return lseek (fd, offset, whence); +} diff --git a/gl/m4/fseeko.m4 b/gl/m4/fseeko.m4 new file mode 100644 index 0000000000..40be63b4c2 --- /dev/null +++ b/gl/m4/fseeko.m4 @@ -0,0 +1,30 @@ +# fseeko.m4 serial 3 +dnl Copyright (C) 2007 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. + +AC_DEFUN([gl_FUNC_FSEEKO], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) + AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko], + [ + AC_TRY_LINK([#include <stdio.h>], [fseeko (stdin, 0, 0);], + [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no]) + ]) + if test $gl_cv_func_fseeko = no; then + HAVE_FSEEKO=0 + gl_REPLACE_FSEEKO + elif test $gl_cv_var_stdin_large_offset = no; then + gl_REPLACE_FSEEKO + fi +]) + +AC_DEFUN([gl_REPLACE_FSEEKO], +[ + AC_LIBOBJ([fseeko]) + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + REPLACE_FSEEKO=1 +]) diff --git a/gl/m4/getpass.m4 b/gl/m4/getpass.m4 new file mode 100644 index 0000000000..54348ce7c7 --- /dev/null +++ b/gl/m4/getpass.m4 @@ -0,0 +1,47 @@ +# getpass.m4 serial 10 +dnl Copyright (C) 2002-2003, 2005-2006 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. + +# Provide a getpass() function if the system doesn't have it. +AC_DEFUN([gl_FUNC_GETPASS], +[ + AC_REPLACE_FUNCS(getpass) + AC_CHECK_DECLS_ONCE(getpass) + if test $ac_cv_func_getpass = no; then + gl_PREREQ_GETPASS + fi +]) + +# Provide the GNU getpass() implementation. It supports passwords of +# arbitrary length (not just 8 bytes as on HP-UX). +AC_DEFUN([gl_FUNC_GETPASS_GNU], +[ + AC_CHECK_DECLS_ONCE(getpass) + dnl TODO: Detect when GNU getpass() is already found in glibc. + AC_LIBOBJ(getpass) + gl_PREREQ_GETPASS + dnl We must choose a different name for our function, since on ELF systems + dnl an unusable getpass() in libc.so would override our getpass() if it is + dnl compiled into a shared library. + AC_DEFINE([getpass], [gnu_getpass], + [Define to a replacement function name for getpass().]) +]) + +# Prerequisites of lib/getpass.c. +AC_DEFUN([gl_PREREQ_GETPASS], [ + AC_CHECK_HEADERS_ONCE(stdio_ext.h termios.h) + AC_CHECK_FUNCS_ONCE(__fsetlocking tcgetattr tcsetattr) + AC_CHECK_DECLS([__fsetlocking],,, + [#include <stdio.h> + #if HAVE_STDIO_EXT_H + #include <stdio_ext.h> + #endif]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([flockfile]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([funlockfile]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + : +]) diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index 5d0831b692..00da5468c4 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --aux-dir=build-aux --avoid=snprintf --avoid=vasnprintf --makefile-name=gnulib.mk --libtool --macro-prefix=gl arpa_inet error fdl gendocs getaddrinfo getline gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf +# gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --aux-dir=build-aux --avoid=snprintf --avoid=vasnprintf --makefile-name=gnulib.mk --libtool --macro-prefix=gl arpa_inet error fdl gendocs getaddrinfo getline getpass gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([gl/override]) -gl_MODULES([arpa_inet error fdl gendocs getaddrinfo getline gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf]) +gl_MODULES([arpa_inet error fdl gendocs getaddrinfo getline getpass gpl-2.0 inet_ntop inet_pton lgpl-2.1 maintainer-makefile progname readline version-etc-fsf]) gl_AVOID([snprintf vasnprintf]) gl_SOURCE_BASE([gl]) gl_M4_BASE([gl/m4]) diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index e5689086b5..6aaf9bfa4d 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 @@ -27,6 +27,7 @@ AC_DEFUN([gl_EARLY], AC_REQUIRE([AC_PROG_RANLIB]) AC_REQUIRE([AC_GNU_SOURCE]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_FUNC_FSEEKO]) dnl Some compilers (e.g., AIX 5.3 cc) need to be in c99 mode dnl for the builtin va_copy to work. With Autoconf 2.60 or later, dnl AC_PROG_CC_STDC arranges for this. With older Autoconf AC_PROG_CC_STDC @@ -47,24 +48,31 @@ AC_DEFUN([gl_INIT], gl_HEADER_ARPA_INET AC_PROG_MKDIR_P gl_ERROR + gl_FUNC_FSEEKO + gl_STDIO_MODULE_INDICATOR([fseeko]) gl_GETADDRINFO gl_FUNC_GETDELIM gl_FUNC_GETLINE + gl_FUNC_GETPASS AC_SUBST([LIBINTL]) AC_SUBST([LTLIBINTL]) gl_INET_NTOP gl_INET_PTON + gl_FUNC_LSEEK + gl_UNISTD_MODULE_INDICATOR([lseek]) gl_HEADER_NETINET_IN AC_PROG_MKDIR_P gl_FUNC_READLINE gl_TYPE_SOCKLEN_T gl_STDARG_H AM_STDBOOL_H + gl_STDIO_H gl_FUNC_STRDUP gl_STRING_MODULE_INDICATOR([strdup]) gl_HEADER_STRING_H gl_HEADER_SYS_SOCKET AC_PROG_MKDIR_P + gl_UNISTD_H m4_popdef([AC_LIBSOURCES]) m4_popdef([AC_REPLACE_FUNCS]) m4_popdef([AC_LIBOBJ]) @@ -113,6 +121,7 @@ AC_DEFUN([gl_FILE_LIST], [ doc/lgpl-2.1.texi lib/error.c lib/error.h + lib/fseeko.c lib/gai_strerror.c lib/getaddrinfo.c lib/getaddrinfo.h @@ -120,29 +129,36 @@ AC_DEFUN([gl_FILE_LIST], [ lib/getdelim.h lib/getline.c lib/getline.h + lib/getpass.c + lib/getpass.h lib/gettext.h lib/inet_ntop.c lib/inet_ntop.h lib/inet_pton.c lib/inet_pton.h + lib/lseek.c lib/netinet_in_.h lib/progname.c lib/progname.h lib/readline.c lib/readline.h lib/stdbool_.h + lib/stdio_.h lib/strdup.c lib/string_.h lib/sys_socket_.h + lib/unistd_.h lib/version-etc-fsf.c lib/version-etc.c lib/version-etc.h m4/arpa_inet_h.m4 m4/error.m4 m4/extensions.m4 + m4/fseeko.m4 m4/getaddrinfo.m4 m4/getdelim.m4 m4/getline.m4 + m4/getpass.m4 m4/gnulib-common.m4 m4/include_next.m4 m4/inet_ntop.m4 @@ -150,13 +166,16 @@ AC_DEFUN([gl_FILE_LIST], [ m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4 + m4/lseek.m4 m4/netinet_in_h.m4 m4/readline.m4 m4/socklen.m4 m4/sockpfaf.m4 m4/stdarg.m4 m4/stdbool.m4 + m4/stdio_h.m4 m4/strdup.m4 m4/string_h.m4 m4/sys_socket_h.m4 + m4/unistd_h.m4 ]) diff --git a/gl/m4/lseek.m4 b/gl/m4/lseek.m4 new file mode 100644 index 0000000000..f336990709 --- /dev/null +++ b/gl/m4/lseek.m4 @@ -0,0 +1,50 @@ +# lseek.m4 serial 4 +dnl Copyright (C) 2007 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. + +AC_DEFUN([gl_FUNC_LSEEK], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([whether lseek detects pipes], [gl_cv_func_lseek_pipe], + [if test $cross_compiling = no; then + AC_LINK_IFELSE([ +#include <sys/types.h> /* for off_t */ +#include <stdio.h> /* for SEEK_CUR */ +#include <unistd.h> +int main () +{ + /* Exit with success only if stdin is seekable. */ + return lseek (0, (off_t)0, SEEK_CUR) < 0; +}], + [if test -s conftest$ac_exeext \ + && ./conftest$ac_exeext < conftest.$ac_ext \ + && { echo hi | ./conftest$ac_exeext; test $? = 1; }; then + gl_cv_func_lseek_pipe=yes + else + gl_cv_func_lseek_pipe=no + fi], + [gl_cv_func_lseek_pipe=no]) + else + AC_COMPILE_IFELSE([ +#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) || defined __BEOS__ +/* mingw and BeOS mistakenly return 0 when trying to seek on pipes. */ + Choke me. +#endif], + [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no]) + fi]) + if test $gl_cv_func_lseek_pipe = no; then + gl_REPLACE_LSEEK + fi +]) + +AC_DEFUN([gl_REPLACE_LSEEK], +[ + AC_LIBOBJ([lseek]) + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + REPLACE_LSEEK=1 + AC_DEFINE([LSEEK_PIPE_BROKEN], [1], + [Define to 1 if lseek does not detect pipes.]) +]) |