diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-06-27 13:30:12 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-06-27 13:30:12 +0000 |
commit | a0fb51e136d3df620eb3189683aae90b25bd8dd7 (patch) | |
tree | 5a07d715690693d7f7ff6b7dc2761a0cbd5dc42f /lib | |
parent | ac8690fc4e1f697b89e00a0335eeaf6d27b33288 (diff) | |
download | tar-a0fb51e136d3df620eb3189683aae90b25bd8dd7.tar.gz |
Relicense under GPLv3
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/prepargs.c | 4 | ||||
-rw-r--r-- | lib/printf-parse.c | 535 | ||||
-rw-r--r-- | lib/stdopen.c | 4 | ||||
-rw-r--r-- | lib/vasnprintf.c | 918 | ||||
-rw-r--r-- | lib/waitpid.c | 75 |
6 files changed, 6 insertions, 1534 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index b9fc8a45..466a477a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,11 +1,11 @@ # Makefile for GNU tar library. -*- Makefile -*- # Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# 2005, 2006, 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 of the License, or +# 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, diff --git a/lib/prepargs.c b/lib/prepargs.c index 1b0d9f5e..1b6b0ce6 100644 --- a/lib/prepargs.c +++ b/lib/prepargs.c @@ -1,9 +1,9 @@ /* Parse arguments from a string and prepend them to an argv. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 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) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/lib/printf-parse.c b/lib/printf-parse.c deleted file mode 100644 index f8e0ceda..00000000 --- a/lib/printf-parse.c +++ /dev/null @@ -1,535 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 1999-2000, 2002-2004, 2006 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. */ -#if WIDE_CHAR_VERSION -# include "wprintf-parse.h" -#else -# include "printf-parse.h" -#endif - -/* Get size_t, NULL. */ -#include <stddef.h> - -/* Get intmax_t. */ -#if HAVE_STDINT_H_WITH_UINTMAX -# include <stdint.h> -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -# include <inttypes.h> -#endif - -/* malloc(), realloc(), free(). */ -#include <stdlib.h> - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#if WIDE_CHAR_VERSION -# define PRINTF_PARSE wprintf_parse -# define CHAR_T wchar_t -# define DIRECTIVE wchar_t_directive -# define DIRECTIVES wchar_t_directives -#else -# define PRINTF_PARSE printf_parse -# define CHAR_T char -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -#endif - -#ifdef STATIC -STATIC -#endif -int -PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) -{ - const CHAR_T *cp = format; /* pointer into format */ - size_t arg_posn = 0; /* number of regular arguments consumed */ - size_t d_allocated; /* allocated elements of d->dir */ - size_t a_allocated; /* allocated elements of a->arg */ - size_t max_width_length = 0; - size_t max_precision_length = 0; - - d->count = 0; - d_allocated = 1; - d->dir = malloc (d_allocated * sizeof (DIRECTIVE)); - if (d->dir == NULL) - /* Out of memory. */ - return -1; - - a->count = 0; - a_allocated = 0; - a->arg = NULL; - -#define REGISTER_ARG(_index_,_type_) \ - { \ - size_t n = (_index_); \ - if (n >= a_allocated) \ - { \ - size_t memory_size; \ - argument *memory; \ - \ - a_allocated *= 2; \ - if (a_allocated <= n) \ - a_allocated = n + 1; \ - if (SIZE_MAX / sizeof (argument) < a_allocated) \ - /* Overflow, would lead to out of memory. */ \ - goto error; \ - memory_size = a_allocated * sizeof (argument); \ - memory = (a->arg \ - ? realloc (a->arg, memory_size) \ - : malloc (memory_size)); \ - if (memory == NULL) \ - /* Out of memory. */ \ - goto error; \ - a->arg = memory; \ - } \ - while (a->count <= n) \ - a->arg[a->count++].type = TYPE_NONE; \ - if (a->arg[n].type == TYPE_NONE) \ - a->arg[n].type = (_type_); \ - else if (a->arg[n].type != (_type_)) \ - /* Ambiguous type for positional argument. */ \ - goto error; \ - } - - while (*cp != '\0') - { - CHAR_T c = *cp++; - if (c == '%') - { - size_t arg_index = ARG_NONE; - DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */ - - /* Initialize the next directive. */ - dp->dir_start = cp - 1; - dp->flags = 0; - dp->width_start = NULL; - dp->width_end = NULL; - dp->width_arg_index = ARG_NONE; - dp->precision_start = NULL; - dp->precision_end = NULL; - dp->precision_arg_index = ARG_NONE; - dp->arg_index = ARG_NONE; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - if (n < SIZE_MAX / 10) - n = 10 * n + (*np - '0'); - else - /* n too large for memory. */ - goto error; - if (n == 0) - /* Positional argument 0. */ - goto error; - arg_index = n - 1; - cp = np + 1; - } - } - - /* Read the flags. */ - for (;;) - { - if (*cp == '\'') - { - dp->flags |= FLAG_GROUP; - cp++; - } - else if (*cp == '-') - { - dp->flags |= FLAG_LEFT; - cp++; - } - else if (*cp == '+') - { - dp->flags |= FLAG_SHOWSIGN; - cp++; - } - else if (*cp == ' ') - { - dp->flags |= FLAG_SPACE; - cp++; - } - else if (*cp == '#') - { - dp->flags |= FLAG_ALT; - cp++; - } - else if (*cp == '0') - { - dp->flags |= FLAG_ZERO; - cp++; - } - else - break; - } - - /* Parse the field width. */ - if (*cp == '*') - { - dp->width_start = cp; - cp++; - dp->width_end = cp; - if (max_width_length < 1) - max_width_length = 1; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - if (n < SIZE_MAX / 10) - n = 10 * n + (*np - '0'); - else - /* n too large for memory. */ - goto error; - if (n == 0) - /* Positional argument 0. */ - goto error; - dp->width_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->width_arg_index == ARG_NONE) - { - dp->width_arg_index = arg_posn++; - if (dp->width_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->width_arg_index, TYPE_INT); - } - else if (*cp >= '0' && *cp <= '9') - { - size_t width_length; - - dp->width_start = cp; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->width_end = cp; - width_length = dp->width_end - dp->width_start; - if (max_width_length < width_length) - max_width_length = width_length; - } - - /* Parse the precision. */ - if (*cp == '.') - { - cp++; - if (*cp == '*') - { - dp->precision_start = cp - 1; - cp++; - dp->precision_end = cp; - if (max_precision_length < 2) - max_precision_length = 2; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - if (n < SIZE_MAX / 10) - n = 10 * n + (*np - '0'); - else - /* n too large for memory. */ - goto error; - if (n == 0) - /* Positional argument 0. */ - goto error; - dp->precision_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->precision_arg_index == ARG_NONE) - { - dp->precision_arg_index = arg_posn++; - if (dp->precision_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->precision_arg_index, TYPE_INT); - } - else - { - size_t precision_length; - - dp->precision_start = cp - 1; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->precision_end = cp; - precision_length = dp->precision_end - dp->precision_start; - if (max_precision_length < precision_length) - max_precision_length = precision_length; - } - } - - { - arg_type type; - - /* Parse argument type/size specifiers. */ - { - int flags = 0; - - for (;;) - { - if (*cp == 'h') - { - flags |= (1 << (flags & 1)); - cp++; - } - else if (*cp == 'L') - { - flags |= 4; - cp++; - } - else if (*cp == 'l') - { - flags += 8; - cp++; - } -#ifdef HAVE_INTMAX_T - else if (*cp == 'j') - { - if (sizeof (intmax_t) > sizeof (long)) - { - /* intmax_t = long long */ - flags += 16; - } - else if (sizeof (intmax_t) > sizeof (int)) - { - /* intmax_t = long */ - flags += 8; - } - cp++; - } -#endif - else if (*cp == 'z' || *cp == 'Z') - { - /* 'z' is standardized in ISO C 99, but glibc uses 'Z' - because the warning facility in gcc-2.95.2 understands - only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ - if (sizeof (size_t) > sizeof (long)) - { - /* size_t = long long */ - flags += 16; - } - else if (sizeof (size_t) > sizeof (int)) - { - /* size_t = long */ - flags += 8; - } - cp++; - } - else if (*cp == 't') - { - if (sizeof (ptrdiff_t) > sizeof (long)) - { - /* ptrdiff_t = long long */ - flags += 16; - } - else if (sizeof (ptrdiff_t) > sizeof (int)) - { - /* ptrdiff_t = long */ - flags += 8; - } - cp++; - } - else - break; - } - - /* Read the conversion character. */ - c = *cp++; - switch (c) - { - case 'd': case 'i': -#ifdef HAVE_LONG_LONG - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGLONGINT; - else -#endif - if (flags >= 8) - type = TYPE_LONGINT; - else if (flags & 2) - type = TYPE_SCHAR; - else if (flags & 1) - type = TYPE_SHORT; - else - type = TYPE_INT; - break; - case 'o': case 'u': case 'x': case 'X': -#ifdef HAVE_LONG_LONG - if (flags >= 16 || (flags & 4)) - type = TYPE_ULONGLONGINT; - else -#endif - if (flags >= 8) - type = TYPE_ULONGINT; - else if (flags & 2) - type = TYPE_UCHAR; - else if (flags & 1) - type = TYPE_USHORT; - else - type = TYPE_UINT; - break; - case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': -#ifdef HAVE_LONG_DOUBLE - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGDOUBLE; - else -#endif - type = TYPE_DOUBLE; - break; - case 'c': - if (flags >= 8) -#ifdef HAVE_WINT_T - type = TYPE_WIDE_CHAR; -#else - goto error; -#endif - else - type = TYPE_CHAR; - break; -#ifdef HAVE_WINT_T - case 'C': - type = TYPE_WIDE_CHAR; - c = 'c'; - break; -#endif - case 's': - if (flags >= 8) -#ifdef HAVE_WCHAR_T - type = TYPE_WIDE_STRING; -#else - goto error; -#endif - else - type = TYPE_STRING; - break; -#ifdef HAVE_WCHAR_T - case 'S': - type = TYPE_WIDE_STRING; - c = 's'; - break; -#endif - case 'p': - type = TYPE_POINTER; - break; - case 'n': -#ifdef HAVE_LONG_LONG - if (flags >= 16 || (flags & 4)) - type = TYPE_COUNT_LONGLONGINT_POINTER; - else -#endif - if (flags >= 8) - type = TYPE_COUNT_LONGINT_POINTER; - else if (flags & 2) - type = TYPE_COUNT_SCHAR_POINTER; - else if (flags & 1) - type = TYPE_COUNT_SHORT_POINTER; - else - type = TYPE_COUNT_INT_POINTER; - break; - case '%': - type = TYPE_NONE; - break; - default: - /* Unknown conversion character. */ - goto error; - } - } - - if (type != TYPE_NONE) - { - dp->arg_index = arg_index; - if (dp->arg_index == ARG_NONE) - { - dp->arg_index = arg_posn++; - if (dp->arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->arg_index, type); - } - dp->conversion = c; - dp->dir_end = cp; - } - - d->count++; - if (d->count >= d_allocated) - { - DIRECTIVE *memory; - - if (SIZE_MAX / (2 * sizeof (DIRECTIVE)) < d_allocated) - /* Overflow, would lead to out of memory. */ - goto error; - d_allocated *= 2; - memory = realloc (d->dir, d_allocated * sizeof (DIRECTIVE)); - if (memory == NULL) - /* Out of memory. */ - goto error; - d->dir = memory; - } - } - } - d->dir[d->count].dir_start = cp; - - d->max_width_length = max_width_length; - d->max_precision_length = max_precision_length; - return 0; - -error: - if (a->arg) - free (a->arg); - if (d->dir) - free (d->dir); - return -1; -} - -#undef DIRECTIVES -#undef DIRECTIVE -#undef CHAR_T -#undef PRINTF_PARSE diff --git a/lib/stdopen.c b/lib/stdopen.c index 92825b58..0b637ad1 100644 --- a/lib/stdopen.c +++ b/lib/stdopen.c @@ -1,10 +1,10 @@ /* stdopen.c - ensure that the three standard file descriptors are in use - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 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) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c deleted file mode 100644 index 78ead8e3..00000000 --- a/lib/vasnprintf.c +++ /dev/null @@ -1,918 +0,0 @@ -/* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2006 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. */ - -/* Tell glibc's <stdio.h> to provide a prototype for snprintf(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#include <config.h> - -#ifndef IN_LIBINTL -# include <alloca.h> -#endif - -/* Specification. */ -#if WIDE_CHAR_VERSION -# include "vasnwprintf.h" -#else -# include "vasnprintf.h" -#endif - -#include <stdio.h> /* snprintf(), sprintf() */ -#include <stdlib.h> /* abort(), malloc(), realloc(), free() */ -#include <string.h> /* memcpy(), strlen() */ -#include <errno.h> /* errno */ -#include <limits.h> /* CHAR_BIT, INT_MAX */ -#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */ -#if WIDE_CHAR_VERSION -# include "wprintf-parse.h" -#else -# include "printf-parse.h" -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ -#ifndef EOVERFLOW -# define EOVERFLOW E2BIG -#endif - -#ifdef HAVE_WCHAR_T -# ifdef HAVE_WCSLEN -# define local_wcslen wcslen -# else - /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid - a dependency towards this library, here is a local substitute. - Define this substitute only once, even if this file is included - twice in the same compilation unit. */ -# ifndef local_wcslen_defined -# define local_wcslen_defined 1 -static size_t -local_wcslen (const wchar_t *s) -{ - const wchar_t *ptr; - - for (ptr = s; *ptr != (wchar_t) 0; ptr++) - ; - return ptr - s; -} -# endif -# endif -#endif - -#if WIDE_CHAR_VERSION -# define VASNPRINTF vasnwprintf -# define CHAR_T wchar_t -# define DIRECTIVE wchar_t_directive -# define DIRECTIVES wchar_t_directives -# define PRINTF_PARSE wprintf_parse -# define USE_SNPRINTF 1 -# if HAVE_DECL__SNWPRINTF - /* On Windows, the function swprintf() has a different signature than - on Unix; we use the _snwprintf() function instead. */ -# define SNPRINTF _snwprintf -# else - /* Unix. */ -# define SNPRINTF swprintf -# endif -#else -# define VASNPRINTF vasnprintf -# define CHAR_T char -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -# define PRINTF_PARSE printf_parse -# define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) -# if HAVE_DECL__SNPRINTF - /* Windows. */ -# define SNPRINTF _snprintf -# else - /* Unix. */ -# define SNPRINTF snprintf -# endif -#endif - -CHAR_T * -VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args) -{ - DIRECTIVES d; - arguments a; - - if (PRINTF_PARSE (format, &d, &a) < 0) - { - errno = EINVAL; - return NULL; - } - -#define CLEANUP() \ - free (d.dir); \ - if (a.arg) \ - free (a.arg); - - if (printf_fetchargs (args, &a) < 0) - { - CLEANUP (); - errno = EINVAL; - return NULL; - } - - { - size_t buf_neededlength; - CHAR_T *buf; - CHAR_T *buf_malloced; - const CHAR_T *cp; - size_t i; - DIRECTIVE *dp; - /* Output string accumulator. */ - CHAR_T *result; - size_t allocated; - size_t length; - - /* Allocate a small buffer that will hold a directive passed to - sprintf or snprintf. */ - buf_neededlength = 7 + d.max_width_length + d.max_precision_length + 6; -#if HAVE_ALLOCA - if (buf_neededlength < 4000 / sizeof (CHAR_T)) - { - buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T)); - buf_malloced = NULL; - } - else -#endif - { - if (SIZE_MAX / sizeof (CHAR_T) < buf_neededlength) - goto out_of_memory_1; - buf = (CHAR_T *) malloc (buf_neededlength * sizeof (CHAR_T)); - if (buf == NULL) - goto out_of_memory_1; - buf_malloced = buf; - } - - if (resultbuf != NULL) - { - result = resultbuf; - allocated = *lengthp; - } - else - { - result = NULL; - allocated = 0; - } - length = 0; - /* Invariants: - result is either == resultbuf or == NULL or malloc-allocated. - If length > 0, then result != NULL. */ - - /* Ensures that allocated >= length + extra. Aborts through a jump to - out_of_memory if size is too big. */ -#define ENSURE_ALLOCATION(extra) \ - { \ - size_t needed = length + (extra); \ - if (needed < length) \ - goto out_of_memory; \ - if (needed > allocated) \ - { \ - size_t memory_size; \ - CHAR_T *memory; \ - \ - allocated = (allocated > 0 ? 2 * allocated : 12); \ - if (needed > allocated) \ - allocated = needed; \ - if (SIZE_MAX / sizeof (CHAR_T) < allocated) \ - goto out_of_memory; \ - memory_size = allocated * sizeof (CHAR_T); \ - if (result == resultbuf || result == NULL) \ - memory = (CHAR_T *) malloc (memory_size); \ - else \ - memory = (CHAR_T *) realloc (result, memory_size); \ - if (memory == NULL) \ - goto out_of_memory; \ - if (result == resultbuf && length > 0) \ - memcpy (memory, result, length * sizeof (CHAR_T)); \ - result = memory; \ - } \ - } - - for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) - { - if (cp != dp->dir_start) - { - size_t n = dp->dir_start - cp; - - ENSURE_ALLOCATION (n); - memcpy (result + length, cp, n * sizeof (CHAR_T)); - length += n; - } - if (i == d.count) - break; - - /* Execute a single directive. */ - if (dp->conversion == '%') - { - if (!(dp->arg_index == ARG_NONE)) - abort (); - ENSURE_ALLOCATION (1); - result[length] = '%'; - length += 1; - } - else - { - if (!(dp->arg_index != ARG_NONE)) - abort (); - - if (dp->conversion == 'n') - { - switch (a.arg[dp->arg_index].type) - { - case TYPE_COUNT_SCHAR_POINTER: - *a.arg[dp->arg_index].a.a_count_schar_pointer = length; - break; - case TYPE_COUNT_SHORT_POINTER: - *a.arg[dp->arg_index].a.a_count_short_pointer = length; - break; - case TYPE_COUNT_INT_POINTER: - *a.arg[dp->arg_index].a.a_count_int_pointer = length; - break; - case TYPE_COUNT_LONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longint_pointer = length; - break; -#ifdef HAVE_LONG_LONG - case TYPE_COUNT_LONGLONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; - break; -#endif - default: - abort (); - } - } - else - { - arg_type type = a.arg[dp->arg_index].type; - CHAR_T *p; - unsigned int prefix_count; - int prefixes[2]; -#if !USE_SNPRINTF - size_t tmp_length; - CHAR_T tmpbuf[700]; - CHAR_T *tmp; - - /* Allocate a temporary buffer of sufficient size for calling - sprintf. */ - { - size_t width; - size_t precision; - - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - width = (arg < 0 ? (unsigned int) (-arg) : arg); - } - else - { - const CHAR_T *digitp = dp->width_start; - - do - { - size_t w_tmp = width * 10 + (*digitp++ - '0'); - if (SIZE_MAX / 10 < width || w_tmp < width) - goto out_of_memory; - width = w_tmp; - } - while (digitp != dp->width_end); - } - } - - precision = 6; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - precision = (arg < 0 ? 0 : arg); - } - else - { - const CHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - { - size_t p1 = 10 * precision + (*digitp++ - '0'); - precision = ((SIZE_MAX / 10 < precision - || p1 < precision) - ? SIZE_MAX : p1); - } - } - } - - switch (dp->conversion) - { - - case 'd': case 'i': case 'u': -# ifdef HAVE_LONG_LONG - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Multiply by 2, as an estimate for FLAG_GROUP. */ - /* Add 1, to account for a leading sign. */ - tmp_length = (tmp_length < SIZE_MAX / 2 - ? 2 * tmp_length + 1 - : SIZE_MAX); - break; - - case 'o': -# ifdef HAVE_LONG_LONG - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 1, to account for a leading sign. */ - tmp_length += (tmp_length < SIZE_MAX); - break; - - case 'x': case 'X': -# ifdef HAVE_LONG_LONG - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 2, to account for a leading sign or alternate form. */ - if (tmp_length <= SIZE_MAX / 2) - tmp_length *= 2; - break; - - case 'f': case 'F': -# ifdef HAVE_LONG_DOUBLE - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) (LDBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - else -# endif - tmp_length = - (unsigned int) (DBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - tmp_length += precision; - if (tmp_length < precision) - goto out_of_memory; - break; - - case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': - tmp_length = - 12; /* sign, decimal point, exponent etc. */ - tmp_length += precision; - if (tmp_length < precision) - goto out_of_memory; - break; - - case 'c': -# if defined HAVE_WINT_T && !WIDE_CHAR_VERSION - if (type == TYPE_WIDE_CHAR) - tmp_length = MB_CUR_MAX; - else -# endif - tmp_length = 1; - break; - - case 's': -# ifdef HAVE_WCHAR_T - if (type == TYPE_WIDE_STRING) - { - tmp_length = - local_wcslen (a.arg[dp->arg_index].a.a_wide_string); - -# if !WIDE_CHAR_VERSION - if (SIZE_MAX / MB_CUR_MAX < tmp_length) - goto out_of_memory; - tmp_length *= MB_CUR_MAX; -# endif - } - else -# endif - tmp_length = strlen (a.arg[dp->arg_index].a.a_string); - break; - - case 'p': - tmp_length = - (unsigned int) (sizeof (void *) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading 0x */ - break; - - default: - abort (); - } - - if (tmp_length < width) - tmp_length = width; - - tmp_length++; /* account for trailing NUL */ - if (!tmp_length) - goto out_of_memory; - } - - if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T)) - tmp = tmpbuf; - else - { - if (SIZE_MAX / sizeof (CHAR_T) < tmp_length) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (CHAR_T *) malloc (tmp_length * sizeof (CHAR_T)); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } -#endif - - /* Construct the format string for calling snprintf or - sprintf. */ - p = buf; - *p++ = '%'; - if (dp->flags & FLAG_GROUP) - *p++ = '\''; - if (dp->flags & FLAG_LEFT) - *p++ = '-'; - if (dp->flags & FLAG_SHOWSIGN) - *p++ = '+'; - if (dp->flags & FLAG_SPACE) - *p++ = ' '; - if (dp->flags & FLAG_ALT) - *p++ = '#'; - if (dp->flags & FLAG_ZERO) - *p++ = '0'; - if (dp->width_start != dp->width_end) - { - size_t n = dp->width_end - dp->width_start; - memcpy (p, dp->width_start, n * sizeof (CHAR_T)); - p += n; - } - if (dp->precision_start != dp->precision_end) - { - size_t n = dp->precision_end - dp->precision_start; - memcpy (p, dp->precision_start, n * sizeof (CHAR_T)); - p += n; - } - - switch (type) - { -#ifdef HAVE_LONG_LONG - case TYPE_LONGLONGINT: - case TYPE_ULONGLONGINT: - *p++ = 'l'; - /*FALLTHROUGH*/ -#endif - case TYPE_LONGINT: - case TYPE_ULONGINT: -#ifdef HAVE_WINT_T - case TYPE_WIDE_CHAR: -#endif -#ifdef HAVE_WCHAR_T - case TYPE_WIDE_STRING: -#endif - *p++ = 'l'; - break; -#ifdef HAVE_LONG_DOUBLE - case TYPE_LONGDOUBLE: - *p++ = 'L'; - break; -#endif - default: - break; - } - *p = dp->conversion; -#if USE_SNPRINTF - p[1] = '%'; - p[2] = 'n'; - p[3] = '\0'; -#else - p[1] = '\0'; -#endif - - /* Construct the arguments for calling snprintf or sprintf. */ - prefix_count = 0; - if (dp->width_arg_index != ARG_NONE) - { - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; - } - if (dp->precision_arg_index != ARG_NONE) - { - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; - } - -#if USE_SNPRINTF - /* Prepare checking whether snprintf returns the count - via %n. */ - ENSURE_ALLOCATION (1); - result[length] = '\0'; -#endif - - for (;;) - { - size_t maxlen; - int count; - int retcount; - - maxlen = allocated - length; - count = -1; - retcount = 0; - -#if USE_SNPRINTF -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - retcount = SNPRINTF (result + length, maxlen, buf, \ - arg, &count); \ - break; \ - case 1: \ - retcount = SNPRINTF (result + length, maxlen, buf, \ - prefixes[0], arg, &count); \ - break; \ - case 2: \ - retcount = SNPRINTF (result + length, maxlen, buf, \ - prefixes[0], prefixes[1], arg, \ - &count); \ - break; \ - default: \ - abort (); \ - } -#else -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - count = sprintf (tmp, buf, arg); \ - break; \ - case 1: \ - count = sprintf (tmp, buf, prefixes[0], arg); \ - break; \ - case 2: \ - count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ - arg); \ - break; \ - default: \ - abort (); \ - } -#endif - - switch (type) - { - case TYPE_SCHAR: - { - int arg = a.arg[dp->arg_index].a.a_schar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UCHAR: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uchar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_SHORT: - { - int arg = a.arg[dp->arg_index].a.a_short; - SNPRINTF_BUF (arg); - } - break; - case TYPE_USHORT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_ushort; - SNPRINTF_BUF (arg); - } - break; - case TYPE_INT: - { - int arg = a.arg[dp->arg_index].a.a_int; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UINT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_LONGINT: - { - long int arg = a.arg[dp->arg_index].a.a_longint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGINT: - { - unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; - SNPRINTF_BUF (arg); - } - break; -#ifdef HAVE_LONG_LONG - case TYPE_LONGLONGINT: - { - long long int arg = a.arg[dp->arg_index].a.a_longlongint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGLONGINT: - { - unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_DOUBLE: - { - double arg = a.arg[dp->arg_index].a.a_double; - SNPRINTF_BUF (arg); - } - break; -#ifdef HAVE_LONG_DOUBLE - case TYPE_LONGDOUBLE: - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_CHAR: - { - int arg = a.arg[dp->arg_index].a.a_char; - SNPRINTF_BUF (arg); - } - break; -#ifdef HAVE_WINT_T - case TYPE_WIDE_CHAR: - { - wint_t arg = a.arg[dp->arg_index].a.a_wide_char; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_STRING: - { - const char *arg = a.arg[dp->arg_index].a.a_string; - SNPRINTF_BUF (arg); - } - break; -#ifdef HAVE_WCHAR_T - case TYPE_WIDE_STRING: - { - const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_POINTER: - { - void *arg = a.arg[dp->arg_index].a.a_pointer; - SNPRINTF_BUF (arg); - } - break; - default: - abort (); - } - -#if USE_SNPRINTF - /* Portability: Not all implementations of snprintf() - are ISO C 99 compliant. Determine the number of - bytes that snprintf() has produced or would have - produced. */ - if (count >= 0) - { - /* Verify that snprintf() has NUL-terminated its - result. */ - if (count < maxlen && result[length + count] != '\0') - abort (); - /* Portability hack. */ - if (retcount > count) - count = retcount; - } - else - { - /* snprintf() doesn't understand the '%n' - directive. */ - if (p[1] != '\0') - { - /* Don't use the '%n' directive; instead, look - at the snprintf() return value. */ - p[1] = '\0'; - continue; - } - else - { - /* Look at the snprintf() return value. */ - if (retcount < 0) - { - /* HP-UX 10.20 snprintf() is doubly deficient: - It doesn't understand the '%n' directive, - *and* it returns -1 (rather than the length - that would have been required) when the - buffer is too small. */ - size_t bigger_need = - (allocated > 12 ? allocated : 12); - ENSURE_ALLOCATION (bigger_need); - continue; - } - else - count = retcount; - } - } -#endif - - /* Attempt to handle failure. */ - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EINVAL; - return NULL; - } - -#if !USE_SNPRINTF - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); -#endif - - /* Make room for the result. */ - if (count >= maxlen) - { - /* Need at least count bytes. But allocate - proportionally, to avoid looping eternally if - snprintf() reports a too small count. */ - ENSURE_ALLOCATION (count < allocated - ? allocated : count); -#if USE_SNPRINTF - continue; -#endif - } - -#if USE_SNPRINTF - /* The snprintf() result did fit. */ -#else - /* Append the sprintf() result. */ - memcpy (result + length, tmp, count * sizeof (CHAR_T)); - if (tmp != tmpbuf) - free (tmp); -#endif - - length += count; - break; - } - } - } - } - - /* Add the final NUL. */ - ENSURE_ALLOCATION (1); - result[length] = '\0'; - - if (result != resultbuf && length + 1 < allocated) - { - /* Shrink the allocated memory if possible. */ - CHAR_T *memory; - - memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T)); - if (memory != NULL) - result = memory; - } - - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - *lengthp = length; - if (length > INT_MAX) - goto length_overflow; - return result; - - length_overflow: - /* We could produce such a big string, but its length doesn't fit into - an 'int'. POSIX says that snprintf() fails with errno = EOVERFLOW in - this case. */ - if (result != resultbuf) - free (result); - errno = EOVERFLOW; - return NULL; - - out_of_memory: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - out_of_memory_1: - CLEANUP (); - errno = ENOMEM; - return NULL; - } -} - -#undef SNPRINTF -#undef USE_SNPRINTF -#undef PRINTF_PARSE -#undef DIRECTIVES -#undef DIRECTIVE -#undef CHAR_T -#undef VASNPRINTF diff --git a/lib/waitpid.c b/lib/waitpid.c deleted file mode 100644 index b6f585e4..00000000 --- a/lib/waitpid.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Emulate waitpid on systems that just have wait. - Copyright 1994, 1995, 1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if HAVE_CONFIG_H -# include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> -#ifndef errno -extern int errno; -#endif - -#define WAITPID_CHILDREN 8 -static pid_t waited_pid[WAITPID_CHILDREN]; -static int waited_status[WAITPID_CHILDREN]; - -pid_t -waitpid (pid_t pid, int *stat_loc, int options) -{ - int i; - pid_t p; - - if (!options && (pid == -1 || 0 < pid)) - { - /* If we have already waited for this child, return it immediately. */ - for (i = 0; i < WAITPID_CHILDREN; i++) - { - p = waited_pid[i]; - if (p && (p == pid || pid == -1)) - { - waited_pid[i] = 0; - goto success; - } - } - - /* The child has not returned yet; wait for it, accumulating status. */ - for (i = 0; i < WAITPID_CHILDREN; i++) - if (! waited_pid[i]) - { - p = wait (&waited_status[i]); - if (p < 0) - return p; - if (p == pid || pid == -1) - goto success; - waited_pid[i] = p; - } - } - - /* We cannot emulate this wait call, e.g. because of too many children. */ - errno = EINVAL; - return -1; - -success: - if (stat_loc) - *stat_loc = waited_status[i]; - return p; -} |