diff options
-rw-r--r-- | lib/Makefile.am | 37 | ||||
-rw-r--r-- | lib/canonicalize-lgpl.c | 362 | ||||
-rw-r--r-- | lib/canonicalize.h | 52 | ||||
-rw-r--r-- | lib/malloca.c | 137 | ||||
-rw-r--r-- | lib/malloca.h | 134 | ||||
-rw-r--r-- | lib/malloca.valgrind | 7 | ||||
-rw-r--r-- | lib/pathmax.h | 47 | ||||
-rw-r--r-- | lib/readlink.c | 49 | ||||
-rw-r--r-- | lib/string.in.h | 17 | ||||
-rw-r--r-- | m4/canonicalize-lgpl.m4 | 35 | ||||
-rw-r--r-- | m4/eealloc.m4 | 32 | ||||
-rw-r--r-- | m4/gnulib-cache.m4 | 3 | ||||
-rw-r--r-- | m4/gnulib-comp.m4 | 18 | ||||
-rw-r--r-- | m4/malloca.m4 | 14 | ||||
-rw-r--r-- | m4/pathmax.m4 | 12 | ||||
-rw-r--r-- | m4/readlink.m4 | 29 | ||||
-rw-r--r-- | m4/string_h.m4 | 6 |
17 files changed, 986 insertions, 5 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 704c2bcaa..f488fa188 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap count-one-bits environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl count-one-bits environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects @@ -90,6 +90,15 @@ EXTRA_DIST += c-strcaseeq.h ## end gnulib module c-strcaseeq +## begin gnulib module canonicalize-lgpl + + +EXTRA_DIST += canonicalize-lgpl.c canonicalize.h + +EXTRA_libgnu_la_SOURCES += canonicalize-lgpl.c + +## end gnulib module canonicalize-lgpl + ## begin gnulib module configmake # Retrieve values of the variables through 'configure' followed by @@ -346,6 +355,14 @@ EXTRA_libgnu_la_SOURCES += malloc.c ## end gnulib module malloc-posix +## begin gnulib module malloca + +libgnu_la_SOURCES += malloca.c + +EXTRA_DIST += malloca.h malloca.valgrind + +## end gnulib module malloca + ## begin gnulib module mbrlen @@ -373,6 +390,13 @@ EXTRA_libgnu_la_SOURCES += mbsinit.c ## end gnulib module mbsinit +## begin gnulib module pathmax + + +EXTRA_DIST += pathmax.h + +## end gnulib module pathmax + ## begin gnulib module putenv @@ -382,6 +406,15 @@ EXTRA_libgnu_la_SOURCES += putenv.c ## end gnulib module putenv +## begin gnulib module readlink + + +EXTRA_DIST += readlink.c + +EXTRA_libgnu_la_SOURCES += readlink.c + +## end gnulib module readlink + ## begin gnulib module safe-read @@ -581,6 +614,7 @@ string.h: string.in.h -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ + -e 's|@''GNULIB_MEMCHR''@|$(GNULIB_MEMCHR)|g' \ -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ @@ -617,6 +651,7 @@ string.h: string.in.h -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c new file mode 100644 index 000000000..8bc24680f --- /dev/null +++ b/lib/canonicalize-lgpl.c @@ -0,0 +1,362 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-2003, 2005-2008 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 Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Avoid a clash of our rpl_realpath() function with the prototype in + <stdlib.h> on Solaris 2.5.1. */ +#undef realpath + +#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC + +#include <alloca.h> + +/* Specification. */ +#include "canonicalize.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#if HAVE_UNISTD_H || defined _LIBC +# include <unistd.h> +#endif + +#include <limits.h> + +#if HAVE_SYS_PARAM_H || defined _LIBC +# include <sys/param.h> +#endif +#ifndef MAXSYMLINKS +# define MAXSYMLINKS 20 +#endif + +#include <sys/stat.h> + +#include <errno.h> +#ifndef _LIBC +# define __set_errno(e) errno = (e) +# ifndef ENAMETOOLONG +# define ENAMETOOLONG EINVAL +# endif +#endif + +#ifdef _LIBC +# include <shlib-compat.h> +#else +# define SHLIB_COMPAT(lib, introduced, obsoleted) 0 +# define versioned_symbol(lib, local, symbol, version) +# define compat_symbol(lib, local, symbol, version) +# define weak_alias(local, symbol) +# define __canonicalize_file_name canonicalize_file_name +# define __realpath rpl_realpath +# include "pathmax.h" +# include "malloca.h" +# if HAVE_GETCWD +# ifdef VMS + /* We want the directory in Unix syntax, not in VMS syntax. */ +# define __getcwd(buf, max) getcwd (buf, max, 0) +# else +# define __getcwd getcwd +# endif +# else +# define __getcwd(buf, max) getwd (buf) +# endif +# define __readlink readlink + /* On systems without symbolic links, call stat() instead of lstat(). */ +# if !defined S_ISLNK && !HAVE_READLINK +# define lstat stat +# endif +#endif + +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any `.', `..' components nor any repeated path + separators ('/') or symlinks. All path components must exist. If + RESOLVED is null, the result is malloc'd; otherwise, if the + canonical name is PATH_MAX chars or more, returns null with `errno' + set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, + returns the name in RESOLVED. If the name cannot be resolved and + RESOLVED is non-NULL, it contains the path of the first component + that cannot be resolved. If the path can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + char *rpath, *dest, *extra_buf = NULL; + const char *start, *end, *rpath_limit; + long int path_max; +#if HAVE_READLINK + int num_links = 0; +#endif + + if (name == NULL) + { + /* As per Single Unix Specification V2 we must return an error if + either parameter is a null pointer. We extend this to allow + the RESOLVED parameter to be NULL in case the we are expected to + allocate the room for the return value. */ + __set_errno (EINVAL); + return NULL; + } + + if (name[0] == '\0') + { + /* As per Single Unix Specification V2 we must return an error if + the name argument points to an empty string. */ + __set_errno (ENOENT); + return NULL; + } + +#ifdef PATH_MAX + path_max = PATH_MAX; +#else + path_max = pathconf (name, _PC_PATH_MAX); + if (path_max <= 0) + path_max = 1024; +#endif + + if (resolved == NULL) + { + rpath = malloc (path_max); + if (rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'malloc-posix' gnulib module. */ + errno = ENOMEM; + return NULL; + } + } + else + rpath = resolved; + rpath_limit = rpath + path_max; + + if (name[0] != '/') + { + if (!__getcwd (rpath, path_max)) + { + rpath[0] = '\0'; + goto error; + } + dest = strchr (rpath, '\0'); + } + else + { + rpath[0] = '/'; + dest = rpath + 1; + } + + for (start = end = name; *start; start = end) + { +#ifdef _LIBC + struct stat64 st; +#else + struct stat st; +#endif + + /* Skip sequence of multiple path-separators. */ + while (*start == '/') + ++start; + + /* Find end of path component. */ + for (end = start; *end && *end != '/'; ++end) + /* Nothing. */; + + if (end - start == 0) + break; + else if (end - start == 1 && start[0] == '.') + /* nothing */; + else if (end - start == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + } + else + { + size_t new_size; + + if (dest[-1] != '/') + *dest++ = '/'; + + if (dest + (end - start) >= rpath_limit) + { + ptrdiff_t dest_offset = dest - rpath; + char *new_rpath; + + if (resolved) + { + __set_errno (ENAMETOOLONG); + if (dest > rpath + 1) + dest--; + *dest = '\0'; + goto error; + } + new_size = rpath_limit - rpath; + if (end - start + 1 > path_max) + new_size += end - start + 1; + else + new_size += path_max; + new_rpath = (char *) realloc (rpath, new_size); + if (new_rpath == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'realloc-posix' gnulib module. */ + errno = ENOMEM; + goto error; + } + rpath = new_rpath; + rpath_limit = rpath + new_size; + + dest = rpath + dest_offset; + } + +#ifdef _LIBC + dest = __mempcpy (dest, start, end - start); +#else + memcpy (dest, start, end - start); + dest += end - start; +#endif + *dest = '\0'; + +#ifdef _LIBC + if (__lxstat64 (_STAT_VER, rpath, &st) < 0) +#else + if (lstat (rpath, &st) < 0) +#endif + goto error; + +#if HAVE_READLINK + if (S_ISLNK (st.st_mode)) + { + char *buf; + size_t len; + int n; + + if (++num_links > MAXSYMLINKS) + { + __set_errno (ELOOP); + goto error; + } + + buf = malloca (path_max); + if (!buf) + { + errno = ENOMEM; + goto error; + } + + n = __readlink (rpath, buf, path_max - 1); + if (n < 0) + { + int saved_errno = errno; + freea (buf); + errno = saved_errno; + goto error; + } + buf[n] = '\0'; + + if (!extra_buf) + { + extra_buf = malloca (path_max); + if (!extra_buf) + { + freea (buf); + errno = ENOMEM; + goto error; + } + } + + len = strlen (end); + if ((long int) (n + len) >= path_max) + { + freea (buf); + __set_errno (ENAMETOOLONG); + goto error; + } + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + + if (buf[0] == '/') + dest = rpath + 1; /* It's an absolute symlink */ + else + /* Back up to previous component, ignore if at root already: */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + } +#endif + } + } + if (dest > rpath + 1 && dest[-1] == '/') + --dest; + *dest = '\0'; + + if (extra_buf) + freea (extra_buf); + + return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; + +error: + { + int saved_errno = errno; + if (extra_buf) + freea (extra_buf); + if (resolved) + strcpy (resolved, rpath); + else + free (rpath); + errno = saved_errno; + } + return NULL; +} +#ifdef _LIBC +versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); +#endif + + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) +char * +__old_realpath (const char *name, char *resolved) +{ + if (resolved == NULL) + { + __set_errno (EINVAL); + return NULL; + } + + return __realpath (name, resolved); +} +compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0); +#endif + + +char * +__canonicalize_file_name (const char *name) +{ + return __realpath (name, NULL); +} +weak_alias (__canonicalize_file_name, canonicalize_file_name) + +#else + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#endif diff --git a/lib/canonicalize.h b/lib/canonicalize.h new file mode 100644 index 000000000..184cf1637 --- /dev/null +++ b/lib/canonicalize.h @@ -0,0 +1,52 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-2007 Free Software Foundation, Inc. + + This program 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 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef CANONICALIZE_H_ +# define CANONICALIZE_H_ + +# if GNULIB_CANONICALIZE +enum canonicalize_mode_t + { + /* All components must exist. */ + CAN_EXISTING = 0, + + /* All components excluding last one must exist. */ + CAN_ALL_BUT_LAST = 1, + + /* No requirements on components existence. */ + CAN_MISSING = 2 + }; +typedef enum canonicalize_mode_t canonicalize_mode_t; + +/* Return a malloc'd string containing the canonical absolute name of + the named file. This acts like canonicalize_file_name, except that + whether components must exist depends on the canonicalize_mode_t + argument. */ +char *canonicalize_filename_mode (const char *, canonicalize_mode_t); +# endif + +# if HAVE_DECL_CANONICALIZE_FILE_NAME +# include <stdlib.h> +# else +/* Return a malloc'd string containing the canonical absolute name of + the named file. If any file name component does not exist or is a + symlink to a nonexistent file, return NULL. A canonical name does + not contain any `.', `..' components nor any repeated file name + separators ('/') or symlinks. */ +char *canonicalize_file_name (const char *); +# endif + +#endif /* !CANONICALIZE_H_ */ diff --git a/lib/malloca.c b/lib/malloca.c new file mode 100644 index 000000000..7905e6152 --- /dev/null +++ b/lib/malloca.c @@ -0,0 +1,137 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003, 2006-2007 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program 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, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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 "malloca.h" + +/* The speed critical point in this file is freea() applied to an alloca() + result: it must be fast, to match the speed of alloca(). The speed of + mmalloca() and freea() in the other case are not critical, because they + are only invoked for big memory sizes. */ + +#if HAVE_ALLOCA + +/* Store the mmalloca() results in a hash table. This is needed to reliably + distinguish a mmalloca() result and an alloca() result. + + Although it is possible that the same pointer is returned by alloca() and + by mmalloca() at different times in the same application, it does not lead + to a bug in freea(), because: + - Before a pointer returned by alloca() can point into malloc()ed memory, + the function must return, and once this has happened the programmer must + not call freea() on it anyway. + - Before a pointer returned by mmalloca() can point into the stack, it + must be freed. The only function that can free it is freea(), and + when freea() frees it, it also removes it from the hash table. */ + +#define MAGIC_NUMBER 0x1415fb4a +#define MAGIC_SIZE sizeof (int) +/* This is how the header info would look like without any alignment + considerations. */ +struct preliminary_header { void *next; char room[MAGIC_SIZE]; }; +/* But the header's size must be a multiple of sa_alignment_max. */ +#define HEADER_SIZE \ + (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) +struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; }; +/* Verify that HEADER_SIZE == sizeof (struct header). */ +typedef int verify1[2 * (HEADER_SIZE == sizeof (struct header)) - 1]; +/* We make the hash table quite big, so that during lookups the probability + of empty hash buckets is quite high. There is no need to make the hash + table resizable, because when the hash table gets filled so much that the + lookup becomes slow, it means that the application has memory leaks. */ +#define HASH_TABLE_SIZE 257 +static void * mmalloca_results[HASH_TABLE_SIZE]; + +#endif + +void * +mmalloca (size_t n) +{ +#if HAVE_ALLOCA + /* Allocate one more word, that serves as an indicator for malloc()ed + memory, so that freea() of an alloca() result is fast. */ + size_t nplus = n + HEADER_SIZE; + + if (nplus >= n) + { + char *p = (char *) malloc (nplus); + + if (p != NULL) + { + size_t slot; + + p += HEADER_SIZE; + + /* Put a magic number into the indicator word. */ + ((int *) p)[-1] = MAGIC_NUMBER; + + /* Enter p into the hash table. */ + slot = (unsigned long) p % HASH_TABLE_SIZE; + ((struct header *) (p - HEADER_SIZE))->next = mmalloca_results[slot]; + mmalloca_results[slot] = p; + + return p; + } + } + /* Out of memory. */ + return NULL; +#else +# if !MALLOC_0_IS_NONNULL + if (n == 0) + n = 1; +# endif + return malloc (n); +#endif +} + +#if HAVE_ALLOCA +void +freea (void *p) +{ + /* mmalloca() may have returned NULL. */ + if (p != NULL) + { + /* Attempt to quickly distinguish the mmalloca() result - which has + a magic indicator word - and the alloca() result - which has an + uninitialized indicator word. It is for this test that sa_increment + additional bytes are allocated in the alloca() case. */ + if (((int *) p)[-1] == MAGIC_NUMBER) + { + /* Looks like a mmalloca() result. To see whether it really is one, + perform a lookup in the hash table. */ + size_t slot = (unsigned long) p % HASH_TABLE_SIZE; + void **chain = &mmalloca_results[slot]; + for (; *chain != NULL;) + { + if (*chain == p) + { + /* Found it. Remove it from the hash table and free it. */ + char *p_begin = (char *) p - HEADER_SIZE; + *chain = ((struct header *) p_begin)->next; + free (p_begin); + return; + } + chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next; + } + } + /* At this point, we know it was not a mmalloca() result. */ + } +} +#endif diff --git a/lib/malloca.h b/lib/malloca.h new file mode 100644 index 000000000..7d92b0af5 --- /dev/null +++ b/lib/malloca.h @@ -0,0 +1,134 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003-2007 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2003. + + This program 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, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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 _MALLOCA_H +#define _MALLOCA_H + +#include <alloca.h> +#include <stddef.h> +#include <stdlib.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call + alloca(N); otherwise it returns NULL. It either returns N bytes of + memory allocated on the stack, that lasts until the function returns, + or NULL. + Use of safe_alloca should be avoided: + - inside arguments of function calls - undefined behaviour, + - in inline functions - the allocation may actually last until the + calling function returns. +*/ +#if HAVE_ALLOCA +/* The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. + This must be a macro, not an inline function. */ +# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) +#else +# define safe_alloca(N) ((void) (N), NULL) +#endif + +/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of + memory allocated on the stack, that must be freed using freea() before + the function returns. Upon failure, it returns NULL. */ +#if HAVE_ALLOCA +# define malloca(N) \ + ((N) < 4032 - sa_increment \ + ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ + : mmalloca (N)) +#else +# define malloca(N) \ + mmalloca (N) +#endif +extern void * mmalloca (size_t n); + +/* Free a block of memory allocated through malloca(). */ +#if HAVE_ALLOCA +extern void freea (void *p); +#else +# define freea free +#endif + +/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). + It allocates an array of N objects, each with S bytes of memory, + on the stack. S must be positive and N must be nonnegative. + The array must be freed using freea() before the function returns. */ +#if 1 +/* Cf. the definition of xalloc_oversized. */ +# define nmalloca(n, s) \ + ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ + ? NULL \ + : malloca ((n) * (s))) +#else +extern void * nmalloca (size_t n, size_t s); +#endif + + +#ifdef __cplusplus +} +#endif + + +/* ------------------- Auxiliary, non-public definitions ------------------- */ + +/* Determine the alignment of a type at compile time. */ +#if defined __GNUC__ +# define sa_alignof __alignof__ +#elif defined __cplusplus + template <class type> struct sa_alignof_helper { char __slot1; type __slot2; }; +# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2) +#elif defined __hpux + /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#elif defined _AIX + /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#else +# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2) +#endif + +enum +{ +/* The desired alignment of memory allocations is the maximum alignment + among all elementary types. */ + sa_alignment_long = sa_alignof (long), + sa_alignment_double = sa_alignof (double), +#if HAVE_LONG_LONG_INT + sa_alignment_longlong = sa_alignof (long long), +#endif + sa_alignment_longdouble = sa_alignof (long double), + sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) +#if HAVE_LONG_LONG_INT + | (sa_alignment_longlong - 1) +#endif + | (sa_alignment_longdouble - 1) + ) + 1, +/* The increment that guarantees room for a magic word must be >= sizeof (int) + and a multiple of sa_alignment_max. */ + sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max +}; + +#endif /* _MALLOCA_H */ diff --git a/lib/malloca.valgrind b/lib/malloca.valgrind new file mode 100644 index 000000000..52f0a50f5 --- /dev/null +++ b/lib/malloca.valgrind @@ -0,0 +1,7 @@ +# Suppress a valgrind message about use of uninitialized memory in freea(). +# This use is OK because it provides only a speedup. +{ + freea + Memcheck:Cond + fun:freea +} diff --git a/lib/pathmax.h b/lib/pathmax.h new file mode 100644 index 000000000..a5d433560 --- /dev/null +++ b/lib/pathmax.h @@ -0,0 +1,47 @@ +/* Define PATH_MAX somehow. Requires sys/types.h. + Copyright (C) 1992, 1999, 2001, 2003, 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 Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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 _PATHMAX_H +# define _PATHMAX_H + +# include <unistd.h> + +# include <limits.h> + +# ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 256 +# endif + +# if !defined PATH_MAX && defined _PC_PATH_MAX && defined HAVE_PATHCONF +# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \ + : pathconf ("/", _PC_PATH_MAX)) +# endif + +/* Don't include sys/param.h if it already has been. */ +# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN +# include <sys/param.h> +# endif + +# if !defined PATH_MAX && defined MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# endif + +# ifndef PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +# endif + +#endif /* _PATHMAX_H */ diff --git a/lib/readlink.c b/lib/readlink.c new file mode 100644 index 000000000..c9f49f815 --- /dev/null +++ b/lib/readlink.c @@ -0,0 +1,49 @@ +/* Stub for readlink(). + Copyright (C) 2003-2007 Free Software Foundation, Inc. + + This program 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 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <unistd.h> + +#include <errno.h> +#include <sys/types.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) +{ + 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 + stat(), therefore we can use stat(). This saves us a configure check. */ + if (stat (path, &statbuf) >= 0) + errno = EINVAL; + return -1; +} + +#endif diff --git a/lib/string.in.h b/lib/string.in.h index ca029d7c0..fe1142562 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -1,6 +1,6 @@ /* A GNU-like <string.h>. - Copyright (C) 1995-1996, 2001-2008 Free Software Foundation, Inc. + Copyright (C) 1995-1996, 2001-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -49,6 +49,21 @@ extern "C" { #endif +/* Return the first instance of C within N bytes of S, or NULL. */ +#if @GNULIB_MEMCHR@ +# if @REPLACE_MEMCHR@ +# define memchr rpl_memchr +extern void *memchr (void const *__s, int __c, size_t __n) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memchr +# define memchr(s,c,n) \ + (GL_LINK_WARNING ("memchr has platform-specific bugs - " \ + "use gnulib module memchr for portability" ), \ + memchr (s, c, n)) +#endif + /* Return the first occurrence of NEEDLE in HAYSTACK. */ #if @GNULIB_MEMMEM@ # if @REPLACE_MEMMEM@ diff --git a/m4/canonicalize-lgpl.m4 b/m4/canonicalize-lgpl.m4 new file mode 100644 index 000000000..3a8ee2f95 --- /dev/null +++ b/m4/canonicalize-lgpl.m4 @@ -0,0 +1,35 @@ +# canonicalize-lgpl.m4 serial 5 +dnl Copyright (C) 2003, 2006-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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_CANONICALIZE_LGPL], +[ + dnl Do this replacement check manually because the file name is shorter + dnl than the function name. + AC_CHECK_DECLS_ONCE([canonicalize_file_name]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + if test $ac_cv_func_canonicalize_file_name = no; then + AC_LIBOBJ([canonicalize-lgpl]) + AC_DEFINE([realpath], [rpl_realpath], + [Define to a replacement function name for realpath().]) + gl_PREREQ_CANONICALIZE_LGPL + fi +]) + +# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation +# (no AC_LIBOBJ). +AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], +[ + AC_CHECK_DECLS_ONCE([canonicalize_file_name]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + gl_PREREQ_CANONICALIZE_LGPL +]) + +# Prerequisites of lib/canonicalize-lgpl.c. +AC_DEFUN([gl_PREREQ_CANONICALIZE_LGPL], +[ + AC_CHECK_HEADERS_ONCE([sys/param.h unistd.h]) + AC_CHECK_FUNCS_ONCE([getcwd readlink]) +]) diff --git a/m4/eealloc.m4 b/m4/eealloc.m4 new file mode 100644 index 000000000..3c9c0b52a --- /dev/null +++ b/m4/eealloc.m4 @@ -0,0 +1,32 @@ +# eealloc.m4 serial 2 +dnl Copyright (C) 2003, 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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_EEALLOC], +[ + AC_REQUIRE([gl_EEMALLOC]) + AC_REQUIRE([gl_EEREALLOC]) + AC_REQUIRE([AC_C_INLINE]) +]) + +AC_DEFUN([gl_EEMALLOC], +[ + _AC_FUNC_MALLOC_IF( + [gl_cv_func_malloc_0_nonnull=1], + [gl_cv_func_malloc_0_nonnull=0]) + AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], + [If malloc(0) is != NULL, define this to 1. Otherwise define this + to 0.]) +]) + +AC_DEFUN([gl_EEREALLOC], +[ + _AC_FUNC_REALLOC_IF( + [gl_cv_func_realloc_0_nonnull=1], + [gl_cv_func_realloc_0_nonnull=0]) + AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], + [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this + to 0.]) +]) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index a45029493..e70283f41 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,7 +15,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap count-one-bits environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string +# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl count-one-bits environ extensions flock fpieee full-read full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -23,6 +23,7 @@ gl_MODULES([ alloca-opt autobuild byteswap + canonicalize-lgpl count-one-bits environ extensions diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 8f775107e..ef0534ef8 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -46,6 +46,8 @@ AC_DEFUN([gl_INIT], gl_source_base='lib' gl_FUNC_ALLOCA gl_BYTESWAP + gl_CANONICALIZE_LGPL + gl_MODULE_INDICATOR([canonicalize-lgpl]) gl_COUNT_ONE_BITS gl_ENVIRON gl_UNISTD_MODULE_INDICATOR([environ]) @@ -63,6 +65,7 @@ AC_DEFUN([gl_INIT], AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) gl_FUNC_MALLOC_POSIX gl_STDLIB_MODULE_INDICATOR([malloc-posix]) + gl_MALLOCA gl_FUNC_MBRLEN gl_WCHAR_MODULE_INDICATOR([mbrlen]) gl_FUNC_MBRTOWC @@ -70,8 +73,11 @@ AC_DEFUN([gl_INIT], gl_FUNC_MBSINIT gl_WCHAR_MODULE_INDICATOR([mbsinit]) gl_MULTIARCH + gl_PATHMAX gl_FUNC_PUTENV gl_STDLIB_MODULE_INDICATOR([putenv]) + gl_FUNC_READLINK + gl_UNISTD_MODULE_INDICATOR([readlink]) gl_SAFE_READ gl_SAFE_WRITE gt_TYPE_SSIZE_T @@ -236,6 +242,8 @@ AC_DEFUN([gl_FILE_LIST], [ lib/c-strcasecmp.c lib/c-strcaseeq.h lib/c-strncasecmp.c + lib/canonicalize-lgpl.c + lib/canonicalize.h lib/config.charset lib/count-one-bits.h lib/flock.c @@ -255,10 +263,15 @@ AC_DEFUN([gl_FILE_LIST], [ lib/localcharset.c lib/localcharset.h lib/malloc.c + lib/malloca.c + lib/malloca.h + lib/malloca.valgrind lib/mbrlen.c lib/mbrtowc.c lib/mbsinit.c + lib/pathmax.h lib/putenv.c + lib/readlink.c lib/ref-add.sin lib/ref-del.sin lib/safe-read.c @@ -298,8 +311,10 @@ AC_DEFUN([gl_FILE_LIST], [ m4/alloca.m4 m4/autobuild.m4 m4/byteswap.m4 + m4/canonicalize-lgpl.m4 m4/codeset.m4 m4/count-one-bits.m4 + m4/eealloc.m4 m4/environ.m4 m4/extensions.m4 m4/flock.m4 @@ -321,12 +336,15 @@ AC_DEFUN([gl_FILE_LIST], [ m4/locale-zh.m4 m4/longlong.m4 m4/malloc.m4 + m4/malloca.m4 m4/mbrlen.m4 m4/mbrtowc.m4 m4/mbsinit.m4 m4/mbstate_t.m4 m4/multiarch.m4 + m4/pathmax.m4 m4/putenv.m4 + m4/readlink.m4 m4/safe-read.m4 m4/safe-write.m4 m4/ssize_t.m4 diff --git a/m4/malloca.m4 b/m4/malloca.m4 new file mode 100644 index 000000000..2841ae83a --- /dev/null +++ b/m4/malloca.m4 @@ -0,0 +1,14 @@ +# malloca.m4 serial 1 +dnl Copyright (C) 2003-2004, 2006-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_MALLOCA], +[ + dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables + dnl @ALLOCA@ and @LTALLOCA@. + dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. + AC_REQUIRE([gl_EEMALLOC]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) +]) diff --git a/m4/pathmax.m4 b/m4/pathmax.m4 new file mode 100644 index 000000000..465180161 --- /dev/null +++ b/m4/pathmax.m4 @@ -0,0 +1,12 @@ +# pathmax.m4 serial 8 +dnl Copyright (C) 2002, 2003, 2005, 2006, 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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_PATHMAX], +[ + dnl Prerequisites of lib/pathmax.h. + AC_CHECK_FUNCS_ONCE([pathconf]) + AC_CHECK_HEADERS_ONCE([sys/param.h]) +]) diff --git a/m4/readlink.m4 b/m4/readlink.m4 new file mode 100644 index 000000000..ff3f1f587 --- /dev/null +++ b/m4/readlink.m4 @@ -0,0 +1,29 @@ +# readlink.m4 serial 5 +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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_READLINK], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([readlink]) + if test $ac_cv_func_readlink = no; then + HAVE_READLINK=0 + AC_LIBOBJ([readlink]) + gl_PREREQ_READLINK + fi +]) + +# Like gl_FUNC_READLINK, except prepare for separate compilation (no AC_LIBOBJ). +AC_DEFUN([gl_FUNC_READLINK_SEPARATE], +[ + AC_CHECK_FUNCS_ONCE([readlink]) + gl_PREREQ_READLINK +]) + +# Prerequisites of lib/readlink.c. +AC_DEFUN([gl_PREREQ_READLINK], +[ + : +]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index 2d5553c37..11f09c8b8 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -1,11 +1,11 @@ # Configure a GNU-like replacement for <string.h>. -# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 +# serial 7 # Written by Paul Eggert. @@ -32,6 +32,7 @@ AC_DEFUN([gl_STRING_MODULE_INDICATOR], AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], [ + GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) @@ -83,6 +84,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], HAVE_DECL_STRERROR=1; AC_SUBST([HAVE_DECL_STRERROR]) HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) |