diff options
Diffstat (limited to 'libc/unistd')
| -rw-r--r-- | libc/unistd/Makefile.in | 52 | ||||
| -rw-r--r-- | libc/unistd/__exec_alloc.c | 8 | ||||
| -rw-r--r-- | libc/unistd/confstr.c | 6 | ||||
| -rw-r--r-- | libc/unistd/exec.c | 54 | ||||
| -rw-r--r-- | libc/unistd/execl.c | 8 | ||||
| -rw-r--r-- | libc/unistd/execle.c | 8 | ||||
| -rw-r--r-- | libc/unistd/execlp.c | 8 | ||||
| -rw-r--r-- | libc/unistd/execv.c | 8 | ||||
| -rw-r--r-- | libc/unistd/execvp.c | 8 | ||||
| -rw-r--r-- | libc/unistd/fpathconf.c | 8 | ||||
| -rw-r--r-- | libc/unistd/getlogin.c | 21 | ||||
| -rw-r--r-- | libc/unistd/getopt-susv3.c | 8 | ||||
| -rw-r--r-- | libc/unistd/getopt.c | 1385 | ||||
| -rw-r--r-- | libc/unistd/getopt_int.h | 132 | ||||
| -rw-r--r-- | libc/unistd/getpass.c | 28 | ||||
| -rw-r--r-- | libc/unistd/getsubopt.c | 15 | ||||
| -rw-r--r-- | libc/unistd/pathconf.c | 249 | ||||
| -rw-r--r-- | libc/unistd/sleep.c | 26 | ||||
| -rw-r--r-- | libc/unistd/sysconf.c | 12 | ||||
| -rw-r--r-- | libc/unistd/ualarm.c | 9 | ||||
| -rw-r--r-- | libc/unistd/usershell.c | 19 | ||||
| -rw-r--r-- | libc/unistd/usleep.c | 8 |
22 files changed, 1320 insertions, 760 deletions
diff --git a/libc/unistd/Makefile.in b/libc/unistd/Makefile.in index 84b83b854..4a0bb0734 100644 --- a/libc/unistd/Makefile.in +++ b/libc/unistd/Makefile.in @@ -1,57 +1,39 @@ # Makefile for uClibc # -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC:= sleep.c usleep.c ualarm.c getpass.c sysconf.c getlogin.c \ - fpathconf.c confstr.c pathconf.c swab.c usershell.c \ - getsubopt.c daemon.c +UNISTD_DIR := $(top_srcdir)libc/unistd +UNISTD_OUT := $(top_builddir)libc/unistd -MSRC:=exec.c -MOBJ:=execl.o execv.o execle.o execlp.o execvp.o +CSRC := $(notdir $(wildcard $(UNISTD_DIR)/*.c)) +# multi source +CSRC := $(filter-out exec.c,$(CSRC)) -ifneq ($(ARCH_HAS_MMU),y) -MOBJ+=__exec_alloc.o +ifeq ($(ARCH_USE_MMU),y) +CSRC := $(filter-out __exec_alloc.c,$(CSRC)) +else +CSRC := $(filter-out daemon.c,$(CSRC)) endif ifeq ($(UCLIBC_HAS_GNU_GETOPT),y) -CSRC+=getopt.c +CSRC := $(filter-out getopt-susv3.c,$(CSRC)) else -CSRC+=getopt-susv3.c +CSRC := $(filter-out getopt.c,$(CSRC)) endif ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) -CSRC:=$(filter-out sleep.c,$(CSRC)) +CSRC := $(filter-out sleep.c,$(CSRC)) endif -UNISTD_DIR:=$(top_srcdir)libc/unistd -UNISTD_OUT:=$(top_builddir)libc/unistd - -UNISTD_SRC:=$(patsubst %.c,$(UNISTD_DIR)/%.c,$(CSRC)) -UNISTD_OBJ:=$(patsubst %.c,$(UNISTD_OUT)/%.o,$(CSRC)) - -UNISTD_MSRC:=$(patsubst %.c,$(UNISTD_DIR)/%.c,$(MSRC)) -UNISTD_MOBJ:=$(patsubst %.o,$(UNISTD_OUT)/%.o,$(MOBJ)) - -UNISTD_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(UNISTD_MOBJ)))) - -UNISTD_OBJS:=$(UNISTD_OBJ) $(UNISTD_MOBJ) - -$(UNISTD_MOBJ): $(UNISTD_MSRC) - $(compile.m) - -$(UNISTD_MOBJ:.o=.os): $(UNISTD_MSRC) - $(compile.m) - -libc-a-y+=$(UNISTD_OBJS) -libc-so-y+=$(UNISTD_OBJS:.o=.os) +UNISTD_SRC := $(patsubst %.c,$(UNISTD_DIR)/%.c,$(CSRC)) +UNISTD_OBJ := $(patsubst %.c,$(UNISTD_OUT)/%.o,$(CSRC)) -CFLAGS-multi-y+=$(UNISTD_DEF) -libc-multi-y+=$(UNISTD_SRC) $(UNISTD_MSRC) +libc-y += $(UNISTD_OBJ) -objclean-y+=unistd_objclean +objclean-y += unistd_objclean unistd_objclean: $(RM) $(UNISTD_OUT)/*.{o,os} diff --git a/libc/unistd/__exec_alloc.c b/libc/unistd/__exec_alloc.c new file mode 100644 index 000000000..837ffb472 --- /dev/null +++ b/libc/unistd/__exec_alloc.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___exec_alloc +#include "exec.c" diff --git a/libc/unistd/confstr.c b/libc/unistd/confstr.c index bfaecb198..8d1c8d303 100644 --- a/libc/unistd/confstr.c +++ b/libc/unistd/confstr.c @@ -21,6 +21,8 @@ #include <unistd.h> #include <string.h> +libc_hidden_proto(memcpy) + #define CS_PATH "/bin:/usr/bin" /* If BUF is not NULL and LEN > 0, fill in at most LEN - 1 bytes @@ -48,10 +50,10 @@ size_t confstr ( int name, char *buf, size_t len) if (len > 0 && buf != NULL) { if (string_len <= len) - __memcpy (buf, string, string_len); + memcpy (buf, string, string_len); else { - __memcpy (buf, string, len - 1); + memcpy (buf, string, len - 1); buf[len - 1] = '\0'; } } diff --git a/libc/unistd/exec.c b/libc/unistd/exec.c index e61ff1988..3563723ad 100644 --- a/libc/unistd/exec.c +++ b/libc/unistd/exec.c @@ -30,11 +30,6 @@ * to free the storage allocated for the copy. Better ideas anyone? */ -#define mmap __mmap -#define munmap __munmap -#define execve __execve - -#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -44,10 +39,21 @@ #include <unistd.h> #include <sys/mman.h> -extern char *__strchrnul(const char *s, int c); +libc_hidden_proto(execl) +libc_hidden_proto(execvp) + +libc_hidden_proto(memcpy) +libc_hidden_proto(strchr) +libc_hidden_proto(strlen) +libc_hidden_proto(strchrnul) +libc_hidden_proto(execve) +libc_hidden_proto(mmap) +libc_hidden_proto(munmap) +libc_hidden_proto(getenv) +libc_hidden_proto(__environ) /**********************************************************************/ -#if defined(__ARCH_HAS_MMU__) || defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__) +#if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__) /* We have an MMU, so use alloca() to grab space for buffers and * arg lists. Also fall back to alloca() if munmap() is broken. */ @@ -68,12 +74,12 @@ extern char *__strchrnul(const char *s, int c); # define EXEC_ALLOC(SIZE,VAR) __exec_alloc((VAR = (SIZE))) # define EXEC_FREE(PTR,VAR) __exec_free((PTR),(VAR)) -extern void *__exec_alloc(size_t size); -extern void __exec_free(void *ptr, size_t size); +extern void *__exec_alloc(size_t size) attribute_hidden; +extern void __exec_free(void *ptr, size_t size) attribute_hidden; # ifdef L___exec_alloc -void *__exec_alloc(size_t size) +void attribute_hidden *__exec_alloc(size_t size) { void *p; @@ -82,7 +88,7 @@ void *__exec_alloc(size_t size) return (p != MAP_FAILED) ? p : NULL; } -void __exec_free(void *ptr, size_t size) +void attribute_hidden __exec_free(void *ptr, size_t size) { if (ptr) { munmap(ptr, size); @@ -95,7 +101,7 @@ void __exec_free(void *ptr, size_t size) /**********************************************************************/ #ifdef L_execl -int attribute_hidden __execl(const char *path, const char *arg, ...) +int execl(const char *path, const char *arg, ...) { EXEC_ALLOC_SIZE(size) /* Do NOT add a semicolon! */ int n; @@ -126,7 +132,7 @@ int attribute_hidden __execl(const char *path, const char *arg, ...) return n; } -strong_alias(__execl,execl) +libc_hidden_def(execl) #endif /**********************************************************************/ @@ -179,8 +185,6 @@ int execle(const char *path, const char *arg, ...) /**********************************************************************/ #ifdef L_execlp -extern int __execvp(const char *path, char *const argv[]) attribute_hidden; - int execlp(const char *file, const char *arg, ...) { EXEC_ALLOC_SIZE(size) /* Do NOT add a semicolon! */ @@ -206,7 +210,7 @@ int execlp(const char *file, const char *arg, ...) } while (--n); va_end(args); - n = __execvp(file, (char *const *) argv); + n = execvp(file, (char *const *) argv); EXEC_FREE(argv, size); @@ -222,7 +226,7 @@ int execlp(const char *file, const char *arg, ...) * /bin, and then /usr/bin. */ static const char default_path[] = ":/bin:/usr/bin"; -int attribute_hidden __execvp(const char *path, char *const argv[]) +int execvp(const char *path, char *const argv[]) { char *buf = NULL; char *p; @@ -239,7 +243,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) return -1; } - if (__strchr(path, '/')) { + if (strchr(path, '/')) { execve(path, argv, __environ); CHECK_ENOEXEC: if (errno == ENOEXEC) { @@ -252,12 +256,12 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) nargv = (char **) EXEC_ALLOC((n+2) * sizeof(char *), size2); nargv[0] = argv[0]; nargv[1] = (char *)path; - __memcpy(nargv+2, argv+1, n*sizeof(char *)); + memcpy(nargv+2, argv+1, n*sizeof(char *)); execve("/bin/sh", nargv, __environ); EXEC_FREE(nargv, size2); } } else { - if ((p = __getenv("PATH")) != NULL) { + if ((p = getenv("PATH")) != NULL) { if (!*p) { goto BAD; } @@ -265,7 +269,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) p = (char *) default_path; } - plen = __strlen(path); + plen = strlen(path); if (plen > (FILENAME_MAX - 1)) { ALL_TOO_LONG: __set_errno(ENAMETOOLONG); @@ -276,11 +280,11 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) if ((buf = EXEC_ALLOC(FILENAME_MAX, size)) != NULL) { int seen_small = 0; s0 = buf + len; - __memcpy(s0, path, plen+1); + memcpy(s0, path, plen+1); do { s = s0; - e = __strchrnul(p, ':'); + e = strchrnul(p, ':'); if (e > p) { plen = e - p; if (e[-1] != '/') { @@ -290,7 +294,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) goto NEXT; } s -= plen; - __memcpy(s, p, plen); + memcpy(s, p, plen); s[plen-1] = '/'; } @@ -319,7 +323,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) return -1; } -strong_alias(__execvp,execvp) +libc_hidden_def(execvp) #endif /**********************************************************************/ diff --git a/libc/unistd/execl.c b/libc/unistd/execl.c new file mode 100644 index 000000000..176b18bcc --- /dev/null +++ b/libc/unistd/execl.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execl +#include "exec.c" diff --git a/libc/unistd/execle.c b/libc/unistd/execle.c new file mode 100644 index 000000000..05dd3a028 --- /dev/null +++ b/libc/unistd/execle.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execle +#include "exec.c" diff --git a/libc/unistd/execlp.c b/libc/unistd/execlp.c new file mode 100644 index 000000000..b7e615d7b --- /dev/null +++ b/libc/unistd/execlp.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execlp +#include "exec.c" diff --git a/libc/unistd/execv.c b/libc/unistd/execv.c new file mode 100644 index 000000000..25030428d --- /dev/null +++ b/libc/unistd/execv.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execv +#include "exec.c" diff --git a/libc/unistd/execvp.c b/libc/unistd/execvp.c new file mode 100644 index 000000000..9fc025fcb --- /dev/null +++ b/libc/unistd/execvp.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execvp +#include "exec.c" diff --git a/libc/unistd/fpathconf.c b/libc/unistd/fpathconf.c index 5404e7b01..9cb66a927 100644 --- a/libc/unistd/fpathconf.c +++ b/libc/unistd/fpathconf.c @@ -32,6 +32,8 @@ //#include "linux_fsinfo.h" +libc_hidden_proto(fstat) +libc_hidden_proto(fstatfs) /* The Linux kernel headers mention this as a kind of generic value. */ #define LINUX_LINK_MAX 127 @@ -53,7 +55,7 @@ long int fpathconf(int fd, int name) struct statfs fsbuf; /* Determine the filesystem type. */ - if (__fstatfs (fd, &fsbuf) < 0) + if (fstatfs (fd, &fsbuf) < 0) { if (errno == ENOSYS) /* not possible, return the default value. */ @@ -127,7 +129,7 @@ long int fpathconf(int fd, int name) struct statfs buf; int save_errno = errno; - if (__fstatfs (fd, &buf) < 0) + if (fstatfs (fd, &buf) < 0) { if (errno == ENOSYS) { @@ -201,7 +203,7 @@ long int fpathconf(int fd, int name) /* AIO is only allowed on regular files and block devices. */ struct stat st; - if (__fstat (fd, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) + if (fstat (fd, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) return -1; else return 1; diff --git a/libc/unistd/getlogin.c b/libc/unistd/getlogin.c index 0747a49f6..296d8d7fc 100644 --- a/libc/unistd/getlogin.c +++ b/libc/unistd/getlogin.c @@ -22,6 +22,12 @@ #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <stdio.h> + +libc_hidden_proto(strcpy) +libc_hidden_proto(strncpy) +libc_hidden_proto(getenv) /* uClibc makes it policy to not mess with the utmp file whenever * possible, since I consider utmp a complete waste of time. Since @@ -29,29 +35,30 @@ * the user specify whatever they want via the LOGNAME environment * variable, or we return NULL if getenv() fails to find anything */ -extern char attribute_hidden * __getlogin(void) +libc_hidden_proto(getlogin) +char * getlogin(void) { - return (__getenv("LOGNAME")); + return (getenv("LOGNAME")); } -strong_alias(__getlogin,getlogin) +libc_hidden_def(getlogin) int getlogin_r(char *name, size_t len) { - char * foo = __getenv("LOGNAME"); + char * foo = getenv("LOGNAME"); if (! foo) return -1; - __strncpy(name, foo, len); + strncpy(name, foo, len); name[len-1] = '\0'; return 0; } char *cuserid(char *s) { - char *name = __getlogin(); + char *name = getlogin(); if (s) { - return(__strcpy(s, name ? name : "")); + return(strcpy(s, name ? name : "")); } return name; } diff --git a/libc/unistd/getopt-susv3.c b/libc/unistd/getopt-susv3.c index d9ee18c43..70a616011 100644 --- a/libc/unistd/getopt-susv3.c +++ b/libc/unistd/getopt-susv3.c @@ -30,10 +30,14 @@ * Initial version of a SUSv3 compliant getopt(). */ -#define _GNU_SOURCE #include <unistd.h> #include <string.h> #include <stdio.h> +#include <getopt.h> + +libc_hidden_proto(fprintf) +libc_hidden_proto(strchr) +libc_hidden_proto(stderr) #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Enable gettext awareness. @@ -87,7 +91,7 @@ int getopt(int argc, char * const argv[], const char *optstring) #endif retval = (unsigned char) *o; /* Avoid problems for char val of -1. */ - if ((*o == ':') || !(s = __strchr(optstring, *o))) { /* Illegal option? */ + if ((*o == ':') || !(s = strchr(optstring, *o))) { /* Illegal option? */ s = illegal; retval = '?'; goto BAD; diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c index 2cf5dbb73..cffde47e1 100644 --- a/libc/unistd/getopt.c +++ b/libc/unistd/getopt.c @@ -2,7 +2,7 @@ NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -25,26 +25,85 @@ * Modified for uClibc by Manuel Novoa III on 1/5/01. * Modified once again for uClibc by Erik Andersen 8/7/02 */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define __FORCE_GLIBC #include <features.h> + #include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. 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. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include <gnu-versions.h> +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include <stdlib.h> +# include <unistd.h> +#endif /* GNU C library. */ + #include <string.h> -#include <stdlib.h> -#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ -#include <libintl.h> + +#ifdef VMS +# include <unixlib.h> #endif +#if !defined __UCLIBC__ && !defined __UCLIBC_HAS_GETTEXT_AWARENESS__ +#ifdef _LIBC +# include <libintl.h> +#else +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif +#else #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Enable gettext awareness. #endif /* __UCLIBC_MJN3_ONLY__ */ #undef _ -#define _(X) X +#define _(X) X + +#endif /* Treat '-W foo' the same as the long option '--foo', * disabled for the moment since it costs about 2k... */ #undef SPECIAL_TREATMENT_FOR_W +#if defined _LIBC && defined USE_IN_LIBIO +# include <wchar.h> +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. @@ -59,11 +118,16 @@ GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ -#include "getopt.h" - -extern int _getopt_internal (int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, int long_only) attribute_hidden; +#include <getopt.h> +#include "getopt_int.h" +libc_hidden_proto(strchr) +libc_hidden_proto(strcmp) +libc_hidden_proto(strlen) +libc_hidden_proto(strncmp) +libc_hidden_proto(getenv) +libc_hidden_proto(fprintf) +libc_hidden_proto(stderr) /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, @@ -71,7 +135,7 @@ extern int _getopt_internal (int argc, char *const *argv, const char *optstring, Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ -char *optarg = NULL; +char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller @@ -99,66 +163,49 @@ int opterr = 1; int optopt = '?'; -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -static int __getopt_initialized; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. +/* Keep a global copy of all internal members of getopt_data. */ - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. +static struct _getopt_data getopt_data; - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. + +#ifndef __GNU_LIBRARY__ - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ +/* Avoid depending on library functions or files + whose names are inconsistent. */ -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; +#ifndef getenv +extern char *getenv (); +#endif -# include <string.h> -# define my_index __strchr +#endif /* not __GNU_LIBRARY__ */ -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +# ifdef USE_NONOPTION_FLAGS +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +# define SWAP_FLAGS(ch1, ch2) \ + if (d->__nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -169,90 +216,149 @@ static int last_nonopt; `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ -static void exchange (char **argv) +static void +exchange (char **argv, struct _getopt_data *d) { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ + int bottom = d->__first_nonopt; + int middle = d->__last_nonopt; + int top = d->optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + d->__nonoption_flags_max_len), + '\0', top + 1 - d->__nonoption_flags_max_len); + d->__nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif - while (top > middle && middle > bottom) + while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) + if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; + /* Exclude the moved bottom segment from further swapping. */ + top -= len; } - else + else { - /* Top segment is the short one. */ - int len = top - middle; - register int i; + /* Top segment is the short one. */ + int len = top - middle; + register int i; - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); } - /* Exclude the moved top segment from further swapping. */ - bottom += len; + /* Exclude the moved top segment from further swapping. */ + bottom += len; } } - /* Update records for the slots the non-options now occupy. */ + /* Update records for the slots the non-options now occupy. */ - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; } /* Initialize the internal data when the first call is made. */ -static const char *_getopt_initialize (attribute_unused int argc, attribute_unused char *const * argv, const char *optstring) +static const char * +_getopt_initialize (attribute_unused int argc, attribute_unused char *const *argv, const char *optstring, + struct _getopt_data *d) { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + d->__first_nonopt = d->__last_nonopt = d->optind; - nextchar = NULL; + d->__nextchar = NULL; - /* Determine how to handle the ordering of options and nonoptions. */ + d->__posixly_correct = !!getenv ("POSIXLY_CORRECT"); - if (optstring[0] == '-') + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') { - ordering = RETURN_IN_ORDER; - ++optstring; + d->__ordering = REQUIRE_ORDER; + ++optstring; } - else if (optstring[0] == '+') + else if (d->__posixly_correct) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (!d->__posixly_correct + && argc == __libc_argc && argv == __libc_argv) { - ordering = REQUIRE_ORDER; - ++optstring; + if (d->__nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + d->__nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = d->__nonoption_flags_max_len = strlen (orig_str); + if (d->__nonoption_flags_max_len < argc) + d->__nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (d->__nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + d->__nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', d->__nonoption_flags_max_len - len); + } + } + d->__nonoption_flags_len = d->__nonoption_flags_max_len; } - else if (__getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; + else + d->__nonoption_flags_len = 0; +#endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -311,489 +417,776 @@ static const char *_getopt_initialize (attribute_unused int argc, attribute_unus If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ -int attribute_hidden _getopt_internal (int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, int long_only) +static int +_getopt_internal_r (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d) { - int print_errors = opterr; - if (optstring[0] == ':') - print_errors = 0; + int print_errors = d->opterr; + if (optstring[0] == ':') + print_errors = 0; - if (argc < 1) - return -1; + if (argc < 1) + return -1; - optarg = NULL; + d->optarg = NULL; - if (optind == 0 || !__getopt_initialized) + if (d->optind == 0 || !d->__initialized) { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; + if (d->optind == 0) + d->optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring, d); + d->__initialized = 1; } - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ + || (d->optind < d->__nonoption_flags_len \ + && __getopt_nonoption_flags[d->optind] == '1')) +#else +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') +#endif - if (nextchar == NULL || *nextchar == '\0') + if (d->__nextchar == NULL || *d->__nextchar == '\0') { - /* Advance to the next ARGV-element. */ + /* Advance to the next ARGV-element. */ - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (d->__last_nonopt > d->optind) + d->__last_nonopt = d->optind; + if (d->__first_nonopt > d->optind) + d->__first_nonopt = d->optind; - if (ordering == PERMUTE) + if (d->__ordering == PERMUTE) { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->optind; } - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ - if (optind != argc && !__strcmp (argv[optind], "--")) + if (d->optind != argc && !strcmp (argv[d->optind], "--")) { - optind++; + d->optind++; - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; - optind = argc; + d->optind = argc; } - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ - if (optind == argc) + if (d->optind == argc) { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__first_nonopt; + return -1; } - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ - if (NONOPTION_P) + if (NONOPTION_P) { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; } - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); + d->__nextchar = (argv[d->optind] + 1 + + (longopts != NULL && argv[d->optind][1] == '-')); } - /* Decode the current option-ARGV-element. */ + /* Decode the current option-ARGV-element. */ - /* Check whether the ARGV-element is a long option. + /* Check whether the ARGV-element is a long option. - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". - This distinction seems to be the most useful approach. */ + This distinction seems to be the most useful approach. */ - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + if (longopts != NULL + && (argv[d->optind][1] == '-' + || (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))))) { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!__strncmp (p->name, nextchar, nameend - nextchar)) + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) __strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } + _IO_flockfile (stderr); - if (ambig && !exact) - { - if (print_errors) - { - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[d->optind]); +#endif } - nextchar += __strlen (nextchar); - optind++; - optopt = 0; - return '?'; + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; } - if (pfound != NULL) + if (pfound != NULL) { - option_index = indfound; - optind++; - if (*nameend) + option_index = indfound; + d->optind++; + if (*nameend) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else { - if (print_errors) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif - if (argv[optind - 1][1] == '-') + if (argv[d->optind - 1][1] == '-') { - /* --option */ - fprintf (stderr, _("\ - %s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif } - else + else { - /* +option or -option */ - fprintf (stderr, _("\ - %s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#endif } +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif } - nextchar += __strlen (nextchar); + d->__nextchar += strlen (d->__nextchar); - optopt = pfound->val; - return '?'; + d->optopt = pfound->val; + return '?'; } } - else if (pfound->has_arg == 1) + else if (pfound->has_arg == 1) { - if (optind < argc) - optarg = argv[optind++]; - else + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else { - if (print_errors) + if (print_errors) { - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); +#endif } - nextchar += __strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; + d->__nextchar += strlen (d->__nextchar); + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; } } - nextchar += __strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; + *(pfound->flag) = pfound->val; + return 0; } - return pfound->val; + return pfound->val; } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) { - if (print_errors) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif - if (argv[optind][1] == '-') + if (argv[d->optind][1] == '-') { - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], d->__nextchar); +#endif } - else + else { - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#endif } +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; + d->__nextchar = (char *) ""; + d->optind++; + d->optopt = 0; + return '?'; } } - /* Look at and handle the next short option-character. */ + /* Look at and handle the next short option-character. */ - { - char c = *nextchar++; - char *temp = my_index (optstring, c); + { + char c = *d->__nextchar++; + char *temp = strchr (optstring, c); - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; + /* Increment `optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; - if (temp == NULL || c == ':') - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); - } - optopt = c; - return '?'; - } + if (temp == NULL || c == ':') + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (d->__posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->optopt = c; + return '?'; + } #ifdef SPECIAL_TREATMENT_FOR_W - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; + c = '?'; + return c; + } + else + /* We already incremented `d->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; - /* optarg is now the argument, see if it's in the - table of longopts. */ + /* optarg is now the argument, see if it's in the + table of longopts. */ - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; + for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; + nameend++) + /* Do nothing. */ ; - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!__strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == __strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - } - nextchar += __strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) { - option_index = indfound; - if (*nameend) + if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - { - fprintf (stderr, _("\ - %s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - } - - nextchar += __strlen (nextchar); - return '?'; - } + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; } - else if (pfound->has_arg == 1) + else if (pfound == NULL) { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - { - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - } - nextchar += __strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += __strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; + /* First nonexact match found. */ + pfound = p; + indfound = option_index; } - return pfound->val; + else + /* Second or later nonexact match found. */ + ambig = 1; } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[d->optind]); #endif - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { + { if (print_errors) - { - /* 1003.2 specifies the format of this message. */ + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + d->__nextchar += strlen (d->__nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } + _("%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); +#endif + } + d->__nextchar += strlen (d->__nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + d->__nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } +#endif + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } + } + return c; + } +} + +int +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, int long_only) +{ + int result; + + getopt_data.optind = optind; + getopt_data.opterr = opterr; + + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data); + + optind = getopt_data.optind; + optarg = getopt_data.optarg; + optopt = getopt_data.optopt; + + return result; } -int getopt (int argc, char *const *argv, const char *optstring) +int +getopt (int argc, char *const *argv, const char *optstring) { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, (int *) 0, 0); + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); } -int getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) +int +getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -801,9 +1194,11 @@ int getopt_long (int argc, char *const *argv, const char *options, but does match a short option, it is parsed as a short option instead. */ -int getopt_long_only (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) +int +getopt_long_only (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } +#endif /* Not ELIDE_CODE. */ diff --git a/libc/unistd/getopt_int.h b/libc/unistd/getopt_int.h new file mode 100644 index 000000000..e2a005db9 --- /dev/null +++ b/libc/unistd/getopt_int.h @@ -0,0 +1,132 @@ +/* Internal declarations for getopt. + Copyright (C) 1989-1994,1996-1999,2001,2003,2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C Library 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only) attribute_hidden; + + +/* Reentrant versions which can handle parsing multiple argument + vectors at the same time. */ + +/* Data type for reentrant functions. */ +struct _getopt_data +{ + /* These have exactly the same meaning as the corresponding global + variables, except that they are used for the reentrant + versions of getopt. */ + int optind; + int opterr; + int optopt; + char *optarg; + + /* Internal members. */ + + /* True if the internal members have been initialized. */ + int __initialized; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + char *__nextchar; + + /* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we + scan, so that eventually all the non-options are at the end. + This allows options to be given in any order, even with programs + that were not written to expect this. + + RETURN_IN_ORDER is an option available to programs that were + written to expect options and other ARGV-elements in any order + and that care about the ordering of the two. We describe each + non-option ARGV-element as if it were the argument of an option + with character code 1. Using `-' as the first character of the + list of option characters selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + + enum + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + } __ordering; + + /* If the POSIXLY_CORRECT environment variable is set. */ + int __posixly_correct; + + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first + of them; `last_nonopt' is the index after the last of them. */ + + int __first_nonopt; + int __last_nonopt; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + int __nonoption_flags_max_len; + int __nonoption_flags_len; +# endif +}; + +/* The initializer is necessary to set OPTIND and OPTERR to their + default values and to clear the initialization flag. */ +#define _GETOPT_DATA_INITIALIZER { 1, 1 } + +#if 0 /* first is static on uClibc, the others not used */ +extern int _getopt_internal_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data); + +extern int _getopt_long_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); + +extern int _getopt_long_only_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); +#endif + +#endif /* getopt_int.h */ diff --git a/libc/unistd/getpass.c b/libc/unistd/getpass.c index 834fba9d9..455838c62 100644 --- a/libc/unistd/getpass.c +++ b/libc/unistd/getpass.c @@ -16,21 +16,27 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define setvbuf __setvbuf -#define tcsetattr __tcsetattr -#define tcgetattr __tcgetattr -#define fileno __fileno -#define fflush __fflush -#define fgets __fgets -#define fputs __fputs - #include <stdio.h> #include <string.h> #include <termios.h> #include <unistd.h> #include <string.h> -extern int __putc(int c, FILE *stream) attribute_hidden; +libc_hidden_proto(strlen) +libc_hidden_proto(tcsetattr) +libc_hidden_proto(tcgetattr) +libc_hidden_proto(setvbuf) +libc_hidden_proto(fopen) +libc_hidden_proto(fclose) +libc_hidden_proto(fileno) +libc_hidden_proto(fflush) +libc_hidden_proto(fgets) +libc_hidden_proto(fputs) +libc_hidden_proto(fputc) +libc_hidden_proto(putc) +libc_hidden_proto(__fputc_unlocked) +libc_hidden_proto(stdin) +libc_hidden_proto(stderr) /* 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 @@ -90,7 +96,7 @@ getpass (prompt) fgets (buf, PWD_BUFFER_SIZE-1, in); if (buf != NULL) { - nread = __strlen(buf); + nread = strlen(buf); if (nread < 0) buf[0] = '\0'; else if (buf[nread - 1] == '\n') @@ -99,7 +105,7 @@ getpass (prompt) buf[nread - 1] = '\0'; if (tty_changed) /* Write the newline that was not echoed. */ - __putc('\n', out); + putc('\n', out); } } diff --git a/libc/unistd/getsubopt.c b/libc/unistd/getsubopt.c index bebfbc4ed..3cac432ec 100644 --- a/libc/unistd/getsubopt.c +++ b/libc/unistd/getsubopt.c @@ -1,5 +1,5 @@ /* Parse comma separate list into words. - Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -18,12 +18,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define memchr __memchr - #include <stdlib.h> #include <string.h> -extern char *__strchrnul(const char *s, int c); +libc_hidden_proto(memchr) +libc_hidden_proto(strncmp) +libc_hidden_proto(strchrnul) /* Parse comma separated suboption from *OPTIONP and match against strings in TOKENS. If found return index and set *VALUEP to @@ -31,7 +31,8 @@ extern char *__strchrnul(const char *s, int c); not part of TOKENS return in *VALUEP beginning of unknown suboption. On exit *OPTIONP is set to the beginning of the next token or at the terminating NUL character. */ -int getsubopt(char **optionp, char *const *tokens, char **valuep) +int +getsubopt (char **optionp, char *const *tokens, char **valuep) { char *endp, *vstart; int cnt; @@ -40,7 +41,7 @@ int getsubopt(char **optionp, char *const *tokens, char **valuep) return -1; /* Find end of next token. */ - endp = __strchrnul (*optionp, ','); + endp = strchrnul (*optionp, ','); /* Find start of value. */ vstart = memchr (*optionp, '=', endp - *optionp); @@ -50,7 +51,7 @@ int getsubopt(char **optionp, char *const *tokens, char **valuep) /* Try to match the characters between *OPTIONP and VSTART against one of the TOKENS. */ for (cnt = 0; tokens[cnt] != NULL; ++cnt) - if (__memcmp (*optionp, tokens[cnt], vstart - *optionp) == 0 + if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0 && tokens[cnt][vstart - *optionp] == '\0') { /* We found the current option in TOKENS. */ diff --git a/libc/unistd/pathconf.c b/libc/unistd/pathconf.c index 579b99be0..8e3c0a352 100644 --- a/libc/unistd/pathconf.c +++ b/libc/unistd/pathconf.c @@ -1,5 +1,5 @@ -/* pathconf -- adjusted for busybox - Copyright (C) 1991,95,96,98,99,2000,2001 Free Software Foundation, Inc. +/* Copyright (C) 1991,1995,1996,1998,2000,2001,2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,15 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* pathconf -- adjusted for busybox */ /* It would be great it this could be implemented using fpathconf, * but that doesn't work out very well (think FIFOs and sockets) */ #include <errno.h> -#include <unistd.h> -#include <limits.h> -#include <sys/statfs.h> -#include <errno.h> #include <stddef.h> #include <unistd.h> #include <limits.h> @@ -34,217 +31,171 @@ #include <sys/statfs.h> //#include <sys/statvfs.h> -//#include "linux_fsinfo.h" - +libc_hidden_proto(statfs) +libc_hidden_proto(stat) -/* The Linux kernel headers mention this as a kind of generic value. */ -#define LINUX_LINK_MAX 127 +/* The Linux kernel headers mention this as a kind of generic value. */ +#ifndef LINK_MAX +# define LINK_MAX 127 +#endif -/* Get file-specific information about descriptor FD. */ -long int pathconf(const char *path, int name) +/* Get file-specific information about PATH. */ +long int +pathconf (const char *path, int name) { - if (path[0] == '\0') + if (path[0] == '\0') { - __set_errno (ENOENT); - return -1; + __set_errno (ENOENT); + return -1; } - if (name == _PC_LINK_MAX) + switch (name) { - /* Cut some corners */ -#if 0 - struct statfs fsbuf; - - /* Determine the filesystem type. */ - if (__statfs (path, &fsbuf) < 0) - { - if (errno == ENOSYS) - /* not possible, return the default value. */ - return LINUX_LINK_MAX; - - /* Some error occured. */ - return -1; - } - - switch (fsbuf.f_type) - { - case EXT2_SUPER_MAGIC: - return EXT2_LINK_MAX; + default: + __set_errno (EINVAL); + return -1; - case MINIX_SUPER_MAGIC: - case MINIX_SUPER_MAGIC2: - return MINIX_LINK_MAX; - - case MINIX2_SUPER_MAGIC: - case MINIX2_SUPER_MAGIC2: - return MINIX2_LINK_MAX; - - case XENIX_SUPER_MAGIC: - return XENIX_LINK_MAX; - - case SYSV4_SUPER_MAGIC: - case SYSV2_SUPER_MAGIC: - return SYSV_LINK_MAX; - - case COH_SUPER_MAGIC: - return COH_LINK_MAX; - - case UFS_MAGIC: - case UFS_CIGAM: - return UFS_LINK_MAX; - - case REISERFS_SUPER_MAGIC: - return REISERFS_LINK_MAX; - - default: - return LINUX_LINK_MAX; - } + case _PC_LINK_MAX: +#ifdef LINK_MAX + return LINK_MAX; #else - return LINUX_LINK_MAX; + return -1; #endif - } - switch (name) - { - default: - __set_errno (EINVAL); - return -1; - - case _PC_MAX_CANON: + case _PC_MAX_CANON: #ifdef MAX_CANON - return MAX_CANON; + return MAX_CANON; #else - return -1; + return -1; #endif - case _PC_MAX_INPUT: + case _PC_MAX_INPUT: #ifdef MAX_INPUT - return MAX_INPUT; + return MAX_INPUT; #else - return -1; + return -1; #endif - case _PC_NAME_MAX: + case _PC_NAME_MAX: #ifdef NAME_MAX - { - struct statfs buf; - int save_errno = errno; - - if (__statfs (path, &buf) < 0) - { - if (errno == ENOSYS) - { - errno = save_errno; - return NAME_MAX; - } - return -1; - } - else - { + { + struct statfs buf; + int save_errno = errno; + + if (statfs (path, &buf) < 0) + { + if (errno == ENOSYS) + { + errno = save_errno; + return NAME_MAX; + } + return -1; + } + else + { #ifdef _STATFS_F_NAMELEN - return buf.f_namelen; + return buf.f_namelen; #else # ifdef _STATFS_F_NAME_MAX - return buf.f_name_max; + return buf.f_name_max; # else - return NAME_MAX; + return NAME_MAX; # endif #endif - } - } + } + } #else - return -1; + return -1; #endif - case _PC_PATH_MAX: + case _PC_PATH_MAX: #ifdef PATH_MAX - return PATH_MAX; + return PATH_MAX; #else - return -1; + return -1; #endif - case _PC_PIPE_BUF: + case _PC_PIPE_BUF: #ifdef PIPE_BUF - return PIPE_BUF; + return PIPE_BUF; #else - return -1; + return -1; #endif - case _PC_CHOWN_RESTRICTED: + case _PC_CHOWN_RESTRICTED: #ifdef _POSIX_CHOWN_RESTRICTED - return _POSIX_CHOWN_RESTRICTED; + return _POSIX_CHOWN_RESTRICTED; #else - return -1; + return -1; #endif - case _PC_NO_TRUNC: + case _PC_NO_TRUNC: #ifdef _POSIX_NO_TRUNC - return _POSIX_NO_TRUNC; + return _POSIX_NO_TRUNC; #else - return -1; + return -1; #endif - case _PC_VDISABLE: + case _PC_VDISABLE: #ifdef _POSIX_VDISABLE - return _POSIX_VDISABLE; + return _POSIX_VDISABLE; #else - return -1; + return -1; #endif - case _PC_SYNC_IO: + case _PC_SYNC_IO: #ifdef _POSIX_SYNC_IO - return _POSIX_SYNC_IO; + return _POSIX_SYNC_IO; #else - return -1; + return -1; #endif - case _PC_ASYNC_IO: -#if defined _POSIX_ASYNC_IO && defined __UCLIBC_HAS_LFS__ - { - /* AIO is only allowed on regular files and block devices. */ - struct stat st; - - if (__stat (path, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) - return -1; - else - return 1; - } + case _PC_ASYNC_IO: +#if defined _POSIX_ASYNC_IO && defined __UCLIBC_HAS_LFS__ + { + /* AIO is only allowed on regular files and block devices. */ + struct stat st; + + if (stat (path, &st) < 0 + || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) + return -1; + else + return 1; + } #else - return -1; + return -1; #endif - case _PC_PRIO_IO: + case _PC_PRIO_IO: #ifdef _POSIX_PRIO_IO - return _POSIX_PRIO_IO; + return _POSIX_PRIO_IO; #else - return -1; + return -1; #endif - case _PC_SOCK_MAXBUF: + case _PC_SOCK_MAXBUF: #ifdef SOCK_MAXBUF - return SOCK_MAXBUF; + return SOCK_MAXBUF; #else - return -1; + return -1; #endif - case _PC_FILESIZEBITS: + case _PC_FILESIZEBITS: #ifdef FILESIZEBITS - return FILESIZEBITS; + return FILESIZEBITS; #else - /* We let platforms with larger file sizes overwrite this value. */ - return 32; + /* We let platforms with larger file sizes overwrite this value. */ + return 32; #endif - /* Be lazy -- skip these */ - case _PC_REC_INCR_XFER_SIZE: - case _PC_REC_MAX_XFER_SIZE: - case _PC_REC_MIN_XFER_SIZE: - case _PC_REC_XFER_ALIGN: - case _PC_ALLOC_SIZE_MIN: - case _PC_SYMLINK_MAX: - return -1; + /* Be lazy -- skip these */ + case _PC_REC_INCR_XFER_SIZE: + case _PC_REC_MAX_XFER_SIZE: + case _PC_REC_MIN_XFER_SIZE: + case _PC_REC_XFER_ALIGN: + case _PC_ALLOC_SIZE_MIN: + case _PC_SYMLINK_MAX: + return -1; } - } - diff --git a/libc/unistd/sleep.c b/libc/unistd/sleep.c index 3d3d516ab..92944af18 100644 --- a/libc/unistd/sleep.c +++ b/libc/unistd/sleep.c @@ -18,19 +18,25 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define sigaction __sigaction -#define nanosleep __nanosleep - #include <errno.h> #include <time.h> #include <signal.h> #include <unistd.h> +libc_hidden_proto(sleep) + +libc_hidden_proto(sigaction) +libc_hidden_proto(sigprocmask) +//libc_hidden_proto(__sigaddset) +//libc_hidden_proto(__sigemptyset) +//libc_hidden_proto(__sigismember) +libc_hidden_proto(nanosleep) + #if 0 /* This is a quick and dirty, but not 100% compliant with * the stupid SysV SIGCHLD vs. SIG_IGN behaviour. It is * fine unless you are messing with SIGCHLD... */ -unsigned int attribute_hidden __sleep (unsigned int sec) +unsigned int sleep (unsigned int sec) { unsigned int res; struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 }; @@ -44,7 +50,7 @@ unsigned int attribute_hidden __sleep (unsigned int sec) /* We are going to use the `nanosleep' syscall of the kernel. But the kernel does not implement the sstupid SysV SIGCHLD vs. SIG_IGN behaviour for this syscall. Therefore we have to emulate it here. */ -unsigned int attribute_hidden __sleep (unsigned int seconds) +unsigned int sleep (unsigned int seconds) { struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 }; sigset_t set, oset; @@ -59,7 +65,7 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) in libc. We block SIGCHLD first. */ if (__sigemptyset (&set) < 0 || __sigaddset (&set, SIGCHLD) < 0 - || __sigprocmask (SIG_BLOCK, &set, &oset)) + || sigprocmask (SIG_BLOCK, &set, &oset)) return -1; /* If SIGCHLD is already blocked, we don't have to do anything. */ @@ -76,7 +82,7 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) { saved_errno = errno; /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); __set_errno (saved_errno); return -1; } @@ -88,13 +94,13 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) saved_errno = errno; /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); __set_errno (saved_errno); } else { /* We should unblock SIGCHLD. Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); result = nanosleep (&ts, &ts); } } @@ -108,4 +114,4 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) return result; } #endif -strong_alias(__sleep,sleep) +libc_hidden_def(sleep) diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index c80a9e94e..0dde75102 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -16,9 +16,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define getpagesize __getpagesize_internal -#define getdtablesize __getdtablesize - #define _XOPEN_SOURCE 500 #include <features.h> #include <errno.h> @@ -36,6 +33,11 @@ #include <regex.h> #endif +libc_hidden_proto(sysconf) + +libc_hidden_proto(getpagesize) +libc_hidden_proto(getdtablesize) + #ifndef __UCLIBC_CLK_TCK_CONST #error __UCLIBC_CLK_TCK_CONST not defined! #endif @@ -71,7 +73,7 @@ #endif /* _UCLIBC_GENERATE_SYSCONF_ARCH */ /* Get the value of the system variable NAME. */ -long int attribute_hidden __sysconf(int name) +long int sysconf(int name) { switch (name) { @@ -883,4 +885,4 @@ long int attribute_hidden __sysconf(int name) #endif } } -strong_alias(__sysconf,sysconf) +libc_hidden_def(sysconf) diff --git a/libc/unistd/ualarm.c b/libc/unistd/ualarm.c index 3bcb8e463..07bea2a50 100644 --- a/libc/unistd/ualarm.c +++ b/libc/unistd/ualarm.c @@ -1,11 +1,16 @@ -#define setitimer __setitimer +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ -#define _GNU_SOURCE #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> +libc_hidden_proto(setitimer) + useconds_t ualarm(useconds_t value, useconds_t interval) { struct itimerval otimer; diff --git a/libc/unistd/usershell.c b/libc/unistd/usershell.c index bc29cf247..e053d94b7 100644 --- a/libc/unistd/usershell.c +++ b/libc/unistd/usershell.c @@ -30,11 +30,6 @@ * November 2002, Erik Andersen <andersen@codepoet.org> */ -#define __fsetlocking __fsetlocking_internal -#define fileno __fileno -#define fgets_unlocked __fgets_unlocked - -#define _GNU_SOURCE #include <sys/param.h> #include <sys/file.h> #include <sys/stat.h> @@ -45,6 +40,18 @@ #include <unistd.h> #include <paths.h> +libc_hidden_proto(fstat) +libc_hidden_proto(fopen) +libc_hidden_proto(fclose) +libc_hidden_proto(__fsetlocking) +libc_hidden_proto(fileno) +libc_hidden_proto(fgets_unlocked) +#ifdef __UCLIBC_HAS_XLOCALE__ +libc_hidden_proto(__ctype_b_loc) +#else +libc_hidden_proto(__ctype_b) +#endif + /* * Local shells should NOT be added here. They should be added in * /etc/shells. @@ -104,7 +111,7 @@ static char ** initshells(void) if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) return (char **) validsh; - if (__fstat(fileno(fp), &statb) == -1) { + if (fstat(fileno(fp), &statb) == -1) { goto cleanup; } if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) { diff --git a/libc/unistd/usleep.c b/libc/unistd/usleep.c index db8b8710c..09bb09f41 100644 --- a/libc/unistd/usleep.c +++ b/libc/unistd/usleep.c @@ -1,10 +1,16 @@ -#define nanosleep __nanosleep +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> +libc_hidden_proto(nanosleep) + int usleep (__useconds_t usec) { const struct timespec ts = { |
