diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-02-23 14:09:34 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-02-23 14:09:34 +0000 |
commit | 48442c8f89b9de078fe91ac9d0a7495bcb7882f1 (patch) | |
tree | fca6f860a5167b5fbbfb8c535fdd1071f8ac7f80 /lib | |
parent | 91cfb5889764c8edc3352069f11fb5df3e99ca33 (diff) | |
download | mailutils-48442c8f89b9de078fe91ac9d0a7495bcb7882f1.tar.gz mailutils-48442c8f89b9de078fe91ac9d0a7495bcb7882f1.tar.bz2 |
Updated by gnulib-sync
Diffstat (limited to 'lib')
-rw-r--r-- | lib/error.h | 38 | ||||
-rw-r--r-- | lib/fnmatch.c | 522 | ||||
-rw-r--r-- | lib/getpass.c | 248 | ||||
-rw-r--r-- | lib/malloc.c | 22 | ||||
-rw-r--r-- | lib/obstack.c | 452 | ||||
-rw-r--r-- | lib/obstack.h | 482 | ||||
-rw-r--r-- | lib/realloc.c | 34 |
7 files changed, 1013 insertions, 785 deletions
diff --git a/lib/error.h b/lib/error.h index 1f6817180..8ed63595f 100644 --- a/lib/error.h +++ b/lib/error.h @@ -1,12 +1,9 @@ /* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. - - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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 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. @@ -17,6 +14,5 @@ - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -27,3 +23,3 @@ /* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) # define __attribute__(Spec) /* empty */ @@ -42,4 +38,2 @@ extern "C" { -#if defined (__STDC__) && __STDC__ - /* Print a message with `fprintf (stderr, FORMAT, ...)'; @@ -48,7 +42,7 @@ extern "C" { -extern void error (int status, int errnum, const char *format, ...) +extern void error (int __status, int __errnum, const char *__format, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -extern void error_at_line (int status, int errnum, const char *fname, - unsigned int lineno, const char *format, ...) +extern void error_at_line (int __status, int __errnum, const char *__fname, + unsigned int __lineno, const char *__format, ...) __attribute__ ((__format__ (__printf__, 5, 6))); @@ -60,8 +54,2 @@ extern void (*error_print_progname) (void); -#else -void error (); -void error_at_line (); -extern void (*error_print_progname) (); -#endif - /* This variable is incremented each time `error' is called. */ diff --git a/lib/fnmatch.c b/lib/fnmatch.c index 9bff8c220..011a14503 100644 --- a/lib/fnmatch.c +++ b/lib/fnmatch.c @@ -1,2 +1,3 @@ -/* Copyright 1991, 1992, 1993, 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004 + Free Software Foundation, Inc. @@ -12,5 +13,5 @@ - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -25,206 +26,361 @@ -#include <errno.h> +#if ! defined __builtin_expect && __GNUC__ < 3 +# define __builtin_expect(expr, expected) (expr) +#endif + #include <fnmatch.h> -#include <ctype.h> -#if defined STDC_HEADERS || !defined isascii -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) isascii (c) +#include <alloca.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <stddef.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#define WIDE_CHAR_SUPPORT \ + (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC \ + && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ +# include <wchar.h> +# include <wctype.h> #endif -#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) - +/* We need some of the locale data (the collation sequence information) + but there is no interface to get this information in general. Therefore + we support a correct implementation only in glibc. */ +#ifdef _LIBC +# include "../locale/localeinfo.h" +# include "../locale/elem-hash.h" +# include "../locale/coll-lookup.h" +# include <shlib-compat.h> + +# define CONCAT(a,b) __CONCAT(a,b) +# define mbsrtowcs __mbsrtowcs +# define fnmatch __fnmatch +extern int fnmatch (const char *pattern, const char *string, int flags); +#endif -#ifndef errno -extern int errno; +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) #endif -/* Match STRING against the filename pattern PATTERN, returning zero if - it matches, nonzero if not. */ -int -fnmatch (const char *pattern, const char *string, int flags) -{ - register const char *p = pattern, *n = string; - register char c; +/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ +#define NO_LEADING_PERIOD(flags) \ + ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself, and have not detected a bug + in the library. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU + + +# if defined STDC_HEADERS || !defined isascii +# define ISASCII(c) 1 +# else +# define ISASCII(c) isascii(c) +# endif + +# ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +# else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +# endif +# ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +# else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +# endif + +# define ISPRINT(c) (ISASCII (c) && isprint (c)) +# define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +# define ISALNUM(c) (ISASCII (c) && isalnum (c)) +# define ISALPHA(c) (ISASCII (c) && isalpha (c)) +# define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +# define ISLOWER(c) (ISASCII (c) && islower (c)) +# define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +# define ISSPACE(c) (ISASCII (c) && isspace (c)) +# define ISUPPER(c) (ISASCII (c) && isupper (c)) +# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +# if defined _LIBC || WIDE_CHAR_SUPPORT +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif + +# ifdef _LIBC +# define ISWCTYPE(WC, WT) __iswctype (WC, WT) +# else +# define ISWCTYPE(WC, WT) iswctype (WC, WT) +# endif + +# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC +/* In this case we are implementing the multibyte character handling. */ +# define HANDLE_MULTIBYTE 1 +# endif + +# else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +/* Global variable. */ +static int posixly_correct; + +# ifndef internal_function +/* Inside GNU libc we mark some function in a special way. In other + environments simply ignore the marking. */ +# define internal_function +# endif /* Note that this evaluates C many times. */ -#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER ((unsigned char) (c)) \ - ? tolower ((unsigned char) (c)) \ - : (c)) +# ifdef _LIBC +# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) +# else +# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) +# endif +# define CHAR char +# define UCHAR unsigned char +# define INT int +# define FCT internal_fnmatch +# define EXT ext_match +# define END end_pattern +# define L(CS) CS +# ifdef _LIBC +# define BTOWC(C) __btowc (C) +# else +# define BTOWC(C) btowc (C) +# endif +# define STRLEN(S) strlen (S) +# define STRCAT(D, S) strcat (D, S) +# ifdef _LIBC +# define MEMPCPY(D, S, N) __mempcpy (D, S, N) +# else +# if HAVE_MEMPCPY +# define MEMPCPY(D, S, N) mempcpy (D, S, N) +# else +# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) +# endif +# endif +# define MEMCHR(S, C, N) memchr (S, C, N) +# define STRCOLL(S1, S2) strcoll (S1, S2) +# include "fnmatch_loop.c" + + +# if HANDLE_MULTIBYTE +# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) +# define CHAR wchar_t +# define UCHAR wint_t +# define INT wint_t +# define FCT internal_fnwmatch +# define EXT ext_wmatch +# define END end_wpattern +# define L(CS) L##CS +# define BTOWC(C) (C) +# ifdef _LIBC +# define STRLEN(S) __wcslen (S) +# define STRCAT(D, S) __wcscat (D, S) +# define MEMPCPY(D, S, N) __wmempcpy (D, S, N) +# else +# define STRLEN(S) wcslen (S) +# define STRCAT(D, S) wcscat (D, S) +# if HAVE_WMEMPCPY +# define MEMPCPY(D, S, N) wmempcpy (D, S, N) +# else +# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N)) +# endif +# endif +# define MEMCHR(S, C, N) wmemchr (S, C, N) +# define STRCOLL(S1, S2) wcscoll (S1, S2) +# define WIDE_CHAR_VERSION 1 + +# undef IS_CHAR_CLASS +/* We have to convert the wide character string in a multibyte string. But + we know that the character class names consist of alphanumeric characters + from the portable character set, and since the wide character encoding + for a member of the portable character set is the same code point as + its single-byte encoding, we can use a simplified method to convert the + string to a multibyte character string. */ +static wctype_t +is_char_class (const wchar_t *wcs) +{ + char s[CHAR_CLASS_MAX_LENGTH + 1]; + char *cp = s; - while ((c = *p++) != '\0') + do { - c = FOLD (c); - - switch (c) + /* Test for a printable character from the portable character set. */ +# ifdef _LIBC + if (*wcs < 0x20 || *wcs > 0x7e + || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) + return (wctype_t) 0; +# else + switch (*wcs) { - case '?': - if (*n == '\0') - return FNM_NOMATCH; - else if ((flags & FNM_FILE_NAME) && *n == '/') - return FNM_NOMATCH; - else if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) - return FNM_NOMATCH; + case L' ': case L'!': case L'"': case L'#': case L'%': + case L'&': case L'\'': case L'(': case L')': case L'*': + case L'+': case L',': case L'-': case L'.': case L'/': + case L'0': case L'1': case L'2': case L'3': case L'4': + case L'5': case L'6': case L'7': case L'8': case L'9': + case L':': case L';': case L'<': case L'=': case L'>': + case L'?': + case L'A': case L'B': case L'C': case L'D': case L'E': + case L'F': case L'G': case L'H': case L'I': case L'J': + case L'K': case L'L': case L'M': case L'N': case L'O': + case L'P': case L'Q': case L'R': case L'S': case L'T': + case L'U': case L'V': case L'W': case L'X': case L'Y': + case L'Z': + case L'[': case L'\\': case L']': case L'^': case L'_': + case L'a': case L'b': case L'c': case L'd': case L'e': + case L'f': case L'g': case L'h': case L'i': case L'j': + case L'k': case L'l': case L'm': case L'n': case L'o': + case L'p': case L'q': case L'r': case L's': case L't': + case L'u': case L'v': case L'w': case L'x': case L'y': + case L'z': case L'{': case L'|': case L'}': case L'~': break; + default: + return (wctype_t) 0; + } +# endif - case '\\': - if (!(flags & FNM_NOESCAPE)) - { - c = *p++; - if (c == '\0') - /* Trailing \ loses. */ - return FNM_NOMATCH; - c = FOLD (c); - } - if (FOLD (*n) != c) - return FNM_NOMATCH; - break; + /* Avoid overrunning the buffer. */ + if (cp == s + CHAR_CLASS_MAX_LENGTH) + return (wctype_t) 0; - case '*': - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) - return FNM_NOMATCH; + *cp++ = (char) *wcs++; + } + while (*wcs != L'\0'); - for (c = *p++; c == '?' || c == '*'; c = *p++) - { - if (c == '?') - { - /* A ? needs to match one character. */ - if (*n == '\0' || (*n == '/' && (flags & FNM_FILE_NAME))) - /* There isn't another character; no match. */ - return FNM_NOMATCH; - else - /* One character of the string is consumed in matching - this ? wildcard, so *??? won't match if there are - less than three characters. */ - ++n; - } - } + *cp = '\0'; - if (c == '\0') - { - if ((flags & (FNM_FILE_NAME | FNM_LEADING_DIR)) == FNM_FILE_NAME) - for (; *n != '\0'; n++) - if (*n == '/') - return FNM_NOMATCH; - return 0; - } +# ifdef _LIBC + return __wctype (s); +# else + return wctype (s); +# endif +} +# define IS_CHAR_CLASS(string) is_char_class (string) - { - char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; - c1 = FOLD (c1); - for (--p; *n != '\0'; ++n) - if ((c == '[' || FOLD (*n) == c1) && - fnmatch (p, n, flags & ~FNM_PERIOD) == 0) - return 0; - else if (*n == '/' && (flags & FNM_FILE_NAME)) - break; - return FNM_NOMATCH; - } - - case '[': - { - /* Nonzero if the sense of the character class is inverted. */ - register int not; - - if (*n == '\0') - return FNM_NOMATCH; - - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - not = (*p == '!' || *p == '^'); - if (not) - ++p; - - c = *p++; - for (;;) - { - register char cstart = c, cend = c; - - if (!(flags & FNM_NOESCAPE) && c == '\\') - { - if (*p == '\0') - return FNM_NOMATCH; - cstart = cend = *p++; - } - - cstart = cend = FOLD (cstart); - - if (c == '\0') - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - c = FOLD (c); - - if ((flags & FNM_FILE_NAME) && c == '/') - /* [/] can never match. */ - return FNM_NOMATCH; - - if (c == '-' && *p != ']') - { - cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == '\\') - cend = *p++; - if (cend == '\0') - return FNM_NOMATCH; - cend = FOLD (cend); - - c = *p++; - } - - if (FOLD (*n) >= cstart && FOLD (*n) <= cend) - goto matched; - - if (c == ']') - break; - } - if (!not) - return FNM_NOMATCH; - break; - - matched:; - /* Skip the rest of the [...] that already matched. */ - while (c != ']') - { - if (c == '\0') - /* [... (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - if (!(flags & FNM_NOESCAPE) && c == '\\') - { - if (*p == '\0') - return FNM_NOMATCH; - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; - } - } - if (not) - return FNM_NOMATCH; - } - break; +# include "fnmatch_loop.c" +# endif - default: - if (c != FOLD (*n)) - return FNM_NOMATCH; + +int +fnmatch (const char *pattern, const char *string, int flags) +{ +# if HANDLE_MULTIBYTE +# define ALLOCA_LIMIT 2000 + if (__builtin_expect (MB_CUR_MAX, 1) != 1) + { + mbstate_t ps; + size_t patsize; + size_t strsize; + size_t totsize; + wchar_t *wpattern; + wchar_t *wstring; + int res; + + /* Calculate the size needed to convert the strings to + wide characters. */ + memset (&ps, '\0', sizeof (ps)); + patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; + if (__builtin_expect (patsize == 0, 0)) + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + return -1; + assert (mbsinit (&ps)); + strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; + if (__builtin_expect (strsize == 0, 0)) + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + return -1; + assert (mbsinit (&ps)); + totsize = patsize + strsize; + if (__builtin_expect (! (patsize <= totsize + && totsize <= SIZE_MAX / sizeof (wchar_t)), + 0)) + { + errno = ENOMEM; + return -1; } - ++n; - } + /* Allocate room for the wide characters. */ + if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) + wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); + else + { + wpattern = malloc (totsize * sizeof (wchar_t)); + if (__builtin_expect (! wpattern, 0)) + { + errno = ENOMEM; + return -1; + } + } + wstring = wpattern + patsize; - if (*n == '\0') - return 0; + /* Convert the strings into wide characters. */ + mbsrtowcs (wpattern, &pattern, patsize, &ps); + assert (mbsinit (&ps)); + mbsrtowcs (wstring, &string, strsize, &ps); - if ((flags & FNM_LEADING_DIR) && *n == '/') - /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ - return 0; + res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, + flags & FNM_PERIOD, flags); - return FNM_NOMATCH; + if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) + free (wpattern); + return res; + } +# endif /* HANDLE_MULTIBYTE */ -#undef FOLD + return internal_fnmatch (pattern, string, string + strlen (string), + flags & FNM_PERIOD, flags); } + +# ifdef _LIBC +# undef fnmatch +versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); +# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) +strong_alias (__fnmatch, __fnmatch_old) +compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); +# endif +libc_hidden_ver (__fnmatch, fnmatch) +# endif + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/lib/getpass.c b/lib/getpass.c index 8daca0aee..4f520aef3 100644 --- a/lib/getpass.c +++ b/lib/getpass.c @@ -1,39 +1,109 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1992-2001, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + 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 library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. + 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 Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <termios.h> +#if HAVE_CONFIG_H +# include <config.h> +#endif -/* Alain: Parts originally from GNU Lib C. */ +#if !_LIBC +# include "getpass.h" +#endif -static void -echo_off(int fd, struct termios *stored_settings) -{ - struct termios new_settings; - tcgetattr (fd, stored_settings); - new_settings = *stored_settings; - new_settings.c_lflag &= (~ECHO); - tcsetattr (fd, TCSANOW, &new_settings); -} +#if _LIBC +# define HAVE_STDIO_EXT_H 1 +#endif + +#include <stdbool.h> + +#include <stdio.h> +#if HAVE_STDIO_EXT_H +# include <stdio_ext.h> +#else +# define __fsetlocking(stream, type) /* empty */ +#endif +#if !_LIBC +# include "getline.h" +#endif + +#include <termios.h> +#include <unistd.h> + +#if _LIBC +# include <wchar.h> +#endif + +#if _LIBC +# define NOTCANCEL_MODE "c" +#else +# define NOTCANCEL_MODE +#endif + +#if _LIBC +# define flockfile(s) _IO_flockfile (s) +# define funlockfile(s) _IO_funlockfile (s) +#elif 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 + +#if _LIBC +# include <bits/libc-lock.h> +#else +# define __libc_cleanup_push(function, arg) /* empty */ +# define __libc_cleanup_pop(execute) /* empty */ +#endif + +#if !_LIBC +# define __getline getline +# define __tcgetattr tcgetattr +#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 -echo_on(int fd, struct termios *stored_settings) +call_fclose (void *arg) { - tcsetattr (fd, TCSANOW, stored_settings); + if (arg != NULL) + fclose (arg); } @@ -41,40 +111,94 @@ echo_on(int fd, struct termios *stored_settings) char * -getpass (const char * prompt) +getpass (const char *prompt) { + FILE *tty; FILE *in, *out; - struct termios stored_settings; + struct termios s, t; + bool tty_changed; static char *buf; - static size_t buf_size; - char *pbuf; + 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. */ - /* First pass initialize the buffer. */ - if (buf_size == 0) + tty = fopen ("/dev/tty", "w+" NOTCANCEL_MODE); + if (tty == NULL) { - buf_size = 256; - buf = calloc (1, buf_size); - if (buf == NULL) - return NULL; + in = stdin; + out = stderr; } else - memset (buf, '\0', buf_size); + { + /* We do the locking ourselves. */ + __fsetlocking (tty, FSETLOCKING_BYCALLER); + + out = in = tty; + } + + /* Make sure the stream we opened is closed even if the thread is + canceled. */ + __libc_cleanup_push (call_fclose, tty); + + flockfile (out); /* Turn echoing off if it is on now. */ - echo_off (fileno (stdin), &stored_settings); + + 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); + } + else + tty_changed = false; /* Write the prompt. */ - fputs (prompt, stdout); - fflush (stdout); +#ifdef USE_IN_LIBIO + if (_IO_fwide (out, 0) > 0) + __fwprintf (out, L"%s", prompt); + else +#endif + fputs_unlocked (prompt, out); + fflush_unlocked (out); /* Read the password. */ - pbuf = fgets (buf, buf_size, stdin); - if (pbuf) + nread = __getline (&buf, &bufsize, in); + +#if !_LIBC + /* As far as is known, glibc doesn't need this no-op fseek. */ + + /* 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. */ + fseek (out, 0, SEEK_CUR); +#endif + + if (buf != NULL) { - size_t nread = strlen (pbuf); - if (nread && pbuf[nread - 1] == '\n') - { - /* Remove the newline. */ - pbuf[nread - 1] = '\0'; - /* Write the newline that was not echoed. */ - putc ('\n', stdout); - } + 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. */ +#ifdef USE_IN_LIBIO + if (_IO_fwide (out, 0) > 0) + putwc_unlocked (L'\n', out); + else +#endif + putc_unlocked ('\n', out); + } + } } @@ -82,18 +206,12 @@ getpass (const char * prompt) /* Restore the original setting. */ - echo_on (fileno (stdin), &stored_settings); + if (tty_changed) + (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s); - return pbuf; -} + funlockfile (out); -#ifdef _GETPASS_STANDALONE_TEST + __libc_cleanup_pop (0); -int -main () -{ - char *p; - p = getpass ("my prompt: "); - if (p) - printf ("Passwd: %s\n", p); - return 0; + call_fclose (tty); + + return buf; } -#endif diff --git a/lib/malloc.c b/lib/malloc.c index 1d198709a..ca04c57cd 100644 --- a/lib/malloc.c +++ b/lib/malloc.c @@ -1,3 +1,3 @@ -/* rpl_malloc.c -- a replacement for malloc that don't accept 0 size - Copyright (C) 2001 Free Software Foundation, Inc. +/* malloc() function that is glibc compatible. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. @@ -17,10 +17,20 @@ +/* written by Jim Meyering */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif +#undef malloc + #include <stdlib.h> +/* Allocate an N-byte block of memory from the heap. + If N is zero, allocate a 1-byte block. */ + void * -rpl_malloc(size_t size) +rpl_malloc (size_t n) { - if (!size) - size++; - return malloc(size); + if (n == 0) + n = 1; + return malloc (n); } diff --git a/lib/obstack.c b/lib/obstack.c index 3853c8c2f..63396131c 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -1,19 +1,31 @@ /* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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. + Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, + Inc. -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. + 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. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + 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. -#include "obstack.h" + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef _LIBC +# include <obstack.h> +# include <shlib-compat.h> +#else +# include "obstack.h" +#endif @@ -34,9 +46,14 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */ -#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 -#include <gnu-versions.h> -#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION -#define ELIDE_CODE +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include <gnu-versions.h> +# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION +# define ELIDE_CODE +# endif #endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include <wchar.h> #endif +#include <stddef.h> @@ -45,12 +62,21 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if defined (__STDC__) && __STDC__ -#define POINTER void * -#else -#define POINTER char * -#endif +# if HAVE_INTTYPES_H +# include <inttypes.h> +# endif +# if HAVE_STDINT_H || defined _LIBC +# include <stdint.h> +# endif /* Determine default alignment. */ -struct fooalign {char x; double d;}; -#define DEFAULT_ALIGNMENT \ - ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0)) +union fooround +{ + uintmax_t i; + long double d; + void *p; +}; +struct fooalign +{ + char c; + union fooround u; +}; /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. @@ -58,4 +84,7 @@ struct fooalign {char x; double d;}; DEFAULT_ROUNDING. So we prepare for it to do that. */ -union fooround {long x; double d;}; -#define DEFAULT_ROUNDING (sizeof (union fooround)) +enum + { + DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), + DEF |