Sync libc/stdlib with FreeBSD (ignoring jemalloc, pts, and gdtoa):
authorPeter Avalos <pavalos@theshell.com>
Mon, 19 Jan 2009 02:51:47 +0000 (21:51 -0500)
committerPeter Avalos <pavalos@theshell.com>
Tue, 7 Apr 2009 07:08:56 +0000 (21:08 -1000)
-Add a64l(), l64a(), and l64a_r() XSI extentions.  These functions
convert between a 32-bit integer and a radix-64 ASCII string.

-Replace some syscalls with libc version.

-Remove advertising clause.

-alloca() cannot check if the allocation is valid; mention the
consequences.

-Include some verbage about not calling exit() from functions registered
by atexit().

-Use pthread mutexes where possible instead of libc spinlocks.

-Significantly reduce the memory leak as noted in the BUGS section of
setenv(3) by tracking the size of the memory allocated instead of using
strlen() on the current value.

-Prefer setenv() instead of putenv().

-Convert *env() calls to POSIX:
-unsetenv returns an int.
-putenv takes a char * instead of const char *.
-putenv no longer makes a copy of the input string.
-errno is set appropriately.  Exceptions involve bad environ
variable and internal initialization code.  These both set errno
to EFAULT.

-Make getopt_long() more GNU compatible and sync up with OpenBSD's
version.

-POSIX clearly states that getsubopt() should be declared in <stdlib.h>
not in <unistd.h>

-Use size_t to avoid overflow when sorting arrays larger than 2 GB in
heapsort() and qsort().

-Add new implementations of insque() and remque() which conform to
IEEE Std 1003.1-2001.

-Add qsort_r() for functions that need to be reentrant.

-Improve radixsort()'s preformance when sorting strings with common
prefixes.

-Use 'uint32_t' instead of 'long' when a 32-bit integer is intended in
random(3).

-Rearrange <stdlib.h> in a more logical order based on visibility.

-Move getsubopt()'s prototype to <stdlib.h> (standards).

-Make an internal _getprogname() that is used only inside
libc. For libc, getprogname(3) is a weak symbol in case a
function of the same name is defined in userland.

82 files changed:
bin/df/df.c
bin/sh/var.c
include/search.h
include/stdlib.h
include/unistd.h
lib/libc/gen/getprogname.c
lib/libc/include/libc_private.h
lib/libc/stdlib/Makefile.inc
lib/libc/stdlib/a64l.3 [new file with mode: 0644]
lib/libc/stdlib/a64l.c [new file with mode: 0644]
lib/libc/stdlib/abort.3
lib/libc/stdlib/abort.c
lib/libc/stdlib/abs.3
lib/libc/stdlib/abs.c
lib/libc/stdlib/alloca.3
lib/libc/stdlib/atexit.3
lib/libc/stdlib/atexit.c
lib/libc/stdlib/atexit.h
lib/libc/stdlib/atof.3
lib/libc/stdlib/atof.c
lib/libc/stdlib/atoi.3
lib/libc/stdlib/atoi.c
lib/libc/stdlib/atol.3
lib/libc/stdlib/atol.c
lib/libc/stdlib/bsearch.3
lib/libc/stdlib/bsearch.c
lib/libc/stdlib/div.3
lib/libc/stdlib/div.c
lib/libc/stdlib/exit.3
lib/libc/stdlib/exit.c
lib/libc/stdlib/getenv.3
lib/libc/stdlib/getenv.c
lib/libc/stdlib/getopt.3
lib/libc/stdlib/getopt.c
lib/libc/stdlib/getopt_long.3
lib/libc/stdlib/getopt_long.c
lib/libc/stdlib/getsubopt.3
lib/libc/stdlib/getsubopt.c
lib/libc/stdlib/hcreate.3
lib/libc/stdlib/hcreate.c
lib/libc/stdlib/heapsort.c
lib/libc/stdlib/insque.3 [new file with mode: 0644]
lib/libc/stdlib/insque.c [new file with mode: 0644]
lib/libc/stdlib/l64a.c [new file with mode: 0644]
lib/libc/stdlib/labs.3
lib/libc/stdlib/labs.c
lib/libc/stdlib/ldiv.3
lib/libc/stdlib/ldiv.c
lib/libc/stdlib/lsearch.c
lib/libc/stdlib/malloc.c
lib/libc/stdlib/memory.3
lib/libc/stdlib/merge.c
lib/libc/stdlib/putenv.c [deleted file]
lib/libc/stdlib/qsort.3
lib/libc/stdlib/qsort.c
lib/libc/stdlib/qsort_r.c [new file with mode: 0644]
lib/libc/stdlib/radixsort.3
lib/libc/stdlib/radixsort.c
lib/libc/stdlib/rand.3
lib/libc/stdlib/rand.c
lib/libc/stdlib/random.3
lib/libc/stdlib/random.c
lib/libc/stdlib/realpath.3
lib/libc/stdlib/realpath.c
lib/libc/stdlib/remque.c [new file with mode: 0644]
lib/libc/stdlib/setenv.c [deleted file]
lib/libc/stdlib/strtol.3
lib/libc/stdlib/strtoq.c
lib/libc/stdlib/strtoul.3
lib/libc/stdlib/strtouq.c
lib/libc/stdlib/system.3
lib/libc/stdlib/system.c
lib/libc/stdlib/tdelete.c
lib/libc/stdlib/tfind.c
lib/libc/stdlib/tsearch.3
lib/libc/stdlib/tsearch.c
lib/libc/stdlib/twalk.c
libexec/pppoed/pppoed.c
usr.bin/du/du.c
usr.bin/env/env.c
usr.bin/limits/limits.c
usr.sbin/pstat/pstat.c

index 5a6025e..af62648 100644 (file)
@@ -128,13 +128,13 @@ main(int argc, char **argv)
                case 'b':
                                /* FALLTHROUGH */
                case 'P':
-                       if (putenv("BLOCKSIZE=512") != 0)
-                               warn("putenv: cannot set BLOCKSIZE=512");
+                       if (setenv("BLOCKSIZE", "512", 1) != 0)
+                               warn("setenv: cannot set BLOCKSIZE=512");
                        hflag = 0;
                        break;
                case 'g':
-                       if (putenv("BLOCKSIZE=1g") != 0)
-                               warn("putenv: cannot set BLOCKSIZE=1g");
+                       if (setenv("BLOCKSIZE", "1g", 1) != 0)
+                               warn("setenv: cannot set BLOCKSIZE=1g");
                        hflag = 0;
                        break;
                case 'H':
@@ -147,8 +147,8 @@ main(int argc, char **argv)
                        iflag = 1;
                        break;
                case 'k':
-                       if (putenv("BLOCKSIZE=1k") != 0)
-                               warn("putenv: cannot set BLOCKSIZE=1k");
+                       if (setenv("BLOCKSIZE", "1k", 1) != 0)
+                               warn("setenv: cannot set BLOCKSIZE=1k");
                        hflag = 0;
                        break;
                case 'l':
@@ -157,8 +157,8 @@ main(int argc, char **argv)
                        vfslist = makevfslist(makenetvfslist());
                        break;
                case 'm':
-                       if (putenv("BLOCKSIZE=1m") != 0)
-                               warn("putenv: cannot set BLOCKSIZE=1m");
+                       if (setenv("BLOCKSIZE", "1m", 1) != 0)
+                               warn("setenv: cannot set BLOCKSIZE=1m");
                        hflag = 0;
                        break;
                case 'n':
index bb87eb0..e78d67b 100644 (file)
@@ -280,6 +280,28 @@ localevar(const char *s)
        return 0;
 }
 
+/*
+ * Sets/unsets an environment variable from a pointer that may actually be a
+ * pointer into environ where the string should not be manipulated.
+ */
+static void
+change_env(char *s, int set)
+{
+       char *eqp;
+       char *ss;
+
+       ss = savestr(s);
+       if ((eqp = strchr(ss, '=')) != NULL)
+               *eqp = '\0';
+       if (set && eqp != NULL) {
+               if (setenv(ss, eqp + 1, 1) != 0)
+                       error("setenv: cannot set %s=%s", ss, eqp + 1);
+       } else
+               unsetenv(ss);
+       ckfree(ss);
+}
+
+
 /*
  * Same as setvar except that the variable and value are passed in
  * the first argument as name=value.  Since the first argument will
@@ -321,8 +343,7 @@ setvareq(char *s, int flags)
                        if (vp == &vmpath || (vp == &vmail && ! mpathset()))
                                chkmail(1);
                        if ((vp->flags & VEXPORT) && localevar(s)) {
-                               if (putenv(s) != 0)
-                                       error("putenv: cannot set %s", s);
+                               change_env(s, 1);
                                setlocale(LC_ALL, "");
                        }
                        INTON;
@@ -338,8 +359,7 @@ setvareq(char *s, int flags)
        INTOFF;
        *vpp = vp;
        if ((vp->flags & VEXPORT) && localevar(s)) {
-               if (putenv(s) != 0)
-                       error("putenv: cannot set %s", s);
+               change_env(s, 1);
                setlocale(LC_ALL, "");
        }
        INTON;
@@ -600,8 +620,7 @@ exportcmd(int argc, char **argv)
 
                                                vp->flags |= flag;
                                                if ((vp->flags & VEXPORT) && localevar(vp->text)) {
-                                                       if (putenv(vp->text) != 0)
-                                                               error("putenv: cannot set %s", vp->text);
+                                                       change_env(vp->text, 1);
                                                        setlocale(LC_ALL, "");
                                                }
                                                goto found;
@@ -793,7 +812,7 @@ unsetvar(const char *s)
                        if (*(strchr(vp->text, '=') + 1) != '\0')
                                setvar(s, nullstr, 0);
                        if ((vp->flags & VEXPORT) && localevar(vp->text)) {
-                               unsetenv(s);
+                               change_env(s, 0);
                                setlocale(LC_ALL, "");
                        }
                        vp->flags &= ~VEXPORT;
index ccd7427..1e9b99c 100644 (file)
@@ -1,33 +1,33 @@
-/*     $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $     */
-/* $FreeBSD: src/include/search.h,v 1.3.2.1 2000/08/17 07:38:34 jhb Exp $ */
-/* $DragonFly: src/include/search.h,v 1.6 2008/05/19 10:05:18 corecode Exp $ */
-
-/*
+/*-
  * Written by J.T. Conklin <jtc@netbsd.org>
  * Public domain.
+ *
+ *     $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
+ * $FreeBSD: src/include/search.h,v 1.10 2002/10/16 14:29:23 robert Exp $
+ * $DragonFly: src/include/search.h,v 1.6 2008/05/19 10:05:18 corecode Exp $
  */
 
 #ifndef _SEARCH_H_
 #define _SEARCH_H_
 
 #include <sys/cdefs.h>
-#include <machine/stdint.h>
+#include <sys/types.h>
 
 #ifndef _SIZE_T_DECLARED
-#define _SIZE_T_DECLARED
-typedef __size_t        size_t;
+typedef        __size_t        size_t;
+#define        _SIZE_T_DECLARED
 #endif
 
-typedef struct entry {
-       char *key;
-       void *data;
+typedef        struct entry {
+       char    *key;
+       void    *data;
 } ENTRY;
 
-typedef enum {
+typedef        enum {
        FIND, ENTER
 } ACTION;
 
-typedef enum {
+typedef        enum {
        preorder,
        postorder,
        endorder,
@@ -35,27 +35,33 @@ typedef enum {
 } VISIT;
 
 #ifdef _SEARCH_PRIVATE
-typedef struct node {
+typedef        struct node {
        char         *key;
        struct node  *llink, *rlink;
 } node_t;
+
+struct que_elem {
+       struct que_elem *next;
+       struct que_elem *prev;
+};
 #endif
 
 __BEGIN_DECLS
-int     hcreate (size_t);
-void    hdestroy (void);
-ENTRY  *hsearch (ENTRY, ACTION);
+int     hcreate(size_t);
+void    hdestroy(void);
+ENTRY  *hsearch(ENTRY, ACTION);
+void    insque(void *, void *);
 void   *lfind(const void *, const void *, size_t *, size_t,
-           int (*)(const void *, const void *));
+              int (*)(const void *, const void *));
 void   *lsearch(const void *, void *, size_t *, size_t,
-           int (*)(const void *, const void *));
-void   *tdelete (const void *, void **,
-                     int (*)(const void *, const void *));
-void   *tfind (const void *, void **,
-                     int (*)(const void *, const void *));
-void   *tsearch (const void *, void **, 
-                     int (*)(const void *, const void *));
-void      twalk (const void *, void (*)(const void *, VISIT, int));
+                int (*)(const void *, const void *));
+void    remque(void *);
+void   *tdelete(const void * __restrict, void ** __restrict,
+                int (*)(const void *, const void *));
+void   *tfind(const void *, void * const *,
+              int (*)(const void *, const void *));
+void   *tsearch(const void *, void **, int (*)(const void *, const void *));
+void    twalk(const void *, void (*)(const void *, VISIT, int));
 __END_DECLS
 
 #endif /* !_SEARCH_H_ */
index 6f54500..7f717c0 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *     @(#)stdlib.h    8.5 (Berkeley) 5/19/95
- * $FreeBSD: src/include/stdlib.h,v 1.16.2.5 2002/12/13 01:34:00 tjr Exp $
+ * $FreeBSD: src/include/stdlib.h,v 1.67 2008/07/22 11:40:42 ache Exp $
  * $DragonFly: src/include/stdlib.h,v 1.22 2008/06/05 17:53:10 swildner Exp $
  */
 
 #define        _STDLIB_H_
 
 #include <sys/cdefs.h>
+#include <sys/_null.h>
 #include <sys/types.h>
 
-#ifndef _SYS_STDINT_H_
-#include <sys/stdint.h>
+#ifndef _SIZE_T_DECLARED
+typedef        __size_t        size_t;
+#define        _SIZE_T_DECLARED
 #endif
 
-#ifndef __cplusplus
+#ifndef        __cplusplus
 #ifndef _WCHAR_T_DECLARED
-#define _WCHAR_T_DECLARED
-typedef __wchar_t      wchar_t;
+typedef        __wchar_t       wchar_t;
+#define        _WCHAR_T_DECLARED
 #endif
 #endif
 
-#ifndef _SIZE_T_DECLARED
-#define _SIZE_T_DECLARED
-typedef __size_t       size_t;
-#endif
-
 typedef struct {
-       int quot;               /* quotient */
-       int rem;                /* remainder */
+       int     quot;           /* quotient */
+       int     rem;            /* remainder */
 } div_t;
 
 typedef struct {
-       long quot;              /* quotient */
-       long rem;               /* remainder */
+       long    quot;
+       long    rem;
 } ldiv_t;
 
-#if __ISO_C_VISIBLE >= 1999
-typedef struct {
-        long long quot;
-        long long rem;
-} lldiv_t;
-#endif
-
-#include <sys/_null.h>
-
 #define        EXIT_FAILURE    1
 #define        EXIT_SUCCESS    0
 
@@ -85,8 +73,8 @@ extern int __mb_cur_max;
 #define        MB_CUR_MAX      __mb_cur_max
 
 __BEGIN_DECLS
-void    _Exit(int) __dead2;
 void    abort(void) __dead2;
+/* void         abort2(const char *, int, void **) __dead2; */
 int     abs(int) __pure2;
 int     atexit(void (*)(void));
 double  atof(const char *);
@@ -101,54 +89,146 @@ void       free(void *);
 char   *getenv(const char *);
 long    labs(long) __pure2;
 ldiv_t  ldiv(long, long) __pure2;
-#if __ISO_C_VISIBLE >= 1999
-lldiv_t         lldiv(long long, long long) __pure2;
-#endif
 void   *malloc(size_t);
-void    qsort(void *, size_t, size_t, int(*)(const void *, const void *));
+int     mblen(const char *, size_t);
+size_t  mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
+int     mbtowc(wchar_t * __restrict, const char * __restrict, size_t);
+void    qsort(void *, size_t, size_t, int (*)(const void *, const void *));
 int     rand(void);
 void   *realloc(void *, size_t);
 void    srand(unsigned);
-double  strtod(const char *, char **);
-#ifdef __LONG_LONG_SUPPORTED
-long long int  atoll(const char *);
-long long      llabs(long long) __pure2;
-long long      strtoll(const char *, char **, int);
-unsigned long long strtoull(const char *, char **, int);
+double  strtod(const char * __restrict, char ** __restrict);
+/* float        strtof(const char * __restrict, char ** __restrict); */
+#if !defined(_KERNEL_VIRTUAL)
+long    strtol(const char * __restrict, char ** __restrict, int);
 #endif
-int     system(const char *);
-
+/* long double
+        strtold(const char * __restrict, char ** __restrict); */
 #if !defined(_KERNEL_VIRTUAL)
-long    strtol(const char *, char **, int);
-unsigned long  strtoul(const char *, char **, int);
+unsigned long
+        strtoul(const char * __restrict, char ** __restrict, int);
 #endif
-
-int     mblen(const char *, size_t);
-size_t  mbstowcs(wchar_t *, const char *, size_t);
+int     system(const char *);
 int     wctomb(char *, wchar_t);
-int     mbtowc(wchar_t *, const char *, size_t);
-size_t  wcstombs(char *, const wchar_t *, size_t);
+size_t  wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
+
+/*
+ * Functions added in C99 which we make conditionally available in the
+ * BSD^C89 namespace if the compiler supports `long long'.
+ * The #if test is more complicated than it ought to be because
+ * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long'
+ * is not supported in the compilation environment (which therefore means
+ * that it can't really be ISO C99).
+ *
+ * (The only other extension made by C99 in this header is _Exit().)
+ */
+#if __ISO_C_VISIBLE >= 1999
+#ifdef __LONG_LONG_SUPPORTED
+/* LONGLONG */
+typedef struct {
+       long long quot;
+       long long rem;
+} lldiv_t;
 
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-int     putenv(const char *);
+/* LONGLONG */
+long long
+        atoll(const char *);
+/* LONGLONG */
+long long
+        llabs(long long) __pure2;
+/* LONGLONG */
+lldiv_t         lldiv(long long, long long) __pure2;
+/* LONGLONG */
+long long
+        strtoll(const char * __restrict, char ** __restrict, int);
+/* LONGLONG */
+unsigned long long
+        strtoull(const char * __restrict, char ** __restrict, int);
+#endif /* __LONG_LONG_SUPPORTED */
+
+void    _Exit(int) __dead2;
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * Extensions made by POSIX relative to C.  We don't know yet which edition
+ * of POSIX made these extensions, so assume they've always been there until
+ * research can be done.
+ */
+#if __POSIX_VISIBLE /* >= ??? */
+/*int   posix_memalign(void **, size_t, size_t); (ADV) */
+int     rand_r(unsigned *);                    /* (TSF) */
 int     setenv(const char *, const char *, int);
+int     unsetenv(const char *);
+#endif
 
+/*
+ * The only changes to the XSI namespace in revision 6 were the deletion
+ * of the ttyslot() and valloc() functions, which we never declared
+ * in this header.  For revision 7, ecvt(), fcvt(), and gcvt(), which
+ * we also do not have, and mktemp(), are to be deleted.
+ */
+#if __XSI_VISIBLE
+/* XXX XSI requires pollution from <sys/wait.h> here.  We'd rather not. */
+long    a64l(const char *);
 double  drand48(void);
+/* char        *ecvt(double, int, int * __restrict, int * __restrict); */
 double  erand48(unsigned short[3]);
+/* char        *fcvt(double, int, int * __restrict, int * __restrict); */
+/* char        *gcvt(double, int, int * __restrict, int * __restrict); */
+int     getsubopt(char **, char *const *, char **);
+int     grantpt(int);
+char   *initstate(unsigned long /* XSI requires u_int */, char *, long);
 long    jrand48(unsigned short[3]);
+char   *l64a(long);
 void    lcong48(unsigned short[7]);
 long    lrand48(void);
+int     mkstemp(char *);
 long    mrand48(void);
 long    nrand48(unsigned short[3]);
-unsigned short *seed48(unsigned short[3]);
+/* int  posix_openpt(int); */
+/* char        *ptsname(int); */
+int     putenv(char *);
+long    random(void);
+char   *realpath(const char *, char resolved_path[]);
+unsigned short
+       *seed48(unsigned short[3]);
+int     setkey(const char *);
+char   *setstate(/* const */ char *);
 void    srand48(long);
+void    srandom(unsigned long);
+/* int  unlockpt(int); */
+#endif /* __XSI_VISIBLE */
 
-void   *alloca(size_t);                /* built-in for gcc */
-                                       /* getcap(3) functions */
-__uint32_t arc4random(void);
+#if __BSD_VISIBLE
+/* extern const char *_malloc_options;
+extern void (*_malloc_message)(const char *, const char *, const char *,
+           const char *); */
+
+/*
+ * The alloca() function can't be implemented in C, and on some
+ * platforms it can't be implemented at all as a callable function.
+ * The GNU C compiler provides a built-in alloca() which we can use;
+ * in all other cases, provide a prototype, mainly to pacify various
+ * incarnations of lint.  On platforms where alloca() is not in libc,
+ * programs which use it will fail to link when compiled with non-GNU
+ * compilers.
+ */
+#if __GNUC__ >= 2 || defined(__INTEL_COMPILER)
+#undef  alloca /* some GNU bits try to get cute and define this on their own */
+#define alloca(sz) __builtin_alloca(sz)
+#elif defined(lint)
+void   *alloca(size_t);
+#endif
+
+__uint32_t
+        arc4random(void);
 void    arc4random_addrandom(__uint8_t *, size_t);
+void    arc4random_buf(void *, size_t);
 void    arc4random_stir(void);
+__uint32_t
+        arc4random_uniform(__uint32_t);
 char   *getbsize(int *, long *);
+                                       /* getcap(3) functions */
 char   *cgetcap(char *, char *, int);
 int     cgetclose(void);
 int     cgetent(char **, char **, char *);
@@ -164,37 +244,36 @@ int        daemon(int, int);
 char   *devname(dev_t, mode_t);
 char   *devname_r(dev_t, mode_t, char *, size_t);
 int     getloadavg(double [], int);
-const char *getprogname(void);
+__const char *
+        getprogname(void);
 
 int     heapsort(void *, size_t, size_t, int (*)(const void *, const void *));
-char   *initstate(unsigned long, char *, long);
+int     l64a_r(long, char *, int);
 int     mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
+void    qsort_r(void *, size_t, size_t, void *,
+                int (*)(void *, const void *, const void *));
 int     radixsort(const unsigned char **, int, const unsigned char *,
                   unsigned int);
-int     sradixsort(const unsigned char **, int, const unsigned char *,
-                   unsigned int);
-int     rand_r(unsigned *);
-long    random(void);
 void    *reallocf(void *, size_t);
-char   *realpath(const char *, char []);
+int     rpmatch(const char *);
 void    setprogname(const char *);
-char   *setstate(char *);
-void    srandom(unsigned long);
+int     sradixsort(const unsigned char **, int, const unsigned char *,
+                   unsigned int);
+void    sranddev(void);
 void    srandomdev(void);
+long long
+       strtonum(const char *, long long, long long, const char **);
 
-#if !defined(__STRICT_ANSI__) && !defined(_KERNEL_VIRTUAL)
-__int64_t      strtoq(const char *, char **, int);
-__uint64_t     strtouq(const char *, char **, int);
+/* Deprecated interfaces. */
+#if !defined(_KERNEL_VIRTUAL)
+__int64_t
+        strtoq(const char *, char **, int);
+__uint64_t
+        strtouq(const char *, char **, int);
 #endif
 
-#ifndef __STRICT_ANSI__
-#ifdef __LONG_LONG_SUPPORTED
-long long
-        strtonum(const char *, long long, long long, const char **);
-#endif
-#endif
-void    unsetenv(const char *);
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+extern char *suboptarg;                        /* getsubopt(3) external variable */
+#endif /* __BSD_VISIBLE */
 __END_DECLS
 
 #endif /* !_STDLIB_H_ */
index c57a1dc..4eb3796 100644 (file)
@@ -159,7 +159,6 @@ int  lwp_create(struct lwp_params *);
 lwpid_t         lwp_gettid(void);
 char   *mkdtemp(char *);
 int     mknod(const char *, mode_t, dev_t);
-int     mkstemp(char *);
 int     mkstemps(char *, int);
 char   *mktemp(char *);
 int     nfssvc(int, void *);
@@ -226,8 +225,6 @@ int  varsym_set(int, const char *, const char *);
 int     varsym_get(int, const char *, char *, int);
 int     varsym_list(int, char *, int, int *);
 
-extern char *suboptarg;                        /* getsubopt(3) external variable */
-int     getsubopt(char **, char * const *, char **);
 #endif /* !_POSIX_SOURCE */
 extern int optreset;                   /* getopt(3) external variable */
 __END_DECLS
index ca70dea..619039f 100644 (file)
@@ -1,14 +1,19 @@
 /*
- * $FreeBSD: src/lib/libc/gen/getprogname.c,v 1.1.2.1 2001/06/14 00:06:12 dd Exp $
+ * $FreeBSD: src/lib/libc/gen/getprogname.c,v 1.4 2002/03/29 22:43:41 markm Exp $
  * $DragonFly: src/lib/libc/gen/getprogname.c,v 1.3 2005/03/09 18:52:21 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdlib.h>
+#include "un-namespace.h"
 
-extern const char *__progname;
+#include "libc_private.h"
+
+__weak_reference(_getprogname, getprogname);
 
 const char *
-getprogname(void)
+_getprogname(void)
 {
+
        return (__progname);
 }
index ec87234..962ab6b 100644 (file)
@@ -81,4 +81,15 @@ void *__get_errno_GOT_ptr(void);
 struct statfs;
 struct statvfs;
 
+/*
+ * This is a pointer in the C run-time startup code. It is used
+ * by getprogname() and setprogname().
+ */
+extern const char *__progname;
+
+/*
+ * Function to clean up streams, called from abort() and exit().
+ */
+extern void (*__cleanup)(void);
+
 #endif /* _LIBC_PRIVATE_H_ */
index d8c5cf0..eb3f737 100644 (file)
@@ -1,19 +1,18 @@
 #      from @(#)Makefile.inc   8.3 (Berkeley) 2/4/95
-# $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.19.2.4 2001/10/02 11:15:38 ru Exp $
+# $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.56 2008/10/17 08:30:20 netchild Exp $
 # $DragonFly: src/lib/libc/stdlib/Makefile.inc,v 1.24 2008/10/06 21:01:37 swildner Exp $
 
 # machine-independent stdlib sources
 .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib ${.CURDIR}/../libc/stdlib
 
-MISRCS+=abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c bsearch.c calloc.c div.c \
-       exit.c getenv.c getopt.c getopt_long.c getsubopt.c hcreate.c heapsort.c \
-       imaxabs.c imaxdiv.c \
-       labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c merge.c putenv.c \
-       qsort.c radixsort.c rand.c \
-       random.c reallocf.c realpath.c \
-       setenv.c strfmon.c strtod.c strtoimax.c strtol.c \
-       strtoll.c strtonum.c strtoq.c strtoul.c strtoull.c strtoumax.c \
-       strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
+MISRCS+=a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
+       bsearch.c calloc.c div.c exit.c getenv.c getopt.c getopt_long.c \
+       getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \
+       insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c \
+       merge.c qsort.c qsort_r.c radixsort.c rand.c random.c \
+       reallocf.c realpath.c remque.c strfmon.c strtod.c strtoimax.c \
+       strtol.c strtoll.c strtonum.c strtoq.c strtoul.c strtoull.c \
+       strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
 
 # machine-dependent stdlib sources
 .if exists(${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib/Makefile.inc)
@@ -21,26 +20,29 @@ MISRCS+=abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c bsearch.c calloc.c d
 .endif
 
 .if ${LIB} == "c"
-MAN+=  abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
-       div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 hcreate.3 \
-       imaxabs.3 imaxdiv.3 \
-       labs.3 ldiv.3 llabs.3 lldiv.3 lsearch.3 malloc.3 memory.3 \
-       qsort.3 radixsort.3 rand.3 random.3 realpath.3 \
-       strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 tsearch.3
+MAN+=  a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
+       div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
+       hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
+       lsearch.3 malloc.3 memory.3 qsort.3 \
+       radixsort.3 rand.3 random.3 \
+       realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
+       tsearch.3
 
+MLINKS+=a64l.3 l64a.3 a64l.3 l64a_r.3
 MLINKS+=atol.3 atoll.3
 MLINKS+=exit.3 _Exit.3
 MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3
 MLINKS+=getopt_long.3 getopt_long_only.3
 MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
+MLINKS+=insque.3 remque.3
 MLINKS+=lsearch.3 lfind.3
 MLINKS+=malloc.3 calloc.3 malloc.3 free.3 malloc.3 realloc.3 malloc.3 reallocf.3
-MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
+MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 qsort.3 qsort_r.3
 MLINKS+=radixsort.3 sradixsort.3
 MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3
 MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \
        random.3 srandomdev.3
-MLINKS+=strtol.3 strtoll.3 strtol.3 strtoimax.3 strtol.3 strtoq.3
+MLINKS+=strtol.3 strtoimax.3 strtol.3 strtoll.3 strtol.3 strtoq.3
 MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtoumax.3 strtoul.3 strtouq.3
 MLINKS+=tsearch.3 tdelete.3 tsearch.3 tfind.3 tsearch.3 twalk.3
 .endif
diff --git a/lib/libc/stdlib/a64l.3 b/lib/libc/stdlib/a64l.3
new file mode 100644 (file)
index 0000000..49c03e7
--- /dev/null
@@ -0,0 +1,187 @@
+.\" Copyright (c) 2005 Tom Rhodes
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Portions of this text are reprinted and reproduced in electronic form
+.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology --
+.\" Portable Operating System Interface (POSIX), The Open Group Base
+.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
+.\" Electrical and Electronics Engineers, Inc and The Open Group.  In the
+.\" event of any discrepancy between this version and the original IEEE and
+.\" The Open Group Standard, the original IEEE and The Open Group Standard is
+.\" the referee document.  The original Standard can be obtained online at
+.\"    http://www.opengroup.org/unix/online.html.
+.\"
+.\" $FreeBSD: src/lib/libc/stdlib/a64l.3,v 1.3 2006/09/30 10:29:43 ru Exp $
+.\"
+.Dd November 20, 2005
+.Dt A64L 3
+.Os
+.Sh NAME
+.Nm a64l ,
+.Nm l64a ,
+.Nm l64a_r
+.Nd "convert between a long integer and a base-64 ASCII string"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft long
+.Fn a64l "const char *s"
+.Ft char *
+.Fn l64a "long int l"
+.Ft int
+.Fn l64a_r "long int l" "char *buffer" "int buflen"
+.Sh DESCRIPTION
+These functions are used to maintain numbers stored in radix-64
+.Tn ASCII
+characters.
+This is a notation by which 32-bit integers can be represented by
+up to six characters; each character represents a digit in
+radix-64 notation.
+If the type long contains more than 32 bits, only the low-order
+32 bits are used for these operations.
+.Pp
+The characters used to represent
+.Dq digits
+are
+.Ql .\&
+for 0,
+.Ql /
+for 1,
+.Ql 0
+-
+.Ql 9
+for 2 - 11,
+.Ql A
+-
+.Ql Z
+for 12 - 37, and
+.Ql a
+-
+.Ql z
+for 38 - 63.
+.Pp
+The
+.Fn a64l
+function takes a pointer to a radix-64 representation, in which the first
+digit is the least significant, and returns a corresponding
+.Vt long
+value.
+If the string pointed to by
+.Fa s
+contains more than six characters,
+.Fn a64l
+uses the first six.
+If the first six characters of the string contain a null terminator,
+.Fn a64l
+uses only characters preceding the null terminator.
+The
+.Fn a64l
+function scans the character string from left to right with the least
+significant digit on the left, decoding each character as a 6-bit
+radix-64 number.
+If the type long contains more than 32 bits, the resulting value is
+sign-extended.
+The behavior of
+.Fn a64l
+is unspecified if
+.Fa s
+is a null pointer or the string pointed to by
+.Fa s
+was not generated by a previous call to
+.Fn l64a .
+.Pp
+The
+.Fn l64a
+function takes a
+.Vt long
+argument and returns a pointer to the corresponding
+radix-64 representation.
+The behavior of
+.Fn l64a
+is unspecified if value is negative.
+.Pp
+The value returned by
+.Fn l64a
+is a pointer into a static buffer.
+Subsequent calls to
+.Fn l64a
+may overwrite the buffer.
+.Pp
+The
+.Fn l64a_r
+function performs a conversion identical to that of
+.Fn l64a
+and stores the resulting representation in the memory area pointed to by
+.Fa buffer ,
+consuming at most
+.Fa buflen
+characters including the terminating
+.Dv NUL
+character.
+.Sh RETURN VALUES
+On successful completion,
+.Fn a64l
+returns the
+.Vt long
+value resulting from conversion of the input string.
+If a string pointed to by
+.Fa s
+is an empty string,
+.Fn a64l
+returns 0.
+.Pp
+The
+.Fn l64a
+function returns a pointer to the radix-64 representation.
+If value is 0,
+.Fn l64a
+returns a pointer to an empty string.
+.Sh SEE ALSO
+.Xr strtoul 3
+.Sh HISTORY
+The
+.Fn a64l ,
+.Fn l64a ,
+and
+.Fn l64a_r
+functions are derived from
+.Nx
+with modifications.
+They appeared in
+.Fx 6.1 .
+.Sh AUTHORS
+The
+.Fn a64l ,
+.Fn l64a ,
+and
+.Fn l64a_r
+functions
+were added to
+.Fx
+by
+.An Tom Rhodes Aq trhodes@FreeBSD.org .
+Almost all of this manual page came from the
+.Tn POSIX
+standard.
diff --git a/lib/libc/stdlib/a64l.c b/lib/libc/stdlib/a64l.c
new file mode 100644 (file)
index 0000000..52b8b17
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * $NetBSD: a64l.c,v 1.8 2000/01/22 22:19:19 mycroft Exp $
+ * $FreeBSD: src/lib/libc/stdlib/a64l.c,v 1.2 2006/05/19 19:06:38 jkim Exp $
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+long
+a64l(const char *s)
+{
+       long shift;
+       int digit, i, value;
+
+       value = 0;
+       shift = 0;
+       for (i = 0; *s != '\0' && i < 6; i++, s++) {
+               if (*s <= '/')
+                       digit = *s - '/' + 1;
+               else if (*s <= '0' + 9)
+                       digit = *s - '0' + 2;
+               else if (*s <= 'A' + 25)
+                       digit = *s - 'A' + 12;
+               else
+                       digit = *s - 'a' + 38;
+
+               value |= digit << shift;
+               shift += 6;
+       }
+       return (value);
+}
index a30a8f3..2751577 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)abort.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/abort.3,v 1.6.2.2 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/abort.3,v 1.10 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/abort.3,v 1.3 2005/06/02 18:44:07 asmodai Exp $
 .\"
 .Dd June 4, 1993
@@ -62,7 +58,7 @@ Any open streams are flushed and closed.
 The
 .Fn abort
 function is thread-safe.
-It is not async-cancel-safe.
+It is unknown if it is async-cancel-safe.
 .Sh RETURN VALUES
 The
 .Fn abort
@@ -77,3 +73,8 @@ The
 function
 conforms to
 .St -p1003.1-90 .
+The
+.Fn abort
+function also conforms to
+.St -isoC-99
+with the implementation specific details as noted above.
index e315a74..b8df1fb 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/abort.c,v 1.5.6.2 2002/10/15 19:46:46 fjoe Exp $
- * $DragonFly: src/lib/libc/stdlib/abort.c,v 1.4 2005/11/20 12:37:48 swildner Exp $
- *
  * @(#)abort.c 8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/abort.c,v 1.11 2007/01/09 00:28:09 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/abort.c,v 1.4 2005/11/20 12:37:48 swildner Exp $
  */
 
+#include "namespace.h"
 #include <signal.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
-void (*__cleanup)();
-
-extern int     __sys_sigprocmask(int, const sigset_t *, sigset_t *);
-extern int     __sys_sigaction(int, const struct sigaction *,
-                   struct sigaction *);
+#include "libc_private.h"
 
 void
 abort(void)
@@ -54,31 +47,31 @@ abort(void)
        struct sigaction act;
 
        /*
-        * POSIX requires we flush stdio buffers on abort
+        * POSIX requires we flush stdio buffers on abort.
+        * XXX ISO C requires that abort() be async-signal-safe.
         */
        if (__cleanup)
                (*__cleanup)();
 
        sigfillset(&act.sa_mask);
        /*
-        * don't block SIGABRT to give any handler a chance; we ignore
-        * any errors -- X311J doesn't allow abort to return anyway.
+        * Don't block SIGABRT to give any handler a chance; we ignore
+        * any errors -- ISO C doesn't allow abort to return anyway.
         */
        sigdelset(&act.sa_mask, SIGABRT);
-       __sys_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
-       kill(getpid(), SIGABRT);
+       _sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
+       raise(SIGABRT);
 
        /*
-        * if SIGABRT ignored, or caught and the handler returns, do
+        * If SIGABRT was ignored, or caught and the handler returns, do
         * it again, only harder.
         */
        act.sa_handler = SIG_DFL;
        act.sa_flags = 0;
        sigfillset(&act.sa_mask);
-       __sys_sigaction(SIGABRT, &act, NULL);
+       _sigaction(SIGABRT, &act, NULL);
        sigdelset(&act.sa_mask, SIGABRT);
-       __sys_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
-       kill(getpid(), SIGABRT);
+       _sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
+       raise(SIGABRT);
        exit(1);
 }
-
index 7071234..bec6f10 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)abs.3      8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.7.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/abs.3,v 1.13 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/abs.3,v 1.4 2007/12/02 03:29:47 swildner Exp $
 .\"
-.Dd June 4, 1993
+.Dd November 14, 2001
 .Dt ABS 3
 .Os
 .Sh NAME
@@ -55,7 +51,7 @@ The
 function
 computes
 the absolute value of the integer
-.Ar j .
+.Fa j .
 .Sh IMPLEMENTATION NOTES
 The
 .Fn abs
@@ -80,6 +76,6 @@ the absolute value.
 The
 .Fn abs
 function conforms to
-.St -isoC .
+.St -isoC-99 .
 .Sh BUGS
 The absolute value of the most negative integer remains negative.
index 9e0b8f6..1ae34d4 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -31,6 +27,7 @@
  * SUCH DAMAGE.
  *
  * @(#)abs.c   8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/abs.c,v 1.3 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/abs.c,v 1.3 2005/06/02 18:45:06 asmodai Exp $
  */
 
index 2200dd8..2db52a7 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)alloca.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.4.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/alloca.3,v 1.13 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/alloca.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
-.Dd June 4, 1993
+.Dd September 5, 2006
 .Dt ALLOCA 3
 .Os
 .Sh NAME
@@ -58,25 +54,36 @@ return.
 The
 .Fn alloca
 function returns a pointer to the beginning of the allocated space.
-If the allocation failed, a
-.Dv NULL
-pointer is returned.
 .Sh SEE ALSO
 .Xr brk 2 ,
 .Xr calloc 3 ,
 .Xr getpagesize 3 ,
 .Xr malloc 3 ,
 .Xr realloc 3
-.Sh BUGS
+.Sh HISTORY
 The
 .Fn alloca
-function
-is machine dependent; its use is discouraged.
-.\" .Sh HISTORY
-.\" The
-.\" .Fn alloca
-.\" function appeared in
+function appeared in
+.At 32v .
 .\" .Bx ?? .
 .\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
 .\" The first man page (or link to a man page that I can find at the
 .\" moment is 4.3...
+.Sh BUGS
+The
+.Fn alloca
+function
+is machine and compiler dependent;
+its use is discouraged.
+.Pp
+The
+.Fn alloca
+function is slightly unsafe because it cannot ensure that the pointer
+returned points to a valid and usable block of memory.
+The allocation made may exceed the bounds of the stack, or even go
+further into other objects in memory, and
+.Fn alloca
+cannot determine such an error.
+Avoid
+.Fn alloca
+with large unbounded allocations.
index 07fcb19..80f7bdc 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)atexit.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.3.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/atexit.3,v 1.11 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/atexit.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
-.Dd June 4, 1993
+.Dd September 6, 2002
 .Dt ATEXIT 3
 .Os
 .Sh NAME
@@ -54,15 +50,27 @@ The
 .Fn atexit
 function
 registers the given
-.Ar function
+.Fa function
 to be called at program exit, whether via
 .Xr exit 3
 or via return from the program's
-.Em main .
+.Fn main .
 Functions so registered are called in reverse order;
 no arguments are passed.
+.Pp
+These functions must not call
+.Fn exit ;
+if it should be necessary to terminate the process while in such a
+function, the
+.Xr _exit 2
+function should be used.
+(Alternatively, the function may cause abnormal
+process termination, for example by calling
+.Xr abort 3 . )
+.Pp
 At least 32 functions can always be registered,
 and more are allowed as long as sufficient memory can be allocated.
+.\" XXX {ATEXIT_MAX} is not implemented yet
 .Sh RETURN VALUES
 .Rv -std atexit
 .Sh ERRORS
index ace6245..03f8c2b 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.3.6.1 2002/03/10 20:28:40 tegge Exp $
- * $DragonFly: src/lib/libc/stdlib/atexit.c,v 1.7 2006/08/03 16:40:46 swildner Exp $
- *
  * @(#)atexit.c        8.2 (Berkeley) 7/3/94
+ * $FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.8 2007/01/09 00:28:09 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/atexit.c,v 1.7 2006/08/03 16:40:46 swildner Exp $
  */
 
+#include "namespace.h"
 #include <stddef.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <pthread.h>
 #include "atexit.h"
+#include "un-namespace.h"
 
 #include "libc_private.h"
-#include "spinlock.h"
 
-#define                ATEXIT_FN_EMPTY 0
-#define                ATEXIT_FN_STD   1
-#define                ATEXIT_FN_CXA   2
+#define        ATEXIT_FN_EMPTY 0
+#define        ATEXIT_FN_STD   1
+#define        ATEXIT_FN_CXA   2
 
-static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
+static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-#define THREAD_LOCK()          if (__isthreaded) _SPINLOCK(&thread_lock);
-#define THREAD_UNLOCK()                if (__isthreaded) _SPINUNLOCK(&thread_lock);
+#define _MUTEX_LOCK(x)         if (__isthreaded) _pthread_mutex_lock(x)
+#define _MUTEX_UNLOCK(x)       if (__isthreaded) _pthread_mutex_unlock(x)
 
 struct atexit {
        struct atexit *next;                    /* next in list */
@@ -83,21 +80,21 @@ atexit_register(struct atexit_fn *fptr)
        static struct atexit __atexit0; /* one guaranteed table */
        struct atexit *p;
 
-       THREAD_LOCK();
+       _MUTEX_LOCK(&atexit_mutex);
        if ((p = __atexit) == NULL)
                __atexit = p = &__atexit0;
        else while (p->ind >= ATEXIT_SIZE) {
                struct atexit *old__atexit;
                old__atexit = __atexit;
-               THREAD_UNLOCK();
+               _MUTEX_UNLOCK(&atexit_mutex);
                if ((p = (struct atexit *)malloc(sizeof(*p))) == NULL)
                        return (-1);
-               THREAD_LOCK();
+               _MUTEX_LOCK(&atexit_mutex);
                if (old__atexit != __atexit) {
                        /* Lost race, retry operation */
-                       THREAD_UNLOCK();
+                       _MUTEX_UNLOCK(&atexit_mutex);
                        free(p);
-                       THREAD_LOCK();
+                       _MUTEX_LOCK(&atexit_mutex);
                        p = __atexit;
                        continue;
                }
@@ -106,7 +103,7 @@ atexit_register(struct atexit_fn *fptr)
                __atexit = p;
        }
        p->fns[p->ind++] = *fptr;
-       THREAD_UNLOCK();
+       _MUTEX_UNLOCK(&atexit_mutex);
        return (0);
 }
 
@@ -124,7 +121,7 @@ atexit(void (*func)(void))
        fn.fn_arg = NULL;
        fn.fn_dso = NULL;
 
-       error = atexit_register(&fn);   
+       error = atexit_register(&fn);
        return (error);
 }
 
@@ -143,7 +140,7 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso)
        fn.fn_arg = arg;
        fn.fn_dso = dso;
 
-       error = atexit_register(&fn);   
+       error = atexit_register(&fn);
        return (error);
 }
 
@@ -159,7 +156,7 @@ __cxa_finalize(void *dso)
        struct atexit_fn fn;
        int n;
 
-       THREAD_LOCK();
+       _MUTEX_LOCK(&atexit_mutex);
        for (p = __atexit; p; p = p->next) {
                for (n = p->ind; --n >= 0;) {
                        if (p->fns[n].fn_type == ATEXIT_FN_EMPTY)
@@ -172,15 +169,15 @@ __cxa_finalize(void *dso)
                          has already been called.
                        */
                        p->fns[n].fn_type = ATEXIT_FN_EMPTY;
-                       THREAD_UNLOCK();
-               
+                       _MUTEX_UNLOCK(&atexit_mutex);
+
                        /* Call the function of correct type. */
                        if (fn.fn_type == ATEXIT_FN_CXA)
                                fn.fn_ptr.cxa_func(fn.fn_arg);
                        else if (fn.fn_type == ATEXIT_FN_STD)
                                fn.fn_ptr.std_func();
-                       THREAD_LOCK();
+                       _MUTEX_LOCK(&atexit_mutex);
                }
        }
-       THREAD_UNLOCK();
+       _MUTEX_UNLOCK(&atexit_mutex);
 }
index bb424f7..f55b1f6 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  *     @(#)atexit.h    8.2 (Berkeley) 7/3/94
+ * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.4 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/atexit.h,v 1.3 2004/01/24 22:18:12 joerg Exp $
  */
 
 /* must be at least 32 to guarantee ANSI conformance */
 #define        ATEXIT_SIZE     32
 
-void __cxa_finalize(void *dso);
+void __cxa_finalize(void *);
index 1ceb89e..6d8a03a 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)atof.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.4.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/atof.3,v 1.17 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/atof.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 4, 1993
@@ -55,15 +51,35 @@ string to double
 The
 .Fn atof
 function converts the initial portion of the string pointed to by
-.Ar nptr
+.Fa nptr
 to
-.Ar double
+.Vt double
 representation.
 .Pp
 It is equivalent to:
 .Bd -literal -offset indent
 strtod(nptr, (char **)NULL);
 .Ed
+.Pp
+The decimal point
+character is defined in the program's locale (category
+.Dv LC_NUMERIC ) .
+.Sh IMPLEMENTATION NOTES
+The
+.Fn atof
+function is not thread-safe and also not async-cancel-safe.
+.Pp
+The
+.Fn atof
+function has been deprecated by
+.Fn strtod
+and should not be used in new code.
+.Sh ERRORS
+The function
+.Fn atof
+need not affect the value of
+.Va errno
+on an error.
 .Sh SEE ALSO
 .Xr atoi 3 ,
 .Xr atol 3 ,
@@ -74,4 +90,7 @@ strtod(nptr, (char **)NULL);
 The
 .Fn atof
 function conforms to
-.St -isoC .
+.St -p1003.1-90 ,
+.St -isoC ,
+and
+.St -isoC-99 .
index 1d1e914..30ec8cf 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  * @(#)atof.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/atof.c,v 1.6 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/atof.c,v 1.3 2005/11/20 12:37:48 swildner Exp $
  */
 
 #include <stdlib.h>
-#include <stddef.h>
 
 double
 atof(const char *ascii)
 {
-       return (strtod(ascii, NULL));
+       return(strtod(ascii, (char **)NULL));
 }
index 7617239..3f58a43 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)atoi.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.3.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/atoi.3,v 1.14 2007/10/19 06:23:39 davidxu Exp $
 .\" $DragonFly: src/lib/libc/stdlib/atoi.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 4, 1993
@@ -55,15 +51,27 @@ string to integer
 The
 .Fn atoi
 function converts the initial portion of the string pointed to by
-.Em nptr
+.Fa nptr
 to
-.Em integer
+.Vt int
 representation.
 .Pp
 It is equivalent to:
 .Bd -literal -offset indent
 (int)strtol(nptr, (char **)NULL, 10);
 .Ed
+.Pp
+The
+.Fn atoi
+function has been deprecated by
+.Fn strtol
+and should not be used in new code.
+.Sh ERRORS
+The function
+.Fn atoi
+need not affect the value of
+.Va errno
+on an error.
 .Sh SEE ALSO
 .Xr atof 3 ,
 .Xr atol 3 ,
@@ -74,4 +82,7 @@ It is equivalent to:
 The
 .Fn atoi
 function conforms to
-.St -isoC .
+.St -p1003.1-90 ,
+.St -isoC ,
+and
+.St -isoC-99 .
index 9c92db5..ed243c3 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  * @(#)atoi.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/atoi.c,v 1.6 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/atoi.c,v 1.3 2005/11/20 12:37:48 swildner Exp $
  */
 
 #include <stdlib.h>
-#include <stddef.h>
 
 int
 atoi(const char *str)
index cb95bf3..76c1f29 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)atol.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.13 2002/01/09 14:03:54 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/atol.3,v 1.14 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/atol.3,v 1.3 2005/11/01 18:16:52 swildner Exp $
 .\"
 .Dd November 28, 2001
 .Dt ATOL 3
 .Os
 .Sh NAME
-.Nm atol , atoll
+.Nm atol ,
+.Nm atoll
 .Nd convert
 .Tn ASCII
 string to
index dbc227d..b0ca813 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  * @(#)atol.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/atol.c,v 1.5 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/atol.c,v 1.3 2005/11/20 12:37:48 swildner Exp $
  */
 
-#include <stddef.h>
 #include <stdlib.h>
 
 long
index 6306b75..abe85e1 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)bsearch.3  8.3 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.4.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/bsearch.3,v 1.9 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/bsearch.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd April 19, 1994
index 44dd92e..5ee5d37 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -31,6 +27,7 @@
  * SUCH DAMAGE.
  *
  * @(#)bsearch.c       8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/bsearch.c,v 1.4 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/bsearch.c,v 1.5 2005/11/20 12:37:48 swildner Exp $
  */
 
@@ -66,7 +63,7 @@ bsearch(const void *key, const void *base0, size_t nmemb, size_t size,
                p = base + (lim >> 1) * size;
                cmp = (*compar)(key, p);
                if (cmp == 0)
-                       return ((void *)p);
+                       return (__DECONST(void *, p));
                if (cmp > 0) {  /* key > p: move right */
                        base = (char *)p + size;
                        lim--;
index a937f5e..d306759 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)div.3      8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.3.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/div.3,v 1.9 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/div.3,v 1.3 2008/01/25 23:24:31 swildner Exp $
 .\"
-.Dd June 4, 1993
+.Dd November 14, 2001
 .Dt DIV 3
 .Os
 .Sh NAME
@@ -56,11 +52,11 @@ computes the value
 and returns the quotient and remainder in a structure named
 .Fa div_t
 that contains two
-.Em int
+.Vt int
 members named
-.Fa quot
+.Va quot
 and
-.Fa rem .
+.Va rem .
 .Sh SEE ALSO
 .Xr imaxdiv 3 ,
 .Xr ldiv 3 ,
@@ -70,4 +66,4 @@ The
 .Fn div
 function
 conforms to
-.St -isoC .
+.St -isoC-99 .
index d3066d2..dc7759a 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -34,6 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)div.c   8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/div.c,v 1.3 2007/01/09 00:28:09 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/div.c,v 1.3 2005/11/20 12:37:48 swildner Exp $
  */
 
index 2d49974..12f9aac 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)exit.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.6.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/exit.3,v 1.16 2007/01/09 00:28:09 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/exit.3,v 1.3 2007/06/15 19:36:33 swildner Exp $
 .\"
 .Dd June 15, 2007
@@ -77,36 +73,52 @@ Unlink all files created with the
 function.
 .El
 .Pp
-The C99 function
+The
 .Fn _Exit
-terminates without calling the functions registered with
+function terminates without calling the functions registered with the
 .Xr atexit 3
-by just calling
-.Xr _exit 2 .
-Code intended to be portable should always use
-.Xr _exit 2
-directly as it is defined by
-.St -susv2
-as well.
+function, and may or may not perform the other actions listed.
+Both functions make the low-order eight bits of the
+.Fa status
+argument available to a parent process which has called a
+.Xr wait 2 Ns -family
+function.
 .Pp
-Passing arbitrary values back to the environment as
-.Ar status
-is considered bad style;
-you should use the values
-.Dv EXIT_SUCCESS
+The C Standard
+.Pq St -isoC-99
+defines the values
+.Li 0 ,
+.Dv EXIT_SUCCESS ,
 and
-.Dv EXIT_FAILURE .
-If portability is not a concern, you may
-use the values described in
-.Xr sysexits 3 .
+.Dv EXIT_FAILURE
+as possible values of
+.Fa status .
+Cooperating processes may use other values;
+in a program which might be called by a mail transfer agent, the
+values described in
+.Xr sysexits 3
+may be used to provide more information to the parent process.
+.Pp
+Note that
+.Fn exit
+does nothing to prevent bottomless recursion should a function registered
+using
+.Xr atexit 3
+itself call
+.Fn exit .
+Such functions must call
+.Fn _Exit
+instead (although this has other effects as well which may not be desired).
 .Sh RETURN VALUES
 The
 .Fn exit
 and
 .Fn _Exit
-functions never return.
+functions
+never return.
 .Sh SEE ALSO
 .Xr _exit 2 ,
+.Xr wait 2 ,
 .Xr atexit 3 ,
 .Xr intro 3 ,
 .Xr sysexits 3 ,
index 6f2e929..ee33ea5 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/exit.c,v 1.3.6.1 2001/03/05 11:33:57 obrien Exp $
- * $DragonFly: src/lib/libc/stdlib/exit.c,v 1.8 2005/11/20 12:37:48 swildner Exp $
- *
  * @(#)exit.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/exit.c,v 1.9 2007/01/09 00:28:09 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/exit.c,v 1.8 2005/11/20 12:37:48 swildner Exp $
  */
 
 #include "namespace.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include "un-namespace.h"
+
 #include "atexit.h"
+#include "libc_private.h"
 
-void (*__cleanup)();
+void (*__cleanup)(void);
 
 /*
  * This variable is zero until a process has created a thread.
@@ -60,12 +57,11 @@ void
 exit(int status)
 {
        /* Ensure that the auto-initialization routine is linked in: */
-       extern int _thread_autoinit_dummy_decl; 
+       extern int _thread_autoinit_dummy_decl;
 
        _thread_autoinit_dummy_decl = 1;
 
        __cxa_finalize(NULL);
-
        if (__cleanup)
                (*__cleanup)();
        _exit(status);
index 57b4495..34a89c6 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getenv.3   8.2 (Berkeley) 12/11/93
-.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.4.2.7 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.27 2007/07/04 00:00:39 scf Exp $
 .\" $DragonFly: src/lib/libc/stdlib/getenv.3,v 1.5 2006/02/17 19:35:06 swildner Exp $
 .\"
-.Dd December 11, 1993
+.Dd June 20, 2007
 .Dt GETENV 3
 .Os
 .Sh NAME
 .Ft int
 .Fn setenv "const char *name" "const char *value" "int overwrite"
 .Ft int
-.Fn putenv "const char *string"
-.Ft void
+.Fn putenv "char *string"
+.Ft int
 .Fn unsetenv "const char *name"
 .Sh DESCRIPTION
 These functions set, unset and fetch environment variables from the
 host
 .Em environment list .
-For compatibility with differing environment conventions,
-the given arguments
-.Ar name
-and
-.Ar value
-may be appended and prepended,
-respectively,
-with an equal sign
-.Dq Li \&= .
 .Pp
 The
 .Fn getenv
 function obtains the current value of the environment variable,
-.Ar name .
-If the variable
-.Ar name
-is not in the current environment,
-a null pointer is returned.
+.Fa name .
+The application should not modify the string pointed
+to by the
+.Fn getenv
+function.
 .Pp
 The
 .Fn setenv
 function inserts or resets the environment variable
-.Ar name
+.Fa name
 in the current environment list.
 If the variable
-.Ar name
+.Fa name
 does not exist in the list,
 it is inserted with the given
-.Ar value .
+.Fa value .
 If the variable does exist, the argument
-.Ar overwrite
+.Fa overwrite
 is tested; if
-.Ar overwrite is
-zero, the
+.Fa overwrite
+is zero, the
 variable is not reset, otherwise it is reset
 to the given
-.Ar value .
+.Fa value .
 .Pp
 The
 .Fn putenv
-function takes an argument of the form ``name=value'' and is
-equivalent to:
-.Bd -literal -offset indent
-setenv(name, value, 1);
-.Ed
+function takes an argument of the form ``name=value'' and
+puts it directly into the current environment,
+so altering the argument shall change the environment.
+If the variable
+.Fa name
+does not exist in the list,
+it is inserted with the given
+.Fa value .
+If the variable
+.Fa name
+does exist, it is reset to the given
+.Fa value .
 .Pp
 The
 .Fn unsetenv
@@ -115,22 +109,66 @@ deletes all instances of the variable name pointed to by
 .Fa name
 from the list.
 .Sh RETURN VALUES
-.Rv -std setenv putenv
-.Pp
 The
 .Fn getenv
-function returns NULL if the environment variable was not found.
-If the variable was found,
-it returns the value of the variable as a NULL terminated string.
-This string should not be modified or freed.
+function returns the value of the environment variable as a
+.Dv NUL Ns
+-terminated string.
+If the variable
+.Fa name
+is not in the current environment,
+.Dv NULL
+is returned.
+.Pp
+.Rv -std setenv putenv unsetenv
 .Sh ERRORS
 .Bl -tag -width Er
-.It Bq Er ENOMEM
+.It Bq Er EINVAL
 The function
+.Fn getenv ,
 .Fn setenv
 or
+.Fn unsetenv
+failed because the
+.Fa name
+is a
+.Dv NULL
+pointer, points to an empty string, or points to a string containing an
+.Dq Li \&=
+character.
+.Pp
+The function
+.Fn putenv
+failed because
+.Fa string
+is a
+.Dv NULL
+pointer,
+.Fa string is without an
+.Dq Li \&=
+character or
+.Dq Li \&=
+is the first character in
+.Fa string .
+This does not follow the
+.Tn POSIX
+specification.
+.It Bq Er ENOMEM
+The function
+.Fn setenv ,
+.Fn unsetenv
+or
 .Fn putenv
 failed because they were unable to allocate memory for the environment.
+.It Bq Er EFAULT
+The functions
+.Fn setenv ,
+.Fn unsetenv
+or
+.Fn putenv
+failed to make a valid copy of the environment due to the environment being
+corrupt (i.e., a name without a value).  A warning will be output to stderr with
+information about the issue.
 .El
 .Sh SEE ALSO
 .Xr csh 1 ,
@@ -142,6 +180,13 @@ The
 .Fn getenv
 function conforms to
 .St -isoC .
+The
+.Fn setenv ,
+.Fn putenv
+and
+.Fn unsetenv
+functions conforms to
+.St -p1003.1-2001 .
 .Sh HISTORY
 The functions
 .Fn setenv
@@ -153,20 +198,33 @@ The
 .Fn putenv
 function appeared in
 .Bx 4.3 Reno .
+.Pp
+Until
+.Fx 7.0 ,
+.Fn putenv
+would make a copy of
+.Fa string
+and insert it into the environment using
+.Fn setenv .
+This was changed to use
+.Fa string
+as the memory location of the ``name=value'' pair to follow the
+.Tn POSIX
+specification.
 .Sh BUGS
 Successive calls to
 .Fn setenv
-or
-.Fn putenv
-assigning a differently sized
-.Ar value
-to the same
-.Ar name
-will result in a memory leak.  The
+that assign a larger-sized
+.Fa value
+than any previous value to the same
+.Fa name
+will result in a memory leak.
+The
 .Dx
-semantics for these functions
+semantics for this function
 (namely, that the contents of
-.Ar value
+.Fa value
 are copied and that old values remain accessible indefinitely) make this
-bug unavoidable.  Future versions may eliminate one or both of these
+bug unavoidable.
+Future versions may eliminate one or both of these
 semantic guarantees in order to fix the bug.
index aa552da..731b3c5 100644 (file)
-/*
- * Copyright (c) 1987, 1993
- *     The Regents of the University of California.  All rights reserved.
+/*-
+ * Copyright (c) 2007-2008 Sean C. Farley <scf@FreeBSD.org>
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * @(#)getenv.c        8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.15 2008/08/03 22:47:23 scf Exp $
  * $DragonFly: src/lib/libc/stdlib/getenv.c,v 1.5 2005/04/28 13:51:55 joerg Exp $
  */
 
-#include <stdlib.h>
+#include "namespace.h"
+#include <sys/types.h>
+#include <errno.h>
+#include <stdbool.h>
 #include <stddef.h>
+#include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include "un-namespace.h"
 
-char *__findenv(const char *, size_t *);
 
+static const char CorruptEnvFindMsg[] = "environment corrupt; unable to find ";
+static const char CorruptEnvValueMsg[] =
+    "environment corrupt; missing value for ";
+
+
+/*
+ * Standard environ.  environ variable is exposed to entire process.
+ *
+ *     origEnviron:    Upon cleanup on unloading of library or failure, this
+ *                     allows environ to return to as it was before.
+ *     environSize:    Number of variables environ can hold.  Can only
+ *                     increase.
+ *     intEnviron:     Internally-built environ.  Exposed via environ during
+ *                     (re)builds of the environment.
+ */
 extern char **environ;
+static char **origEnviron;
+static char **intEnviron = NULL;
+static int environSize = 0;
+
+/*
+ * Array of environment variables built from environ.  Each element records:
+ *     name:           Pointer to name=value string
+ *     name length:    Length of name not counting '=' character
+ *     value:          Pointer to value within same string as name
+ *     value size:     Size (not length) of space for value not counting the
+ *                     nul character
+ *     active state:   true/false value to signify whether variable is active.
+ *                     Useful since multiple variables with the same name can
+ *                     co-exist.  At most, one variable can be active at any
+ *                     one time.
+ *     putenv:         Created from putenv() call.  This memory must not be
+ *                     reused.
+ */
+static struct envVars {
+       size_t nameLen;
+       size_t valueSize;
+       char *name;
+       char *value;
+       bool active;
+       bool putenv;
+} *envVars = NULL;
 
 /*
- * __findenv --
- *     Returns pointer to value associated with name, if any, else NULL.
- *     Sets offset to be the offset of the name/value combination in the
- *     environmental array, for use by setenv(3) and unsetenv(3).
- *     Explicitly removes '=' in argument name.
+ * Environment array information.
  *
- *     This routine *should* be a static; don't use it.
+ *     envActive:      Number of active variables in array.
+ *     envVarsSize:    Size of array.
+ *     envVarsTotal:   Number of total variables in array (active or not).
  */
-char *
-__findenv(const char *name, size_t *offset)
+static int envActive = 0;
+static int envVarsSize = 0;
+static int envVarsTotal = 0;
+
+
+/* Deinitialization of new environment. */
+static void __attribute__ ((destructor)) __clean_env_destructor(void);
+
+
+/*
+ * A simple version of warnx() to avoid the bloat of including stdio in static
+ * binaries.
+ */
+static void
+__env_warnx(const char *msg, const char *name, size_t nameLen)
 {
-       size_t len, i;
-       const char *np;
-       char **p, *cp;
+       static const char nl[] = "\n";
+       static const char progSep[] = ": ";
 
-       if (name == NULL || environ == NULL)
-               return (NULL);
-       for (np = name; *np && *np != '='; ++np)
-               continue;
-       len = np - name;
-       for (p = environ; (cp = *p) != NULL; ++p) {
-               for (np = name, i = len; i && *cp; i--)
-                       if (*cp++ != *np++)
-                               break;
-               if (i == 0 && *cp++ == '=') {
-                       *offset = p - environ;
-                       return (cp);
+       _write(STDERR_FILENO, _getprogname(), strlen(_getprogname()));
+       _write(STDERR_FILENO, progSep, sizeof(progSep) - 1);
+       _write(STDERR_FILENO, msg, strlen(msg));
+       _write(STDERR_FILENO, name, nameLen);
+       _write(STDERR_FILENO, nl, sizeof(nl) - 1);
+
+       return;
+}
+
+
+/*
+ * Inline strlen() for performance.  Also, perform check for an equals sign.
+ * Cheaper here than peforming a strchr() later.
+ */
+static inline size_t
+__strleneq(const char *str)
+{
+       const char *s;
+
+       for (s = str; *s != '\0'; ++s)
+               if (*s == '=')
+                       return (0);
+
+       return (s - str);
+}
+
+
+/*
+ * Comparison of an environment name=value to a name.
+ */
+static inline bool
+strncmpeq(const char *nameValue, const char *name, size_t nameLen)
+{
+       if (strncmp(nameValue, name, nameLen) == 0 && nameValue[nameLen] == '=')
+               return (true);
+
+       return (false);
+}
+
+
+/*
+ * Using environment, returns pointer to value associated with name, if any,
+ * else NULL.  If the onlyActive flag is set to true, only variables that are
+ * active are returned else all are.
+ */
+static inline char *
+__findenv(const char *name, size_t nameLen, int *envNdx, bool onlyActive)
+{
+       int ndx;
+
+       /*
+        * Find environment variable from end of array (more likely to be
+        * active).  A variable created by putenv is always active or it is not
+        * tracked in the array.
+        */
+       for (ndx = *envNdx; ndx >= 0; ndx--)
+               if (envVars[ndx].putenv) {
+                       if (strncmpeq(envVars[ndx].name, name, nameLen)) {
+                               *envNdx = ndx;
+                               return (envVars[ndx].name + nameLen +
+                                   sizeof ("=") - 1);
+                       }
+               } else if ((!onlyActive || envVars[ndx].active) &&
+                   (envVars[ndx].nameLen == nameLen &&
+                   strncmpeq(envVars[ndx].name, name, nameLen))) {
+                       *envNdx = ndx;
+                       return (envVars[ndx].value);
                }
-       }
+
        return (NULL);
 }
 
+
 /*
- * getenv --
- *     Returns ptr to value associated with name, if any, else NULL.
+ * Using environ, returns pointer to value associated with name, if any, else
+ * NULL.  Used on the original environ passed into the program.
+ */
+static char *
+__findenv_environ(const char *name, size_t nameLen)
+{
+       int envNdx;
+
+       /* Find variable within environ. */
+       for (envNdx = 0; environ[envNdx] != NULL; envNdx++)
+               if (strncmpeq(environ[envNdx], name, nameLen))
+                       return (&(environ[envNdx][nameLen + sizeof("=") - 1]));
+
+       return (NULL);
+}
+
+
+/*
+ * Remove variable added by putenv() from variable tracking array.
+ */
+static void
+__remove_putenv(int envNdx)
+{
+       envVarsTotal--;
+       if (envVarsTotal > envNdx)
+               memmove(&(envVars[envNdx]), &(envVars[envNdx + 1]),
+                   (envVarsTotal - envNdx) * sizeof (*envVars));
+       memset(&(envVars[envVarsTotal]), 0, sizeof (*envVars));
+
+       return;
+}
+
+
+/*
+ * Deallocate the environment built from environ as well as environ then set
+ * both to NULL.  Eases debugging of memory leaks.
+ */
+static void
+__clean_env(bool freeVars)
+{
+       int envNdx;
+
+       /* Deallocate environment and environ if created by *env(). */
+       if (envVars != NULL) {
+               for (envNdx = envVarsTotal - 1; envNdx >= 0; envNdx--)
+                       /* Free variables or deactivate them. */
+                       if (envVars[envNdx].putenv) {
+                               if (!freeVars)
+                                       __remove_putenv(envNdx);
+                       } else {
+                               if (freeVars)
+                                       free(envVars[envNdx].name);
+                               else
+                                       envVars[envNdx].active = false;
+                       }
+               if (freeVars) {
+                       free(envVars);
+                       envVars = NULL;
+               } else
+                       envActive = 0;
+
+               /* Restore original environ if it has not updated by program. */
+               if (origEnviron != NULL) {
+                       if (environ == intEnviron)
+                               environ = origEnviron;
+                       free(intEnviron);
+                       intEnviron = NULL;
+                       environSize = 0;
+               }
+       }
+
+       return;
+}
+
+
+/*
+ * Using the environment, rebuild the environ array for use by other C library
+ * calls that depend upon it.
+ */
+static int
+__rebuild_environ(int newEnvironSize)
+{
+       char **tmpEnviron;
+       int envNdx;
+       int environNdx;
+       int tmpEnvironSize;
+
+       /* Resize environ. */
+       if (newEnvironSize > environSize) {
+               tmpEnvironSize = newEnvironSize * 2;
+               tmpEnviron = realloc(intEnviron, sizeof (*intEnviron) *
+                   (tmpEnvironSize + 1));
+               if (tmpEnviron == NULL)
+                       return (-1);
+               environSize = tmpEnvironSize;
+               intEnviron = tmpEnviron;
+       }
+       envActive = newEnvironSize;
+
+       /* Assign active variables to environ. */
+       for (envNdx = envVarsTotal - 1, environNdx = 0; envNdx >= 0; envNdx--)
+               if (envVars[envNdx].active)
+                       intEnviron[environNdx++] = envVars[envNdx].name;
+       intEnviron[environNdx] = NULL;
+
+       /* Always set environ which may have been replaced by program. */
+       environ = intEnviron;
+
+       return (0);
+}
+
+
+/*
+ * Enlarge new environment.
+ */
+static inline bool
+__enlarge_env(void)
+{
+       int newEnvVarsSize;
+       struct envVars *tmpEnvVars;
+
+       envVarsTotal++;
+       if (envVarsTotal > envVarsSize) {
+               newEnvVarsSize = envVarsTotal * 2;
+               tmpEnvVars = realloc(envVars, sizeof (*envVars) *
+                   newEnvVarsSize);
+               if (tmpEnvVars == NULL) {
+                       envVarsTotal--;
+                       return (false);
+               }
+               envVarsSize = newEnvVarsSize;
+               envVars = tmpEnvVars;
+       }
+
+       return (true);
+}
+
+
+/*
+ * Using environ, build an environment for use by standard C library calls.
+ */
+static int
+__build_env(void)
+{
+       char **env;
+       int activeNdx;
+       int envNdx;
+       int savedErrno;
+       size_t nameLen;
+
+       /* Check for non-existant environment. */
+       if (environ == NULL || environ[0] == NULL)
+               return (0);
+
+       /* Count environment variables. */
+       for (env = environ, envVarsTotal = 0; *env != NULL; env++)
+               envVarsTotal++;
+       envVarsSize = envVarsTotal * 2;
+
+       /* Create new environment. */
+       envVars = calloc(1, sizeof (*envVars) * envVarsSize);
+       if (envVars == NULL)
+               goto Failure;
+
+       /* Copy environ values and keep track of them. */
+       for (envNdx = envVarsTotal - 1; envNdx >= 0; envNdx--) {
+               envVars[envNdx].putenv = false;
+               envVars[envNdx].name =
+                   strdup(environ[envVarsTotal - envNdx - 1]);
+               if (envVars[envNdx].name == NULL)
+                       goto Failure;
+               envVars[envNdx].value = strchr(envVars[envNdx].name, '=');
+               if (envVars[envNdx].value != NULL) {
+                       envVars[envNdx].value++;
+                       envVars[envNdx].valueSize =
+                           strlen(envVars[envNdx].value);
+               } else {
+                       __env_warnx(CorruptEnvValueMsg, envVars[envNdx].name,
+                           strlen(envVars[envNdx].name));
+                       errno = EFAULT;
+                       goto Failure;
+               }
+
+               /*
+                * Find most current version of variable to make active.  This
+                * will prevent multiple active variables from being created
+                * during this initialization phase.
+                */
+               nameLen = envVars[envNdx].value - envVars[envNdx].name - 1;
+               envVars[envNdx].nameLen = nameLen;
+               activeNdx = envVarsTotal - 1;
+               if (__findenv(envVars[envNdx].name, nameLen, &activeNdx,
+                   false) == NULL) {
+                       __env_warnx(CorruptEnvFindMsg, envVars[envNdx].name,
+                           nameLen);
+                       errno = EFAULT;
+                       goto Failure;
+               }
+               envVars[activeNdx].active = true;
+       }
+
+       /* Create a new environ. */
+       origEnviron = environ;
+       environ = NULL;
+       if (__rebuild_environ(envVarsTotal) == 0)
+               return (0);
+
+Failure:
+       savedErrno = errno;
+       __clean_env(true);
+       errno = savedErrno;
+
+       return (-1);
+}
+
+
+/*
+ * Destructor function with default argument to __clean_env().
+ */
+static void
+__clean_env_destructor(void)
+{
+       __clean_env(true);
+
+       return;
+}
+
+
+/*
+ * Returns the value of a variable or NULL if none are found.
  */
 char *
 getenv(const char *name)
 {
-       size_t offset;
+       int envNdx;
+       size_t nameLen;
+
+       /* Check for malformed name. */
+       if (name == NULL || (nameLen = __strleneq(name)) == 0) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       /*
+        * An empty environment (environ or its first value) regardless if
+        * environ has been copied before will return a NULL.
+        *
+        * If the environment is not empty, find an environment variable via
+        * environ if environ has not been copied via an *env() call or been
+        * replaced by a running program, otherwise, use the rebuilt
+        * environment.
+        */
+       if (environ == NULL || environ[0] == NULL)
+               return (NULL);
+       else if (envVars == NULL || environ != intEnviron)
+               return (__findenv_environ(name, nameLen));
+       else {
+               envNdx = envVarsTotal - 1;
+               return (__findenv(name, nameLen, &envNdx, true));
+       }
+}
+
+
+/*
+ * Set the value of a variable.  Older settings are labeled as inactive.  If an
+ * older setting has enough room to store the new value, it will be reused.  No
+ * previous variables are ever freed here to avoid causing a segmentation fault
+ * in a user's code.
+ *
+ * The variables nameLen and valueLen are passed into here to allow the caller
+ * to calculate the length by means besides just strlen().
+ */
+static int
+__setenv(const char *name, size_t nameLen, const char *value, int overwrite)
+{
+       bool reuse;
+       char *env;
+       int envNdx;
+       int newEnvActive;
+       size_t valueLen;
+
+       /* Find existing environment variable large enough to use. */
+       envNdx = envVarsTotal - 1;
+       newEnvActive = envActive;
+       valueLen = strlen(value);
+       reuse = false;
+       if (__findenv(name, nameLen, &envNdx, false) != NULL) {
+               /* Deactivate entry if overwrite is allowed. */
+               if (envVars[envNdx].active) {
+                       if (overwrite == 0)
+                               return (0);
+                       envVars[envNdx].active = false;
+                       newEnvActive--;
+               }
+
+               /* putenv() created variable cannot be reused. */
+               if (envVars[envNdx].putenv)
+                       __remove_putenv(envNdx);
+
+               /* Entry is large enough to reuse. */
+               else if (envVars[envNdx].valueSize >= valueLen)
+                       reuse = true;
+       }
+
+       /* Create new variable if none was found of sufficient size. */
+       if (! reuse) {
+               /* Enlarge environment. */
+               envNdx = envVarsTotal;
+               if (!__enlarge_env())
+                       return (-1);
+
+               /* Create environment entry. */
+               envVars[envNdx].name = malloc(nameLen + sizeof ("=") +
+                   valueLen);
+               if (envVars[envNdx].name == NULL) {
+                       envVarsTotal--;
+                       return (-1);
+               }
+               envVars[envNdx].nameLen = nameLen;
+               envVars[envNdx].valueSize = valueLen;
+
+               /* Save name of name/value pair. */
+               env = stpcpy(envVars[envNdx].name, name);
+               if ((envVars[envNdx].name)[nameLen] != '=')
+                       env = stpcpy(env, "=");
+       }
+       else
+               env = envVars[envNdx].value;
+
+       /* Save value of name/value pair. */
+       strcpy(env, value);
+       envVars[envNdx].value = env;
+       envVars[envNdx].active = true;
+       newEnvActive++;
+
+       /* No need to rebuild environ if an active variable was reused. */
+       if (reuse && newEnvActive == envActive)
+               return (0);
+       else
+               return (__rebuild_environ(newEnvActive));
+}
+
+
+/*
+ * If the program attempts to replace the array of environment variables
+ * (environ) environ or sets the first varible to NULL, then deactivate all
+ * variables and merge in the new list from environ.
+ */
+static int
+__merge_environ(void)
+{
+       char **env;
+       char *equals;
+
+       /*
+        * Internally-built environ has been replaced or cleared (detected by
+        * using the count of active variables against a NULL as the first value
+        * in environ).  Clean up everything.
+        */
+       if (intEnviron != NULL && (environ != intEnviron || (envActive > 0 &&
+           environ[0] == NULL))) {
+               /* Deactivate all environment variables. */
+               if (envActive > 0) {
+                       origEnviron = NULL;
+                       __clean_env(false);
+               }
+
+               /*
+                * Insert new environ into existing, yet deactivated,
+                * environment array.
+                */
+               origEnviron = environ;
+               if (origEnviron != NULL)
+                       for (env = origEnviron; *env != NULL; env++) {
+                               if ((equals = strchr(*env, '=')) == NULL) {
+                                       __env_warnx(CorruptEnvValueMsg, *env,
+                                           strlen(*env));
+                                       errno = EFAULT;
+                                       return (-1);
+                               }
+                               if (__setenv(*env, equals - *env, equals + 1,
+                                   1) == -1)
+                                       return (-1);
+                       }
+       }
+
+       return (0);
+}
+
+
+/*
+ * The exposed setenv() that peforms a few tests before calling the function
+ * (__setenv()) that does the actual work of inserting a variable into the
+ * environment.
+ */
+int
+setenv(const char *name, const char *value, int overwrite)
+{
+       size_t nameLen;
+
+       /* Check for malformed name. */
+       if (name == NULL || (nameLen = __strleneq(name)) == 0) {
+               errno = EINVAL;
+               return (-1);
+       }
+
+       /* Initialize environment. */
+       if (__merge_environ() == -1 || (envVars == NULL && __build_env() == -1))
+               return (-1);
+
+       return (__setenv(name, nameLen, value, overwrite));
+}
+
+
+/*
+ * Insert a "name=value" string into the environment.  Special settings must be
+ * made to keep setenv() from reusing this memory block and unsetenv() from
+ * allowing it to be tracked.
+ */
+int
+putenv(char *string)
+{
+       char *equals;
+       int envNdx;
+       int newEnvActive;
+       size_t nameLen;
+
+       /* Check for malformed argument. */
+       if (string == NULL || (equals = strchr(string, '=')) == NULL ||
+           (nameLen = equals - string) == 0) {
+               errno = EINVAL;
+               return (-1);
+       }
+
+       /* Initialize environment. */
+       if (__merge_environ() == -1 || (envVars == NULL && __build_env() == -1))
+               return (-1);
+
+       /* Deactivate previous environment variable. */
+       envNdx = envVarsTotal - 1;
+       newEnvActive = envActive;
+       if (__findenv(string, nameLen, &envNdx, true) != NULL) {
+               /* Reuse previous putenv slot. */
+               if (envVars[envNdx].putenv) {
+                       envVars[envNdx].name = string;
+                       return (__rebuild_environ(envActive));
+               } else {
+                       newEnvActive--;
+                       envVars[envNdx].active = false;
+               }
+       }
+
+       /* Enlarge environment. */
+       envNdx = envVarsTotal;
+       if (!__enlarge_env())
+               return (-1);
+
+       /* Create environment entry. */
+       envVars[envNdx].name = string;
+       envVars[envNdx].nameLen = -1;
+       envVars[envNdx].value = NULL;
+       envVars[envNdx].valueSize = -1;
+       envVars[envNdx].putenv = true;
+       envVars[envNdx].active = true;
+       newEnvActive++;
+
+       return (__rebuild_environ(newEnvActive));
+}
+
+
+/*
+ * Unset variable with the same name by flagging it as inactive.  No variable is
+ * ever freed.
+ */
+int
+unsetenv(const char *name)
+{
+       int envNdx;
+       size_t nameLen;
+
+       /* Check for malformed name. */
+       if (name == NULL || (nameLen = __strleneq(name)) == 0) {
+               errno = EINVAL;
+               return (-1);
+       }
+
+       /* Initialize environment. */
+       if (__merge_environ() == -1 || (envVars == NULL && __build_env() == -1))
+               return (-1);
+
+       /* Deactivate specified variable. */
+       envNdx = envVarsTotal - 1;
+       if (__findenv(name, nameLen, &envNdx, true) != NULL) {
+               envVars[envNdx].active = false;
+               if (envVars[envNdx].putenv)
+                       __remove_putenv(envNdx);
+               __rebuild_environ(envActive - 1);
+       }
 
-       return (__findenv(name, &offset));
+       return (0);
 }
index 975da05..1d7824e 100644 (file)
@@ -1,3 +1,5 @@
+.\"    $NetBSD: getopt.3,v 1.31 2003/09/23 10:26:54 wiz Exp $
+.\"
 .\" Copyright (c) 1988, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -9,10 +11,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -30,7 +28,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getopt.3   8.5 (Berkeley) 4/27/95
-.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.11.2.8 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.26 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/getopt.3,v 1.5 2006/05/26 19:39:37 swildner Exp $
 .\"
 .Dd April 27, 1995
 .Sh SYNOPSIS
 .In unistd.h
 .Vt extern char *optarg ;
-.Vt extern int   optind ;
-.Vt extern int   optopt ;
-.Vt extern int   opterr ;
-.Vt extern int   optreset ;
+.Vt extern int optind ;
+.Vt extern int optopt ;
+.Vt extern int opterr ;
+.Vt extern int optreset ;
 .Ft int
-.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Fn getopt "int argc" "char * const argv[]" "const char *optstring"
 .Sh DESCRIPTION
 The
 .Fn getopt
@@ -98,7 +96,7 @@ saves the last
 option character returned by
 .Fn getopt .
 .Pp
-The variable
+The variables
 .Va opterr
 and
 .Va optind
@@ -123,12 +121,7 @@ must be reinitialized.
 .Pp
 The
 .Fn getopt
-function
-returns \-1
-when the argument list is exhausted, or
-.Ql ?\&
-if a non-recognized
-option is encountered.
+function returns \-1 when the argument list is exhausted.
 The interpretation of options in the argument list may be cancelled
 by the option
 .Ql --
@@ -139,8 +132,36 @@ When all options have been processed (i.e., up to the first non-option
 argument),
 .Fn getopt
 returns \-1.
+.Sh RETURN VALUES
+The
+.Fn getopt
+function returns the next known option character in
+.Fa optstring .
+If
+.Fn getopt
+encounters a character not found in
+.Fa optstring
+or if it detects a missing option argument,
+it returns
+.Ql \&?
+(question mark).
+If
+.Fa optstring
+has a leading
+.Ql \&:
+then a missing option argument causes
+.Ql \&:
+to be returned instead of
+.Ql \&? .
+In either case, the variable
+.Va optopt
+is set to the character that caused the error.
+The
+.Fn getopt
+function returns \-1 when the argument list is exhausted.
 .Sh EXAMPLES
 .Bd -literal -compact
+#include <unistd.h>
 int bflag, ch, fd;
 
 bflag = 0;
@@ -150,8 +171,11 @@ while ((ch = getopt(argc, argv, "bf:")) != -1) {
                bflag = 1;
                break;
        case 'f':
-               if ((fd = open(optarg, O_RDONLY, 0)) < 0)
-                       err(1, "%s", optarg);
+               if ((fd = open(optarg, O_RDONLY, 0)) \*[Lt] 0) {
+                       fprintf(stderr,
+                           "myname: %s: %s\en", optarg, strerror(errno));
+                       exit(1);
+               }
                break;
        default:
                usage();
@@ -164,17 +188,17 @@ argv += optind;
 If the
 .Fn getopt
 function encounters a character not found in the string
-.Va optstring
+.Fa optstring
 or detects
 a missing option argument it writes an error message to the
-.Em stderr
+.Dv stderr
 and returns
-.Ql ?\& .
+.Ql \&? .
 Setting
 .Va opterr
 to a zero will disable these error messages.
 If
-.Va optstring
+.Fa optstring
 has a leading
 .Ql \&:
 then a missing option argument causes a
@@ -183,9 +207,12 @@ to be returned in addition to suppressing any error messages.
 .Pp
 Option arguments are allowed to begin with
 .Dq Li \- ;
-this is reasonable but
-reduces the amount of error checking possible.
-.Sh EXTENSIONS
+this is reasonable but reduces the amount of error checking possible.
+.Sh SEE ALSO
+.Xr getopt 1 ,
+.Xr getopt_long 3 ,
+.Xr getsubopt 3
+.Sh STANDARDS
 The
 .Va optreset
 variable was added to make it possible to call the
@@ -227,10 +254,20 @@ as an option flag.
 This practice is wrong, and should not be used in any current development.
 It is provided for backward compatibility
 .Em only .
+Care should be taken not to use
+.Ql \&-
+as the first character in
+.Fa optstring
+to avoid a semantic conflict with
+.Tn GNU
+.Fn getopt ,
+which assigns different meaning to an
+.Fa optstring
+that begins with a
+.Ql \&- .
 By default, a single dash causes
 .Fn getopt
 to return \-1.
-This is, we believe, compatible with System V.
 .Pp
 It is also possible to handle digits as option letters.
 This allows
@@ -241,9 +278,10 @@ as an option.
 This practice is wrong, and should not be used in any current development.
 It is provided for backward compatibility
 .Em only .
-The following code fragment works in most (but not all) cases.
+The following code fragment works in most cases.
 .Bd -literal -offset indent
-int length;
+int ch;
+long length;
 char *p, *ep;
 
 while ((ch = getopt(argc, argv, "0123456789")) != -1) {
@@ -251,16 +289,17 @@ while ((ch = getopt(argc, argv, "0123456789")) != -1) {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
                p = argv[optind - 1];
-               if (p[0] == '-' && p[1] == ch && !p[2])
-                       length = strtol(++p, &ep, 10);
-               else if (argv[optind] && argv[optind][1] == ch) {
+               if (p[0] == '-' \*[Am]\*[Am] p[1] == ch \*[Am]\*[Am] !p[2]) {
+                       length = ch - '0';
+                       ep = "";
+               } else if (argv[optind] \*[Am]\*[Am] argv[optind][1] == ch) {
                        length = strtol((p = argv[optind] + 1),
-                           &ep, 10);
+                           \*[Am]ep, 10);
                        optind++;
                        optreset = 1;
                } else
                        usage();
-               if (*ep != '\0')
+               if (*ep != '\e0')
                        errx(EX_USAGE, "illegal number -- %s", p);
                break;
        }
index ad841be..402dd3b 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  * @(#)getopt.c        8.3 (Berkeley) 4/27/95
- * $FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.2.2.2 2001/08/26 03:36:04 jkoshy Exp $
+ * $FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.8 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/getopt.c,v 1.7 2005/11/20 12:37:48 swildner Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "un-namespace.h"
+
+#include "libc_private.h"
 
 int    opterr = 1,             /* if error message should be printed */
        optind = 1,             /* index into parent argv vector */
@@ -102,7 +102,7 @@ getopt(int nargc, char * const nargv[], const char *ostr)
                        ++optind;
                if (opterr && *ostr != ':')
                        fprintf(stderr,
-                           "%s: illegal option -- %c\n", getprogname(),
+                           "%s: illegal option -- %c\n", _getprogname(),
                            optopt);
                return (BADCH);
        }
@@ -128,7 +128,7 @@ getopt(int nargc, char * const nargv[], const char *ostr)
                        if (opterr)
                                fprintf(stderr,
                                    "%s: option requires an argument -- %c\n",
-                                   getprogname(), optopt);
+                                   _getprogname(), optopt);
                        return (BADCH);
                }
                place = EMSG;
index e67e8c9..9226a85 100644 (file)
@@ -1,5 +1,5 @@
+.\"    $OpenBSD: getopt_long.3,v 1.10 2004/01/06 23:44:28 fgsch Exp $
 .\"    $NetBSD: getopt_long.3,v 1.14 2003/08/07 16:43:40 agc Exp $
-.\"    $DragonFly: src/lib/libc/stdlib/getopt_long.3,v 1.7 2008/11/23 21:55:52 swildner Exp $
 .\"
 .\" Copyright (c) 1988, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getopt.3   8.5 (Berkeley) 4/27/95
+.\" $FreeBSD: src/lib/libc/stdlib/getopt_long.3,v 1.13 2005/01/20 09:17:04 ru Exp $
+.\" $DragonFly: src/lib/libc/stdlib/getopt_long.3,v 1.7 2008/11/23 21:55:52 swildner Exp $
 .\"
-.Dd March 14, 2007
+.Dd April 1, 2000
 .Dt GETOPT_LONG 3
 .Os
 .Sh NAME
-.Nm getopt_long
+.Nm getopt_long ,
+.Nm getopt_long_only
 .Nd get long options from command line argument list
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .In getopt.h
+.Vt extern char *optarg ;
+.Vt extern int optind ;
+.Vt extern int optopt ;
+.Vt extern int opterr ;
+.Vt extern int optreset ;
 .Ft int
-.Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "struct option *long_options" "int *index"
-.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "struct option *long_options" "int *index"
+.Fo getopt_long
+.Fa "int argc" "char * const *argv" "const char *optstring"
+.Fa "const struct option *longopts" "int *longindex"
+.Fc
+.Ft int
+.Fo getopt_long_only
+.Fa "int argc" "char * const *argv" "const char *optstring"
+.Fa "const struct option *longopts" "int *longindex"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getopt_long
@@ -53,11 +68,14 @@ The
 .Fn getopt_long
 function provides a superset of the functionality of
 .Xr getopt 3 .
+The
 .Fn getopt_long
+function
 can be used in two ways.
-In the first way, every long option understood by the program has a
-corresponding short option, and the option structure is only used to
-translate from long options to short options.
+In the first way, every long option understood
+by the program has a corresponding short option, and the option
+structure is only used to translate from long options to short
+options.
 When used in this fashion,
 .Fn getopt_long
 behaves identically to
@@ -66,18 +84,18 @@ This is a good way to add long option processing to an existing program
 with the minimum of rewriting.
 .Pp
 In the second mechanism, a long option sets a flag in the
-.Fa option
+.Vt option
 structure passed, or will store a pointer to the command line argument
 in the
-.Fa option
+.Vt option
 structure passed to it for options that take arguments.
-Additionally, the long option's argument may be specified as a single
-argument with an equal sign, e.g.
-.Bd -literal
-myprogram --myoption=somevalue
-.Ed
+Additionally,
+the long option's argument may be specified as a single argument with
+an equal sign, e.g.,
+.Pp
+.Dl "myprogram --myoption=somevalue"
 .Pp
-When a long option is processed the call to
+When a long option is processed, the call to
 .Fn getopt_long
 will return 0.
 For this reason, long option processing without
@@ -86,13 +104,15 @@ shortcuts is not backwards compatible with
 .Pp
 It is possible to combine these methods, providing for long options
 processing with short option equivalents for some options.
-Less frequently used options would be processed as long options only.
+Less
+frequently used options would be processed as long options only.
 .Pp
 The
 .Fn getopt_long
-call requires a structure to be initialized describing the long options.
+call requires a structure to be initialized describing the long
+options.
 The structure is:
-.Bd -literal
+.Bd -literal -offset indent
 struct option {
        char *name;
        int has_arg;
@@ -102,59 +122,58 @@ struct option {
 .Ed
 .Pp
 The
-.Fa name
+.Va name
 field should contain the option name without the leading double dash.
 .Pp
 The
-.Fa has_arg
+.Va has_arg
 field should be one of:
-.Bl -tag -width "optional_argument"
-.It Li no_argument
-no argument to the option is expect.
-.It Li required_argument
-an argument to the option is required.
-.It Li optional_argument
+.Pp
+.Bl -tag -width ".Dv optional_argument" -offset indent -compact
+.It Dv no_argument
+no argument to the option is expect
+.It Dv required_argument
+an argument to the option is required
+.It Dv optional_argument
 an argument to the option may be presented.
 .El
 .Pp
 If
-.Fa flag
+.Va flag
 is not
 .Dv NULL ,
-then the integer pointed to by it will be set to the value in the
-.Fa val
+then the integer pointed to by it will be set to the
+value in the
+.Va val
 field.
 If the
-.Fa flag
+.Va flag
 field is
 .Dv NULL ,
 then the
-.Fa val
+.Va val
 field will be returned.
 Setting
-.Fa flag
+.Va flag
 to
 .Dv NULL
 and setting
-.Fa val
+.Va val
 to the corresponding short option will make this function act just
 like
 .Xr getopt 3 .
 .Pp
 If the
-.Fa index
+.Fa longindex
 field is not
 .Dv NULL ,
-the integer it points to will be set to the index of the long option
-in the
-.Fa long_options
-array.
+then the integer pointed to by it will be set to the index of the long
+option relative to
+.Fa longopts .
 .Pp
 The last element of the
-.Fa long_options
-array has to be filled with zeroes (see
-.Sx EXAMPLES
-section).
+.Fa longopts
+array has to be filled with zeroes.
 .Pp
 The
 .Fn getopt_long_only
@@ -168,126 +187,54 @@ If an option starting with
 .Ql -
 does not match a long option but does match a single-character option,
 the single-character option is returned.
-Note that the
+.Sh RETURN VALUES
+If the
+.Fa flag
+field in
+.Vt "struct option"
+is
+.Dv NULL ,
+.Fn getopt_long
+and
 .Fn getopt_long_only
-function is deprecated.
-New programs should use
-.Fn getopt_long .
-.Sh IMPLEMENTATION DIFFERENCES
-This section describes differences to the GNU implementation
-found in glibc-2.1.3:
-.Bl -tag -width "xxx"
-.It Li o
-handling of - as first char of option string in presence of
-environment variable POSIXLY_CORRECT:
-.Bl -tag -width "NetBSD"
-.It Li GNU
-ignores POSIXLY_CORRECT and returns non-options as
-arguments to option '\e1'.
-.It Li NetBSD
-honors POSIXLY_CORRECT and stops at the first non-option.
-.El
-.It Li o
-handling of :: in options string in presence of POSIXLY_CORRECT:
-.Bl -tag -width "NetBSD"
-.It Li Both
-GNU and
-.Nx
-ignore POSIXLY_CORRECT here and take :: to
-mean the preceding option takes an optional argument.
-.El
-.It Li o
-return value in case of missing argument if first character
-(after + or -) in option string is not ':':
-.Bl -tag -width "NetBSD"
-.It Li GNU
-returns '?'
-.It NetBSD
-returns ':' (since
-.Nx Ap s
-.Fn getopt
-does).
-.El
-.It Li o
-handling of --a in
-.Fn getopt :
-.Bl -tag -width "NetBSD"
-.It Li GNU
-parses this as option '-', option 'a'.
-.It Li NetBSD
-parses this as '--', and returns \-1 (ignoring the a).
-(Because the original
-.Fn getopt
-does.)
-.El
-.It Li o
-setting of optopt for long options with flag !=
-.Dv NULL :
-.Bl -tag -width "NetBSD"
-.It Li GNU
-sets optopt to val.
-.It Li NetBSD
-sets optopt to 0 (since val would never be returned).
-.El
-.It Li o
-handling of -W with W; in option string in
-.Fn getopt
-(not
-.Fn getopt_long ) :
-.Bl -tag -width "NetBSD"
-.It Li GNU
-causes a segfault.
-.It Li NetBSD
-returns \-1, with optind pointing past the argument of -W
-(as if `-W arg' were `--arg', and thus '--' had been found).
-.\" How should we treat W; in the option string when called via
-.\" getopt?  Ignore the ';' or treat it as a ':'? Issue a warning?
-.El
-.It Li o
-setting of optarg for long options without an argument that are
-invoked via -W (W; in option string):
-.Bl -tag -width "NetBSD"
-.It Li GNU
-sets optarg to the option name (the argument of -W).
-.It Li NetBSD
-sets optarg to
-.Dv NULL
-(the argument of the long option).
-.El
-.It Li o
-handling of -W with an argument that is not (a prefix to) a known
-long option (W; in option string):
-.Bl -tag -width "NetBSD"
-.It Li GNU
-returns -W with optarg set to the unknown option.
-.It Li NetBSD
-treats this as an error (unknown option) and returns '?' with
-optopt set to 0 and optarg set to
-.Dv NULL
-(as GNU's man page documents).
-.El
-.It Li o
-The error messages are different.
-.It Li o
-.Nx
-does not permute the argument vector at the same points in
-the calling sequence as GNU does.
-The aspects normally used by the caller
-(ordering after \-1 is returned, value of optind relative
-to current positions) are the same, though.
-(We do fewer variable swaps.)
+return the value specified in the
+.Fa val
+field, which is usually just the corresponding short option.
+If
+.Fa flag
+is not
+.Dv NULL ,
+these functions return 0 and store
+.Fa val
+in the location pointed to by
+.Fa flag .
+These functions return
+.Ql \&:
+if there was a missing option argument,
+.Ql \&?
+if the user specified an unknown or ambiguous option, and
+\-1 when the argument list has been exhausted.
+.Sh ENVIRONMENT
+.Bl -tag -width ".Ev POSIXLY_CORRECT"
+.It Ev POSIXLY_CORRECT
+If set, option processing stops when the first non-option is found and
+a leading
+.Ql -
+or
+.Ql +
+in the
+.Fa optstring
+is ignored.
 .El
 .Sh EXAMPLES
 .Bd -literal -compact
-extern char *optarg;
-extern int optind;
 int bflag, ch, fd;
 int daggerset;
 
 /* options descriptor */
 static struct option longopts[] = {
-       { "buffy",      no_argument,            0,              'b' },
-       { "fluoride",   required_argument,      0,              'f' },
+       { "buffy",      no_argument,            NULL,           'b' },
+       { "fluoride",   required_argument,      NULL,           'f' },
        { "daggerset",  no_argument,            \*[Am]daggerset,        1 },
        { NULL,         0,                      NULL,           0 }
 };
@@ -299,31 +246,262 @@ while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
                bflag = 1;
                break;
        case 'f':
-               if ((fd = open(optarg, O_RDONLY, 0)) \*[Lt] 0) {
-                       (void)fprintf(stderr,
-                           "myname: %s: %s\en", optarg, strerror(errno));
-                       exit(1);
-               }
+               if ((fd = open(optarg, O_RDONLY, 0)) == -1)
+                       err(1, "unable to open %s", optarg);
                break;
        case 0:
-               if(daggerset) {
+               if (daggerset) {
                        fprintf(stderr,"Buffy will use her dagger to "
-                                      "apply fluoride to dracula's teeth\en");
+                           "apply fluoride to dracula's teeth\en");
                }
                break;
-       case '?':
        default:
                usage();
 }
 argc -= optind;
 argv += optind;
 .Ed
+.Sh IMPLEMENTATION DIFFERENCES
+This section describes differences to the
+.Tn GNU
+implementation
+found in glibc-2.1.3:
+.Bl -bullet
+.\" .It
+.\" Handling of
+.\" .Ql -
+.\" as first char of option string in presence of
+.\" environment variable
+.\" .Ev POSIXLY_CORRECT :
+.\" .Bl -tag -width ".Bx"
+.\" .It Tn GNU
+.\" ignores
+.\" .Ev POSIXLY_CORRECT
+.\" and returns non-options as
+.\" arguments to option '\e1'.
+.\" .It Bx
+.\" honors
+.\" .Ev POSIXLY_CORRECT
+.\" and stops at the first non-option.
+.\" .El
+.\" .It
+.\" Handling of
+.\" .Ql -
+.\" within the option string (not the first character):
+.\" .Bl -tag -width ".Bx"
+.\" .It Tn GNU
+.\" treats a
+.\" .Ql -
+.\" on the command line as a non-argument.
+.\" .It Bx
+.\" a
+.\" .Ql -
+.\" within the option string matches a
+.\" .Ql -
+.\" (single dash) on the command line.
+.\" This functionality is provided for backward compatibility with
+.\" programs, such as
+.\" .Xr su 1 ,
+.\" that use
+.\" .Ql -
+.\" as an option flag.
+.\" This practice is wrong, and should not be used in any current development.
+.\" .El
+.\" .It
+.\" Handling of
+.\" .Ql ::
+.\" in options string in presence of
+.\" .Ev POSIXLY_CORRECT :
+.\" .Bl -tag -width ".Bx"
+.\" .It Both
+.\" .Tn GNU
+.\" and
+.\" .Bx
+.\" ignore
+.\" .Ev POSIXLY_CORRECT
+.\" here and take
+.\" .Ql ::
+.\" to
+.\" mean the preceding option takes an optional argument.
+.\" .El
+.\" .It
+.\" Return value in case of missing argument if first character
+.\" (after
+.\" .Ql +
+.\" or
+.\" .Ql - )
+.\" in option string is not
+.\" .Ql \&: :
+.\" .Bl -tag -width ".Bx"
+.\" .It Tn GNU
+.\" returns
+.\" .Ql \&?
+.\" .It Bx
+.\" returns
+.\" .Ql \&:
+.\" (since
+.\" .Bx Ns 's
+.\" .Fn getopt
+.\" does).
+.\" .El
+.\" .It
+.\" Handling of
+.\" .Ql --a
+.\" in getopt:
+.\" .Bl -tag -width ".Bx"
+.\" .It Tn GNU
+.\" parses this as option
+.\" .Ql - ,
+.\" option
+.\" .Ql a .
+.\" .It Bx
+.\" parses this as
+.\" .Ql -- ,
+.\" and returns \-1 (ignoring the
+.\" .Ql a ) .
+.\" (Because the original
+.\" .Fn getopt
+.\" does.)
+.\" .El
+.It
+Setting of
+.Va optopt
+for long options with
+.Va flag
+!=
+.Dv NULL :
+.Bl -tag -width ".Bx"
+.It Tn GNU
+sets
+.Va optopt
+to
+.Va val .
+.It Bx
+sets
+.Va optopt
+to 0 (since
+.Va val
+would never be returned).
+.El
+.\" .It
+.\" Handling of
+.\" .Ql -W
+.\" with
+.\" .Ql W;
+.\" in option string in
+.\" .Fn getopt
+.\" (not
+.\" .Fn getopt_long ) :
+.\" .Bl -tag -width ".Bx"
+.\" .It Tn GNU
+.\" causes a segfault.
+.\" .It Bx
+.\" no special handling is done;
+.\" .Ql W;
+.\" is interpreted as two separate options, neither of which take an argument.
+.\" .El
+.It
+Setting of
+.Va optarg
+for long options without an argument that are
+invoked via
+.Ql -W
+.Ql ( W;
+in option string):
+.Bl -tag -width ".Bx"
+.It Tn GNU
+sets
+.Va optarg
+to the option name (the argument of
+.Ql -W ) .
+.It Bx
+sets
+.Va optarg
+to
+.Dv NULL
+(the argument of the long option).
+.El
+.It
+Handling of
+.Ql -W
+with an argument that is not (a prefix to) a known
+long option
+.Ql ( W;
+in option string):
+.Bl -tag -width ".Bx"
+.It Tn GNU
+returns
+.Ql -W
+with
+.Va optarg
+set to the unknown option.
+.It Bx
+treats this as an error (unknown option) and returns
+.Ql \&?
+with
+.Va optopt
+set to 0 and
+.Va optarg
+set to
+.Dv NULL
+(as
+.Tn GNU Ns 's
+man page documents).
+.El
+.\" .It
+.\" The error messages are different.
+.It
+.Bx
+does not permute the argument vector at the same points in
+the calling sequence as
+.Tn GNU
+does.
+The aspects normally used by
+the caller (ordering after \-1 is returned, value of
+.Va optind
+relative
+to current positions) are the same, though.
+(We do fewer variable swaps.)
+.El
 .Sh SEE ALSO
 .Xr getopt 3
 .Sh HISTORY
 The
 .Fn getopt_long
-function first appeared in GNU libiberty.
+and
+.Fn getopt_long_only
+functions first appeared in
+.Tn GNU
+libiberty.
 The first
-.Nx
-implementation appeared in 1.5.
+.Bx
+implementation of
+.Fn getopt_long
+appeared in
+.Nx 1.5 ,
+the first
+.Bx
+implementation of
+.Fn getopt_long_only
+in
+.Ox 3.3 .
+.Fx
+first included
+.Fn getopt_long
+in
+.Fx 5.0 ,
+.Fn getopt_long_only
+in
+.Fx 5.2 .
+.Sh BUGS
+The
+.Fa argv
+argument is not really
+.Vt const
+as its elements may be permuted (unless
+.Ev POSIXLY_CORRECT
+is set).
+.Pp
+The implementation can completely replace
+.Xr getopt 3 ,
+but right now we are using separate code.
index 68e6b14..e27326f 100644 (file)
@@ -1,6 +1,25 @@
-/*     $NetBSD: getopt_long.c,v 1.16 2003/10/27 00:12:42 lukem Exp $   */
-/*     $DragonFly: src/lib/libc/stdlib/getopt_long.c,v 1.14 2005/11/20 12:37:48 swildner Exp $ */
+/*     $OpenBSD: getopt_long.c,v 1.21 2006/09/22 17:22:05 millert Exp $        */
+/*     $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $      */
 
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.15 2006/09/23 14:48:31 ache Exp $
+ * $DragonFly: src/lib/libc/stdlib/getopt_long.c,v 1.14 2005/11/20 12:37:48 swildner Exp $
  */
 
-#include <sys/cdefs.h>
-
 #include <err.h>
 #include <errno.h>
 #include <getopt.h>
 #include <stdlib.h>
 #include <string.h>
 
-/* XXX BOOTSTRAPPING */
-#ifndef        __DECONST
-#define        __DECONST(type, var)    ((type)(uintptr_t)(const void *)(var))
+#define GNU_COMPATIBLE         /* Be more compatible, configure's use us! */
+
+#if 0                          /* we prefer to keep our getopt(3) */
+#define        REPLACE_GETOPT          /* use this getopt as the system getopt(3) */
 #endif
 
 #ifdef REPLACE_GETOPT
@@ -58,28 +79,33 @@ int optreset;               /* reset getopt */
 char    *optarg;               /* argument associated with option */
 #endif
 
-#define IGNORE_FIRST   (*options == '-' || *options == '+')
-#define PRINT_ERROR    ((opterr) && ((*options != ':') \
-                                     || (IGNORE_FIRST && options[1] != ':')))
-#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
-#define PERMUTE         (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
-/* XXX: GNU ignores PC if *options == '-' */
-#define IN_ORDER        (!IS_POSIXLY_CORRECT && *options == '-')
+#define PRINT_ERROR    ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE   0x01    /* permute non-options to the end of argv */
+#define FLAG_ALLARGS   0x02    /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY  0x04    /* operate as getopt_long_only */
 
 /* return values */
-#define        BADCH   (int)'?'
-#define        BADARG          ((IGNORE_FIRST && options[1] == ':') \
-                        || (*options == ':') ? (int)':' : (int)'?')
-#define INORDER (int)1
-
-static int getopt_internal(int, char * const *, const char *, int);
-static int getopt_internal_short(int, char * const *, const char *, int);
-static int getopt_long_internal(int, char * const *, const char *,
-                               const struct option *, int *, int);
+#define        BADCH           (int)'?'
+#define        BADARG          ((*options == ':') ? (int)':' : (int)'?')
+#define        INORDER         (int)1
+
+#define        EMSG            ""
+
+#ifdef GNU_COMPATIBLE
+#define NO_PREFIX      (-1)
+#define D_PREFIX       0
+#define DD_PREFIX      1
+#define W_PREFIX       2
+#endif
+
+static int getopt_internal(int, char * const *, const char *,
+                          const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+                             const struct option *, int *, int, int);
 static int gcd(int, int);
 static void permute_args(int, int, int, char * const *);
 
-static char EMSG[] = {0};
 static char *place = EMSG; /* option letter processing */
 
 /* XXX: set optreset to 1 rather than these two */
@@ -88,12 +114,21 @@ static int nonopt_end = -1;   /* first option after non options (for permute) */
 
 /* Error messages */
 static const char recargchar[] = "option requires an argument -- %c";
+static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
+#ifdef GNU_COMPATIBLE
+static int dash_prefix = NO_PREFIX;
+static const char gnuoptchar[] = "invalid option -- %c";
+
+static const char recargstring[] = "option `%s%s' requires an argument";
+static const char ambig[] = "option `%s%.*s' is ambiguous";
+static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
+static const char illoptstring[] = "unrecognized option `%s%s'";
+#else
 static const char recargstring[] = "option requires an argument -- %s";
 static const char ambig[] = "ambiguous option -- %.*s";
 static const char noarg[] = "option doesn't take an argument -- %.*s";
-static const char illoptchar[] = "unknown option -- %c";
 static const char illoptstring[] = "unknown option -- %s";
-
+#endif
 
 /*
  * Compute the greatest common divisor of a and b.
@@ -109,8 +144,8 @@ gcd(int a, int b)
                b = c;
                c = a % b;
        }
-          
-       return b;
+
+       return (b);
 }
 
 /*
@@ -150,25 +185,214 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,
        }
 }
 
+/*
+ * parse_long_options --
+ *     Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+       const struct option *long_options, int *idx, int short_too, int flags)
+{
+       char *current_argv, *has_equal;
+#ifdef GNU_COMPATIBLE
+       char *current_dash;
+#endif
+       size_t current_argv_len;
+       int i, match, exact_match, second_partial_match;
+
+       current_argv = place;
+#ifdef GNU_COMPATIBLE
+       switch (dash_prefix) {
+               case D_PREFIX:
+                       current_dash = "-";
+                       break;
+               case DD_PREFIX:
+                       current_dash = "--";
+                       break;
+               case W_PREFIX:
+                       current_dash = "-W ";
+                       break;
+               default:
+                       current_dash = "";
+                       break;
+       }
+#endif
+       match = -1;
+       exact_match = 0;
+       second_partial_match = 0;
+
+       optind++;
+
+       if ((has_equal = strchr(current_argv, '=')) != NULL) {
+               /* argument found (--option=arg) */
+               current_argv_len = has_equal - current_argv;
+               has_equal++;
+       } else
+               current_argv_len = strlen(current_argv);
+
+       for (i = 0; long_options[i].name; i++) {
+               /* find matching long option */
+               if (strncmp(current_argv, long_options[i].name,
+                   current_argv_len))
+                       continue;
+
+               if (strlen(long_options[i].name) == current_argv_len) {
+                       /* exact match */
+                       match = i;
+                       exact_match = 1;
+                       break;
+               }
+               /*
+                * If this is a known short option, don't allow
+                * a partial match of a single character.
+                */
+               if (short_too && current_argv_len == 1)
+                       continue;
+
+               if (match == -1)        /* first partial match */
+                       match = i;
+               else if ((flags & FLAG_LONGONLY) ||
+                        long_options[i].has_arg !=
+                            long_options[match].has_arg ||
+                        long_options[i].flag != long_options[match].flag ||
+                        long_options[i].val != long_options[match].val)
+                       second_partial_match = 1;
+       }
+       if (!exact_match && second_partial_match) {
+               /* ambiguous abbreviation */
+               if (PRINT_ERROR)
+                       warnx(ambig,
+#ifdef GNU_COMPATIBLE
+                            current_dash,
+#endif
+                            (int)current_argv_len,
+                            current_argv);
+               optopt = 0;
+               return (BADCH);
+       }
+       if (match != -1) {              /* option found */
+               if (long_options[match].has_arg == no_argument
+                   && has_equal) {
+                       if (PRINT_ERROR)
+                               warnx(noarg,
+#ifdef GNU_COMPATIBLE
+                                    current_dash,
+#endif
+                                    (int)current_argv_len,
+                                    current_argv);
+                       /*
+                        * XXX: GNU sets optopt to val regardless of flag
+                        */
+                       if (long_options[match].flag == NULL)
+                               optopt = long_options[match].val;
+                       else
+                               optopt = 0;
+#ifdef GNU_COMPATIBLE
+                       return (BADCH);
+#else
+                       return (BADARG);
+#endif
+               }
+               if (long_options[match].has_arg == required_argument ||
+                   long_options[match].has_arg == optional_argument) {
+                       if (has_equal)
+                               optarg = has_equal;
+                       else if (long_options[match].has_arg ==
+                           required_argument) {
+                               /*
+                                * optional argument doesn't use next nargv
+                                */
+                               optarg = nargv[optind++];
+                       }
+               }
+               if ((long_options[match].has_arg == required_argument)
+                   && (optarg == NULL)) {
+                       /*
+                        * Missing argument; leading ':' indicates no error
+                        * should be generated.
+                        */
+                       if (PRINT_ERROR)
+                               warnx(recargstring,
+#ifdef GNU_COMPATIBLE
+                                   current_dash,
+#endif
+                                   current_argv);
+                       /*
+                        * XXX: GNU sets optopt to val regardless of flag
+                        */
+                       if (long_options[match].flag == NULL)
+                               optopt = long_options[match].val;
+                       else
+                               optopt = 0;
+                       --optind;
+                       return (BADARG);
+               }
+       } else {                        /* unknown option */
+               if (short_too) {
+                       --optind;
+                       return (-1);
+               }
+               if (PRINT_ERROR)
+                       warnx(illoptstring,
+#ifdef GNU_COMPATIBLE
+                             current_dash,
+#endif
+                             current_argv);
+               optopt = 0;
+               return (BADCH);
+       }
+       if (idx)
+               *idx = match;
+       if (long_options[match].flag) {
+               *long_options[match].flag = long_options[match].val;
+               return (0);
+       } else
+               return (long_options[match].val);
+}
+
 /*
  * getopt_internal --
  *     Parse argc/argv argument vector.  Called by user level routines.
- *  Returns -2 if -- is found (can be long option or end of options marker).
  */
 static int
 getopt_internal(int nargc, char * const *nargv, const char *options,
-               int long_support)
+       const struct option *long_options, int *idx, int flags)
 {
-       optarg = NULL;
+       char *oli;                              /* option letter list index */
+       int optchar, short_too;
+       int posixly_correct;    /* no static, can be changed on the fly */
+
+       if (options == NULL)
+               return (-1);
+
+       /*
+        * Disable GNU extensions if POSIXLY_CORRECT is set or options
+        * string begins with a '+'.
+        */
+       posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+#ifdef GNU_COMPATIBLE
+       if (*options == '-')
+               flags |= FLAG_ALLARGS;
+       else if (posixly_correct || *options == '+')
+               flags &= ~FLAG_PERMUTE;
+#else
+       if (posixly_correct || *options == '+')
+               flags &= ~FLAG_PERMUTE;
+       else if (*options == '-')
+               flags |= FLAG_ALLARGS;
+#endif
+       if (*options == '+' || *options == '-')
+               options++;
 
        /*
-        * XXX Some programs (like rsyncd) expect to be able to
-        * XXX re-initialize optind to 0 and have getopt_long(3)
-        * XXX properly function again.  Work around this braindamage.
+        * XXX Some GNU programs (like cvs) set optind to 0 instead of
+        * XXX using optreset.  Work around this braindamage.
         */
        if (optind == 0)
-               optind = 1;
+               optind = optreset = 1;
 
+       optarg = NULL;
        if (optreset)
                nonopt_start = nonopt_end = -1;
 start:
@@ -190,29 +414,29 @@ start:
                                optind = nonopt_start;
                        }
                        nonopt_start = nonopt_end = -1;
-                       return -1;
+                       return (-1);
                }
-               place = nargv[optind];
-               if ((*place == '-') && (place[1] == '\0') && long_support == 0)
-                       return -1;
-               if ((*place != '-') ||
-                   ((*place == '-') && (place[1] == '\0') && long_support != 0)) {
-                       /* found non-option */
-                       place = EMSG;
-                       if (IN_ORDER) {
+               if (*(place = nargv[optind]) != '-' ||
+#ifdef GNU_COMPATIBLE
+                   place[1] == '\0') {
+#else
+                   (place[1] == '\0' && strchr(options, '-') == NULL)) {
+#endif
+                       place = EMSG;           /* found non-option */
+                       if (flags & FLAG_ALLARGS) {
                                /*
-                                * GNU extension: 
+                                * GNU extension:
                                 * return non-option as argument to option 1
                                 */
                                optarg = nargv[optind++];
-                               return INORDER;
+                               return (INORDER);
                        }
-                       if (!PERMUTE) {
+                       if (!(flags & FLAG_PERMUTE)) {
                                /*
-                                * if no permutation wanted, stop parsing
-                                * at first non-option
+                                * If no permutation wanted, stop parsing
+                                * at first non-option.
                                 */
-                               return -1;
+                               return (-1);
                        }
                        /* do permutation */
                        if (nonopt_start == -1)
@@ -230,72 +454,97 @@ start:
                }
                if (nonopt_start != -1 && nonopt_end == -1)
                        nonopt_end = optind;
-               if (place[1] && *++place == '-') {      /* found "--" */
-                       if (place[1] == '\0') {
-                               ++optind;
-                               /*
-                                * We found an option (--), so if we skipped
-                                * non-options, we have to permute.
-                                */
-                               if (nonopt_end != -1) {
-                                       permute_args(nonopt_start, nonopt_end,
-                                                    optind, nargv);
-                                       optind -= nonopt_end - nonopt_start;
-                               }
-                               nonopt_start = nonopt_end = -1;
-                               return -1;
-                       } else if (long_support) {
-                               place++;
-                               return -2;
+
+               /*
+                * If we have "-" do nothing, if "--" we are done.
+                */
+               if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+                       optind++;
+                       place = EMSG;
+                       /*
+                        * We found an option (--), so if we skipped
+                        * non-options, we have to permute.
+                        */
+                       if (nonopt_end != -1) {
+                               permute_args(nonopt_start, nonopt_end,
+                                   optind, nargv);
+                               optind -= nonopt_end - nonopt_start;
                        }
+                       nonopt_start = nonopt_end = -1;
+                       return (-1);
                }
        }
-       if (long_support == 2 && (place[1] || strchr(options, *place) == NULL))
-               return -3;
-       return getopt_internal_short(nargc, nargv, options, long_support);
-}
 
-static int
-getopt_internal_short(int nargc, char * const *nargv, const char *options,
-                     int long_support)
-{
-       const char *oli;                        /* option letter list index */
-       int optchar;
+       /*
+        * Check long options if:
+        *  1) we were passed some
+        *  2) the arg is not just "-"
+        *  3) either the arg starts with -- we are getopt_long_only()
+        */
+       if (long_options != NULL && place != nargv[optind] &&
+           (*place == '-' || (flags & FLAG_LONGONLY))) {
+               short_too = 0;
+#ifdef GNU_COMPATIBLE
+               dash_prefix = D_PREFIX;
+#endif
+               if (*place == '-') {
+                       place++;                /* --foo long option */
+#ifdef GNU_COMPATIBLE
+                       dash_prefix = DD_PREFIX;
+#endif
+               } else if (*place != ':' && strchr(options, *place) != NULL)
+                       short_too = 1;          /* could be short option too */
 
-       if ((optchar = (int)*place++) == (int)':' ||
-           (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
-               /* option letter unknown or ':' */
-               if (PRINT_ERROR) {
-                       if (long_support == 2)
-                               warnx(illoptstring, --place);
-                       else
-                               warnx(illoptchar, optchar);
-               }
-               if (long_support == 2)
+               optchar = parse_long_options(nargv, options, long_options,
+                   idx, short_too, flags);
+               if (optchar != -1) {
                        place = EMSG;
-               if (*place == 0)
+                       return (optchar);
+               }
+       }
+
+       if ((optchar = (int)*place++) == (int)':' ||
+           (optchar == (int)'-' && *place != '\0') ||
+           (oli = strchr(options, optchar)) == NULL) {
+               /*
+                * If the user specified "-" and  '-' isn't listed in
+                * options, return -1 (non-option) as per POSIX.
+                * Otherwise, it is an unknown option character (or ':').
+                */
+               if (optchar == (int)'-' && *place == '\0')
+                       return (-1);
+               if (!*place)
                        ++optind;
+#ifdef GNU_COMPATIBLE
+               if (PRINT_ERROR)
+                       warnx(posixly_correct ? illoptchar : gnuoptchar,
+                             optchar);
+#else
+               if (PRINT_ERROR)
+                       warnx(illoptchar, optchar);
+#endif
                optopt = optchar;
-               return BADCH;
+               return (BADCH);
        }
-       if (long_support && optchar == 'W' && oli[1] == ';') {
+       if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
                /* -W long-option */
-               if (*place) 
-                       return -2;
-
-               if (++optind >= nargc) {        /* no arg */
+               if (*place)                     /* no space */
+                       /* NOTHING */;
+               else if (++optind >= nargc) {   /* no arg */
                        place = EMSG;
                        if (PRINT_ERROR)
                                warnx(recargchar, optchar);
                        optopt = optchar;
-                       return BADARG;
+                       return (BADARG);
                } else                          /* white space */
                        place = nargv[optind];
-               /*
-                * Handle -W arg the same as --arg (which causes getopt to
-                * stop parsing).
-                */
-               return -2;
+#ifdef GNU_COMPATIBLE
+               dash_prefix = W_PREFIX;
+#endif
+               optchar = parse_long_options(nargv, options, long_options,
+                   idx, 0, flags);
+               place = EMSG;
+               return (optchar);
        }
        if (*++oli != ':') {                    /* doesn't take argument */
                if (!*place)
@@ -304,14 +553,13 @@ getopt_internal_short(int nargc, char * const *nargv, const char *options,
                optarg = NULL;
                if (*place)                     /* no white space */
                        optarg = place;
-               /* XXX: disable test for :: if PC? (GNU doesn't) */
                else if (oli[1] != ':') {       /* arg not optional */
                        if (++optind >= nargc) {        /* no arg */
                                place = EMSG;
                                if (PRINT_ERROR)
                                        warnx(recargchar, optchar);
                                optopt = optchar;
-                               return BADARG;
+                               return (BADARG);
                        } else
                                optarg = nargv[optind];
                }
@@ -319,129 +567,7 @@ getopt_internal_short(int nargc, char * const *nargv, const char *options,
                ++optind;
        }
        /* dump back option letter */
-       return optchar;
-}
-
-static int
-getopt_long_internal(int nargc, char * const *nargv, const char *options,
-                    const struct option *long_options, int *idx, int long_only)
-{
-       int retval;
-
-       /* idx may be NULL */
-
-       retval = getopt_internal(nargc, nargv, options, long_only ? 2 : 1);
-recheck:
-       if (retval == -2 || retval == -3) {
-               char *current_argv, *has_equal;
-               size_t current_argv_len;
-               int i, match;
-
-               current_argv = place;
-               match = -1;
-
-               optind++;
-               place = EMSG;
-
-               if ((has_equal = strchr(current_argv, '=')) != NULL) {
-                       /* argument found (--option=arg) */
-                       current_argv_len = has_equal - current_argv;
-                       has_equal++;
-               } else
-                       current_argv_len = strlen(current_argv);
-           
-               for (i = 0; long_options[i].name; i++) {
-                       /* find matching long option */
-                       if (strncmp(current_argv, long_options[i].name,
-                           current_argv_len))
-                               continue;
-
-                       if (strlen(long_options[i].name) ==
-                           (unsigned)current_argv_len) {
-                               /* exact match */
-                               match = i;
-                               break;
-                       }
-                       if (match == -1)                /* partial match */
-                               match = i;
-                       else {
-                               /* ambiguous abbreviation */
-                               if (PRINT_ERROR)
-                                       warnx(ambig, (int)current_argv_len,
-                                            current_argv);
-                               optopt = 0;
-                               return BADCH;
-                       }
-               }
-               if (match != -1) {                      /* option found */
-                       if (long_options[match].has_arg == no_argument
-                           && has_equal) {
-                               if (PRINT_ERROR)
-                                       warnx(noarg, (int)current_argv_len,
-                                            current_argv);
-                               /*
-                                * XXX: GNU sets optopt to val regardless of
-                                * flag
-                                */
-                               if (long_options[match].flag == NULL)
-                                       optopt = long_options[match].val;
-                               else
-                                       optopt = 0;
-                               return BADARG;
-                       }
-                       if (long_options[match].has_arg == required_argument ||
-                           long_options[match].has_arg == optional_argument) {
-                               if (has_equal)
-                                       optarg = has_equal;
-                               else if (long_options[match].has_arg ==
-                                   required_argument) {
-                                       /*
-                                        * optional argument doesn't use
-                                        * next nargv
-                                        */
-                                       optarg = nargv[optind++];
-                               }
-                       }
-                       if ((long_options[match].has_arg == required_argument)
-                           && (optarg == NULL)) {
-                               /*
-                                * Missing argument; leading ':'
-                                * indicates no error should be generated
-                                */
-                               if (PRINT_ERROR)
-                                       warnx(recargstring, current_argv);
-                               /*
-                                * XXX: GNU sets optopt to val regardless
-                                * of flag
-                                */
-                               if (long_options[match].flag == NULL)
-                                       optopt = long_options[match].val;
-                               else
-                                       optopt = 0;
-                               --optind;
-                               return BADARG;
-                       }
-               } else if (retval == -3) {
-                       --optind;
-                       place = current_argv;
-                       retval = getopt_internal_short(nargc, nargv,
-                           options, long_only ? 2 : 1);
-                       goto recheck;
-               } else {                        /* unknown option */
-                       if (PRINT_ERROR)
-                               warnx(illoptstring, current_argv);
-                       optopt = 0;
-                       return BADCH;
-               }
-               if (long_options[match].flag) {
-                       *long_options[match].flag = long_options[match].val;
-                       retval = 0;
-               } else 
-                       retval = long_options[match].val;
-               if (idx)
-                       *idx = match;
-       }
-       return retval;
+       return (optchar);
 }
 
 #ifdef REPLACE_GETOPT
@@ -449,38 +575,46 @@ recheck:
  * getopt --
  *     Parse argc/argv argument vector.
  *
- * [eventually this will replace the real getopt]
+ * [eventually this will replace the BSD getopt]
  */
 int
 getopt(int nargc, char * const *nargv, const char *options)
 {
-       return getopt_internal(nargc, nargv, options, 0);
+
+       /*
+        * We don't pass FLAG_PERMUTE to getopt_internal() since
+        * the BSD getopt(3) (unlike GNU) has never done this.
+        *
+        * Furthermore, since many privileged programs call getopt()
+        * before dropping privileges it makes sense to keep things
+        * as simple (and bug-free) as possible.
+        */
+       return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
 }
-#endif
+#endif /* REPLACE_GETOPT */
 
 /*
  * getopt_long --
  *     Parse argc/argv argument vector.
  */
-
 int
 getopt_long(int nargc, char * const *nargv, const char *options,
-           const struct option *long_options, int *idx)
+       const struct option *long_options, int *idx)
 {
-       return getopt_long_internal(nargc, nargv, options, long_options,
-                                   idx, 0);
+
+       return (getopt_internal(nargc, nargv, options, long_options, idx,
+           FLAG_PERMUTE));
 }
 
 /*
  * getopt_long_only --
  *     Parse argc/argv argument vector.
- *     Prefers long options over short options for single dash arguments.
  */
-
 int
 getopt_long_only(int nargc, char * const *nargv, const char *options,
-                const struct option *long_options, int *idx)
+       const struct option *long_options, int *idx)
 {
-       return getopt_long_internal(nargc, nargv, options, long_options,
-                                   idx, 1);
+
+       return (getopt_internal(nargc, nargv, options, long_options, idx,
+           FLAG_PERMUTE|FLAG_LONGONLY));
 }
index 059a751..e467495 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -30,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getsubopt.3        8.1 (Berkeley) 6/9/93
-.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.5.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/getsubopt.3,v 1.11 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/getsubopt.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 9, 1993
@@ -42,7 +38,7 @@
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
-.In unistd.h
+.In stdlib.h
 .Vt extern char *suboptarg ;
 .Ft int
 .Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
index fa0f0eb..57faadb 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/lib/libc/stdlib/getsubopt.c,v 1.4 2005/11/20 12:37:48 swildner Exp $
- *
  * @(#)getsubopt.c     8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/getsubopt.c,v 1.7 2007/01/09 00:28:10 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/getsubopt.c,v 1.4 2005/11/20 12:37:48 swildner Exp $
  */
 
-#include <string.h>
-#include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 
 /*
  * The SVID interface to getsubopt provides no way of figuring out which
index 5d31269..cfa5991 100644 (file)
@@ -1,7 +1,35 @@
-.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.2.2.2 2003/04/05 13:53:05 dwmalone Exp $
+.\"-
+.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Klaus Klein.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.7 2008/07/06 17:03:37 danger Exp $
 .\" $DragonFly: src/lib/libc/stdlib/hcreate.3,v 1.5 2006/05/26 19:39:37 swildner Exp $
 .\"
-.Dd May 8, 2001
+.Dd July 6, 2008
 .Os
 .Dt HCREATE 3
 .Sh NAME
@@ -114,8 +142,10 @@ is called.
 .Sh RETURN VALUES
 The
 .Fn hcreate
-function returns 0 if it cannot allocate sufficient space for the table;
-otherwise, it returns non-zero.
+function returns 0 if the table creation failed and the global variable
+.Va errno
+is set to indicate the error;
+otherwise, a non-zero value is returned.
 .Pp
 The
 .Fn hdestroy
@@ -202,6 +232,8 @@ functions may fail if:
 .Bl -tag -width Er
 .It Bq Er ENOMEM
 Insufficient storage space is available.
+.It Bq Er EINVAL
+A table already exists.
 .El
 .Sh SEE ALSO
 .Xr bsearch 3 ,
index 4ded5ae..2d542e8 100644 (file)
@@ -32,7 +32,7 @@
  * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
  *
  * $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $
- * $FreeBSD: src/lib/libc/stdlib/hcreate.c,v 1.1.2.2 2001/10/02 11:22:56 ru Exp $
+ * $FreeBSD: src/lib/libc/stdlib/hcreate.c,v 1.4 2008/07/06 11:31:20 danger Exp $
  * $DragonFly: src/lib/libc/stdlib/hcreate.c,v 1.2 2003/06/17 04:26:46 dillon Exp $
  */
 
@@ -48,8 +48,6 @@
  * nobody had a copy in the office, so...
  */
 
-#include <sys/cdefs.h>
-
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <errno.h>
@@ -89,7 +87,7 @@ hcreate(size_t nel)
        size_t idx;
        unsigned int p2;
 
-       /* Make sure this this isn't called when a table already exists. */
+       /* Make sure this is not called when a table already exists. */
        if (htable != NULL) {
                errno = EINVAL;
                return 0;
@@ -99,11 +97,11 @@ hcreate(size_t nel)
        if (nel < MIN_BUCKETS)
                nel = MIN_BUCKETS;
 
-       /* If it's too large, cap it. */
+       /* If it is too large, cap it. */
        if (nel > MAX_BUCKETS)
                nel = MAX_BUCKETS;
 
-       /* If it's is not a power of two in size, round up. */
+       /* If it is not a power of two in size, round up. */
        if ((nel & (nel - 1)) != 0) {
                for (p2 = 0; nel != 0; p2++)
                        nel >>= 1;
index 71845de..02d3fd0 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -33,9 +29,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/lib/libc/stdlib/heapsort.c,v 1.5 2005/11/20 12:37:48 swildner Exp $
- *
  * @(#)heapsort.c      8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/heapsort.c,v 1.6 2008/01/13 02:11:10 das Exp $
+ * $DragonFly: src/lib/libc/stdlib/heapsort.c,v 1.5 2005/11/20 12:37:48 swildner Exp $
  */
 
 #include <errno.h>
@@ -141,7 +137,7 @@ int
 heapsort(void *vbase, size_t nmemb, size_t size,
         int (*compar)(const void *, const void *))
 {
-       int cnt, i, j, l;
+       size_t cnt, i, j, l;
        char tmp, *tmp1, *tmp2;
        char *base, *k, *p, *t;
 
diff --git a/lib/libc/stdlib/insque.3 b/lib/libc/stdlib/insque.3
new file mode 100644 (file)
index 0000000..06f93bf
--- /dev/null
@@ -0,0 +1,61 @@
+.\"
+.\" Initial implementation:
+.\" Copyright (c) 2002 Robert Drehmel
+.\" All rights reserved.
+.\"
+.\" As long as the above copyright statement and this notice remain
+.\" unchanged, you can do what ever you want with this file.
+.\"
+.\" $FreeBSD: src/lib/libc/stdlib/insque.3,v 1.3 2003/02/25 21:59:36 robert Exp $
+.\"
+.Dd October 10, 2002
+.Dt INSQUE 3
+.Os
+.Sh NAME
+.Nm insque ,
+.Nm remque
+.Nd doubly-linked list management
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In search.h
+.Ft void
+.Fn insque "void *element1" "void *pred"
+.Ft void
+.Fn remque "void *element"
+.Sh DESCRIPTION
+The
+.Fn insque
+and
+.Fn remque
+functions encapsulate the ever-repeating task of doing insertion and
+removal operations on doubly linked lists.
+The functions expect their
+arguments to point to a structure whose first and second members are
+pointers to the next and previous element, respectively.
+The
+.Fn insque
+function also allows the
+.Fa pred
+argument to be a
+.Dv NULL
+pointer for the initialization of a new list's
+head element.
+.Sh STANDARDS
+The
+.Fn insque
+and
+.Fn remque
+functions conform to
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Fn insque
+and
+.Fn remque
+functions appeared in
+.Bx 4.2 .
+In
+.Fx 5.0 ,
+they reappeared conforming to
+.St -p1003.1-2001 .
diff --git a/lib/libc/stdlib/insque.c b/lib/libc/stdlib/insque.c
new file mode 100644 (file)
index 0000000..d98400d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Initial implementation:
+ * Copyright (c) 2002 Robert Drehmel
+ * All rights reserved.
+ *
+ * As long as the above copyright statement and this notice remain
+ * unchanged, you can do what ever you want with this file.
+ *
+ * $FreeBSD: src/lib/libc/stdlib/insque.c,v 1.3 2003/01/04 07:34:41 tjr Exp $
+ */
+
+#define        _SEARCH_PRIVATE
+#include <search.h>
+#ifdef DEBUG
+#include <stdio.h>
+#else
+#include <stdlib.h>    /* for NULL */
+#endif
+
+void
+insque(void *element, void *pred)
+{
+       struct que_elem *prev, *next, *elem;
+
+       elem = (struct que_elem *)element;
+       prev = (struct que_elem *)pred;
+
+       if (prev == NULL) {
+               elem->prev = elem->next = NULL;
+               return;
+       }
+
+       next = prev->next;
+       if (next != NULL) {
+#ifdef DEBUG
+               if (next->prev != prev) {
+                       fprintf(stderr, "insque: Inconsistency detected:"
+                           " next(%p)->prev(%p) != prev(%p)\n",
+                           next, next->prev, prev);
+               }
+#endif
+               next->prev = elem;
+       }
+       prev->next = elem;
+       elem->prev = prev;
+       elem->next = next;
+}
diff --git a/lib/libc/stdlib/l64a.c b/lib/libc/stdlib/l64a.c
new file mode 100644 (file)
index 0000000..d3fc949
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ *
+ * $NetBSD: l64a.c,v 1.13 2003/07/26 19:24:54 salo Exp $
+ * $FreeBSD: src/lib/libc/stdlib/l64a.c,v 1.1 2005/12/24 22:37:59 trhodes Exp $
+ */
+
+#include <stdlib.h>
+
+char *
+l64a(long value)
+{
+       static char buf[8];
+
+       l64a_r(value, buf, sizeof(buf));
+       return (buf);
+}
+
+int
+l64a_r(long value, char *buffer, int buflen)
+{
+       long v;
+       int digit;
+
+       v = value & (long)0xffffffff;
+       for (; v != 0 && buflen > 1; buffer++, buflen--) {
+               digit = v & 0x3f;
+               if (digit < 2)
+                       *buffer = digit + '.';
+               else if (digit < 12)
+                       *buffer = digit + '0' - 2;
+               else if (digit < 38)
+                       *buffer = digit + 'A' - 12;
+               else
+                       *buffer = digit + 'a' - 38;
+               v >>= 6;
+       }
+       return (v == 0 ? 0 : -1);
+}
index 6159757..9fd70de 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)labs.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.4.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/labs.3,v 1.10 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/labs.3,v 1.3 2007/12/02 03:29:47 swildner Exp $
 .\"
-.Dd June 4, 1993
+.Dd November 14, 2001
 .Dt LABS 3
 .Os
 .Sh NAME
@@ -54,7 +50,7 @@ The
 .Fn labs
 function
 returns the absolute value of the long integer
-.Ar j .
+.Fa j .
 .Sh SEE ALSO
 .Xr abs 3 ,
 .Xr cabs 3 ,
index 27d83df..a30d8ee 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -31,6 +27,7 @@
  * SUCH DAMAGE.
  *
  * @(#)labs.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/labs.c,v 1.3 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/labs.c,v 1.3 2005/11/20 12:37:48 swildner Exp $
  */
 
index 49e8266..e66b68b 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)ldiv.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.4.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/ldiv.3,v 1.10 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/ldiv.3,v 1.3 2008/01/25 23:24:31 swildner Exp $
 .\"
-.Dd June 4, 1993
+.Dd November 14, 2001
 .Dt LDIV 3
 .Os
 .Sh NAME
@@ -54,15 +50,15 @@ The
 .Fn ldiv
 function
 computes the value
-.Ar num/denom
+.Fa num Ns / Ns Fa denom
 and returns the quotient and remainder in a structure named
-.Ar ldiv_t
+.Vt ldiv_t
 that contains two
-.Em long integer
+.Vt long
 members named
-.Ar quot
+.Va quot
 and
-.Ar rem .
+.Va rem .
 .Sh SEE ALSO
 .Xr div 3 ,
 .Xr imaxdiv 3 ,
@@ -73,4 +69,4 @@ The
 .Fn ldiv
 function
 conforms to
-.St -isoC .
+.St -isoC-99 .
index 49f82d1..355e6b2 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -34,6 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)ldiv.c  8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/ldiv.c,v 1.3 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/ldiv.c,v 1.4 2005/11/23 08:55:59 swildner Exp $
  */
 
index 42c1ca8..88c6b6a 100644 (file)
@@ -6,10 +6,10 @@
  * As long as the above copyright statement and this notice remain
  * unchanged, you can do what ever you want with this file. 
  *
+ * $FreeBSD: src/lib/libc/stdlib/lsearch.c,v 1.1 2002/10/16 14:29:22 robert Exp $
  * $DragonFly: src/lib/libc/stdlib/lsearch.c,v 1.1 2008/05/19 10:06:34 corecode Exp $
  */
 #include <sys/types.h>
-#include <sys/cdefs.h>
 
 #define        _SEARCH_PRIVATE
 #include <search.h>
index f65c34f..71fedc0 100644 (file)
@@ -447,8 +447,6 @@ malloc_dump(int fd)
 }
 #endif /* MALLOC_STATS */
 
-extern char    *__progname;
-
 static void
 wrterror(char *p)
 {
index e2fc987..fa57107 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -30,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)memory.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.5.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/memory.3,v 1.12 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/memory.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 4, 1993
@@ -41,7 +37,8 @@
 .Nm free ,
 .Nm realloc ,
 .Nm calloc ,
-.Nm alloca
+.Nm alloca ,
+.Nm mmap
 .Nd general memory allocation operations
 .Sh LIBRARY
 .Lb libc
 .Fn calloc "size_t nelem" "size_t elsize"
 .Ft void *
 .Fn alloca "size_t size"
+.In sys/types.h
+.In sys/mman.h
+.Ft void *
+.Fn mmap "void * addr" "size_t len" "int prot" "int flags" "int fd" "off_t offset"
 .Sh DESCRIPTION
 These functions allocate and free memory for the calling process.
 They are described in the
 individual manual pages.
 .Sh SEE ALSO
+.Xr mmap 2 ,
 .Xr alloca 3 ,
 .Xr calloc 3 ,
 .Xr free 3 ,
@@ -70,5 +72,7 @@ individual manual pages.
 .Sh STANDARDS
 These functions, with the exception of
 .Fn alloca
+and
+.Fn mmap
 conform to
 .St -isoC .
index 3a7ad9d..12c5153 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -34,6 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)merge.c 8.2 (Berkeley) 2/14/94
+ * $FreeBSD: src/lib/libc/stdlib/merge.c,v 1.8 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/merge.c,v 1.6 2005/11/20 12:37:48 swildner Exp $
  */
 
@@ -100,7 +97,7 @@ mergesort(void *base, size_t nmemb, size_t size,
          int (*cmp)(const void *, const void *))
 {
        size_t i;
-       int  sense;
+       int sense;
        int big, iflag;
        u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
        u_char *list2, *list1, *p2, *p, *last, **p1;
diff --git a/lib/libc/stdlib/putenv.c b/lib/libc/stdlib/putenv.c
deleted file mode 100644 (file)
index da524ac..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1988, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)putenv.c        8.2 (Berkeley) 3/27/94
- * $DragonFly: src/lib/libc/stdlib/putenv.c,v 1.3 2005/11/20 12:37:49 swildner Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-int
-putenv(const char *str)
-{
-       char *p, *equal;
-       int rval;
-
-       if ((p = strdup(str)) == NULL)
-               return (-1);
-       if ((equal = index(p, '=')) == NULL) {
-               free(p);
-               return (-1);
-       }
-       *equal = '\0';
-       rval = setenv(p, equal + 1, 1);
-       free(p);
-       return (rval);
-}
index a0c143f..cfa7338 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)qsort.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.4.2.5 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/qsort.3,v 1.17 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/qsort.3,v 1.4 2006/02/17 19:35:06 swildner Exp $
 .\"
-.Dd June 4, 1993
+.Dd September 30, 2003
 .Dt QSORT 3
 .Os
 .Sh NAME
 .Nm qsort ,
+.Nm qsort_r ,
 .Nm heapsort ,
 .Nm mergesort
 .Nd sort functions
 .Sh SYNOPSIS
 .In stdlib.h
 .Ft void
-.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Fo qsort
+.Fa "void *base"
+.Fa "size_t nmemb"
+.Fa "size_t size"
+.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
+.Fc
+.Ft void
+.Fo qsort_r
+.Fa "void *base"
+.Fa "size_t nmemb"
+.Fa "size_t size"
+.Fa "void *thunk"
+.Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]"
+.Fc
 .Ft int
-.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Fo heapsort
+.Fa "void *base"
+.Fa "size_t nmemb"
+.Fa "size_t size"
+.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
+.Fc
 .Ft int
-.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
+.Fo mergesort
+.Fa "void *base"
+.Fa "size_t nmemb"
+.Fa "size_t size"
+.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn qsort
@@ -77,7 +97,9 @@ objects, the initial member of which is pointed to by
 .Fa base .
 The size of each object is specified by
 .Fa size .
-.Fn Mergesort
+The
+.Fn mergesort
+function
 behaves similarly, but
 .Em requires
 that
@@ -97,33 +119,58 @@ The comparison function must return an integer less than, equal to, or
 greater than zero if the first argument is considered to be respectively
 less than, equal to, or greater than the second.
 .Pp
-The functions
-.Fn qsort
+The
+.Fn qsort_r
+function behaves identically to
+.Fn qsort ,
+except that it takes an additional argument,
+.Fa thunk ,
+which is passed unchanged as the first argument to function pointed to
+.Fa compar .
+This allows the comparison function to access additional
+data without using global variables, and thus
+.Fn qsort_r
+is suitable for use in functions which must be reentrant.
+.Pp
+The algorithms implemented by
+.Fn qsort ,
+.Fn qsort_r ,
 and
 .Fn heapsort
 are
 .Em not
 stable, that is, if two members compare as equal, their order in
 the sorted array is undefined.
-The function
+The
 .Fn mergesort
-is stable.
+algorithm is stable.
 .Pp
 The
 .Fn qsort
-function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm,
-a variant of partition-exchange sorting; in particular, see D.E. Knuth's
-Algorithm Q.
-.Fn Qsort
+and
+.Fn qsort_r
+functions are an implementation of C.A.R.
+Hoare's
+.Dq quicksort
+algorithm,
+a variant of partition-exchange sorting; in particular, see
+.An D.E. Knuth Ns 's
+.%T "Algorithm Q" .
+.Sy Quicksort
 takes O N lg N average time.
 This implementation uses median selection to avoid its
 O N**2 worst-case behavior.
 .Pp
 The
 .Fn heapsort
-function is an implementation of J.W.J. William's ``heapsort'' algorithm,
-a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
-.Fn Heapsort
+function is an implementation of
+.An "J.W.J. William" Ns 's
+.Dq heapsort
+algorithm,
+a variant of selection sorting; in particular, see
+.An "D.E. Knuth" Ns 's
+.%T "Algorithm H" .
+.Sy Heapsort
 takes O N lg N worst-case time.
 Its
 .Em only
@@ -139,7 +186,9 @@ requires additional memory of size
 .Fa nmemb *
 .Fa size
 bytes; it should be used only when space is not at a premium.
-.Fn Mergesort
+The
+.Fn mergesort
+function
 is optimized for data with pre-existing order; its worst case
 time is O N lg N; its best case is O N.
 .Pp
@@ -154,8 +203,10 @@ untrue.
 .Sh RETURN VALUES
 The
 .Fn qsort
-function
-returns no value.
+and
+.Fn qsort_r
+functions
+return no value.
 .Pp
 .Rv -std heapsort mergesort
 .Sh COMPATIBILITY
@@ -182,9 +233,11 @@ argument to
 is less than
 .Dq "sizeof(void *) / 2" .
 .It Bq Er ENOMEM
-.Fn Heapsort
+The
+.Fn heapsort
 or
 .Fn mergesort
+functions
 were unable to allocate memory.
 .El
 .Sh SEE ALSO
@@ -215,16 +268,19 @@ were unable to allocate memory.
 .%P pp. 114-123, 145-149
 .Re
 .Rs
-.%A Mcilroy, P.M.
+.%A McIlroy, P.M.
 .%T "Optimistic Sorting and Information Theoretic Complexity"
 .%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
 .%V January 1992
 .Re
 .Rs
 .%A Bentley, J.L.
+.%A McIlroy, M.D.
 .%T "Engineering a Sort Function"
-.%J "bentley@research.att.com"
-.%V January 1992
+.%J "Software--Practice and Experience"
+.%V Vol. 23(11)
+.%P pp. 1249-1265
+.%D November\ 1993
 .Re
 .Sh STANDARDS
 The
index e5e6a3e..214b701 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  *
  * @(#)qsort.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.8 1999/08/28 00:01:35 peter Exp $
+ * $FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15 2008/01/14 09:21:34 das Exp $
  * $DragonFly: src/lib/libc/stdlib/qsort.c,v 1.5 2005/11/20 12:37:49 swildner Exp $
  */
 
 #include <stdlib.h>
 
-typedef int             cmp_t (const void *, const void *);
-static inline char     *med3 (char *, char *, char *, cmp_t *);
-static inline void      swapfunc (char *, char *, int, int);
+#ifdef I_AM_QSORT_R
+typedef int             cmp_t(void *, const void *, const void *);
+#else
+typedef int             cmp_t(const void *, const void *);
+#endif
+static inline char     *med3(char *, char *, char *, cmp_t *, void *);
+static inline void      swapfunc(char *, char *, int, int);
 
 #define min(a, b)      (a) < (b) ? a : b
 
@@ -79,25 +79,44 @@ swapfunc(char *a, char *b, int n, int swaptype)
 
 #define vecswap(a, b, n)       if ((n) > 0) swapfunc(a, b, n, swaptype)
 
+#ifdef I_AM_QSORT_R
+#define        CMP(t, x, y) (cmp((t), (x), (y)))
+#else
+#define        CMP(t, x, y) (cmp((x), (y)))
+#endif
+
 static inline char *
-med3(char *a, char *b, char *c, cmp_t *cmp)
+med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
+#ifndef I_AM_QSORT_R
+__unused
+#endif
+)
 {
-       return cmp(a, b) < 0 ?
-              (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
-              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
+       return CMP(thunk, a, b) < 0 ?
+              (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
+              :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
 }
 
+#ifdef I_AM_QSORT_R
+void
+qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
+#else
+#define thunk NULL
 void
 qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+#endif
 {
        char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
-       int d, r, swaptype, swap_cnt;
+       size_t d, r;
+       int cmp_result;
+       int swaptype, swap_cnt;
 
 loop:  SWAPINIT(a, es);
        swap_cnt = 0;
        if (n < 7) {
                for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
-                       for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
+                       for (pl = pm;
+                            pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
                             pl -= es)
                                swap(pl, pl - es);
                return;
@@ -108,27 +127,27 @@ loop:     SWAPINIT(a, es);
                pn = (char *)a + (n - 1) * es;
                if (n > 40) {
                        d = (n / 8) * es;
-                       pl = med3(pl, pl + d, pl + 2 * d, cmp);
-                       pm = med3(pm - d, pm, pm + d, cmp);
-                       pn = med3(pn - 2 * d, pn - d, pn, cmp);
+                       pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
+                       pm = med3(pm - d, pm, pm + d, cmp, thunk);
+                       pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
                }
-               pm = med3(pl, pm, pn, cmp);
+               pm = med3(pl, pm, pn, cmp, thunk);
        }
        swap(a, pm);
        pa = pb = (char *)a + es;
 
        pc = pd = (char *)a + (n - 1) * es;
        for (;;) {
-               while (pb <= pc && (r = cmp(pb, a)) <= 0) {
-                       if (r == 0) {
+               while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
+                       if (cmp_result == 0) {
                                swap_cnt = 1;
                                swap(pa, pb);
                                pa += es;
                        }
                        pb += es;
                }
-               while (pb <= pc && (r = cmp(pc, a)) >= 0) {
-                       if (r == 0) {
+               while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
+                       if (cmp_result == 0) {
                                swap_cnt = 1;
                                swap(pc, pd);
                                pd -= es;
@@ -144,7 +163,8 @@ loop:       SWAPINIT(a, es);
        }
        if (swap_cnt == 0) {  /* Switch to insertion sort */
                for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
-                       for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
+                       for (pl = pm;
+                            pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
                             pl -= es)
                                swap(pl, pl - es);
                return;
@@ -156,7 +176,11 @@ loop:      SWAPINIT(a, es);
        r = min(pd - pc, pn - pd - es);
        vecswap(pb, pn - r, r);
        if ((r = pb - pa) > es)
+#ifdef I_AM_QSORT_R
+               qsort_r(a, r / es, es, thunk, cmp);
+#else
                qsort(a, r / es, es, cmp);
+#endif
        if ((r = pd - pc) > es) {
                /* Iterate rather than recurse to save stack space */
                a = pn - r;
diff --git a/lib/libc/stdlib/qsort_r.c b/lib/libc/stdlib/qsort_r.c
new file mode 100644 (file)
index 0000000..f7c0e54
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * This file is in the public domain.  Originally written by Garrett
+ * A. Wollman.
+ *
+ * $FreeBSD: src/lib/libc/stdlib/qsort_r.c,v 1.1 2002/09/10 02:04:49 wollman Exp $
+ */
+#define I_AM_QSORT_R
+#include "qsort.c"
index 5d77618..1a57076 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)radixsort.3        8.2 (Berkeley) 1/27/94
-.\" $FreeBSD: src/lib/libc/stdlib/radixsort.3,v 1.5.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/radixsort.3,v 1.12 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/radixsort.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd January 27, 1994
 .Dt RADIXSORT 3
 .Os
 .Sh NAME
-.Nm radixsort
+.Nm radixsort ,
+.Nm sradixsort
 .Nd radix sort
 .Sh LIBRARY
 .Lb libc
@@ -106,7 +103,10 @@ The
 function is not stable, but uses no additional memory.
 .Pp
 These functions are variants of most-significant-byte radix sorting; in
-particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
+particular, see
+.An "D.E. Knuth" Ns 's
+.%T "Algorithm R"
+and section 5.2.5, exercise 10.
 They take linear time relative to the number of bytes in the strings.
 .Sh RETURN VALUES
 .Rv -std radixsort
index 51c9fe9..aeb3c27 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -33,9 +29,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/lib/libc/stdlib/radixsort.c,v 1.5 2005/11/20 12:37:49 swildner Exp $
- *
  * @(#)radixsort.c     8.2 (Berkeley) 4/28/95
+ * $FreeBSD: src/lib/libc/stdlib/radixsort.c,v 1.8 2007/01/09 00:28:10 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/radixsort.c,v 1.5 2005/11/20 12:37:49 swildner Exp $
  */
 
 /*
@@ -61,11 +57,10 @@ typedef struct {
        int sn, si;
 } stack;
 
-static inline void simplesort
-           (const u_char **, int, int, const u_char *, u_int);
-static void r_sort_a (const u_char **, int, int, const u_char *, u_int);
-static void r_sort_b (const u_char **,
-           const u_char **, int, int, const u_char *, u_int);
+static inline void simplesort(const u_char **, int, int, const u_char *, u_int);
+static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
+static void r_sort_b(const u_char **, const u_char **, int, int,
+                    const u_char *, u_int);
 
 #define        THRESHOLD       20              /* Divert to simplesort(). */
 #define        SIZE            512             /* Default stack size. */
@@ -164,6 +159,17 @@ r_sort_a(const u_char **a, int n, int i, const u_char *tr, u_int endch)
                        }
                }
 
+               /*
+                * Special case: if all strings have the same
+                * character at position i, move on to the next
+                * character.
+                */
+               if (nc == 1 && count[bmin] == n) {
+                       push(a, n, i+1);
+                       nc = count[bmin] = 0;
+                       continue;
+               }
+
                /*
                 * Set top[]; push incompletely sorted bins onto stack.
                 * top[] = pointers to last out-of-place element in bins.
index e183a1e..d6b8126 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)rand.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.14 2003/09/08 19:57:15 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.16 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/rand.3,v 1.6 2007/06/29 19:34:41 swildner Exp $
 .\"
 .Dd May 25, 1999
@@ -92,8 +88,10 @@ The
 .Fn sranddev
 function initializes a seed using the
 .Xr random 4
-random number device which returns good random numbers,
-suitable for cryptographic use.
+random number device which returns good random numbers.
+However, the
+.Fn rand
+function still remains unsuitable for cryptographic use.
 .Pp
 The
 .Fn rand_r
index dde21aa..4b93a35 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>.
  *
- * $FreeBSD: src/lib/libc/stdlib/rand.c,v 1.15 2001/03/05 11:33:57 ache Exp $
+ * @(#)rand.c  8.1 (Berkeley) 6/14/93
+ * $FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17 2007/12/11 20:39:32 ache Exp $
  * $DragonFly: src/lib/libc/stdlib/rand.c,v 1.6 2005/11/20 14:58:40 swildner Exp $
  */
 
 #include "namespace.h"
 #include <sys/time.h>          /* for sranddev() */
+#include <sys/types.h>
 #include <fcntl.h>             /* for sranddev() */
 #include <stdlib.h>
 #include <unistd.h>            /* for sranddev() */
@@ -47,8 +45,6 @@
 #include <stdio.h>
 #endif /* TEST */
 
-void   sranddev(void);
-
 static int
 do_rand(unsigned long *ctx)
 {
@@ -62,7 +58,7 @@ do_rand(unsigned long *ctx)
 #else   /* !USE_WEAK_SEEDING */
 /*
  * Compute x = (7^5 * x) mod (2^31 - 1)
- * wihout overflowing 31 bits:
+ * without overflowing 31 bits:
  *      (2^31 - 1) = 127773 * (7^5) + 2836
  * From "Random number generators: good ones are hard to find",
  * Park and Miller, Communications of the ACM, vol. 31, no. 10,
@@ -115,11 +111,6 @@ srand(u_int seed)
  * Many programs choose the seed value in a totally predictable manner.
  * This often causes problems.  We seed the generator using the much more
  * secure random(4) interface.
- *
- * FreeBSD chooses to use /dev/random for their seed.  However, because
- * of possible problems surrounding /dev/random, we use /dev/urandom for now,
- * which is guaranteed not to block and will produce a "good enough" seed
- * for us for the time being.
  */
 void
 sranddev(void)
@@ -127,7 +118,7 @@ sranddev(void)
        int fd, done;
 
        done = 0;
-       fd = _open("/dev/urandom", O_RDONLY, 0);
+       fd = _open("/dev/random", O_RDONLY, 0);
        if (fd >= 0) {
                if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next))
                        done = 1;
index b29549c..5ee1a3e 100644 (file)
@@ -9,10 +9,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -30,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)random.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.11.2.6 2003/06/03 19:13:16 schweikh Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/random.3,v 1.22 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/random.3,v 1.5 2007/06/29 19:34:41 swildner Exp $
 .\"
 .Dd June 4, 1993
@@ -82,9 +78,11 @@ functions.
 The difference is that
 .Xr rand 3
 produces a much less random sequence \(em in fact, the low dozen bits
-generated by rand go through a cyclic pattern.  All the bits generated by
+generated by rand go through a cyclic pattern.
+All the bits generated by
 .Fn random
-are usable.  For example,
+are usable.
+For example,
 .Sq Li random()&01
 will produce a random binary
 value.
@@ -102,7 +100,7 @@ as the seed.
 The
 .Fn srandomdev
 routine initializes a state array using the
-.Xr urandom 4
+.Xr random 4
 random number device which returns good random numbers,
 suitable for cryptographic use.
 Note that this particular seeding
@@ -116,13 +114,15 @@ a fixed seed.
 The
 .Fn initstate
 routine allows a state array, passed in as an argument, to be initialized
-for future use.  The size of the state array (in bytes) is used by
+for future use.
+The size of the state array (in bytes) is used by
 .Fn initstate
 to decide how sophisticated a random number generator it should use \(em the
 more state, the better the random numbers will be.
 (Current "optimal" values for the amount of state information are
 8, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
-the nearest known amount.  Using less than 8 bytes will cause an error.)
+the nearest known amount.
+Using less than 8 bytes will cause an error.)
 The seed for the initialization (which specifies a starting point for
 the random number sequence, and provides for restarting at the same
 point) is also an argument.
@@ -176,7 +176,7 @@ messages are printed on the standard error output.
 .Xr arc4random 3 ,
 .Xr rand 3 ,
 .Xr srand 3 ,
-.Xr urandom 4
+.Xr random 4
 .Sh HISTORY
 These
 functions appeared in
@@ -191,3 +191,6 @@ The historical implementation used to have a very weak seeding; the
 random sequence did not vary much with the seed.
 The current implementation employs a better pseudo-random number
 generator for the initial state calculation.
+.Pp
+Applications requiring cryptographic quality randomness should use
+.Xr arc4random 3 .
index dd889ab..fee7bb1 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/random.c,v 1.13 2000/01/27 23:06:49 jasone Exp $
- * $DragonFly: src/lib/libc/stdlib/random.c,v 1.9 2005/11/24 17:18:30 swildner Exp $
- *
  * @(#)random.c        8.2 (Berkeley) 5/19/95
+ * $FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/random.c,v 1.9 2005/11/24 17:18:30 swildner Exp $
  */
 
 #include "namespace.h"
 #include <sys/time.h>          /* for srandomdev() */
 #include <fcntl.h>             /* for srandomdev() */
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>            /* for srandomdev() */
@@ -60,7 +56,7 @@
  * congruential generator.  If the amount of state information is less than
  * 32 bytes, a simple linear congruential R.N.G. is used.
  *
- * Internally, the state information is treated as an array of ints; the
+ * Internally, the state information is treated as an array of uint32_t's; the
  * zeroeth element of the array is the type of R.N.G. being used (small
  * integer); the remainder of the array is the state information for the
  * R.N.G.  Thus, 32 bytes of state information will give 7 ints worth of
@@ -79,7 +75,7 @@
  * period of the generator is approximately deg*(2**deg - 1); thus doubling
  * the amount of state information has a vast influence on the period of the
  * generator.  Note: the deg*(2**deg - 1) is an approximation only good for
- * large deg, when the period of the shift register is the dominant factor.
+ * large deg, when the period of the shift is the dominant factor.
  * With deg equal to seven, the period is actually much longer than the
  * 7*(2**7 - 1) predicted by this formula.
  *
  */
 #define        MAX_TYPES       5               /* max number of types above */
 
+#ifdef  USE_WEAK_SEEDING
+#define NSHUFF 0
+#else   /* !USE_WEAK_SEEDING */
+#define NSHUFF 50       /* to drop some "seed -> 1st value" linearity */
+#endif  /* !USE_WEAK_SEEDING */
+
 static const int degrees[MAX_TYPES] =  { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
 static const int seps [MAX_TYPES] =    { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
 
@@ -212,10 +214,10 @@ static int rand_deg = DEG_3;
 static int rand_sep = SEP_3;
 static uint32_t *end_ptr = &randtbl[DEG_3 + 1];
 
-static inline long good_rand(long);
+static inline uint32_t good_rand(int32_t);
 
-static inline long
-good_rand(long x)
+static inline uint32_t
+good_rand(int32_t x)
 {
 #ifdef  USE_WEAK_SEEDING
 /*
@@ -233,12 +235,15 @@ good_rand(long x)
  * Park and Miller, Communications of the ACM, vol. 31, no. 10,
  * October 1988, p. 1195.
  */
-       long hi, lo;
+       int32_t hi, lo;
 
+       /* Can't be initialized with 0, so use another value. */
+       if (x == 0)
+               x = 123459876;
        hi = x / 127773;
        lo = x % 127773;
        x = 16807 * lo - 2836 * hi;
-       if (x <= 0)
+       if (x < 0)
                x += 0x7fffffff;
        return (x);
 #endif  /* !USE_WEAK_SEEDING */
@@ -259,19 +264,20 @@ good_rand(long x)
 void
 srandom(unsigned long x)
 {
-       int i;
+       int i, lim;
 
+       state[0] = (uint32_t)x;
        if (rand_type == TYPE_0)
-               state[0] = (uint32_t)x;
+               lim = NSHUFF;
        else {
-               state[0] = (uint32_t)x;
                for (i = 1; i < rand_deg; i++)
-                       state[i] = (uint32_t)good_rand(state[i - 1]);
+                       state[i] = good_rand(state[i - 1]);
                fptr = &state[rand_sep];
                rptr = &state[0];
-               for (i = 0; i < 10 * rand_deg; i++)
-                       random();
+               lim = 10 * rand_deg;
        }
+       for (i = 0; i < lim; i++)
+               random();
 }
 
 /*
@@ -279,7 +285,7 @@ srandom(unsigned long x)
  *
  * Many programs choose the seed value in a totally predictable manner.
  * This often causes problems.  We seed the generator using the much more
- * secure urandom(4) interface.  Note that this particular seeding
+ * secure random(4) interface.  Note that this particular seeding
  * procedure can generate states which are impossible to reproduce by
  * calling srandom() with any value, since the succeeding terms in the
  * state buffer are no longer derived from the LC algorithm applied to
@@ -297,7 +303,7 @@ srandomdev(void)
                len = rand_deg * sizeof state[0];
 
        done = 0;
-       fd = _open("/dev/urandom", O_RDONLY, 0);
+       fd = _open("/dev/random", O_RDONLY, 0);
        if (fd >= 0) {
                if (_read(fd, (void *) state, len) == (ssize_t) len)
                        done = 1;
@@ -309,7 +315,7 @@ srandomdev(void)
                unsigned long junk;     /* XXX left uninitialized on purpose */
 
                gettimeofday(&tv, NULL);
-               srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+               srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
                return;
        }
 
@@ -351,12 +357,12 @@ char *
 initstate(unsigned long seed, char *arg_state, long n)
 {
        char *ostate = (char *)(&state[-1]);
-       uint32_t *int_arg_state = (uint32_t *)(void *)arg_state;
+       uint32_t *int_arg_state = (uint32_t *)arg_state;
 
        if (rand_type == TYPE_0)
                state[-1] = rand_type;
        else
-               state[-1] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
+               state[-1] = MAX_TYPES * (rptr - state) + rand_type;
        if (n < BREAK_0) {
                fprintf(stderr,
                    "random: not enough state (%ld bytes); ignored.\n", n);
@@ -383,13 +389,13 @@ initstate(unsigned long seed, char *arg_state, long n)
                rand_deg = DEG_4;
                rand_sep = SEP_4;
        }
-       state = (uint32_t *) (int_arg_state + 1); /* first location */
+       state = int_arg_state + 1; /* first location */
        end_ptr = &state[rand_deg];     /* must set end_ptr before srandom */
-       srandom((uint32_t)seed);
+       srandom(seed);
        if (rand_type == TYPE_0)
                int_arg_state[0] = rand_type;
        else
-               int_arg_state[0] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
+               int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
        return(ostate);
 }
 
@@ -411,14 +417,14 @@ initstate(unsigned long seed, char *arg_state, long n)
  *
  * Returns a pointer to the old state information.
  *
- * Note: The Sparc platform requires that arg_state begin on a long
+ * Note: The Sparc platform requires that arg_state begin on an int
  * word boundary; otherwise a bus error will occur. Even so, lint will
  * complain about mis-alignment, but you should disregard these messages.
  */
 char *
 setstate(char *arg_state)
 {
-       uint32_t *new_state = (uint32_t *)(void *)arg_state;
+       uint32_t *new_state = (uint32_t *)arg_state;
        uint32_t type = new_state[0] % MAX_TYPES;
        uint32_t rear = new_state[0] / MAX_TYPES;
        char *ostate = (char *)(&state[-1]);
@@ -426,7 +432,7 @@ setstate(char *arg_state)
        if (rand_type == TYPE_0)
                state[-1] = rand_type;
        else
-               state[-1] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
+               state[-1] = MAX_TYPES * (rptr - state) + rand_type;
        switch(type) {
        case TYPE_0:
        case TYPE_1:
@@ -441,7 +447,7 @@ setstate(char *arg_state)
                fprintf(stderr,
                    "random: state info corrupted; not changed.\n");
        }
-       state = (uint32_t *) (new_state + 1);
+       state = new_state + 1;
        if (rand_type != TYPE_0) {
                rptr = &state[rear];
                fptr = &state[(rear + rand_sep) % rand_deg];
index 1aefef6..e61b814 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -33,7 +29,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)realpath.3 8.2 (Berkeley) 2/16/94
-.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.7.2.3 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/realpath.3,v 1.14 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/realpath.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd February 16, 1994
@@ -48,7 +44,7 @@
 .In sys/param.h
 .In stdlib.h
 .Ft "char *"
-.Fn realpath "const char *pathname" "char resolved_path[MAXPATHLEN]"
+.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]"
 .Sh DESCRIPTION
 The
 .Fn realpath
@@ -68,7 +64,7 @@ The
 argument
 .Em must
 refer to a buffer capable of storing at least
-.Dv MAXPATHLEN
+.Dv PATH_MAX
 characters.
 .Pp
 The
@@ -100,11 +96,7 @@ The function
 may fail and set the external variable
 .Va errno
 for any of the errors specified for the library functions
-.Xr chdir 2 ,
-.Xr close 2 ,
-.Xr fchdir 2 ,
 .Xr lstat 2 ,
-.Xr open 2 ,
 .Xr readlink 2
 and
 .Xr getcwd 3 .
@@ -125,5 +117,5 @@ when given a relative
 .Sh HISTORY
 The
 .Fn realpath
-function call first appeared in
+function first appeared in
 .Bx 4.4 .
index d556e0e..3b89c80 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * @(#)realpath.c      8.1 (Berkeley) 2/16/94
- * $FreeBSD: src/lib/libc/stdlib/realpath.c,v 1.9.2.2 2003/06/02 13:31:16 fjoe Exp $
+ * $FreeBSD: src/lib/libc/stdlib/realpath.c,v 1.20 2003/05/28 08:23:01 fjoe Exp $
  * $DragonFly: src/lib/libc/stdlib/realpath.c,v 1.4 2005/04/28 13:47:15 joerg Exp $
  */
 
diff --git a/lib/libc/stdlib/remque.c b/lib/libc/stdlib/remque.c
new file mode 100644 (file)
index 0000000..6da9e39
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Initial implementation:
+ * Copyright (c) 2002 Robert Drehmel
+ * All rights reserved.
+ *
+ * As long as the above copyright statement and this notice remain
+ * unchanged, you can do what ever you want with this file.
+ *
+ * $FreeBSD: src/lib/libc/stdlib/remque.c,v 1.3 2003/01/04 07:34:41 tjr Exp $
+ */
+
+#define        _SEARCH_PRIVATE
+#include <search.h>
+#include <stdlib.h>    /* for NULL */
+
+void
+remque(void *element)
+{
+       struct que_elem *prev, *next, *elem;
+
+       elem = (struct que_elem *)element;
+
+       prev = elem->prev;
+       next = elem->next;
+
+       if (prev != NULL)
+               prev->next = next;
+       if (next != NULL)
+               next->prev = prev;
+}
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
deleted file mode 100644 (file)
index 867dab2..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1987, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)setenv.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.5.2.1 2000/09/20 19:46:03 brian Exp $
- * $DragonFly: src/lib/libc/stdlib/setenv.c,v 1.5 2005/04/28 13:51:55 joerg Exp $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern char **environ;
-
-char *__findenv (const char *, size_t *);
-
-/*
- * setenv --
- *     Set the value of the environmental variable "name" to be
- *     "value".  If rewrite is set, replace any current value.
- */
-int
-setenv(const char *name, const char *value, int rewrite)
-{
-       static char **alloced;                  /* if allocated space before */
-       char *c;
-       size_t l_value, offset;
-
-       if (*value == '=')                      /* no `=' in value */
-               ++value;
-       l_value = strlen(value);
-       if ((c = __findenv(name, &offset))) {   /* find if already exists */
-               if (!rewrite)
-                       return (0);
-               if (strlen(c) >= l_value) {     /* old larger; copy over */
-                       while ( (*c++ = *value++) );
-                       return (0);
-               }
-       } else {                                        /* create new slot */
-               int cnt;
-               char **p;
-
-               for (p = environ, cnt = 0; *p; ++p, ++cnt);
-               if (alloced == environ) {
-                       /* just increase size */
-                       p = realloc(environ, sizeof(char *) * (cnt + 2));
-                       if (p == NULL)
-                               return (-1);
-                       alloced = environ = p;
-               }
-               else {                          /* get new space */
-                                               /* copy old entries into it */
-                       p = malloc(sizeof(char *) * (cnt + 2));
-                       if (p == NULL)
-                               return (-1);
-                       bcopy(environ, p, cnt * sizeof(char *));
-                       alloced = environ = p;
-               }
-               environ[cnt + 1] = NULL;
-               offset = cnt;
-       }
-       for (c = (char *)name; *c && *c != '='; ++c);   /* no `=' in name */
-       if (!(environ[offset] =                 /* name + `=' + value */
-           malloc((size_t)((int)(c - name) + l_value + 2))))
-               return (-1);
-       for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
-       for (*c++ = '='; (*c++ = *value++); );
-       return (0);
-}
-
-/*
- * unsetenv(name) --
- *     Delete environmental variable "name".
- */
-void
-unsetenv(const char *name)
-{
-       char **p;
-       size_t offset;
-
-       while (__findenv(name, &offset))        /* if set multiple times */
-               for (p = &environ[offset];; ++p)
-                       if (!(*p = *(p + 1)))
-                               break;
-}
index dcfe1d0..1b03705 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)strtol.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.21 2006/05/20 21:11:35 maxim Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/strtol.3,v 1.23 2007/04/10 11:17:00 ru Exp $
 .\" $DragonFly: src/lib/libc/stdlib/strtol.3,v 1.5 2007/04/10 21:09:00 swildner Exp $
 .\"
 .Dd November 2, 2006
@@ -53,12 +49,12 @@ integer
 .In stdlib.h
 .In limits.h
 .Ft long
-.Fn strtol "const char *nptr" "char **endptr" "int base"
+.Fn strtol "const char * restrict nptr" "char ** restrict endptr" "int base"
 .Ft long long
-.Fn strtoll "const char *nptr" "char **endptr" "int base"
+.Fn strtoll "const char * restrict nptr" "char ** restrict endptr" "int base"
 .In inttypes.h
 .Ft intmax_t
-.Fn strtoimax "const char *nptr" "char **endptr" "int base"
+.Fn strtoimax "const char * restrict nptr" "char ** restrict endptr" "int base"
 .In sys/types.h
 .In stdlib.h
 .In limits.h
index 9fa5e2a..8e09575 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -31,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * @(#)strtoq.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.4.6.1 2001/03/02 09:45:20 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdlib/strtoq.c,v 1.12 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/strtoq.c,v 1.3 2005/11/20 12:37:49 swildner Exp $
  */
 
@@ -41,9 +37,6 @@
 
 /*
  * Convert a string to a quad integer.
- *
- * Ignores `locale' stuff.  Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
  */
 quad_t
 strtoq(const char *nptr, char **endptr, int base)
index 451e21c..7de5498 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)strtoul.3  8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.22 2006/05/20 21:11:35 maxim Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/strtoul.3,v 1.23 2007/01/09 00:28:10 imp Exp $
 .\" $DragonFly: src/lib/libc/stdlib/strtoul.3,v 1.4 2006/11/02 19:48:55 swildner Exp $
 .\"
 .Dd November 2, 2006
@@ -43,6 +39,7 @@
 .Sh NAME
 .Nm strtoul ,
 .Nm strtoull ,
+.Nm strtoumax ,
 .Nm strtouq
 .Nd "convert a string to an"
 .Vt "unsigned long" , "unsigned long long" , uintmax_t ,
@@ -55,12 +52,12 @@ integer
 .In stdlib.h
 .In limits.h
 .Ft "unsigned long"
-.Fn strtoul "const char *nptr" "char **endptr" "int base"
+.Fn strtoul "const char * restrict nptr" "char ** restrict endptr" "int base"
 .Ft "unsigned long long"
-.Fn strtoull "const char *nptr" "char **endptr" "int base"
+.Fn strtoull "const char * restrict nptr" "char ** restrict endptr" "int base"
 .In inttypes.h
 .Ft uintmax_t
-.Fn strtoumax "const char *nptr" "char **endptr" "int base"
+.Fn strtoumax "const char * restrict nptr" "char ** restrict endptr" "int base"
 .In sys/types.h
 .In stdlib.h
 .In limits.h
index 76590cc..bfb2f50 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -31,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * @(#)strtouq.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.4.8.1 2001/03/02 09:45:20 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdlib/strtouq.c,v 1.12 2007/01/09 00:28:10 imp Exp $
  * $DragonFly: src/lib/libc/stdlib/strtouq.c,v 1.3 2005/11/20 12:37:49 swildner Exp $
  */
 
@@ -41,9 +37,6 @@
 
 /*
  * Convert a string to an unsigned quad integer.
- *
- * Ignores `locale' stuff.  Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
  */
 u_quad_t
 strtouq(const char *nptr, char **endptr, int base)
index 5f0f6fa..89dee4f 100644 (file)
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"    This product includes software developed by the University of
-.\"    California, Berkeley and its contributors.
 .\" 4. Neither the name of the University nor the names of its contributors
 .\"    may be used to endorse or promote products derived from this software
 .\"    without specific prior written permission.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)system.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.6.2.4 2001/12/14 18:33:58 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/system.3,v 1.13 2008/06/26 08:24:59 danger Exp $
 .\" $DragonFly: src/lib/libc/stdlib/system.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 4, 1993
@@ -75,7 +71,7 @@ pointer,
 will return non-zero if the command interpreter
 .Xr sh 1
 is available, and zero if it is not.
-.Pp
+.Sh RETURN VALUES
 The
 .Fn system
 function
@@ -98,7 +94,7 @@ The
 .Fn system
 function
 conforms to
-.St -isoC .
+.St -isoC
 and is expected to be
 .St -p1003.2
 compatible.
index d69c650..cff8da8 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/system.c,v 1.5.2.2 2001/10/10 12:50:22 alfred Exp $
- * $DragonFly: src/lib/libc/stdlib/system.c,v 1.5 2005/11/20 12:37:49 swildner Exp $
- *
  * @(#)system.c        8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdlib/system.c,v 1.11 2007/01/09 00:28:10 imp Exp $
+ * $DragonFly: src/lib/libc/stdlib/system.c,v 1.5 2005/11/20 12:37:49 swildner Exp $
  */
 
 #include "namespace.h"
@@ -48,8 +43,6 @@
 #include "un-namespace.h"
 #include "libc_private.h"
 
-int    __system(const char *);
-
 int
 __system(const char *command)
 {
index 7e83d30..5597d46 100644 (file)
@@ -9,32 +9,29 @@
  * Totally public domain.
  *
  * $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $
- * $FreeBSD: src/lib/libc/stdlib/tdelete.c,v 1.1.2.1 2000/08/17 07:38:39 jhb Exp $
+ * $FreeBSD: src/lib/libc/stdlib/tdelete.c,v 1.6 2003/01/05 02:43:18 tjr Exp $
  * $DragonFly: src/lib/libc/stdlib/tdelete.c,v 1.5 2005/11/24 17:18:30 swildner Exp $
  */
 
-#include <sys/cdefs.h>
-
-#include <assert.h>
 #define _SEARCH_PRIVATE
 #include <search.h>
 #include <stdlib.h>
 
 
-/* 
+/*
  * delete node with given key
  *
- * Parameters:
- *     vkey:   key to be deleted
- *     vrootp: address of the root of tree
-*/
+ * vkey:   key to be deleted
+ * vrootp: address of the root of the tree
+ * compar: function to carry out node comparisons
+ */
 void *
-tdelete(const void *vkey, void **vrootp,
+tdelete(const void * __restrict vkey, void ** __restrict vrootp,
        int (*compar)(const void *, const void *))
 {
        node_t **rootp = (node_t **)vrootp;
        node_t *p, *q, *r;
-       int  cmp;
+       int cmp;
 
        if (rootp == NULL || (p = *rootp) == NULL)
                return NULL;
index 462cd9a..21cb5eb 100644 (file)
@@ -9,18 +9,15 @@
  * Totally public domain.
  *
  * $NetBSD: tfind.c,v 1.2 1999/09/16 11:45:37 lukem Exp $
- * $FreeBSD: src/lib/libc/stdlib/tfind.c,v 1.1.2.1 2000/08/17 07:38:39 jhb Exp $
- * $DragonFly: src/lib/libc/stdlib/tfind.c,v 1.5 2005/11/24 17:18:30 swildner Exp $
+ * $FreeBSD: src/lib/libc/stdlib/tfind.c,v 1.5 2003/01/05 02:43:18 tjr Exp $
+ * $DragonFly: src/lib/libc/stdlib/tsearch.c,v 1.6 2005/11/24 17:18:30 swildner Exp $
  */
 
-#include <sys/cdefs.h>
-
-#include <assert.h>
 #define _SEARCH_PRIVATE
 #include <stdlib.h>
 #include <search.h>
 
-/* 
+/*
  * find a node, or return 0
  *
  * Parameters:
@@ -28,7 +25,7 @@
  *     vrootp: address of the tree root
  */
 void *
-tfind(const void *vkey, void **vrootp,
+tfind(const void *vkey, void * const *vrootp,
       int (*compar)(const void *, const void *))
 {
        node_t **rootp = (node_t **)vrootp;
index a42e380..082acf0 100644 (file)
@@ -25,8 +25,8 @@
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\"    OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp
-.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.1.2.6 2001/12/14 18:33:58 ru Exp $
-.\" $DragonFly: src/lib/libc/stdlib/tsearch.3,v 1.5 2007/08/18 20:48:47 swildner Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.15 2006/06/23 13:36:33 keramida Exp $
+.\" $DragonFly: src/lib/libc/stdlib/tsearch.c,v 1.6 2005/11/24 17:18:30 swildner Exp $
 .\"
 .Dd June 15, 1997
 .Dt TSEARCH 3
 .Sh SYNOPSIS
 .In search.h
 .Ft void *
-.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
+.Fn tdelete "const void * restrict key" "void ** restrict rootp" "int (*compar) (const void *, const void *)"
 .Ft void *
-.Fn tfind "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
+.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
 .Ft void *
 .Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
 .Ft void
-.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)"
+.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
 .Sh DESCRIPTION
 The
 .Fn tdelete ,
@@ -57,11 +57,14 @@ The
 and
 .Fn twalk
 functions manage binary search trees based on algorithms T and D
-from Knuth (6.2.2).  The comparison function passed in by
+from Knuth (6.2.2).
+The comparison function passed in by
 the user has the same style of return values as
 .Xr strcmp 3 .
 .Pp
-.Fn Tfind
+The
+.Fn tfind
+function
 searches for the datum matched by the argument
 .Fa key
 in the binary tree rooted at
@@ -69,16 +72,21 @@ in the binary tree rooted at
 returning a pointer to the datum if it is found and NULL
 if it is not.
 .Pp
-.Fn Tsearch
+The
+.Fn tsearch
+function
 is identical to
 .Fn tfind
 except that if no match is found,
 .Fa key
-is inserted into the tree and a pointer to it is returned.  If
+is inserted into the tree and a pointer to it is returned.
+If
 .Fa rootp
 points to a NULL value a new binary search tree is created.
 .Pp
-.Fn Tdelete
+The
+.Fn tdelete
+function
 deletes a node from the specified binary search tree and returns
 a pointer to the parent of the node to be deleted.
 It takes the same arguments as
@@ -89,13 +97,17 @@ If the node to be deleted is the root of the binary search tree,
 .Fa rootp
 will be adjusted.
 .Pp
-.Fn Twalk
+The
+.Fn twalk
+function
 walks the binary search tree rooted in
 .Fa root
 and calls the function
 .Fa action
 on each node.
-.Fa Action
+The
+.Fa action
+function
 is called with three arguments: a pointer to the current node,
 a value from the enum
 .Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
@@ -107,10 +119,12 @@ The
 function returns NULL if allocation of a new node fails (usually
 due to a lack of free memory).
 .Pp
-.Fn Tfind ,
+The
+.Fn tfind ,
 .Fn tsearch ,
 and
 .Fn tdelete
+functions
 return NULL if
 .Fa rootp
 is NULL or the datum cannot be found.
index 9479b4f..ffefef9 100644 (file)
@@ -9,23 +9,22 @@
  * Totally public domain.
  *
  * $NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $
- * $FreeBSD: src/lib/libc/stdlib/tsearch.c,v 1.1.2.1 2000/08/17 07:38:39 jhb Exp $
+ * $FreeBSD: src/lib/libc/stdlib/tsearch.c,v 1.4 2003/01/05 02:43:18 tjr Exp $
  * $DragonFly: src/lib/libc/stdlib/tsearch.c,v 1.6 2005/11/24 17:18:30 swildner Exp $
  */
 
-#include <sys/cdefs.h>
-
-#include <assert.h>
 #define _SEARCH_PRIVATE
 #include <search.h>
 #include <stdlib.h>
 
-/* find or insert datum into search tree
+/*
+ * find or insert datum into search tree
  *
  * Parameters:
  *     vkey:   key to be located
  *     vrootp: address of tree root
  */
+
 void *
 tsearch(const void *vkey, void **vrootp,
        int (*compar)(const void *, const void *))
index c12b600..cb48018 100644 (file)
@@ -9,21 +9,19 @@
  * Totally public domain.
  *
  * $NetBSD: twalk.c,v 1.1 1999/02/22 10:33:16 christos Exp $
- * $FreeBSD: src/lib/libc/stdlib/twalk.c,v 1.1.2.1 2000/08/17 07:38:39 jhb Exp $
+ * $FreeBSD: src/lib/libc/stdlib/twalk.c,v 1.5 2003/01/05 02:43:18 tjr Exp $
  * $DragonFly: src/lib/libc/stdlib/twalk.c,v 1.5 2005/11/24 17:18:30 swildner Exp $
  */
 
-#include <sys/cdefs.h>
-
-#include <assert.h>
 #define _SEARCH_PRIVATE
 #include <search.h>
 #include <stdlib.h>
 
-static void trecurse (const node_t *,
-    void  (*action)(const void *, VISIT, int), int level);
+static void trecurse(const node_t *,
+                    void (*action)(const void *, VISIT, int), int level);
 
-/* Walk the nodes of a tree
+/*
+ * Walk the nodes of a tree
  *
  * Parameters:
  *     root:   Root of the tree to be walked
@@ -46,7 +44,8 @@ trecurse(const node_t *root, void (*action)(const void *, VISIT, int),
        }
 }
 
-/* Walk the nodes of a tree
+/*
+ * Walk the nodes of a tree
  *
  * Parameters:
  *     vroot:  Root of the tree to be walked
index d21e58d..de8304f 100644 (file)
@@ -260,7 +260,7 @@ Spawn(const char *prog __unused, const char *acname, const char *provider,
   struct ng_mesg *rep = (struct ng_mesg *)msgbuf;
   struct ngpppoe_sts *sts = (struct ngpppoe_sts *)(msgbuf + sizeof *rep);
   struct ngpppoe_init_data *data;
-  char env[sizeof(HISMACADDR)+18], unknown[14], sessionid[5], *path;
+  char env[18], unknown[14], sessionid[5], *path;
   unsigned char *macaddr;
   const char *msg;
   int ret, slen;
@@ -354,11 +354,11 @@ Spawn(const char *prog __unused, const char *acname, const char *provider,
       /* Put the peer's MAC address in the environment */
       if (sz >= sizeof(struct ether_header)) {
         macaddr = ((struct ether_header *)request)->ether_shost;
-        snprintf(env, sizeof(env), "%s=%x:%x:%x:%x:%x:%x", HISMACADDR,
+        snprintf(env, sizeof(env), "%x:%x:%x:%x:%x:%x",
                  macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4],
                  macaddr[5]);
-        if (putenv(env) != 0)
-          syslog(LOG_INFO, "putenv: cannot set %s: %m", env);
+        if (setenv(HISMACADDR, env, 1) != 0)
+          syslog(LOG_INFO, "setenv: cannot set %s: %m", HISMACADDR);
       }
 
       /* And send our request data to the waiting node */
index 151fa35..860cf05 100644 (file)
@@ -131,14 +131,14 @@ main(int argc, char **argv)
                                cflag = 1;
                                break;
                        case 'h':
-                               if (putenv("BLOCKSIZE=512") == -1)
-                                       warn("putenv: cannot set BLOCKSIZE=512");
+                               if (setenv("BLOCKSIZE", "512", 1) == -1)
+                                       warn("setenv: cannot set BLOCKSIZE=512");
                                hflag = 1;
                                break;
                        case 'k':
                                hflag = 0;
-                               if (putenv("BLOCKSIZE=1024") == -1)
-                                       warn("putenv: cannot set BLOCKSIZE=1024");
+                               if (setenv("BLOCKSIZE", "1024", 1) == -1)
+                                       warn("setenv: cannot set BLOCKSIZE=1024");
                                break;
                        case 'r':                /* Compatibility. */
                                break;
index 468649b..8b59033 100644 (file)
@@ -65,8 +65,10 @@ main(int argc, char **argv)
                        usage();
                }
        for (argv += optind; *argv && (p = strchr(*argv, '=')); ++argv) {
-               if (setenv(*argv, ++p, 1) == -1)
-                       err(1, "setenv: cannot set %s=%s", *argv, p);
+               *p = '\0';
+               if (setenv(*argv, p + 1, 1) == -1)
+                       err(1, "setenv: cannot set %s=%s", *argv, p + 1);
+               *p = '=';
        }
 
        if (*argv) {
index 6b5f455..0de352a 100644 (file)
@@ -434,8 +434,10 @@ main(int argc, char *argv[])
 
        /* set leading environment variables, like eval(1) */
        while (*argv && (p = strchr(*argv, '='))) {
-           if (setenv(*argv++, ++p, 1) == -1)
-               err(1, "setenv: cannot set %s=%s", *argv, p);
+           *p = '\0';
+           if (setenv(*argv++, p + 1, 1) == -1)
+               err(1, "setenv: cannot set %s=%s", *argv, p + 1);
+           *p = '=';
        }
 
        /* Set limits */
index 1438b95..c2fe784 100644 (file)
@@ -226,8 +226,8 @@ main(int argc, char **argv)
                        fileflag = 1;
                        break;
                case 'k':
-                       if (putenv("BLOCKSIZE=1K") == -1)
-                               warn("putenv: cannot set BLOCKSIZE=1K");
+                       if (setenv("BLOCKSIZE", "1K", 1) == -1)
+                               warn("setenv: cannot set BLOCKSIZE=1K");
                        break;
                case 'M':
                        memf = optarg;