diff options
author | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
commit | 28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch) | |
tree | 15f07c4c43d635959c6afee96bde71fb1b3614ee /posix | |
download | glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.gz glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.xz glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.zip |
initial import
Diffstat (limited to 'posix')
38 files changed, 5773 insertions, 0 deletions
diff --git a/posix/.cvsignore b/posix/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/posix/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/posix/Makefile b/posix/Makefile new file mode 100644 index 0000000000..b6851b99f3 --- /dev/null +++ b/posix/Makefile @@ -0,0 +1,84 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as +# published by the Free Software Foundation; either version 2 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for POSIX portion of the library. +# +subdir := posix + +headers := sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h \ + glob.h wordexp.h fnmatch.h gnu/types.h getopt.h \ + posix1_lim.h posix2_lim.h posix_opt.h local_lim.h tar.h \ + utsnamelen.h confname.h waitflags.h waitstatus.h sys/unistd.h + +distribute := confstr.h + +routines := \ + uname \ + times \ + wait waitpid wait3 wait4 \ + alarm sleep pause \ + fork vfork _exit \ + execve fexecve execv execle execl execvp execlp \ + getpid getppid \ + getuid geteuid getgid getegid getgroups setuid setgid \ + getpgid setpgid getpgrp setsid \ + getlogin setlogin \ + pathconf sysconf fpathconf \ + glob fnmatch \ + confstr \ + getopt getopt1 +aux := init-posix +tests := tstgetopt testfnm +others := getconf +install-bin := getconf +install-lib := libposix.a +gpl2lgpl := getopt.c getopt1.c getopt.h # Frob these guys' copying notices. + +include ../Rules + +$(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib) +lib: $(objpfx)libposix.a + +# Make the standalone glob/fnmatch package. + +glob.tar: glob/ChangeLog glob/COPYING.LIB \ + glob/Makefile.in glob/configure glob/configure.in glob/configure.bat\ + glob/fnmatch.h glob/glob.h glob/fnmatch.c glob/glob.c + tar cho$(verbose)f $@ $^ +glob/%.c: %.c + rm -f $@ + ln -s ../$< $@ +glob/%.h: %.h + rm -f $@ + ln -s ../$< $@ + +glob/configure: glob/configure.in + cd glob; autoconf $(ACFLAGS) + +glob/ChangeLog: ../ChangeLog + changelog-extract --regexp 'posix/(glob|fnmatch).*' < $< > $@.new + chmod a-w $@.new + mv -f $@.new $@ + +%.Z: % + compress -c $< > $@-tmp + mv $@-tmp $@ +%.gz: % + gzip -9v -c $< > $@-tmp + mv $@-tmp $@ diff --git a/posix/confstr.c b/posix/confstr.c new file mode 100644 index 0000000000..5b4a7bea93 --- /dev/null +++ b/posix/confstr.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <confstr.h> + +/* If BUF is not NULL, fill in at most LEN characters of BUF + with the value corresponding to NAME. Return the number + of characters required to hold NAME's entire value. */ +size_t +DEFUN(confstr, (name, buf, len), + int name AND char *buf AND size_t len) +{ + CONST char *string; + size_t string_len; + + switch (name) + { + case _CS_PATH: + { + static CONST char cs_path[] = CS_PATH; + string = cs_path; + string_len = sizeof(cs_path); + } + break; + + default: + errno = EINVAL; + return 0; + } + + if (buf != NULL) + (void) strncpy(buf, string, len); + return string_len; +} diff --git a/posix/execl.c b/posix/execl.c new file mode 100644 index 0000000000..9aa13b958f --- /dev/null +++ b/posix/execl.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992, 1994 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute PATH with all arguments after PATH until + a NULL pointer and environment from `environ'. */ +int +DEFUN(execl, (path, arg), CONST char *path AND CONST char *arg DOTS) +{ + CONST char *argv[1024]; + register unsigned int i; + va_list args; + + argv[0] = arg; + + va_start (args, arg); + i = 1; + do + { + argv[i] = va_arg (args, CONST char *); + } while (argv[i++] != NULL); + va_end (args); + + return __execve (path, (char *CONST *) argv, __environ); +} diff --git a/posix/execle.c b/posix/execle.c new file mode 100644 index 0000000000..a36d49a407 --- /dev/null +++ b/posix/execle.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +/* Execute PATH with all arguments after PATH until a NULL pointer, + and the argument after that for environment. */ +int +DEFUN(execle, (path), CONST char *path AND CONST char *arg DOTS) +{ + CONST char *argv[1024], *CONST *envp; + register unsigned int i; + va_list args; + + va_start(args, arg); + argv[0] = arg; + i = 1; + do + { + argv[i] = va_arg(args, CONST char *); + } while (argv[i++] != NULL); + + envp = va_arg(args, CONST char *CONST *); + va_end(args); + + return __execve(path, (char *CONST *) argv, (char *CONST *) envp); +} diff --git a/posix/execlp.c b/posix/execlp.c new file mode 100644 index 0000000000..af09dacafd --- /dev/null +++ b/posix/execlp.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1993 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +/* Execute FILE, searching in the `PATH' environment variable if + it contains no slashes, with all arguments after FILE until a + NULL pointer and environment from `environ'. */ +int +DEFUN(execlp, (file), CONST char *file DOTS) +{ + CONST char *argv[1024]; + register unsigned int i; + va_list args; + + va_start (args, file); + + i = 0; + do + argv[i] = va_arg (args, CONST char *); + while (argv[i++] != NULL); + + va_end (args); + + return execvp (file, (char *CONST *) argv); +} diff --git a/posix/execv.c b/posix/execv.c new file mode 100644 index 0000000000..1749e24631 --- /dev/null +++ b/posix/execv.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute PATH with arguments ARGV and environment from `environ'. */ +int +DEFUN(execv, (path, argv), CONST char *path AND char *CONST argv[]) +{ + return __execve(path, argv, __environ); +} diff --git a/posix/execvp.c b/posix/execvp.c new file mode 100644 index 0000000000..01ae0d10a9 --- /dev/null +++ b/posix/execvp.c @@ -0,0 +1,112 @@ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <limits.h> +#include <sys/types.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute FILE, searching in the `PATH' environment variable if it contains + no slashes, with arguments ARGV and environment from `environ'. */ +int +DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[]) +{ + if (strchr (file, '/') == NULL) + { + char *path, *p; + struct stat st; + size_t len; + uid_t uid; + gid_t gid; + int ngroups; + gid_t groups[NGROUPS_MAX]; + char *name; + + path = getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. + The default search path is the current directory + followed by the path `confstr' returns for `_CS_PATH'. */ + len = confstr (_CS_PATH, (char *) NULL, 0); + path = (char *) __alloca (1 + len); + path[0] = ':'; + (void) confstr (_CS_PATH, path + 1, len); + } + + len = strlen (file) + 1; + name = __alloca (strlen (path) + len); + uid = geteuid (); + gid = getegid (); + ngroups = getgroups (sizeof (groups) / sizeof (groups[0]), groups); + p = path; + do + { + path = p; + p = strchr (path, ':'); + if (p == NULL) + p = strchr (path, '\0'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + of `PATH' means to search the current directory. */ + (void) memcpy (name, file, len); + else + { + /* Construct the pathname to try. */ + (void) memcpy (name, path, p - path); + name[p - path] = '/'; + (void) memcpy (&name[(p - path) + 1], file, len); + } + if (stat (name, &st) == 0 && S_ISREG (st.st_mode)) + { + int bit = S_IXOTH; + if (st.st_uid == uid) + bit = S_IXUSR; + else if (st.st_gid == gid) + bit = S_IXGRP; + else + { + register int i; + for (i = 0; i < ngroups; ++i) + if (st.st_gid == groups[i]) + { + bit = S_IXGRP; + break; + } + } + if (st.st_mode & bit) + { + file = name; + break; + } + } + } + while (*p++ != '\0'); + } + + return __execve (file, argv, __environ); +} diff --git a/posix/fnmatch.c b/posix/fnmatch.c new file mode 100644 index 0000000000..1ef5599e23 --- /dev/null +++ b/posix/fnmatch.c @@ -0,0 +1,200 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fnmatch.h> +#include <ctype.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. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifndef errno +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evalutes C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c)) + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + c = FOLD (c); + } + if (FOLD (*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_FILE_NAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD (c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD (*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + cstart = cend = FOLD (cstart); + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + c = FOLD (c); + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + cend = FOLD (cend); + + c = *p++; + } + + if (FOLD (*n) >= cstart && FOLD (*n) <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD (*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/posix/fnmatch.h b/posix/fnmatch.h new file mode 100644 index 0000000000..d9d73b3d86 --- /dev/null +++ b/posix/fnmatch.h @@ -0,0 +1,67 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in <unistd.h>. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/posix/getconf.c b/posix/getconf.c new file mode 100644 index 0000000000..e42b909ed9 --- /dev/null +++ b/posix/getconf.c @@ -0,0 +1,134 @@ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +struct conf + { + CONST char *name; + CONST int call_name; + CONST enum { SYSCONF, CONFSTR, PATHCONF } call; + }; + +static struct conf vars[] = + { + { "LINK_MAX", _PC_LINK_MAX, PATHCONF }, + { "MAX_CANON", _PC_MAX_CANON, PATHCONF }, + { "MAX_INPUT", _PC_MAX_INPUT, PATHCONF }, + { "NAME_MAX", _PC_NAME_MAX, PATHCONF }, + { "PATH_MAX", _PC_PATH_MAX, PATHCONF }, + { "PIPE_BUF", _PC_PIPE_BUF, PATHCONF }, + { "_POSIX_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED, PATHCONF }, + { "_POSIX_NO_TRUNC", _PC_NO_TRUNC, PATHCONF }, + { "_POSIX_VDISABLE", _PC_VDISABLE, PATHCONF }, + + { "ARG_MAX", _SC_ARG_MAX, SYSCONF }, + { "CHILD_MAX", _SC_CHILD_MAX, SYSCONF }, + { "CLK_TCK", _SC_CLK_TCK, SYSCONF }, + { "NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF }, + { "OPEN_MAX", _SC_OPEN_MAX, SYSCONF }, + { "_POSIX_JOB_CONTROL", _SC_JOB_CONTROL, SYSCONF }, + { "_POSIX_SAVED_IDS", _SC_SAVED_IDS, SYSCONF }, + { "_POSIX_VERSION", _SC_VERSION, SYSCONF }, + + { "PATH", _CS_PATH, CONFSTR }, + + { NULL, 0, SYSCONF } + }; + +static CONST char *program; + +static void +DEFUN_VOID(usage) +{ + fprintf (stderr, "Usage: %s variable_name [pathname]\n", program); + exit (2); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + register CONST struct conf *c; + + program = strrchr (argv[0], '/'); + if (program == NULL) + program = argv[0]; + else + ++program; + + if (argc < 2 || argc > 3) + usage (); + + for (c = vars; c->name != NULL; ++c) + if (!strcmp (c->name, argv[1])) + { + long int value; + size_t clen; + char *cvalue; + switch (c->call) + { + case PATHCONF: + if (argc < 3) + usage (); + value = pathconf (argv[2], c->call_name); + if (value == -1) + { + fprintf (stderr, "%s: pathconf: %s: %s\n", + program, argv[2], strerror (errno)); + exit (3); + } + printf ("%ld\n", value); + exit (0); + + case SYSCONF: + if (argc > 2) + usage (); + value = sysconf (c->call_name); + printf ("%ld\n", value); + exit (0); + + case CONFSTR: + if (argc > 2) + usage (); + clen = confstr (c->call_name, (char *) NULL, 0); + cvalue = (char *) malloc (clen); + if (cvalue == NULL) + { + fprintf (stderr, "%s: malloc: %s\n", + program, strerror (errno)); + exit (3); + } + if (confstr (c->call_name, cvalue, clen) != clen) + { + fprintf (stderr, "%s: confstr: %s\n", + program, strerror (errno)); + exit (3); + } + printf ("%.*s\n", (int) clen, cvalue); + exit (0); + } + } + + fprintf (stderr, "%s: Unrecognized variable `%s'\n", program, argv[1]); + exit (2); +} diff --git a/posix/getopt.c b/posix/getopt.c new file mode 100644 index 0000000000..7e7fdc7c3b --- /dev/null +++ b/posix/getopt.c @@ -0,0 +1,759 @@ +/* Getopt for GNU. + 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 roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 + Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* 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 +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#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. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* 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> +#endif /* GNU C library. */ + +/* 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. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + 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" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* 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; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* 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 EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include <string.h> +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#ifndef __STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#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; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `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 (argv) + char **argv; +{ + 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. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* 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++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* 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++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* 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 = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0) + optstring = _getopt_initialize (optstring); + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) + { + /* 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; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) + optind++; + last_nonopt = 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. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + 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 (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 EOF; + } + + /* 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 ((argv[optind][0] != '-' || argv[optind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* 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. + + 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. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound; + 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)) + { + if (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 (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + 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 + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + 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; + } + 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) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + else + fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + 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 (opterr) + { + /* 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 = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/posix/getopt.h b/posix/getopt.h new file mode 100644 index 0000000000..ab50378d09 --- /dev/null +++ b/posix/getopt.h @@ -0,0 +1,133 @@ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if __STDC__ +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/posix/getopt1.c b/posix/getopt1.c new file mode 100644 index 0000000000..644894f7bc --- /dev/null +++ b/posix/getopt1.c @@ -0,0 +1,191 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#include "getopt.h" + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#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. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#else +char *getenv (); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + 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); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + 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); +} + + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/posix/glob.c b/posix/glob.c new file mode 100644 index 0000000000..243730d9ae --- /dev/null +++ b/posix/glob.c @@ -0,0 +1,671 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/types.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. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifdef STDC_HEADERS +#include <stddef.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#ifndef POSIX +#ifdef _POSIX_VERSION +#define POSIX +#endif +#endif +#endif + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__) +#include <dirent.h> +#ifndef __GNU_LIBRARY__ +#define D_NAMLEN(d) strlen((d)->d_name) +#else /* GNU C library. */ +#define D_NAMLEN(d) ((d)->d_namlen) +#endif /* Not GNU C library. */ +#else /* Not POSIX or HAVE_DIRENT_H. */ +#define direct dirent +#define D_NAMLEN(d) ((d)->d_namlen) +#ifdef HAVE_SYS_NDIR_H +#include <sys/ndir.h> +#endif /* HAVE_SYS_NDIR_H */ +#ifdef HAVE_SYS_DIR_H +#include <sys/dir.h> +#endif /* HAVE_SYS_DIR_H */ +#ifdef HAVE_NDIR_H +#include <ndir.h> +#endif /* HAVE_NDIR_H */ +#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */ + +#if defined (POSIX) && !defined (__GNU_LIBRARY__) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#define REAL_DIR_ENTRY(dp) 1 +#else +#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ + +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) +#include <stdlib.h> +#include <string.h> +#define ANSI_STRING +#else /* No standard headers. */ + +#ifdef HAVE_STRING_H +#include <string.h> +#define ANSI_STRING +#else +#include <strings.h> +#endif +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif + +extern char *malloc (), *realloc (); +extern void free (); + +extern void qsort (); +extern void abort (), exit (); + +#endif /* Standard headers. */ + +#ifndef ANSI_STRING + +#ifndef bzero +extern void bzero (); +#endif +#ifndef bcopy +extern void bcopy (); +#endif + +#define memcpy(d, s, n) bcopy ((s), (d), (n)) +#define strrchr rindex +/* memset is only used for zero here, but let's be paranoid. */ +#define memset(s, better_be_zero, n) \ + ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) +#endif /* Not ANSI_STRING. */ + +#ifndef HAVE_STRCOLL +#define strcoll strcmp +#endif + + +#ifndef __GNU_LIBRARY__ +#ifdef __GNUC__ +__inline +#endif +static char * +my_realloc (p, n) + char *p; + unsigned int n; +{ + /* These casts are the for sake of the broken Ultrix compiler, + which warns of illegal pointer combinations otherwise. */ + if (p == NULL) + return (char *) malloc (n); + return (char *) realloc (p, n); +} +#define realloc my_realloc +#endif + + +#if !defined(__alloca) && !defined(__GNU_LIBRARY__) + +#ifdef __GNUC__ +#undef alloca +#define alloca(n) __builtin_alloca (n) +#else /* Not GCC. */ +#if defined (sparc) || defined (HAVE_ALLOCA_H) +#include <alloca.h> +#else /* Not sparc or HAVE_ALLOCA_H. */ +#ifndef _AIX +extern char *alloca (); +#endif /* Not _AIX. */ +#endif /* sparc or HAVE_ALLOCA_H. */ +#endif /* GCC. */ + +#define __alloca alloca + +#endif + +#ifndef STDC_HEADERS +#undef size_t +#define size_t unsigned int +#endif + +/* Some system header files erroneously define these. + We want our own definitions from <fnmatch.h> to take precedence. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD +#include <fnmatch.h> + +/* Some system header files erroneously define these. + We want our own definitions from <glob.h> to take precedence. */ +#undef GLOB_ERR +#undef GLOB_MARK +#undef GLOB_NOSORT +#undef GLOB_DOOFFS +#undef GLOB_NOCHECK +#undef GLOB_APPEND +#undef GLOB_NOESCAPE +#undef GLOB_PERIOD +#include <glob.h> + +__ptr_t (*__glob_opendir_hook) __P ((const char *directory)); +const char *(*__glob_readdir_hook) __P ((__ptr_t stream)); +void (*__glob_closedir_hook) __P ((__ptr_t stream)); + +static int glob_pattern_p __P ((const char *pattern, int quote)); +static int glob_in_dir __P ((const char *pattern, const char *directory, + int flags, + int (*errfunc) __P ((const char *, int)), + glob_t *pglob)); +static int prefix_array __P ((const char *prefix, char **array, size_t n)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +int +glob (pattern, flags, errfunc, pglob) + const char *pattern; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + const char *filename; + char *dirname; + size_t dirlen; + int status; + int oldcount; + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { + errno = EINVAL; + return -1; + } + + /* Find the filename. */ + filename = strrchr (pattern, '/'); + if (filename == NULL) + { + filename = pattern; + dirname = (char *) "."; + dirlen = 0; + } + else if (filename == pattern) + { + /* "/pattern". */ + dirname = (char *) "/"; + dirlen = 1; + ++filename; + } + else + { + dirlen = filename - pattern; + dirname = (char *) __alloca (dirlen + 1); + memcpy (dirname, pattern, dirlen); + dirname[dirlen] = '\0'; + ++filename; + } + + if (filename[0] == '\0' && dirlen > 1) + /* "pattern/". Expand "pattern", appending slashes. */ + { + int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (val == 0) + pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK); + return val; + } + + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + + oldcount = pglob->gl_pathc; + + if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) + { + /* The directory name contains metacharacters, so we + have to glob for the directory, and then glob for + the pattern in each directory found. */ + glob_t dirs; + register int i; + + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | + GLOB_NOSORT), + errfunc, &dirs); + if (status != 0) + return status; + + /* We have successfully globbed the preceding directory name. + For each name we found, call glob_in_dir on it and FILENAME, + appending the results to PGLOB. */ + for (i = 0; i < dirs.gl_pathc; ++i) + { + int oldcount; + +#ifdef SHELL + { + /* Make globbing interruptible in the bash shell. */ + extern int interrupt_state; + + if (interrupt_state) + { + globfree (&dirs); + globfree (&files); + return GLOB_ABEND; + } + } +#endif /* SHELL. */ + + oldcount = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + (flags | GLOB_APPEND) & ~GLOB_NOCHECK, + errfunc, pglob); + if (status == GLOB_NOMATCH) + /* No matches in this directory. Try the next. */ + continue; + + if (status != 0) + { + globfree (&dirs); + globfree (pglob); + return status; + } + + /* Stick the directory on the front of each name. */ + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + } + + flags |= GLOB_MAGCHAR; + + if (pglob->gl_pathc == oldcount) + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + size_t len = strlen (pattern) + 1; + char *patcopy = (char *) malloc (len); + if (patcopy == NULL) + return GLOB_NOSPACE; + memcpy (patcopy, pattern, len); + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + 1 + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + { + free (patcopy); + return GLOB_NOSPACE; + } + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + pglob->gl_pathv[pglob->gl_pathc++] = patcopy; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + } + else + return GLOB_NOMATCH; + } + else + { + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + if (status != 0) + return status; + + if (dirlen > 0) + { + /* Stick the directory on the front of each name. */ + if (prefix_array (dirname, + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (pglob); + return GLOB_NOSPACE; + } + } + } + + if (!(flags & GLOB_NOSORT)) + /* Sort the vector. */ + qsort ((__ptr_t) & pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount, + sizeof (char *), collated_compare); + + return 0; +} + + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +void +globfree (pglob) + register glob_t *pglob; +{ + if (pglob->gl_pathv != NULL) + { + register int i; + for (i = 0; i < pglob->gl_pathc; ++i) + if (pglob->gl_pathv[i] != NULL) + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); + } +} + + +/* Do a collated comparison of A and B. */ +static int +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; +{ + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; + + if (s1 == s2) + return 0; + if (s1 == NULL) + return 1; + if (s2 == NULL) + return -1; + return strcoll (s1, s2); +} + + +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's + elements in place. Return nonzero if out of memory, zero if successful. + A slash is inserted between DIRNAME and each elt of ARRAY, + unless DIRNAME is just "/". Each old element of ARRAY is freed. */ +static int +prefix_array (dirname, array, n) + const char *dirname; + char **array; + size_t n; +{ + register size_t i; + size_t dirlen = strlen (dirname); + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; + + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) + free ((__ptr_t) array[--i]); + return 1; + } + + memcpy (new, dirname, dirlen); + new[dirlen] = '/'; + memcpy (&new[dirlen + 1], array[i], eltlen); + free ((__ptr_t) array[i]); + array[i] = new; + } + + return 0; +} + + +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +static int +glob_pattern_p (pattern, quote) + const char *pattern; + int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote) + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} + + +/* Like `glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +static int +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + __ptr_t stream; + + struct globlink + { + struct globlink *next; + char *name; + }; + struct globlink *names = NULL; + size_t nfound = 0; + + if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE))) + { + stream = NULL; + flags |= GLOB_NOCHECK; + } + else + { + flags |= GLOB_MAGCHAR; + + stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory) + : (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if ((errfunc != NULL && (*errfunc) (directory, errno)) || + (flags & GLOB_ERR)) + return GLOB_ABEND; + } + else + while (1) + { + const char *name; + size_t len; + + if (__glob_readdir_hook) + { + name = (*__glob_readdir_hook) (stream); + if (name == NULL) + break; + len = 0; + } + else + { + struct dirent *d = readdir ((DIR *) stream); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + name = d->d_name; +#ifdef HAVE_D_NAMLEN + len = d->d_namlen; +#else + len = 0; +#endif + } + + if (fnmatch (pattern, name, + (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | + ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0) + { + struct globlink *new + = (struct globlink *) __alloca (sizeof (struct globlink)); + if (len == 0) + len = strlen (name); + new->name + = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (new->name == NULL) + goto memory_error; + memcpy ((__ptr_t) new->name, name, len); + if (flags & GLOB_MARK) + new->name[len++] = '/'; + new->name[len] = '\0'; + new->next = names; + names = new; + ++nfound; + } + } + } + + if (nfound == 0 && (flags & GLOB_NOCHECK)) + { + size_t len = strlen (pattern); + nfound = 1; + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->next = NULL; + names->name = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (names->name == NULL) + goto memory_error; + memcpy (names->name, pattern, len); + if (flags & GLOB_MARK) + names->name[len++] = '/'; + names->name[len] = '\0'; + } + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + + if (stream != NULL) + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + return nfound == 0 ? GLOB_NOMATCH : 0; + + memory_error: + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + while (names != NULL) + { + if (names->name != NULL) + free ((__ptr_t) names->name); + names = names->next; + } + return GLOB_NOSPACE; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/posix/glob.h b/posix/glob.h new file mode 100644 index 0000000000..05ad47f05d --- /dev/null +++ b/posix/glob.h @@ -0,0 +1,97 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GLOB_H + +#define _GLOB_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#undef __ptr_t +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +#undef const +#define const +#define __ptr_t char * +#endif /* C++ or ANSI C. */ + +/* Bits set in the FLAGS argument to `glob'. */ +#define GLOB_ERR (1 << 0)/* Return on read errors. */ +#define GLOB_MARK (1 << 1)/* Append a slash to each name. */ +#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ +#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ +#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ +#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ +#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ +#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ +#define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|GLOB_PERIOD) + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE) +#define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ +#endif + +/* Error returns from `glob'. */ +#define GLOB_NOSPACE 1 /* Ran out of memory. */ +#define GLOB_ABEND 2 /* Read error. */ +#define GLOB_NOMATCH 3 /* No matches found. */ + +/* Structure describing a globbing run. */ +typedef struct + { + int gl_pathc; /* Count of paths matched by the pattern. */ + char **gl_pathv; /* List of matched pathnames. */ + int gl_offs; /* Slots to reserve in `gl_pathv'. */ + int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ + } glob_t; + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +extern int glob __P ((const char *__pattern, int __flags, + int (*__errfunc) __P ((const char *, int)), + glob_t *__pglob)); + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +extern void globfree __P ((glob_t *__pglob)); + + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +/* If they are not NULL, `glob' uses these functions to read directories. */ +extern __ptr_t (*__glob_opendir_hook) __P ((const char *__directory)); +extern const char *(*__glob_readdir_hook) __P ((__ptr_t __stream)); +extern void (*__glob_closedir_hook) __P ((__ptr_t __stream)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* glob.h */ diff --git a/posix/glob/.cvsignore b/posix/glob/.cvsignore new file mode 100644 index 0000000000..56631abf19 --- /dev/null +++ b/posix/glob/.cvsignore @@ -0,0 +1 @@ +ChangeLog diff --git a/posix/glob/Makefile.in b/posix/glob/Makefile.in new file mode 100644 index 0000000000..8c091b33ac --- /dev/null +++ b/posix/glob/Makefile.in @@ -0,0 +1,66 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 92, 93, 94, 95 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# This 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = @srcdir@ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = @srcdir@ + +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ + +# Information determined by configure. +DEFS = @DEFS@ + +# How to invoke ar. +AR = @AR@ +ARFLAGS = rv + +# How to invoke ranlib. +RANLIB = @RANLIB@ + +.PHONY: all +all: libglob.a + +libglob.a: glob.o fnmatch.o + $(AR) $(ARFLAGS) $@ glob.o fnmatch.o + $(RANLIB) $@ + +# For some reason, Unix make wants the dependencies on the source files. +# Otherwise it refuses to use an implicit rule! +# And, get this: it doesn't work to use $(srcdir)/foo.c!! +glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h glob.c +fnmatch.o: $(srcdir)/fnmatch.h fnmatch.c + +.c.o: + $(CC) -I. -I$(srcdir) -c \ + $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean distclean +clean glob-clean: + -rm -f libglob.a *.o core +distclean glob-realclean: clean + -rm -f TAGS tags Makefile config.status config.h config.log +realcean: distclean + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff --git a/posix/glob/configure b/posix/glob/configure new file mode 100755 index 0000000000..38315221a1 --- /dev/null +++ b/posix/glob/configure @@ -0,0 +1,1123 @@ +#!/bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 1.11 +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +# This configure script 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 script 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Save the original args to write them into config.status later. +configure_args="$*" + +# Only options that might do something get documented. +ac_usage="Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +--build=BUILD configure for building on BUILD [BUILD=HOST] +--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) +--enable-FEATURE[=ARG] include FEATURE [ARG=yes] +--exec-prefix=PREFIX install host dependent files in PREFIX [/usr/local] +--help print this message +--host=HOST configure for HOST [guessed] +--prefix=PREFIX install host independent files in PREFIX [/usr/local] +--quiet, --silent do not print \`checking for...' messages +--srcdir=DIR find the sources in DIR [configure dir or ..] +--target=TARGET configure for TARGET [TARGET=HOST] +--verbose print results of checks +--version print the version of autoconf that created configure +--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) +--x-includes=DIR X include files are in DIR +--x-libraries=DIR X library files are in DIR" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +exec_prefix= +host=NONE +no_create= +nonopt=NONE +norecursion= +prefix= +program_prefix= +program_suffix= +program_transform_name= +silent= +srcdir= +target=NONE +verbose= +x_includes= +x_libraries= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + # Accept (but ignore some of) the important Cygnus configure + # options, so we can diagnose typos. + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + # For backward compatibility, recognize -exec-prefix and --exec_prefix. + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + with_gas=yes ;; # Obsolete; use --with-gas. + + -help | --help | --hel | --he) + cat << EOF +$ac_usage +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + with_fp=no ;; # Obsolete; use --without-fp. + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) + norecursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 1.11" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) with_x=yes ;; # Obsolete; use --with-x. + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) echo "configure: $ac_option: invalid option; use --help to show usage" >&2; exit 1 + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" >&2 + fi + if test "x$nonopt" != xNONE; then + echo "configure: can only configure for one host and one target at a time" >&2; exit 1 + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + echo "configure: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" >&2; exit 1 +fi + +trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15 +trap 'rm -fr confdefs* $ac_clean_files' 0 + +# Save the original args if we used an alternate arg parser. +ac_configure_temp="${configure_args-$*}" +# Strip out --no-create and --norecursion so they don't pile up. +configure_args= +for ac_arg in $ac_configure_temp; do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) ;; + *) configure_args="$configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = 'set'; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = 'set'; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=fnmatch.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then `..'. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +fi +if test ! -r $srcdir/$ac_unique_file; then + if test x$ac_srcdir_defaulted = xyes; then + echo "configure: can not find sources in ${ac_confdir} or .." >&2; exit 1 + else + echo "configure: can not find sources in ${srcdir}" >&2; exit 1 + fi +fi +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='${CPP}' +ac_compile='${CC-cc} $CFLAGS $LDFLAGS conftest.${ac_ext} -o conftest $LIBS >/dev/null 2>&1' + + if test -z "$RANLIB"; then + # Extract the first word of `ranlib', so it can be a program name with args. + set ac_dummy ranlib; ac_word=$2 + test -n "$silent" || echo "checking for $ac_word" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +test -z "$RANLIB" && RANLIB=":" +test -n "$RANLIB" && test -n "$verbose" && echo " setting RANLIB to $RANLIB" + +test -n "$silent" || echo "checking how to run the C preprocessor" +if test -z "$CPP"; then + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and ``${CC-cc}'' will simply confuse + # make. It must be expanded now. + CPP="${CC-cc} -E" + cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdio.h> +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdio.h> +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +test -n "$verbose" && echo " setting CPP to $CPP" + test -n "$silent" || echo "checking for AIX" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#ifdef _AIX + yes +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining _ALL_SOURCE" +echo "#define" _ALL_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_ALL_SOURCE=1" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for POSIXized ISC" +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + ISC=1 # If later tests want to check for ISC. + +{ +test -n "$verbose" && \ +echo " defining _POSIX_SOURCE" +echo "#define" _POSIX_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_POSIX_SOURCE=1" +} + + if test -n "$GCC"; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +fi + +test -n "$silent" || echo "checking for minix/config.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <minix/config.h> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + MINIX=1 + +fi +rm -f conftest* + +# The Minix shell can't assign to the same variable on the same line! +if test -n "$MINIX"; then + +{ +test -n "$verbose" && \ +echo " defining _POSIX_SOURCE" +echo "#define" _POSIX_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_POSIX_SOURCE=1" +} + + +{ +test -n "$verbose" && \ +echo " defining" _POSIX_1_SOURCE to be "2" +echo "#define" _POSIX_1_SOURCE "2" >> confdefs.h +DEFS="$DEFS -D_POSIX_1_SOURCE=2" +} + + +{ +test -n "$verbose" && \ +echo " defining _MINIX" +echo "#define" _MINIX "1" >> confdefs.h +DEFS="$DEFS -D_MINIX=1" +} + +fi + +test -n "$silent" || echo "checking for ANSI C header files" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +echo '#include "confdefs.h" +#include <string.h>' > conftest.${ac_ext} +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "memchr" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +echo '#include "confdefs.h" +#include <stdlib.h>' > conftest.${ac_ext} +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "free" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining STDC_HEADERS" +echo "#define" STDC_HEADERS "1" >> confdefs.h +DEFS="$DEFS -DSTDC_HEADERS=1" +} + + +fi +rm -f conftest* + + +fi +rm -fr conftest* + +fi +rm -f conftest* + + +fi +rm -f conftest* + +for ac_hdr in memory.h unistd.h string.h +do +ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./' '[A-Z]__'` +test -n "$silent" || echo "checking for ${ac_hdr}" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <${ac_hdr}> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining ${ac_tr_hdr}" +echo "#define" ${ac_tr_hdr} "1" >> confdefs.h +DEFS="$DEFS -D${ac_tr_hdr}=1" +} + + +fi +rm -f conftest* +done + +test -n "$silent" || echo "checking for directory library header" +ac_dir_header= +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for dirent.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <dirent.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining DIRENT" +echo "#define" DIRENT "1" >> confdefs.h +DEFS="$DEFS -DDIRENT=1" +} + ac_dir_header=dirent.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/ndir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <sys/ndir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSNDIR" +echo "#define" SYSNDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSNDIR=1" +} + ac_dir_header=sys/ndir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/dir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <sys/dir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSDIR" +echo "#define" SYSDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSDIR=1" +} + ac_dir_header=sys/dir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for ndir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <ndir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NDIR" +echo "#define" NDIR "1" >> confdefs.h +DEFS="$DEFS -DNDIR=1" +} + ac_dir_header=ndir.h + +fi +rm -f conftest* +fi + +test -n "$silent" || echo "checking for closedir return value" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <$ac_dir_header> +int closedir(); main() { exit(closedir(opendir(".")) != 0); } +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + +{ +test -n "$verbose" && \ +echo " defining VOID_CLOSEDIR" +echo "#define" VOID_CLOSEDIR "1" >> confdefs.h +DEFS="$DEFS -DVOID_CLOSEDIR=1" +} + +fi +rm -fr conftest* + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +test -n "$silent" || echo "checking for working alloca.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <alloca.h> +int main() { return 0; } +int t() { char *p = alloca(2 * sizeof(int));; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_ALLOCA_H" +echo "#define" HAVE_ALLOCA_H "1" >> confdefs.h +DEFS="$DEFS -DHAVE_ALLOCA_H=1" +} + + +fi +rm -f conftest* + +ac_decl="#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#if HAVE_ALLOCA_H +#include <alloca.h> +#else +#ifdef _AIX + #pragma alloca +#else +char *alloca (); +#endif +#endif +#endif +" +test -n "$silent" || echo "checking for alloca" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +$ac_decl +int main() { return 0; } +int t() { char *p = (char *) alloca(1);; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_ALLOCA" +echo "#define" HAVE_ALLOCA "1" >> confdefs.h +DEFS="$DEFS -DHAVE_ALLOCA=1" +} + + +else + rm -rf conftest* + ac_alloca_missing=1 +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" + +#if defined(CRAY) && ! defined(CRAY2) +winnitude +#else +lossage +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "winnitude" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + test -n "$silent" || echo "checking for _getb67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__getb67) || defined (__stub____getb67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char _getb67(); _getb67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "_getb67" +echo "#define" CRAY_STACKSEG_END "_getb67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=_getb67" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for GETB67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_GETB67) || defined (__stub___GETB67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char GETB67(); GETB67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "GETB67" +echo "#define" CRAY_STACKSEG_END "GETB67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=GETB67" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for getb67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getb67) || defined (__stub___getb67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char getb67(); getb67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "getb67" +echo "#define" CRAY_STACKSEG_END "getb67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=getb67" +} + + +fi +rm -f conftest* + +fi +rm -f conftest* + +fi +rm -f conftest* + + +fi +rm -f conftest* + + +fi +rm -f conftest* + +if test -n "$ac_alloca_missing"; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.o + +{ +test -n "$verbose" && \ +echo " defining C_ALLOCA" +echo "#define" C_ALLOCA "1" >> confdefs.h +DEFS="$DEFS -DC_ALLOCA=1" +} + + + test -n "$silent" || echo "checking stack direction for C alloca" + test -n "$silent" || echo "checking whether cross-compiling" +# If we cannot run a trivial program, we must be cross compiling. +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +main(){exit(0);} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + cross_compiling=1 +fi +rm -fr conftest* + +if test -n "$cross_compiling" +then + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "0" +echo "#define" STACK_DIRECTION "0" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=0" +} + +else +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "1" +echo "#define" STACK_DIRECTION "1" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=1" +} + + +else + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "-1" +echo "#define" STACK_DIRECTION "-1" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=-1" +} + +fi +fi +rm -fr conftest* +fi + +test -n "$silent" || echo "checking for strcoll" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <string.h> +main () +{ + exit (strcoll ("abc", "def") >= 0 || + strcoll ("ABC", "DEF") >= 0 || + strcoll ("123", "456") >= 0); +} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + +{ +test -n "$verbose" && \ +echo " defining HAVE_STRCOLL" +echo "#define" HAVE_STRCOLL "1" >> confdefs.h +DEFS="$DEFS -DHAVE_STRCOLL=1" +} + + +fi +rm -fr conftest* +ac_save_LIBS="${LIBS}" +LIBS="${LIBS} -lseq" +ac_have_lib="" +test -n "$silent" || echo "checking for -lseq" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" + +int main() { return 0; } +int t() { main();; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_have_lib="1" + +fi +rm -f conftest* +LIBS="${ac_save_LIBS}" +if test -n "${ac_have_lib}"; then + :; LIBS="$LIBS -lseq" +else + :; +fi + + +test -n "$silent" || echo "checking for Xenix" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#if defined(M_XENIX) && !defined(M_UNIX) + yes +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + XENIX=1 + +fi +rm -f conftest* + +if test -n "$XENIX"; then + LIBS="$LIBS -lx" + case "$DEFS" in + *SYSNDIR*) ;; + *) LIBS="-ldir $LIBS" ;; # Make sure -ldir precedes any -lx. + esac +fi + + +# The preferred way to propogate these variables is regular @ substitutions. +if test -n "$prefix"; then + ac_prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" +else + prefix=/usr/local +fi +if test -n "$exec_prefix"; then + ac_prsub="$ac_prsub +s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%exec_prefix\\1=\\2$exec_prefix%" +else + exec_prefix='${prefix}' # Let make expand it. +fi + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +# Quote sed substitution magic chars in DEFS. +cat >conftest.def <<EOF +$DEFS +EOF +ac_escape_ampersand_and_backslash='s%[&\\]%\\&%g' +DEFS=`sed "$ac_escape_ampersand_and_backslash" <conftest.def` +rm -f conftest.def +# Substitute for predefined variables. + +trap 'rm -f config.status; exit 1' 1 2 15 +echo creating config.status +rm -f config.status +cat > config.status <<EOF +#!/bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $configure_args + +ac_cs_usage="Usage: config.status [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo running \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create + exec \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "config.status generated by autoconf version 1.11" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +trap 'rm -f Makefile; exit 1' 1 2 15 +RANLIB='$RANLIB' +CPP='$CPP' +ALLOCA='$ALLOCA' +LIBS='$LIBS' +srcdir='$srcdir' +top_srcdir='$top_srcdir' +prefix='$prefix' +exec_prefix='$exec_prefix' +DEFS='$DEFS' +ac_prsub='$ac_prsub' +ac_vpsub='$ac_vpsub' +extrasub='$extrasub' +EOF +cat >> config.status <<\EOF + +ac_given_srcdir=$srcdir + +CONFIG_FILES=${CONFIG_FILES-"Makefile"} +for ac_file in .. ${CONFIG_FILES}; do if test "x$ac_file" != x..; then + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/$ac_dir" + else + ac_dir_suffix= + fi + + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dir_suffix"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + comment_str="Generated automatically from `echo $ac_file|sed 's|.*/||'`.in by configure." + case "$ac_file" in + *.c | *.h | *.C | *.cc | *.m ) echo "/* $comment_str */" > "$ac_file" ;; + * ) echo "# $comment_str" > "$ac_file" ;; + esac + sed -e " +$ac_prsub +$ac_vpsub +$extrasub +s%@RANLIB@%$RANLIB%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g +s%@LIBS@%$LIBS%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@prefix@%$prefix%g +s%@exec_prefix@%$exec_prefix%g +s%@DEFS@%$DEFS% +" $ac_given_srcdir/${ac_file}.in >> $ac_file +fi; done + + +exit 0 +EOF +chmod +x config.status +# Some shells look in PATH for config.status without the "./". +test -n "$no_create" || ${CONFIG_SHELL-/bin/sh} ./config.status + diff --git a/posix/glob/configure.bat b/posix/glob/configure.bat new file mode 100644 index 0000000000..f3b0720c43 --- /dev/null +++ b/posix/glob/configure.bat @@ -0,0 +1,23 @@ +@echo off +echo Configuring glob for GO32 +rem This batch file assumes a unix-type "sed" program + +echo # Makefile generated by "configure.bat"> Makefile + +if exist config.sed del config.sed + +echo "s/@srcdir@/./ ">> config.sed +echo "s/@RANLIB@/ranlib/ ">> config.sed +echo "s/@LDFLAGS@// ">> config.sed +echo "s/@DEFS@/-DHAVE_CONFIG_H -I../ ">> config.sed +echo "s/@REMOTE@/s/ ">> config.sed +echo "s/@ALLOCA@// ">> config.sed +echo "s/@LIBS@// ">> config.sed +echo "s/@LIBOBJS@// ">> config.sed +echo "s/^Makefile *:/_Makefile:/ ">> config.sed +echo "s/^config.h *:/_config.h:/ ">> config.sed + +sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed +sed -f config2.sed Makefile.in >> Makefile +del config.sed +del config2.sed diff --git a/posix/glob/configure.in b/posix/glob/configure.in new file mode 100644 index 0000000000..3c85100778 --- /dev/null +++ b/posix/glob/configure.in @@ -0,0 +1,19 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(fnmatch.c) dnl A distinctive file to look for in srcdir. +AC_PREREQ(2.1) dnl Minimum Autoconf version required. +AC_PROG_CC +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB +AC_PROG_CPP dnl Later checks need this. +dnl These two want to come early. +AC_AIX +AC_MINIX +AC_CONST +AC_ISC_POSIX +AC_HEADER_STDC +AC_CHECK_HEADERS(memory.h unistd.h string.h) +AC_HEADER_DIRENT +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_ALLOCA +AC_FUNC_STRCOLL +AC_OUTPUT(Makefile) diff --git a/posix/gnu/types.h b/posix/gnu/types.h new file mode 100644 index 0000000000..30f753f72d --- /dev/null +++ b/posix/gnu/types.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1994 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GNU_TYPES_H + +#define _GNU_TYPES_H 1 + + +/* Convenience types. */ +typedef unsigned char __u_char; +typedef unsigned short __u_short; +typedef unsigned int __u_int; +typedef unsigned long __u_long; +#ifdef __GNUC__ +typedef unsigned long long int __u_quad_t; +typedef long long int __quad_t; +typedef __quad_t *__qaddr_t; +#else +typedef struct +{ + long val[2]; +} __quad_t; +typedef struct +{ + __u_long val[2]; +} __u_quad_t; +#endif +typedef int __dev_t; /* Type of device numbers. */ +typedef unsigned int __uid_t; /* Type of user identifications. */ +typedef unsigned int __gid_t; /* Type of group identifications. */ +typedef unsigned int __ino_t; /* Type of file serial numbers. */ +typedef unsigned int __mode_t; /* Type of file attribute bitmasks. */ +typedef unsigned short int __nlink_t; /* Type of file link counts. */ +typedef long int __off_t; /* Type of file sizes and offsets. */ +typedef int __pid_t; /* Type of process identifications. */ +typedef int __ssize_t; /* Type of a byte count, or error. */ +typedef __u_quad_t __fsid_t; /* Type of file system IDs. */ + +/* Everythin' else. */ +typedef long int __daddr_t; /* The type of a disk address. */ +typedef char *__caddr_t; +typedef long int __time_t; +typedef long int __swblk_t; /* Type of a swap block maybe? */ + +/* fd_set for select. */ + +/* Number of descriptors that can fit in an `fd_set'. */ +#define __FD_SETSIZE 256 + +/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ +#define __NFDBITS (sizeof (unsigned long int) * 8) +#define __FDELT(d) ((d) / __NFDBITS) +#define __FDMASK(d) (1 << ((d) % __NFDBITS)) + +typedef struct + { + /* Some braindead old software uses this member name. */ + unsigned long int fds_bits[(__FD_SETSIZE + (__NFDBITS - 1)) / __NFDBITS]; + } __fd_set; + +/* This line MUST be split! Otherwise m4 will not change it. */ +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (fd_set))) +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + + +#endif /* gnu/types.h */ diff --git a/posix/id.c b/posix/id.c new file mode 100644 index 0000000000..d886e68573 --- /dev/null +++ b/posix/id.c @@ -0,0 +1,173 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <grp.h> +#include <pwd.h> +#include <limits.h> +#include <sys/types.h> + + +static void +DEFUN(print_grpname, (id, parens), + gid_t id AND int parens) +{ + CONST struct group *CONST g = getgrgid(id); + if (g == NULL) + { + if (parens) + return; + else + { + fprintf(stderr, "Couldn't find name for group %d\n", id); + exit(EXIT_FAILURE); + } + } + + if (parens) + printf("(%s)", g->gr_name); + else + puts(g->gr_name); +} + +static void +DEFUN(print_pwdname, (id, parens), + uid_t id AND int parens) +{ + CONST struct passwd *CONST p = getpwuid(id); + if (p == NULL) + { + if (parens) + return; + else + { + fprintf(stderr, "Couldn't find name for user %d\n", (int) id); + exit(EXIT_FAILURE); + } + } + + if (parens) + printf("(%s)", p->pw_name); + else + puts(p->pw_name); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + int print_gid = 1, print_uid = 1; + int real = 0, name = 0; + int error = 0; + register int c; + + uid_t ruid = getuid(), euid = geteuid(); + gid_t rgid = getgid(), egid = getegid(); + + while ((c = getopt(argc, argv, "gurn")) != -1) + switch (c) + { + default: + error = 1; + break; + + case 'g': + print_gid = 1; + print_uid = 0; + break; + + case 'u': + print_uid = 1; + print_gid = 0; + break; + + case 'r': + real = 1; + break; + + case 'n': + name = 1; + break; + } + + if (error || argc != optind) + { + fputs("Usage: id [-gurn]\n", stderr); + exit(EXIT_FAILURE); + } + + if (print_uid && !print_gid) + { + CONST uid_t uid = real ? ruid : euid; + if (name) + print_pwdname(uid, 0); + else + printf("%d\n", (int) uid); + } + else if (print_gid && !print_uid) + { + CONST gid_t gid = real ? rgid : egid; + if (name) + print_grpname(gid, 0); + else + printf("%d\n", (int) gid); + } + else + { +#if NGROUPS_MAX > 0 + gid_t groups[NGROUPS_MAX]; + int ngroups; + ngroups = getgroups(NGROUPS_MAX, groups); +#endif + + printf("uid=%d", (int) ruid); + print_pwdname(ruid, 1); + printf(" gid=%d", (int) rgid); + print_grpname(rgid, 1); + if (euid != ruid) + { + printf(" euid=%d", (int) euid); + print_pwdname(euid, 1); + } + if (egid != rgid) + { + printf(" egid=%d", (int) egid); + print_grpname(egid, 1); + } + +#if NGROUPS > 0 + if (ngroups > 0) + { + register size_t i; + printf(" groups=%d", (int) groups[0]); + print_grpname(groups[0], 1); + for (i = 1; i < ngroups; ++i) + { + printf(", %d", (int) groups[i]); + print_grpname(groups[i], 1); + } + } +#endif + + putchar('\n'); + } + + exit(EXIT_SUCCESS); +} diff --git a/posix/posix1_lim.h b/posix/posix1_lim.h new file mode 100644 index 0000000000..acbfa64481 --- /dev/null +++ b/posix/posix1_lim.h @@ -0,0 +1,87 @@ +/* Copyright (C) 1991, 1992, 1993 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.9.2 Minimum Values Added to <limits.h> + */ + +#ifndef _POSIX1_LIMITS_H + +#define _POSIX1_LIMITS_H 1 + + +/* These are the standard-mandated minimum values. */ + +/* Maximum length of arguments to `execve', including environment. */ +#define _POSIX_ARG_MAX 4096 + +/* Maximum simultaneous processes per real user ID. */ +#define _POSIX_CHILD_MAX 6 + +/* Maximum link count of a file. */ +#define _POSIX_LINK_MAX 8 + +/* Number of bytes in a terminal canonical input queue. */ +#define _POSIX_MAX_CANON 255 + +/* Number of bytes for which space will be + available in a terminal input queue. */ +#define _POSIX_MAX_INPUT 255 + +/* Number of simultaneous supplementary group IDs per process. */ +#define _POSIX_NGROUPS_MAX 0 + +/* Number of files one process can have open at once. */ +#define _POSIX_OPEN_MAX 16 + +/* Number of bytes in a filename. */ +#define _POSIX_NAME_MAX 14 + +/* Number of bytes in a pathname. */ +#define _POSIX_PATH_MAX 255 + +/* Number of bytes than can be written atomically to a pipe. */ +#define _POSIX_PIPE_BUF 512 + +/* Largest value of a `ssize_t'. */ +#define _POSIX_SSIZE_MAX 32767 + +/* Number of streams a process can have open at once. */ +#define _POSIX_STREAM_MAX 8 + +/* Maximum length of a timezone name (element of `tzname'). */ +#define _POSIX_TZNAME_MAX 3 + + +/* Get the implementation-specific values for the above. */ +#include <local_lim.h> + + +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + + +/* This value is a guaranteed minimum maximum. + The current maximum can be got from `sysconf'. */ + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX _POSIX_NGROUPS_MAX +#endif + +#endif /* posix1_limits.h */ diff --git a/posix/posix2_lim.h b/posix/posix2_lim.h new file mode 100644 index 0000000000..05565024f6 --- /dev/null +++ b/posix/posix2_lim.h @@ -0,0 +1,82 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _POSIX2_LIMITS_H + +#define _POSIX2_LIMITS_H 1 + + +/* The maximum `ibase' and `obase' values allowed by the `bc' utility. */ +#define _POSIX2_BC_BASE_MAX 99 + +/* The maximum number of elements allowed in an array by the `bc' utility. */ +#define _POSIX2_BC_DIM_MAX 2048 + +/* The maximum `scale' value allowed by the `bc' utility. */ +#define _POSIX2_BC_SCALE_MAX 99 + +/* The maximum length of a string constant accepted by the `bc' utility. */ +#define _POSIX2_BC_STRING_MAX 1000 + +/* The maximum number of weights that can be assigned to an entry of + the LC_COLLATE category `order' keyword in a locale definition. */ +#define _POSIX2_EQUIV_CLASS_MAX 2 + +/* The maximum number of expressions that can be nested + within parentheses by the `expr' utility. */ +#define _POSIX2_EXPR_NEST_MAX 32 + +/* The maximum length, in bytes, of an input line. */ +#define _POSIX2_LINE_MAX 2048 + +/* The maximum number of repeated occurrences of a regular expression + permitted when using the interval notation `\{M,N\}'. */ +#define _POSIX2_RE_DUP_MAX 255 + + +/* These values are implementation-specific, + and may vary within the implementation. + Their precise values can be obtained from sysconf. */ + +#ifndef BC_BASE_MAX +#define BC_BASE_MAX _POSIX2_BC_BASE_MAX +#endif +#ifndef BC_DIM_MAX +#define BC_DIM_MAX _POSIX2_BC_DIM_MAX +#endif +#ifndef BC_SCALE_MAX +#define BC_SCALE_MAX _POSIX2_BC_SCALE_MAX +#endif +#ifndef BC_STRING_MAX +#define BC_STRING_MAX _POSIX2_BC_STRING_MAX +#endif +#ifndef EQUIV_CLASS_MAX +#define EQUIV_CLASS_MAX _POSIX2_EQUIV_CLASS_MAX +#endif +#ifndef EXPR_NEST_MAX +#define EXPR_NEST_MAX _POSIX2_EXPR_NEST_MAX +#endif +#ifndef LINE_MAX +#define LINE_MAX _POSIX2_LINE_MAX +#endif +#ifndef RE_DUP_MAX +#define RE_DUP_MAX _POSIX2_RE_DUP_MAX +#endif + + +#endif /* posix2_limits.h */ diff --git a/posix/sys/times.h b/posix/sys/times.h new file mode 100644 index 0000000000..b58be8a333 --- /dev/null +++ b/posix/sys/times.h @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 4.5.2 Process Times <sys/times.h> + */ + +#ifndef _SYS_TIMES_H + +#define _SYS_TIMES_H 1 +#include <features.h> + +#define __need_clock_t +#include <time.h> + + +__BEGIN_DECLS + +/* Structure describing CPU time used by a process and its children. */ +struct tms + { + clock_t tms_utime; /* User CPU time. */ + clock_t tms_stime; /* System CPU time. */ + + clock_t tms_cutime; /* User CPU time of dead children. */ + clock_t tms_cstime; /* System CPU time of dead children. */ + }; + + +/* Store the CPU time used by this process and all its + dead children (and their dead children) in BUFFER. + Return the elapsed real time, or (clock_t) -1 for errors. + All times are in CLK_TCKths of a second. */ +extern clock_t __times __P ((struct tms *__buffer)); +extern clock_t times __P ((struct tms *__buffer)); + +__END_DECLS + +#endif /* sys/times.h */ diff --git a/posix/sys/types.h b/posix/sys/types.h new file mode 100644 index 0000000000..b231de93c5 --- /dev/null +++ b/posix/sys/types.h @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992, 1994 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.6 Primitive System Data Types <sys/types.h> + */ + +#ifndef _SYS_TYPES_H + +#define _SYS_TYPES_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +#ifdef __USE_BSD +#define u_char __u_char +#define u_short __u_short +#define u_int __u_int +#define u_long __u_long +#define quad_t __quad_t +#define u_quad_t __u_quad_t +#define fsid_t __fsid_t +#endif + +#define dev_t __dev_t +#define gid_t __gid_t +#define ino_t __ino_t +#define mode_t __mode_t +#define nlink_t __nlink_t +#define off_t __off_t +#define pid_t __pid_t +#define uid_t __uid_t +#ifndef ssize_t +#define ssize_t __ssize_t +#endif + +#ifdef __USE_BSD +#define daddr_t __daddr_t +#define caddr_t __caddr_t +#endif + +#define __need_time_t +#include <time.h> + +#define __need_size_t +#include <stddef.h> + +#ifdef __USE_MISC +/* Old compatibility names for C types. */ +typedef unsigned short int ushort; +typedef unsigned int uint; +#endif + +#ifdef __USE_BSD +/* These size-specific names are used by some of the inet code. */ + +typedef int int32_t; +typedef short int int16_t; +typedef char int8_t; +typedef unsigned int u_int32_t; +typedef unsigned short int u_int16_t; +typedef unsigned char u_int8_t; +#endif + + +#ifdef __USE_BSD + +#define FD_SETSIZE __FD_SETSIZE +#define NFDBITS __NFDBITS +#define fd_set __fd_set +#define FD_ZERO(set) __FD_ZERO(set) +#define FD_SET(d, set) __FD_SET((d), (set)) +#define FD_CLR(d, set) __FD_CLR((d), (set)) +#define FD_ISSET(d, set)__FD_ISSET((d), (set)) + +/* This being here makes the `select' prototype valid whether or not + we have already included <sys/time.h> to define `struct timeval'. */ +struct timeval; + +/* Check the first NFDS descriptors each in READFDS (if not NULL) for read + readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS + (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out + after waiting the interval specified therein. Returns the number of ready + descriptors, or -1 for errors. */ +extern int __select __P ((int __nfds, __fd_set *__readfds, + __fd_set *__writefds, __fd_set *__exceptfds, + struct timeval *__timeout)); +extern int select __P ((int __nfds, __fd_set *__readfds, + __fd_set *__writefds, __fd_set *__exceptfds, + struct timeval *__timeout)); + +#endif /* Use BSD. */ + + +__END_DECLS + +#endif /* sys/types.h */ diff --git a/posix/sys/unistd.h b/posix/sys/unistd.h new file mode 100644 index 0000000000..1e823fbd53 --- /dev/null +++ b/posix/sys/unistd.h @@ -0,0 +1 @@ +#include <unistd.h> diff --git a/posix/sys/utsname.h b/posix/sys/utsname.h new file mode 100644 index 0000000000..16435baf86 --- /dev/null +++ b/posix/sys/utsname.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992, 1994 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 4.4 System Identification <sys/utsname.h> + */ + +#ifndef _SYS_UTSNAME_H + +#define _SYS_UTSNAME_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <utsnamelen.h> +#ifndef _UTSNAME_NODENAME_LENGTH +#define _UTSNAME_NODENAME_LENGTH _UTSNAME_LENGTH +#endif + +/* Structure describing the system and machine. */ +struct utsname + { + /* Name of the implementation of the operating system. */ + char sysname[_UTSNAME_LENGTH]; + + /* Name of this node on the network. */ + char nodename[_UTSNAME_NODENAME_LENGTH]; + + /* Current release level of this implementation. */ + char release[_UTSNAME_LENGTH]; + /* Current version level of this release. */ + char version[_UTSNAME_LENGTH]; + + /* Name of the hardware type the system is running on. */ + char machine[_UTSNAME_LENGTH]; + }; + +#ifdef __USE_SVID +#define SYS_NMLN _UTSNAME_LENGTH +#endif + + +/* Put information about the system in NAME. */ +extern int uname __P ((struct utsname *__name)); + + +__END_DECLS + +#endif /* sys/utsname.h */ diff --git a/posix/sys/wait.h b/posix/sys/wait.h new file mode 100644 index 0000000000..b7800d7090 --- /dev/null +++ b/posix/sys/wait.h @@ -0,0 +1,151 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 3.2.1 Wait for Process Termination <sys/wait.h> + */ + +#ifndef _SYS_WAIT_H + +#define _SYS_WAIT_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +/* This will define the `W*' macros for the flag + bits to `waitpid', `wait3', and `wait4'. */ +#include <waitflags.h> + +#ifdef __USE_BSD + +/* Lots of hair to allow traditional BSD use of `union wait' + as well as POSIX.1 use of `int' for the status word. */ + +#ifdef __GNUC__ +#define __WAIT_INT(status) \ + (__extension__ ({ union { __typeof(status) __in; int __i; } __u; \ + __u.__in = (status); __u.__i; })) +#else +#define __WAIT_INT(status) (*(int *) &(status)) +#endif + +/* This is the type of the argument to `wait'. + + NOTE: Since this functionality is volatile, I'm disabling the use of it for + now. + +With GCC 2.6.1 and later, the funky union causes redeclarations with either + `int *' or `union wait *' to be allowed without complaint. + __WAIT_STATUS_DEFN is the type used in the actual function + definitions. */ + +#if (!defined (__GNUC__) || __GNUC__ < 2 || \ + /*(__GNUC__ == 2 && __GNUC_MINOR__ < 6)*/ 1) +#define __WAIT_STATUS __ptr_t +#define __WAIT_STATUS_DEFN __ptr_t +#else +/* This works in GCC 2.6.1 and later. */ +typedef union + { + union wait *__uptr; + int *__iptr; + } __WAIT_STATUS __attribute__ ((transparent_union)); +#define __WAIT_STATUS_DEFN int * +#endif + +#else /* Don't use BSD. */ + +#define __WAIT_INT(status) (status) +#define __WAIT_STATUS int * +#define __WAIT_STATUS_DEFN int * + +#endif /* Use BSD. */ + +/* This will define all the `__W*' macros. */ +#include <waitstatus.h> + +#define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status)) +#define WTERMSIG(status) __WTERMSIG(__WAIT_INT(status)) +#define WSTOPSIG(status) __WSTOPSIG(__WAIT_INT(status)) +#define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status)) +#define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status)) +#define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status)) + +#ifdef __USE_BSD +#define WCOREFLAG __WCOREFLAG +#define WCOREDUMP(status) __WCOREDUMP(__WAIT_INT(status)) +#define W_EXITCODE(ret, sig) __W_EXITCODE(ret, sig) +#define W_STOPCODE(sig) __W_STOPCODE(sig) +#endif + + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +extern __pid_t __wait __P ((__WAIT_STATUS __stat_loc)); +extern __pid_t wait __P ((__WAIT_STATUS __stat_loc)); + +#ifdef __USE_BSD +/* Special values for the PID argument to `waitpid' and `wait4'. */ +#define WAIT_ANY (-1) /* Any process. */ +#define WAIT_MYPGRP 0 /* Any process in my process group. */ +#endif + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is + set in OPTIONS, return status for stopped children; otherwise don't. */ +extern __pid_t __waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +extern __pid_t waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +#ifdef __USE_BSD +/* This being here makes the prototypes valid whether or not + we have already included <sys/resource.h> to define `struct rusage'. */ +struct rusage; + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not + nil, store information about the child's resource usage there. If the + WUNTRACED bit is set in OPTIONS, return status for stopped children; + otherwise don't. */ +extern __pid_t __wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); +extern __pid_t wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); + +/* PID is like waitpid. Other args are like wait3. */ +extern __pid_t __wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +extern __pid_t wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +#endif /* Use BSD. */ + + +__END_DECLS + +#endif /* sys/wait.h */ diff --git a/posix/tar.h b/posix/tar.h new file mode 100644 index 0000000000..e5e9901bdf --- /dev/null +++ b/posix/tar.h @@ -0,0 +1,110 @@ +/* Extended tar format from POSIX.1. + Copyright (C) 1992 Free Software Foundation, Inc. + Written by David J. MacKenzie. + +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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _TAR_H + +#define _TAR_H 1 + +/* A tar archive consists of 512-byte blocks. + Each file in the archive has a header block followed by 0+ data blocks. + Two blocks of NUL bytes indicate the end of the archive. */ + +/* The fields of header blocks: + All strings are stored as ISO 646 (approximately ASCII) strings. + + Fields are numeric unless otherwise noted below; numbers are ISO 646 + representations of octal numbers, with leading zeros as needed. + + linkname is only valid when typeflag==LNKTYPE. It doesn't use prefix; + files that are links to pathnames >100 chars long can not be stored + in a tar archive. + + If typeflag=={LNKTYPE,SYMTYPE,DIRTYPE} then size must be 0. + + devmajor and devminor are only valid for typeflag=={BLKTYPE,CHRTYPE}. + + chksum contains the sum of all 512 bytes in the header block, + treating each byte as an 8-bit unsigned value and treating the + 8 bytes of chksum as blank characters. + + uname and gname are used in preference to uid and gid, if those + names exist locally. + + Field Name Byte Offset Length in Bytes Field Type + name 0 100 NUL-terminated if NUL fits + mode 100 8 + uid 108 8 + gid 116 8 + size 124 12 + mtime 136 12 + chksum 148 8 + typeflag 156 1 see below + linkname 157 100 NUL-terminated if NUL fits + magic 257 6 must be TMAGIC (NUL term.) + version 263 2 must be TVERSION + uname 265 32 NUL-terminated + gname 297 32 NUL-terminated + devmajor 329 8 + devminor 337 8 + prefix 345 155 NUL-terminated if NUL fits + + If the first character of prefix is '\0', the file name is name; + otherwise, it is prefix/name. Files whose pathnames don't fit in that + length can not be stored in a tar archive. */ + +/* The bits in mode: */ +#define TSUID 04000 +#define TSGID 02000 +#define TSVTX 01000 +#define TUREAD 00400 +#define TUWRITE 00200 +#define TUEXEC 00100 +#define TGREAD 00040 +#define TGWRITE 00020 +#define TGEXEC 00010 +#define TOREAD 00004 +#define TOWRITE 00002 +#define TOEXEC 00001 + +/* The values for typeflag: + Values 'A'-'Z' are reserved for custom implementations. + All other values are reserved for future POSIX.1 revisions. */ + +#define REGTYPE '0' /* Regular file (preferred code). */ +#define AREGTYPE '\0' /* Regular file (alternate code). */ +#define LNKTYPE '1' /* Hard link. */ +#define SYMTYPE '2' /* Symbolic link (hard if not supported). */ +#define CHRTYPE '3' /* Character special. */ +#define BLKTYPE '4' /* Block special. */ +#define DIRTYPE '5' /* Directory. */ +#define FIFOTYPE '6' /* Named pipe. */ +#define CONTTYPE '7' /* Contiguous file */ + /* (regular file if not supported). */ + +/* Contents of magic field and its length. */ +#define TMAGIC "ustar" +#define TMAGLEN 6 + +/* Contents of the version field and its length. */ +#define TVERSION "00" +#define TVERSLEN 2 + +#endif /* tar.h */ diff --git a/posix/testfnm.args b/posix/testfnm.args new file mode 100644 index 0000000000..4a52662d5d --- /dev/null +++ b/posix/testfnm.args @@ -0,0 +1 @@ +*LIB* lib diff --git a/posix/testfnm.c b/posix/testfnm.c new file mode 100644 index 0000000000..648dbd3961 --- /dev/null +++ b/posix/testfnm.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include "fnmatch.h" + +int +main (c, v) + int c; + char **v; +{ + printf ("%d\n", fnmatch (v[1], v[2], FNM_PERIOD)); + printf ("%d\n", fnmatch (v[1], v[2], FNM_CASEFOLD|FNM_PERIOD)); + exit (0); +} diff --git a/posix/tstgetopt.args b/posix/tstgetopt.args new file mode 100644 index 0000000000..023e102a24 --- /dev/null +++ b/posix/tstgetopt.args @@ -0,0 +1 @@ +-a -b -cfoobar diff --git a/posix/tstgetopt.c b/posix/tstgetopt.c new file mode 100644 index 0000000000..fd2d4d0469 --- /dev/null +++ b/posix/tstgetopt.c @@ -0,0 +1,41 @@ +#include <ansidecl.h> +#include <unistd.h> +#include <stdio.h> + +int main (int argc, char **argv) +{ + int aflag = 0; + int bflag = 0; + char *cvalue = NULL; + int index; + int c; + + while ((c = getopt (argc, argv, "abc:")) >= 0) + switch (c) { + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + case 'c': + cvalue = optarg; + break; + case '?': +#if 0 + fprintf (stderr, "Unknown option %c.\n", optopt); +#else + fputs ("Unknown option.\n", stderr); +#endif + return -1; + default: + fprintf (stderr, "This should never happen!\n"); + return -1; + } + + printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue); + + for (index = optind; index < argc; index++) + printf ("Non-option argument %s\n", argv[index]); + return 0; +} diff --git a/posix/unistd.h b/posix/unistd.h new file mode 100644 index 0000000000..7143fe1606 --- /dev/null +++ b/posix/unistd.h @@ -0,0 +1,642 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.10 Symbolic Constants <unistd.h> + */ + +#ifndef _UNISTD_H + +#define _UNISTD_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* These may be used to determine what facilities are present at compile time. + Their values can be obtained at run time from sysconf. */ + +/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */ +#define _POSIX_VERSION 199009L + +/* These are not #ifdef __USE_POSIX2 because they are + in the theoretically application-owned namespace. */ + +#define _POSIX2_C_VERSION 199912L /* Invalid until 1003.2 is done. */ + +/* If defined, the implementation supports the + C Language Bindings Option. */ +#define _POSIX2_C_BIND 1 + +/* If defined, the implementation supports the + C Language Development Utilities Option. */ +#define _POSIX2_C_DEV 1 + +/* If defined, the implementation supports the + Software Development Utilities Option. */ +#define _POSIX2_SW_DEV 1 + + +/* Get values of POSIX options: + + If these symbols are defined, the corresponding features are + always available. If not, they may be available sometimes. + The current values can be obtained with `sysconf'. + + _POSIX_JOB_CONTROL Job control is supported. + _POSIX_SAVED_IDS Processes have a saved set-user-ID + and a saved set-group-ID. + + If any of these symbols is defined as -1, the corresponding option is not + true for any file. If any is defined as other than -1, the corresponding + option is true for all files. If a symbol is not defined at all, the value + for a specific file can be obtained from `pathconf' and `fpathconf'. + + _POSIX_CHOWN_RESTRICTED Only the super user can use `chown' to change + the owner of a file. `chown' can only be used + to change the group ID of a file to a group of + which the calling process is a member. + _POSIX_NO_TRUNC Pathname components longer than + NAME_MAX generate an error. + _POSIX_VDISABLE If defined, if the value of an element of the + `c_cc' member of `struct termios' is + _POSIX_VDISABLE, no character will have the + effect associated with that element. + */ + +#include <posix_opt.h> + + +/* Standard file descriptors. */ +#define STDIN_FILENO 0 /* Standard input. */ +#define STDOUT_FILENO 1 /* Standard output. */ +#define STDERR_FILENO 2 /* Standard error output. */ + + +/* All functions that are not declared anywhere else. */ + +#include <gnu/types.h> + +#ifndef ssize_t +#define ssize_t __ssize_t +#endif + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + + +/* Values for the second argument to access. + These may be OR'd together. */ +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ + +/* Test for access to NAME. */ +extern int __access __P ((__const char *__name, int __type)); +extern int access __P ((__const char *__name, int __type)); + + +/* Values for the WHENCE argument to lseek. */ +#ifndef _STDIO_H /* <stdio.h> has the same definitions. */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ +#endif + +/* Move FD's file position to OFFSET bytes from the + beginning of the file (if WHENCE is SEEK_SET), + the current position (if WHENCE is SEEK_CUR), + or the end of the file (if WHENCE is SEEK_END). + Return the new file position. */ +extern __off_t __lseek __P ((int __fd, __off_t __offset, int __whence)); +extern __off_t lseek __P ((int __fd, __off_t __offset, int __whence)); + +/* Close the file descriptor FD. */ +extern int __close __P ((int __fd)); +extern int close __P ((int __fd)); + +/* Read NBYTES into BUF from FD. Return the + number read, -1 for errors or 0 for EOF. */ +extern ssize_t __read __P ((int __fd, __ptr_t __buf, size_t __nbytes)); +extern ssize_t read __P ((int __fd, __ptr_t __buf, size_t __nbytes)); + +/* Write N bytes of BUF to FD. Return the number written, or -1. */ +extern ssize_t __write __P ((int __fd, __const __ptr_t __buf, size_t __n)); +extern ssize_t write __P ((int __fd, __const __ptr_t __buf, size_t __n)); + + +/* Create a one-way communication channel (pipe). + If successul, two file descriptors are stored in PIPEDES; + bytes written on PIPEDES[1] can be read from PIPEDES[0]. + Returns 0 if successful, -1 if not. */ +extern int __pipe __P ((int __pipedes[2])); +extern int pipe __P ((int __pipedes[2])); + +/* Schedule an alarm. In SECONDS seconds, the process will get a SIGALRM. + If SECONDS is zero, any currently scheduled alarm will be cancelled. + The function returns the number of seconds remaining until the last + alarm scheduled would have signaled, or zero if there wasn't one. + There is no return value to indicate an error, but you can set `errno' + to 0 and check its value after calling `alarm', and this might tell you. + The signal may come late due to processor scheduling. */ +extern unsigned int alarm __P ((unsigned int __seconds)); + +/* Make the process sleep for SECONDS seconds, or until a signal arrives + and is not ignored. The function returns the number of seconds less + than SECONDS which it actually slept (thus zero if it slept the full time). + If a signal handler does a `longjmp' or modifies the handling of the + SIGALRM signal while inside `sleep' call, the handling of the SIGALRM + signal afterwards is undefined. There is no return value to indicate + error, but if `sleep' returns SECONDS, it probably didn't work. */ +extern unsigned int sleep __P ((unsigned int __seconds)); + + +/* Suspend the process until a signal arrives. + This always returns -1 and sets `errno' to EINTR. */ +extern int pause __P ((void)); + + +/* Change the owner and group of FILE. */ +extern int __chown __P ((__const char *__file, + __uid_t __owner, __gid_t __group)); +extern int chown __P ((__const char *__file, + __uid_t __owner, __gid_t __group)); + +#ifdef __USE_BSD +/* Change the owner and group of the file that FD is open on. */ +extern int __fchown __P ((int __fd, + __uid_t __owner, __gid_t __group)); +extern int fchown __P ((int __fd, + __uid_t __owner, __gid_t __group)); +#endif /* Use BSD. */ + +/* Change the process's working directory to PATH. */ +extern int __chdir __P ((__const char *__path)); +extern int chdir __P ((__const char *__path)); + +#ifdef __USE_BSD +/* Change the process's working directory to the one FD is open on. */ +extern int fchdir __P ((int __fd)); +#endif + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +extern char *getcwd __P ((char *__buf, size_t __size)); + +#ifdef __USE_GNU +/* Return a malloc'd string containing the current directory name. + If the environment variable `PWD' is set, and its value is correct, + that value is used. */ +extern char *get_current_dir_name __P ((void)); +#endif + +#ifdef __USE_BSD +/* Put the absolute pathname of the current working directory in BUF. + If successful, return BUF. If not, put an error message in + BUF and return NULL. BUF should be at least PATH_MAX bytes long. */ +extern char *getwd __P ((char *__buf)); +#endif + + +/* Duplicate FD, returning a new file descriptor on the same file. */ +extern int __dup __P ((int __fd)); +extern int dup __P ((int __fd)); + +/* Duplicate FD to FD2, closing FD2 and making it open on the same file. */ +extern int __dup2 __P ((int __fd, int __fd2)); +extern int dup2 __P ((int __fd, int __fd2)); + +/* NULL-terminated array of "NAME=VALUE" environment variables. */ +extern char **__environ; +extern char **environ; + + +/* Replace the current process, executing PATH with arguments ARGV and + environment ENVP. ARGV and ENVP are terminated by NULL pointers. */ +extern int __execve __P ((__const char *__path, char *__const __argv[], + char *__const __envp[])); +extern int execve __P ((__const char *__path, char *__const __argv[], + char *__const __envp[])); + +#ifdef __USE_GNU +/* Execute the file FD refers to, overlaying the running program image. + ARGV and ENVP are passed to the new program, as for `execve'. */ +extern int fexecve __P ((int __fd, + char *const __argv[], char *const __envp[])); + +#endif + + +/* Execute PATH with arguments ARGV and environment from `environ'. */ +extern int execv __P ((__const char *__path, char *__const __argv[])); + +/* Execute PATH with all arguments after PATH until a NULL pointer, + and the argument after that for environment. */ +extern int execle __P ((__const char *__path, __const char *__arg,...)); + +/* Execute PATH with all arguments after PATH until + a NULL pointer and environment from `environ'. */ +extern int execl __P ((__const char *__path, __const char *__arg,...)); + +/* Execute FILE, searching in the `PATH' environment variable if it contains + no slashes, with arguments ARGV and environment from `environ'. */ +extern int execvp __P ((__const char *__file, char *__const __argv[])); + +/* Execute FILE, searching in the `PATH' environment variable if + it contains no slashes, with all arguments after FILE until a + NULL pointer and environment from `environ'. */ +extern int execlp __P ((__const char *__file, ...)); + + +/* Terminate program execution with the low-order 8 bits of STATUS. */ +extern void _exit __P ((int __status)) __attribute__ ((__noreturn__)); + + +/* Get the `_PC_*' symbols for the NAME argument to `pathconf' and `fpathconf'; + the `_SC_*' symbols for the NAME argument to `sysconf'; + and the `_CS_*' symbols for the NAME argument to `confstr'. */ +#include <confname.h> + +/* Get file-specific configuration information about PATH. */ +extern long int __pathconf __P ((__const char *__path, int __name)); +extern long int pathconf __P ((__const char *__path, int __name)); + +/* Get file-specific configuration about descriptor FD. */ +extern long int __fpathconf __P ((int __fd, int __name)); +extern long int fpathconf __P ((int __fd, int __name)); + +/* Get the value of the system variable NAME. */ +extern long int __sysconf __P ((int __name)); +extern long int sysconf __P ((int __name)); + +#ifdef __USE_POSIX2 +/* Get the value of the string-valued system variable NAME. */ +extern size_t confstr __P ((int __name, char *__buf, size_t __len)); +#endif + + +/* Get the process ID of the calling process. */ +extern __pid_t __getpid __P ((void)); +extern __pid_t getpid __P ((void)); + +/* Get the process ID of the calling process's parent. */ +extern __pid_t __getppid __P ((void)); +extern __pid_t getppid __P ((void)); + +/* Get the process group ID of the calling process. */ +extern __pid_t getpgrp __P ((void)); + +/* Set the process group ID of the process matching PID to PGID. + If PID is zero, the current process's process group ID is set. + If PGID is zero, the process ID of the process is used. */ +extern int setpgid __P ((__pid_t __pid, __pid_t __pgid)); + +/* Get the process group ID of process PID. */ +extern __pid_t __getpgid __P ((__pid_t __pid)); +#ifdef __USE_GNU +extern __pid_t getpgid __P ((__pid_t __pid)); +#endif + +#ifdef __USE_BSD +/* Another name for `setpgid'. */ +extern int setpgrp __P ((__pid_t __pid, __pid_t __pgrp)); +#endif /* Use BSD. */ + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +extern __pid_t __setsid __P ((void)); +extern __pid_t setsid __P ((void)); + +/* Get the real user ID of the calling process. */ +extern __uid_t __getuid __P ((void)); +extern __uid_t getuid __P ((void)); + +/* Get the effective user ID of the calling process. */ +extern __uid_t __geteuid __P ((void)); +extern __uid_t geteuid __P ((void)); + +/* Get the real group ID of the calling process. */ +extern __gid_t __getgid __P ((void)); +extern __gid_t getgid __P ((void)); + +/* Get the effective group ID of the calling process. */ +extern __gid_t __getegid __P ((void)); +extern __gid_t getegid __P ((void)); + +/* If SIZE is zero, return the number of supplementary groups + the calling process is in. Otherwise, fill in the group IDs + of its supplementary groups in LIST and return the number written. */ +extern int __getgroups __P ((int __size, __gid_t __list[])); +extern int getgroups __P ((int __size, __gid_t __list[])); + +/* Set the user ID of the calling process to UID. + If the calling process is the super-user, set the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID. */ +extern int __setuid __P ((__uid_t __uid)); +extern int setuid __P ((__uid_t __uid)); + +#ifdef __USE_BSD +/* Set the real user ID of the calling process to RUID, + and the effective user ID of the calling process to EUID. */ +extern int __setreuid __P ((__uid_t __ruid, __uid_t __euid)); +extern int setreuid __P ((__uid_t __ruid, __uid_t __euid)); + +/* Set the effective user ID of the calling process to UID. */ +extern int seteuid __P ((__uid_t __uid)); +#endif /* Use BSD. */ + +/* Set the group ID of the calling process to GID. + If the calling process is the super-user, set the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID. */ +extern int __setgid __P ((__gid_t __gid)); +extern int setgid __P ((__gid_t __gid)); + +#ifdef __USE_BSD +/* Set the real group ID of the calling process to RGID, + and the effective group ID of the calling process to EGID. */ +extern int __setregid __P ((__gid_t __rgid, __gid_t __egid)); +extern int setregid __P ((__gid_t __rgid, __gid_t __egid)); + +/* Set the effective group ID of the calling process to GID. */ +extern int setegid __P ((__gid_t __gid)); +#endif /* Use BSD. */ + + +/* Clone the calling process, creating an exact copy. + Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +extern __pid_t __fork __P ((void)); +extern __pid_t fork __P ((void)); + +#ifdef __USE_BSD +/* Clone the calling process, but without copying the whole address space. + The the calling process is suspended until the the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +extern __pid_t __vfork __P ((void)); +extern __pid_t vfork __P ((void)); +#endif /* Use BSD. */ + + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +extern char *ttyname __P ((int __fd)); + +/* Return 1 if FD is a valid descriptor associated + with a terminal, zero if not. */ +extern int __isatty __P ((int __fd)); +extern int isatty __P ((int __fd)); + + +/* Make a link to FROM named TO. */ +extern int __link __P ((__const char *__from, __const char *__to)); +extern int link __P ((__const char *__from, __const char *__to)); + +#ifdef __USE_BSD +/* Make a symbolic link to FROM named TO. */ +extern int __symlink __P ((__const char *__from, __const char *__to)); +extern int symlink __P ((__const char *__from, __const char *__to)); + +/* Read the contents of the symbolic link PATH into no more than + LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +extern int __readlink __P ((__const char *__path, char *__buf, size_t __len)); +extern int readlink __P ((__const char *__path, char *__buf, size_t __len)); +#endif /* Use BSD. */ + +/* Remove the link NAME. */ +extern int __unlink __P ((__const char *__name)); +extern int unlink __P ((__const char *__name)); + +/* Remove the directory PATH. */ +extern int __rmdir __P ((__const char *__path)); +extern int rmdir __P ((__const char *__path)); + + +/* Return the foreground process group ID of FD. */ +extern __pid_t tcgetpgrp __P ((int __fd)); + +/* Set the foreground process group ID of FD set PGRP_ID. */ +extern int tcsetpgrp __P ((int __fd, __pid_t __pgrp_id)); + + +/* Return the login name of the user. */ +extern char *getlogin __P ((void)); + +#ifdef __USE_BSD +/* Set the login name returned by `getlogin'. */ +extern int setlogin __P ((__const char *__name)); +#endif + + +#ifdef __USE_POSIX2 +/* Process the arguments in ARGV (ARGC of them, minus + the program name) for options given in OPTS. + + If `opterr' is zero, no messages are generated + for invalid options; it defaults to 1. + `optind' is the current index into ARGV. + `optarg' is the argument corresponding to the current option. + Return the option character from OPTS just read. + Return -1 when there are no more options. + For unrecognized options, or options missing arguments, + `optopt' is set to the option letter, and '?' is returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is optional. + This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument scanning, + explicitly telling `getopt' that there are no more options. + + If OPTS begins with `--', then non-option arguments + are treated as arguments to the option '\0'. + This behavior is specific to the GNU `getopt'. */ +extern int getopt __P ((int __argc, char *__const * __argv, + __const char *__opts)); +extern int opterr; +extern int optind; +extern int optopt; +extern char *optarg; +#endif + + +#ifdef __USE_BSD + +/* Put the name of the current host in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +extern int __gethostname __P ((char *__name, size_t __len)); +extern int gethostname __P ((char *__name, size_t __len)); + +/* Set the name of the current host to NAME, which is LEN bytes long. + This call is restricted to the super-user. */ +extern int sethostname __P ((__const char *__name, size_t __len)); + +/* Return the current machine's Internet number. */ +extern long int gethostid __P ((void)); + +/* Set the current machine's Internet number to ID. + This call is restricted to the super-user. */ +extern int sethostid __P ((long int __id)); + + +/* Return the number of bytes in a page. This is the system's page size, + which is not necessarily the same as the hardware page size. */ +extern size_t __getpagesize __P ((void)); +extern size_t getpagesize __P ((void)); + + +/* Return the maximum number of file descriptors + the current process could possibly have. */ +extern int __getdtablesize __P ((void)); +extern int getdtablesize __P ((void)); + + +/* Truncate FILE to LENGTH bytes. */ +extern int truncate __P ((__const char *__file, __off_t __length)); + +/* Truncate the file FD is open on to LENGTH bytes. */ +extern int ftruncate __P ((int __fd, __off_t __length)); + + +/* Make all changes done to FD actually appear on disk. */ +extern int fsync __P ((int __fd)); + +/* Make all changes done to all files actually appear on disk. */ +extern int sync __P ((void)); + + +/* Revoke access permissions to all processes currently communicating + with the control terminal, and then send a SIGHUP signal to the process + group of the control terminal. */ +extern int vhangup __P ((void)); + + +/* Turn accounting on if NAME is an existing file. The system will then write + a record for each process as it terminates, to this file. If NAME is NULL, + turn accounting off. This call is restricted to the super-user. */ +extern int acct __P ((__const char *__name)); + +/* Make PATH be the root directory (the starting point for absolute paths). + This call is restricted to the super-user. */ +extern int chroot __P ((__const char *__path)); + +/* Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user. */ +extern int swapon __P ((__const char *__path)); + +/* Reboot or halt the system. */ +extern int reboot __P ((int __howto)); + + +/* Successive calls return the shells listed in `/etc/shells'. */ +extern char *getusershell __P ((void)); +extern void endusershell __P ((void)); /* Discard cached info. */ +extern void setusershell __P ((void)); /* Rewind and re-read the file. */ + + +/* Prompt with PROMPT and read a string from the terminal without echoing. + Uses /dev/tty if possible; otherwise stderr and stdin. */ +extern char *getpass __P ((const char *__prompt)); + +/* Put the program in the background, and dissociate from the controlling + terminal. If NOCHDIR is zero, do `chdir ("/")'. If NOCLOSE is zero, + redirects stdin, stdout, and stderr to /dev/null. */ +extern int daemon __P ((int __nochdir, int __noclose)); + +#endif /* Use BSD. */ + + +#ifdef __USE_MISC + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique file name. */ +extern char *mktemp __P ((char *__template)); + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns a file descriptor open on the file for reading and writing, + or -1 if it cannot create a uniquely-named file. */ +extern int mkstemp __P ((char *__template)); + + +/* Invoke `system call' number SYSNO, passing it the remaining arguments. + This is completely system-dependent, and not often useful. + + In Unix, `syscall' sets `errno' for all errors and most calls return -1 + for errors; in many systems you cannot pass arguments or get return + values for all system calls (`pipe', `fork', and `getppid' typically + among them). + + In Mach, all system calls take normal arguments and always return an + error code (zero for success). */ +extern int syscall __P ((int __sysno, ...)); + +#endif /* Use misc. */ + + +#if defined (__USE_MISC) && !defined (F_LOCK) +/* NOTE: These declarations also appear in <fcntl.h>; be sure to keep both + files consistent. Some systems have them there and some here, and some + software depends on the macros being defined without including both. */ + +/* `lockf' is a simpler interface to the locking facilities of `fcntl'. + LEN is always relative to the current file position. + The CMD argument is one of the following. */ + +#define F_ULOCK 0 /* Unlock a previously locked region. */ +#define F_LOCK 1 /* Lock a region for exclusive use. */ +#define F_TLOCK 2 /* Test and lock a region for exclusive use. */ +#define F_TEST 3 /* Test a region for other processes locks. */ + +extern int lockf __P ((int __fd, int __cmd, __off_t __len)); +#endif /* Use misc and F_LOCK not already defined. */ + + +#ifdef __USE_GNU + +/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno' + set to EINTR. */ + +#define TEMP_FAILURE_RETRY(expression) \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; }) + +#endif + +__END_DECLS + +#endif /* unistd.h */ diff --git a/posix/wordexp.c b/posix/wordexp.c new file mode 100644 index 0000000000..1922e44642 --- /dev/null +++ b/posix/wordexp.c @@ -0,0 +1,184 @@ +/* Copyright (C) 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <wordexp.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> + + +/* We do word expansion with a pipe to the shell. + The shell command `sh [-P] [-u] -w "words ..."' expands words. + If -P, command substitution is an error. + If -u, reference to an undefined variable is an error. + The shell writes on its stdout: + %u\0 Number of words. + %u\0 Number of bytes in all words together (not counting \0s). + word1\0 + word2\0 + ... + wordN\0 + */ + +#define SHELL_PATH "/bin/sh" +#define SHELL_NAME "sh" + + +int +DEFUN(wordexp, (string, pwordexp, flags), + CONST char *string AND wordexp_t *pwordexp AND int flags) +{ + int error; + pid_t pid; + int d[2]; + int status; + + FILE *f; + size_t wordc, start, buflen; + char *buf; + + /* Create the pipe through which we will communicate to the shell. */ + if (pipe (d) < 0) + return -1; + + pid = fork (); + if (pid < 0) + return -1; + + if (pid == 0) + { + /* Child. Run the shell. */ + + CONST char *argv[5]; + + close (d[STDIN_FILENO]); + dup2 (d[STDOUT_FILENO], STDOUT_FILENO); + if (!(flags & WRDE_SHOWERR)) + close (STDERR_FILENO); + + i = 0; + argv[i++] = SHELL_NAME; + if (flags & WRDE_NOCMD) + argv[i++] = "-P"; + if (flags & WRDE_UNDEF) + argv[i++] = "-u"; + argv[i++] = "-w"; + argv[i++] = string; + argv[i++] = NULL; + + execv (SHELL_PATH, argv); + _exit (WRDE_NOSPACE); + } + + /* Parent. */ + + buf = NULL; + error = WRDE_NOSPACE; + + close (d[STDOUT_FILENO]); + f = fdopen (d[STDIN_FILENO]); + if (f == NULL) + goto lose; + + /* Read the number of words and number of bytes from the shell. */ + if (fscanf (f, "%u", &wordc) != 1 || getc (f) != '\0' || + fscanf (f, "%u", &buflen) != 1 || getc (f) != '\0') + goto lose; + + /* Read the words from the shell, and wait for it to return. */ + buflen += wordc; + buf = malloc (buflen); + if (buf == NULL || + fread (buf, buflen, 1, f) != 1 || + waitpid (pid, &status, 0) != pid) + goto lose; + + if (WIFEXITED (status)) + { + if (WEXITSTATUS (status) != 0) + { + error = WEXITSTATUS (status); + goto lose; + } + } + else + goto lose; + + /* Pack the structure. */ + + start = 0; + if (flags & WRDE_DOOFFS) + start += pwordexp->we_offs; + if (flags & WRDE_APPEND) + start += pwordexp->we_wordc; + wordc = start + wordc + 1; + + if (flags & WRDE_APPEND) + wordv = (char **) realloc ((PTR) pwordexp->we_wordv, + wordc * sizeof (char *)); + else + wordv = (char **) malloc (wordc * sizeof (char *)); + if (wordv == NULL) + goto lose; + + if (flags & WRDE_DOOFFS) + for (i = 0; i < pwordexp->we_offs; ++i) + wordv[i] = NULL; + + for (i = start; i < wordc; ++i) + { + pwordexp->we_wordv[i] = buf; + buf = strchr (buf, '\0') + 1; + } + wordv[i] = NULL; + + if (flags & WRDE_REUSE) + { + free (pwordexp->we_wordv[0]); + if (!(flags & WRDE_APPEND)) + free (pwordexp->we_wordv); + } + + pwordexp->we_wordc = wordc; + pwordexp->we_wordv = wordv; + + return 0; + + lose: + { + int save; + save = errno; + (void) kill (pid, SIGKILL); + free (buf); + (void) waitpid (pid, (int *) NULL, 0); + errno = save; + return error; + } +} + + +void +DEFUN(wordexp, (pwordexp), wordexp_t *pwordexp) +{ + /* All the other elts point into the first. */ + free (pwordexp->we_wordv[0]); + free (pwordexp->we_wordv); +} diff --git a/posix/wordexp.h b/posix/wordexp.h new file mode 100644 index 0000000000..02b1788197 --- /dev/null +++ b/posix/wordexp.h @@ -0,0 +1,66 @@ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _WORDEXP_H + +#define _WORDEXP_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Bits set in the FLAGS argument to `wordexp'. */ +enum + { + WRDE_DOOFFS = (1 << 0), /* Insert PWORDEXP->we_offs NULLs. */ + WRDE_APPEND = (1 << 1), /* Append to results of a previous call. */ + WRDE_NOCMD = (1 << 2), /* Don't do command substitution. */ + WRDE_REUSE = (1 << 3), /* Reuse storage in PWORDEXP. */ + WRDE_SHOWERR = (1 << 4), /* Don't redirect stderr to /dev/null. */ + WRDE_UNDEF = (1 << 5), /* Error for expanding undefined variables. */ + __WRDE_FLAGS = (WRDE_DOOFFS | WRDE_APPEND | WRDE_NOCMD | + WRDE_REUSE | WRDE_SHOWERR | WRDE_UNDEF), + }; + +/* Structure describing a word-expansion run. */ +typedef struct + { + int we_wordc; /* Count of words matched. */ + char **we_wordv; /* List of expanded words. */ + int we_offs; /* Slots to reserve in `we_wordv'. */ + } wordexp_t; + +/* Possible nonzero return values from `wordexp'. */ +enum + { + WRDE_NOSPACE = 1, /* Ran out of memory. */ + WRDE_BADCHAR, /* A metachar appears in the wrong place. */ + WRDE_BADVAL, /* Undefined var reference with WRDE_UNDEF. */ + WRDE_CMDSUB, /* Command substitution with WRDE_NOCMD. */ + WRDE_SYNTAX /* Shell syntax error. */ + }; + +/* Do word expansion of WORDS into PWORDEXP. */ +extern int wordexp __P ((__const char *__words, wordexp_t * __pwordexp, + int __flags)); + +/* Free the storage allocated by a `wordexp' call. */ +extern void wordfree __P ((wordexp_t *)); + +__END_DECLS + +#endif /* wordexp.h */ |