386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 20 Apr 1991 21:02:44 +0000 (13:02 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 20 Apr 1991 21:02:44 +0000 (13:02 -0800)
Work on file usr/src/lib/libc/stdlib/abort.c
Work on file usr/src/lib/libc/stdlib/abs.c
Work on file usr/src/lib/libc/stdlib/atexit.c
Work on file usr/src/lib/libc/stdlib/atexit.h
Work on file usr/src/lib/libc/stdlib/atof.c
Work on file usr/src/lib/libc/stdlib/atoi.c
Work on file usr/src/lib/libc/stdlib/calloc.c
Work on file usr/src/lib/libc/stdlib/bsearch.c
Work on file usr/src/lib/libc/stdlib/atol.c
Work on file usr/src/lib/libc/stdlib/div.c
Work on file usr/src/lib/libc/stdlib/exit.c
Work on file usr/src/lib/libc/stdlib/div.3
Work on file usr/src/lib/libc/stdlib/getopt.c
Work on file usr/src/lib/libc/stdlib/getenv.c
Work on file usr/src/lib/libc/stdlib/getopt.3
Work on file usr/src/lib/libc/stdlib/ldiv.c
Work on file usr/src/lib/libc/stdlib/labs.c
Work on file usr/src/lib/libc/stdlib/putenv.c
Work on file usr/src/lib/libc/stdlib/multibyte.c
Work on file usr/src/lib/libc/stdlib/malloc.c
Work on file usr/src/lib/libc/stdlib/qsort.c
Work on file usr/src/lib/libc/stdlib/radixsort.3
Work on file usr/src/lib/libc/stdlib/radixsort.c
Work on file usr/src/lib/libc/stdlib/random.3
Work on file usr/src/lib/libc/stdlib/random.c
Work on file usr/src/lib/libc/stdlib/strtol.c
Work on file usr/src/lib/libc/stdlib/strtoul.c
Work on file usr/src/lib/libc/stdlib/system.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

28 files changed:
usr/src/lib/libc/stdlib/abort.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/abs.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/atexit.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/atexit.h [new file with mode: 0644]
usr/src/lib/libc/stdlib/atof.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/atoi.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/atol.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/bsearch.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/calloc.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/div.3 [new file with mode: 0644]
usr/src/lib/libc/stdlib/div.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/exit.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/getenv.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/getopt.3 [new file with mode: 0644]
usr/src/lib/libc/stdlib/getopt.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/labs.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/ldiv.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/malloc.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/multibyte.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/putenv.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/qsort.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/radixsort.3 [new file with mode: 0644]
usr/src/lib/libc/stdlib/radixsort.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/random.3 [new file with mode: 0644]
usr/src/lib/libc/stdlib/random.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/strtol.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/strtoul.c [new file with mode: 0644]
usr/src/lib/libc/stdlib/system.c [new file with mode: 0644]

diff --git a/usr/src/lib/libc/stdlib/abort.c b/usr/src/lib/libc/stdlib/abort.c
new file mode 100644 (file)
index 0000000..b5393e9
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1985 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)abort.c    5.11 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/signal.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+
+void
+abort()
+{
+       sigset_t mask;
+
+       sigfillset(&mask);
+       /*
+        * don't block SIGABRT to give any handler a chance; we ignore
+        * any errors -- X311J doesn't allow abort to return anyway.
+        */
+       sigdelset(&mask, SIGABRT);
+       (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+       (void)kill(getpid(), SIGABRT);
+
+       /*
+        * if SIGABRT ignored, or caught and the handler returns, do
+        * it again, only harder.
+        */
+       (void)signal(SIGABRT, SIG_DFL);
+       (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+       (void)kill(getpid(), SIGABRT);
+       exit(1);
+}
diff --git a/usr/src/lib/libc/stdlib/abs.c b/usr/src/lib/libc/stdlib/abs.c
new file mode 100644 (file)
index 0000000..ebfd1a5
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)abs.c      5.2 (Berkeley) 5/17/90";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+int
+abs(j)
+       int j;
+{
+       return(j < 0 ? -j : j);
+}
diff --git a/usr/src/lib/libc/stdlib/atexit.c b/usr/src/lib/libc/stdlib/atexit.c
new file mode 100644 (file)
index 0000000..06d1d6b
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atexit.c   5.2 (Berkeley) 11/14/90";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include "atexit.h"
+
+/*
+ * Register a function to be performed at exit.
+ */
+int
+atexit(fn)
+       void (*fn)();
+{
+       static struct atexit __atexit0; /* one guaranteed table */
+       register struct atexit *p;
+
+       if ((p = __atexit) == NULL)
+               __atexit = p = &__atexit0;
+       else if (p->ind >= ATEXIT_SIZE) {
+               if ((p = malloc(sizeof(*p))) == NULL)
+                       return (-1);
+               p->ind = 0;
+               p->next = __atexit;
+               __atexit = p;
+       }
+       p->fns[p->ind++] = fn;
+       return (0);
+}
diff --git a/usr/src/lib/libc/stdlib/atexit.h b/usr/src/lib/libc/stdlib/atexit.h
new file mode 100644 (file)
index 0000000..4ec9bb9
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990 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.
+ *
+ *     @(#)atexit.h    5.1 (Berkeley) 5/15/90
+ */
+
+/* must be at least 32 to guarantee ANSI conformance */
+#define        ATEXIT_SIZE     32
+
+struct atexit {
+       struct atexit *next;            /* next in list */
+       int ind;                        /* next index in this table */
+       void (*fns[ATEXIT_SIZE])();     /* the table itself */
+};
+
+struct atexit *__atexit;       /* points to head of LIFO stack */
diff --git a/usr/src/lib/libc/stdlib/atof.c b/usr/src/lib/libc/stdlib/atof.c
new file mode 100644 (file)
index 0000000..38fd0a9
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atof.c     5.2 (Berkeley) 6/1/90";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+double
+atof(ascii)
+       char *ascii;
+{
+       return(strtod(ascii, (char **)NULL));
+}
diff --git a/usr/src/lib/libc/stdlib/atoi.c b/usr/src/lib/libc/stdlib/atoi.c
new file mode 100644 (file)
index 0000000..c100c88
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atoi.c     5.7 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+atoi(str)
+       const char *str;
+{
+       return((int)strtol(str, (char **)NULL, 10));
+}
diff --git a/usr/src/lib/libc/stdlib/atol.c b/usr/src/lib/libc/stdlib/atol.c
new file mode 100644 (file)
index 0000000..920302e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atol.c     5.7 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+long
+atol(str)
+       const char *str;
+{
+       return(strtol(str, (char **)NULL, 10));
+}
diff --git a/usr/src/lib/libc/stdlib/bsearch.c b/usr/src/lib/libc/stdlib/bsearch.c
new file mode 100644 (file)
index 0000000..ca7ffe6
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bsearch.c  5.4 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>            /* size_t */
+#include <stdlib.h>
+
+/*
+ * Perform a binary search.
+ *
+ * The code below is a bit sneaky.  After a comparison fails, we
+ * divide the work in half by moving either left or right. If lim
+ * is odd, moving left simply involves halving lim: e.g., when lim
+ * is 5 we look at item 2, so we change lim to 2 so that we will
+ * look at items 0 & 1.  If lim is even, the same applies.  If lim
+ * is odd, moving right again involes halving lim, this time moving
+ * the base up one item past p: e.g., when lim is 5 we change base
+ * to item 3 and make lim 2 so that we will look at items 3 and 4.
+ * If lim is even, however, we have to shrink it by one before
+ * halving: e.g., when lim is 4, we still looked at item 2, so we
+ * have to make lim 3, then halve, obtaining 1, so that we will only
+ * look at item 3.
+ */
+void *
+bsearch(key, base0, nmemb, size, compar)
+       register const void *key;
+       const void *base0;
+       size_t nmemb;
+       register size_t size;
+       register int (*compar) __P((const void *, const void *));
+{
+       register const char *base = base0;
+       register int lim, cmp;
+       register const void *p;
+
+       for (lim = nmemb; lim != 0; lim >>= 1) {
+               p = base + (lim >> 1) * size;
+               cmp = (*compar)(key, p);
+               if (cmp == 0)
+                       return ((void *)p);
+               if (cmp > 0) {  /* key > p: move right */
+                       base = (char *)p + size;
+                       lim--;
+               } /* else move left */
+       }
+       return (NULL);
+}
diff --git a/usr/src/lib/libc/stdlib/calloc.c b/usr/src/lib/libc/stdlib/calloc.c
new file mode 100644 (file)
index 0000000..fbfa1de
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)calloc.c   5.6 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <string.h>
+
+void *
+calloc(num, size)
+       size_t num;
+       register size_t size;
+{
+       register void *p;
+
+       size *= num;
+       if (p = malloc(size))
+               bzero(p, size);
+       return(p);
+}
+
+void
+cfree(p)
+       void *p;
+{
+       (void)free(p);
+}
diff --git a/usr/src/lib/libc/stdlib/div.3 b/usr/src/lib/libc/stdlib/div.3
new file mode 100644 (file)
index 0000000..4c97ffc
--- /dev/null
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1990, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\" 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.
+.\"
+.\"     @(#)div.3      5.2 (Berkeley) 4/19/91
+.\"
+.Dd April 19, 1991
+.Dt DIV 3
+.Os
+.Sh NAME
+.Nm div
+.Nd return quotient and remainder from division
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft div_t
+.Fn div "int num" "int denom"
+.Sh DESCRIPTION
+The
+.Fn div
+function
+computes the value
+.Fa num/denom
+and returns the quotient and remainder in a structure named
+.Fa div_t
+that contains two
+.Em int
+members named
+.Fa quot
+and
+.Fa rem .
+.Sh SEE ALSO
+.Xr ldiv 3
+.Sh STANDARDS
+The
+.Fn div
+function
+conforms to
+.St -ansiC .
diff --git a/usr/src/lib/libc/stdlib/div.c b/usr/src/lib/libc/stdlib/div.c
new file mode 100644 (file)
index 0000000..ce21a72
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)div.c      5.2 (Berkeley) 4/16/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>            /* div_t */
+
+div_t
+div(num, denom)
+       int num, denom;
+{
+       div_t r;
+
+       r.quot = num / denom;
+       r.rem = num % denom;
+       /*
+        * The ANSI standard says that |r.quot| <= |n/d|, where
+        * n/d is to be computed in infinite precision.  In other
+        * words, we should always truncate the quotient towards
+        * 0, never -infinity.
+        *
+        * Machine division and remainer may work either way when
+        * one or both of n or d is negative.  If only one is
+        * negative and r.quot has been truncated towards -inf,
+        * r.rem will have the same sign as denom and the opposite
+        * sign of num; if both are negative and r.quot has been
+        * truncated towards -inf, r.rem will be positive (will
+        * have the opposite sign of num).  These are considered
+        * `wrong'.
+        *
+        * If both are num and denom are positive, r will always
+        * be positive.
+        *
+        * This all boils down to:
+        *      if num >= 0, but r.rem < 0, we got the wrong answer.
+        * In that case, to get the right answer, add 1 to r.quot and
+        * subtract denom from r.rem.
+        */
+       if (num >= 0 && r.rem < 0) {
+               r.quot++;
+               r.rem -= denom;
+       }
+       return (r);
+}
diff --git a/usr/src/lib/libc/stdlib/exit.c b/usr/src/lib/libc/stdlib/exit.c
new file mode 100644 (file)
index 0000000..0d3c725
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)exit.c     5.4 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "atexit.h"
+
+void (*__cleanup)();
+
+/*
+ * Exit, flushing stdio buffers if necessary.
+ */
+void
+exit(status)
+       int status;
+{
+       register struct atexit *p;
+       register int n;
+
+       for (p = __atexit; p; p = p->next)
+               for (n = p->ind; --n >= 0;)
+                       (*p->fns[n])();
+       if (__cleanup)
+               (*__cleanup)();
+       _exit(status);
+}
diff --git a/usr/src/lib/libc/stdlib/getenv.c b/usr/src/lib/libc/stdlib/getenv.c
new file mode 100644 (file)
index 0000000..b07212d
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1987 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getenv.c   5.8 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+/*
+ * getenv --
+ *     Returns ptr to value associated with name, if any, else NULL.
+ */
+char *
+getenv(name)
+       const char *name;
+{
+       int offset;
+       char *_findenv();
+
+       return(_findenv(name, &offset));
+}
+
+/*
+ * _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.
+ *
+ *     This routine *should* be a static; don't use it.
+ */
+char *
+_findenv(name, offset)
+       register char *name;
+       int *offset;
+{
+       extern char **environ;
+       register int len;
+       register char **P, *C;
+
+       for (C = name, len = 0; *C && *C != '='; ++C, ++len);
+       for (P = environ; *P; ++P)
+               if (!strncmp(*P, name, len))
+                       if (*(C = *P + len) == '=') {
+                               *offset = P - environ;
+                               return(++C);
+                       }
+       return(NULL);
+}
diff --git a/usr/src/lib/libc/stdlib/getopt.3 b/usr/src/lib/libc/stdlib/getopt.3
new file mode 100644 (file)
index 0000000..c21a0a7
--- /dev/null
@@ -0,0 +1,210 @@
+.\" Copyright (c) 1988, 1991 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.
+.\"
+.\"     @(#)getopt.3   6.16 (Berkeley) 4/19/91
+.\"
+.Dd April 19, 1991
+.Dt GETOPT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getopt
+.Nd get option letter from argv
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Vt extern char *optarg
+.Vt extern int   optind
+.Vt extern int   opterr
+.Ft int
+.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Sh DESCRIPTION
+The
+.Fn getopt
+function gets 
+the next
+.Em known
+option character from
+.Fa argv .
+An option character is
+.Em known
+if it has been specified in the string of accepted option characters,
+.Fa optstring .
+.Pp
+The option string
+.Fa optstring
+may contain the following characters; letters and
+letters followed by a colon to indicate an option argument
+is to follow. It does not matter to
+.Fn getopt
+if a following argument has leading white space.
+.Pp
+On return from
+.Fn getopt ,
+.Va optarg
+points to an option argument, if it is anticipated,
+and the variable
+.Va optind
+contains the index to the next
+.Fa argv
+argument for a subsequent call
+to
+.Fn getopt .
+.Pp
+The variable
+.Va opterr
+and
+.Va optind
+are both initialized to 1.
+In order to use
+.Fn getopt
+to evaluate multiple sets of arguments, or to evaluate a single set of
+arguments multiple times,
+.Va optind
+must be initialized to the number of argv entries to be skipped in each
+evaluation.
+.Pp
+The
+.Fn getopt
+function
+returns an
+.Dv EOF
+when the argument list is exhausted, or a non-recognized
+option is encountered.
+The interpretation of options in the argument list may be cancelled
+by the option
+.Ql --
+(double dash) which causes
+.Fn getopt
+to signal the end of argument processing and return an
+.Dv EOF . 
+When all options have been processed (i.e., up to the first non-option
+argument),
+.Fn getopt
+returns
+.Dv EOF .
+.Sh DIAGNOSTICS
+If the
+.Fn getopt
+function encounters a character not found in the string
+.Va optarg
+or detects
+a missing option argument
+it writes error message
+.Ql ?
+to the
+.Em stderr .
+Setting
+.Va opterr
+to a zero will disable these error messages.
+.Sh EXAMPLE
+.Bd -literal -compact
+extern char *optarg;
+extern int optind;
+int bflag, ch, fd;
+
+bflag = 0;
+while ((ch = getopt(argc, argv, "bf:")) != EOF)
+       switch(ch) {
+       case 'b':
+               bflag = 1;
+               break;
+       case 'f':
+               if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
+                       (void)fprintf(stderr,
+                               "myname: unable to read file %s.\en", optarg);
+                       exit(1) ;
+               }
+               break;
+       case '?':
+       default:
+               usage();
+}
+argc -= optind;
+argv += optind;
+.Ed
+.Sh HISTORY
+The
+.Fn getopt
+function appeared
+.Bx 4.3 .
+.Sh BUGS
+Option arguments are allowed to begin with
+.Dq Li \- ;
+this is reasonable but
+reduces the amount of error checking possible.
+.Pp
+A single dash
+.Dq Li -
+may be specified as an character in
+.Fa optstring ,
+however it should
+.Em never
+have an argument associated with it.
+This allows
+.Fn getopt
+to be used with programs that expect
+.Dq Li -
+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 .
+By default, a single dash causes
+.Fn getopt
+to return
+.Dv EOF .
+This is, we believe, compatible with System V.
+.Pp
+It is also possible to handle digits as option letters.
+This allows
+.Fn getopt
+to be used with programs that expect a number
+.Pq Dq Li \&-\&3
+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 fairly well.
+.Bd -literal -offset indent
+int length;
+char *p;
+
+while ((c = getopt(argc, argv, "0123456789")) != EOF)
+       switch (c) {
+       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 = atoi(++p);
+               else
+                       length = atoi(argv[optind] + 1);
+               break;
+       }
+}
+.Ed
diff --git a/usr/src/lib/libc/stdlib/getopt.c b/usr/src/lib/libc/stdlib/getopt.c
new file mode 100644 (file)
index 0000000..7126cc1
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1987 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c   4.13 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * get option letter from argument vector
+ */
+int    opterr = 1,             /* if error message should be printed */
+       optind = 1,             /* index into parent argv vector */
+       optopt;                 /* character checked for validity */
+char   *optarg;                /* argument associated with option */
+
+#define        BADCH   (int)'?'
+#define        EMSG    ""
+
+int
+getopt(nargc, nargv, ostr)
+       int nargc;
+       char * const *nargv;
+       const char *ostr;
+{
+       static char *place = EMSG;              /* option letter processing */
+       register char *oli;                     /* option letter list index */
+       char *p;
+
+       if (!*place) {                          /* update scanning pointer */
+               if (optind >= nargc || *(place = nargv[optind]) != '-') {
+                       place = EMSG;
+                       return(EOF);
+               }
+               if (place[1] && *++place == '-') {      /* found "--" */
+                       ++optind;
+                       place = EMSG;
+                       return(EOF);
+               }
+       }                                       /* option letter okay? */
+       if ((optopt = (int)*place++) == (int)':' ||
+           !(oli = index(ostr, optopt))) {
+               /*
+                * if the user didn't specify '-' as an option,
+                * assume it means EOF.
+                */
+               if (optopt == (int)'-')
+                       return(EOF);
+               if (!*place)
+                       ++optind;
+               if (opterr) {
+                       if (!(p = rindex(*nargv, '/')))
+                               p = *nargv;
+                       else
+                               ++p;
+                       (void)fprintf(stderr, "%s: illegal option -- %c\n",
+                           p, optopt);
+               }
+               return(BADCH);
+       }
+       if (*++oli != ':') {                    /* don't need argument */
+               optarg = NULL;
+               if (!*place)
+                       ++optind;
+       }
+       else {                                  /* need an argument */
+               if (*place)                     /* no white space */
+                       optarg = place;
+               else if (nargc <= ++optind) {   /* no arg */
+                       place = EMSG;
+                       if (!(p = rindex(*nargv, '/')))
+                               p = *nargv;
+                       else
+                               ++p;
+                       if (opterr)
+                               (void)fprintf(stderr,
+                                   "%s: option requires an argument -- %c\n",
+                                   p, optopt);
+                       return(BADCH);
+               }
+               else                            /* white space */
+                       optarg = nargv[optind];
+               place = EMSG;
+               ++optind;
+       }
+       return(optopt);                         /* dump back option letter */
+}
diff --git a/usr/src/lib/libc/stdlib/labs.c b/usr/src/lib/libc/stdlib/labs.c
new file mode 100644 (file)
index 0000000..a43a5c1
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)labs.c     5.2 (Berkeley) 5/17/90";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+long
+labs(j)
+       long j;
+{
+       return(j < 0 ? -j : j);
+}
diff --git a/usr/src/lib/libc/stdlib/ldiv.c b/usr/src/lib/libc/stdlib/ldiv.c
new file mode 100644 (file)
index 0000000..0fa1764
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ldiv.c     5.2 (Berkeley) 4/16/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>            /* ldiv_t */
+
+ldiv_t
+ldiv(num, denom)
+       long num, denom;
+{
+       ldiv_t r;
+
+       /* see div.c for comments */
+
+       r.quot = num / denom;
+       r.rem = num % denom;
+       if (num >= 0 && r.rem < 0) {
+               r.quot++;
+               r.rem -= denom;
+       }
+       return (r);
+}
diff --git a/usr/src/lib/libc/stdlib/malloc.c b/usr/src/lib/libc/stdlib/malloc.c
new file mode 100644 (file)
index 0000000..df60e3e
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)malloc.c   5.11 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * malloc.c (Caltech) 2/21/82
+ * Chris Kingsley, kingsley@cit-20.
+ *
+ * This is a very fast storage allocator.  It allocates blocks of a small 
+ * number of different sizes, and keeps free lists of each size.  Blocks that
+ * don't exactly fit are passed up to the next larger size.  In this 
+ * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
+ * This is designed for use in a virtual memory environment.
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define        NULL 0
+
+static void morecore();
+static int findbucket();
+
+/*
+ * The overhead on a block is at least 4 bytes.  When free, this space
+ * contains a pointer to the next free block, and the bottom two bits must
+ * be zero.  When in use, the first byte is set to MAGIC, and the second
+ * byte is the size index.  The remaining bytes are for alignment.
+ * If range checking is enabled then a second word holds the size of the
+ * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
+ * The order of elements is critical: ov_magic must overlay the low order
+ * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
+ */
+union  overhead {
+       union   overhead *ov_next;      /* when free */
+       struct {
+               u_char  ovu_magic;      /* magic number */
+               u_char  ovu_index;      /* bucket # */
+#ifdef RCHECK
+               u_short ovu_rmagic;     /* range magic number */
+               u_int   ovu_size;       /* actual block size */
+#endif
+       } ovu;
+#define        ov_magic        ovu.ovu_magic
+#define        ov_index        ovu.ovu_index
+#define        ov_rmagic       ovu.ovu_rmagic
+#define        ov_size         ovu.ovu_size
+};
+
+#define        MAGIC           0xef            /* magic # on accounting info */
+#define RMAGIC         0x5555          /* magic # on range info */
+
+#ifdef RCHECK
+#define        RSLOP           sizeof (u_short)
+#else
+#define        RSLOP           0
+#endif
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
+ * smallest allocatable block is 8 bytes.  The overhead information
+ * precedes the data area returned to the user.
+ */
+#define        NBUCKETS 30
+static union overhead *nextf[NBUCKETS];
+extern char *sbrk();
+
+static int pagesz;                     /* page size */
+static int pagebucket;                 /* page size bucket */
+
+#ifdef MSTATS
+/*
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+ */
+static u_int nmalloc[NBUCKETS];
+#include <stdio.h>
+#endif
+
+#if defined(DEBUG) || defined(RCHECK)
+#define        ASSERT(p)   if (!(p)) botch("p")
+#include <stdio.h>
+static
+botch(s)
+       char *s;
+{
+       fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
+       (void) fflush(stderr);          /* just in case user buffered it */
+       abort();
+}
+#else
+#define        ASSERT(p)
+#endif
+
+void *
+malloc(nbytes)
+       size_t nbytes;
+{
+       register union overhead *op;
+       register int bucket, n;
+       register unsigned amt;
+
+       /*
+        * First time malloc is called, setup page size and
+        * align break pointer so all data will be page aligned.
+        */
+       if (pagesz == 0) {
+               pagesz = n = getpagesize();
+               op = (union overhead *)sbrk(0);
+               n = n - sizeof (*op) - ((int)op & (n - 1));
+               if (n < 0)
+                       n += pagesz;
+               if (n) {
+                       if (sbrk(n) == (char *)-1)
+                               return (NULL);
+               }
+               bucket = 0;
+               amt = 8;
+               while (pagesz > amt) {
+                       amt <<= 1;
+                       bucket++;
+               }
+               pagebucket = bucket;
+       }
+       /*
+        * Convert amount of memory requested into closest block size
+        * stored in hash buckets which satisfies request.
+        * Account for space used per block for accounting.
+        */
+       if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
+#ifndef RCHECK
+               amt = 8;        /* size of first bucket */
+               bucket = 0;
+#else
+               amt = 16;       /* size of first bucket */
+               bucket = 1;
+#endif
+               n = -(sizeof (*op) + RSLOP);
+       } else {
+               amt = pagesz;
+               bucket = pagebucket;
+       }
+       while (nbytes > amt + n) {
+               amt <<= 1;
+               if (amt == 0)
+                       return (NULL);
+               bucket++;
+       }
+       /*
+        * If nothing in hash bucket right now,
+        * request more memory from the system.
+        */
+       if ((op = nextf[bucket]) == NULL) {
+               morecore(bucket);
+               if ((op = nextf[bucket]) == NULL)
+                       return (NULL);
+       }
+       /* remove from linked list */
+       nextf[bucket] = op->ov_next;
+       op->ov_magic = MAGIC;
+       op->ov_index = bucket;
+#ifdef MSTATS
+       nmalloc[bucket]++;
+#endif
+#ifdef RCHECK
+       /*
+        * Record allocated size of block and
+        * bound space with magic numbers.
+        */
+       op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
+       op->ov_rmagic = RMAGIC;
+       *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+#endif
+       return ((char *)(op + 1));
+}
+
+/*
+ * Allocate more memory to the indicated bucket.
+ */
+static void
+morecore(bucket)
+       int bucket;
+{
+       register union overhead *op;
+       register int sz;                /* size of desired block */
+       int amt;                        /* amount to allocate */
+       int nblks;                      /* how many blocks we get */
+
+       /*
+        * sbrk_size <= 0 only for big, FLUFFY, requests (about
+        * 2^30 bytes on a VAX, I think) or for a negative arg.
+        */
+       sz = 1 << (bucket + 3);
+#ifdef DEBUG
+       ASSERT(sz > 0);
+#else
+       if (sz <= 0)
+               return;
+#endif
+       if (sz < pagesz) {
+               amt = pagesz;
+               nblks = amt / sz;
+       } else {
+               amt = sz + pagesz;
+               nblks = 1;
+       }
+       op = (union overhead *)sbrk(amt);
+       /* no more room! */
+       if ((int)op == -1)
+               return;
+       /*
+        * Add new memory allocated to that on
+        * free list for this hash bucket.
+        */
+       nextf[bucket] = op;
+       while (--nblks > 0) {
+               op->ov_next = (union overhead *)((caddr_t)op + sz);
+               op = (union overhead *)((caddr_t)op + sz);
+       }
+}
+
+void
+free(cp)
+       void *cp;
+{   
+       register int size;
+       register union overhead *op;
+
+       if (cp == NULL)
+               return;
+       op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+#ifdef DEBUG
+       ASSERT(op->ov_magic == MAGIC);          /* make sure it was in use */
+#else
+       if (op->ov_magic != MAGIC)
+               return;                         /* sanity */
+#endif
+#ifdef RCHECK
+       ASSERT(op->ov_rmagic == RMAGIC);
+       ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
+#endif
+       size = op->ov_index;
+       ASSERT(size < NBUCKETS);
+       op->ov_next = nextf[size];      /* also clobbers ov_magic */
+       nextf[size] = op;
+#ifdef MSTATS
+       nmalloc[size]--;
+#endif
+}
+
+/*
+ * When a program attempts "storage compaction" as mentioned in the
+ * old malloc man page, it realloc's an already freed block.  Usually
+ * this is the last block it freed; occasionally it might be farther
+ * back.  We have to search all the free lists for the block in order
+ * to determine its bucket: 1st we make one pass thru the lists
+ * checking only the first block in each; if that fails we search
+ * ``realloc_srchlen'' blocks in each list for a match (the variable
+ * is extern so the caller can modify it).  If that fails we just copy
+ * however many bytes was given to realloc() and hope it's not huge.
+ */
+int realloc_srchlen = 4;       /* 4 should be plenty, -1 =>'s whole list */
+
+void *
+realloc(cp, nbytes)
+       void *cp; 
+       size_t nbytes;
+{   
+       register u_int onb;
+       register int i;
+       union overhead *op;
+       char *res;
+       int was_alloced = 0;
+
+       if (cp == NULL)
+               return (malloc(nbytes));
+       op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+       if (op->ov_magic == MAGIC) {
+               was_alloced++;
+               i = op->ov_index;
+       } else {
+               /*
+                * Already free, doing "compaction".
+                *
+                * Search for the old block of memory on the
+                * free list.  First, check the most common
+                * case (last element free'd), then (this failing)
+                * the last ``realloc_srchlen'' items free'd.
+                * If all lookups fail, then assume the size of
+                * the memory block being realloc'd is the
+                * largest possible (so that all "nbytes" of new
+                * memory are copied into).  Note that this could cause
+                * a memory fault if the old area was tiny, and the moon
+                * is gibbous.  However, that is very unlikely.
+                */
+               if ((i = findbucket(op, 1)) < 0 &&
+                   (i = findbucket(op, realloc_srchlen)) < 0)
+                       i = NBUCKETS;
+       }
+       onb = 1 << (i + 3);
+       if (onb < pagesz)
+               onb -= sizeof (*op) + RSLOP;
+       else
+               onb += pagesz - sizeof (*op) - RSLOP;
+       /* avoid the copy if same size block */
+       if (was_alloced) {
+               if (i) {
+                       i = 1 << (i + 2);
+                       if (i < pagesz)
+                               i -= sizeof (*op) + RSLOP;
+                       else
+                               i += pagesz - sizeof (*op) - RSLOP;
+               }
+               if (nbytes <= onb && nbytes > i) {
+#ifdef RCHECK
+                       op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
+                       *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+#endif
+                       return(cp);
+               } else
+                       free(cp);
+       }
+       if ((res = malloc(nbytes)) == NULL)
+               return (NULL);
+       if (cp != res)          /* common optimization if "compacting" */
+               bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
+       return (res);
+}
+
+/*
+ * Search ``srchlen'' elements of each free list for a block whose
+ * header starts at ``freep''.  If srchlen is -1 search the whole list.
+ * Return bucket number, or -1 if not found.
+ */
+static
+findbucket(freep, srchlen)
+       union overhead *freep;
+       int srchlen;
+{
+       register union overhead *p;
+       register int i, j;
+
+       for (i = 0; i < NBUCKETS; i++) {
+               j = 0;
+               for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
+                       if (p == freep)
+                               return (i);
+                       j++;
+               }
+       }
+       return (-1);
+}
+
+#ifdef MSTATS
+/*
+ * mstats - print out statistics about malloc
+ * 
+ * Prints two lines of numbers, one showing the length of the free list
+ * for each size category, the second showing the number of mallocs -
+ * frees for each size category.
+ */
+mstats(s)
+       char *s;
+{
+       register int i, j;
+       register union overhead *p;
+       int totfree = 0,
+       totused = 0;
+
+       fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
+       for (i = 0; i < NBUCKETS; i++) {
+               for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
+                       ;
+               fprintf(stderr, " %d", j);
+               totfree += j * (1 << (i + 3));
+       }
+       fprintf(stderr, "\nused:\t");
+       for (i = 0; i < NBUCKETS; i++) {
+               fprintf(stderr, " %d", nmalloc[i]);
+               totused += nmalloc[i] * (1 << (i + 3));
+       }
+       fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
+           totused, totfree);
+}
+#endif
diff --git a/usr/src/lib/libc/stdlib/multibyte.c b/usr/src/lib/libc/stdlib/multibyte.c
new file mode 100644 (file)
index 0000000..6951279
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1991 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)multibyte.c        5.1 (Berkeley) 2/18/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+
+/*
+ * Stub multibyte character functions.
+ * These ignore the current fixed ("C") locale and
+ * always indicate that no multibyte characters are supported.
+ */
+
+int
+mblen(s, n)
+       const char *s;
+       size_t n;
+{
+       if (s && n && *s)
+               return -1;
+       return 0;
+}
+
+/*ARGSUSED*/
+int
+mbtowc(pwc, s, n)
+       wchar_t *pwc;
+       const char *s;
+       size_t n;
+{
+       if (s && n && *s)
+               return -1;
+       return 0;
+}
+
+/*ARGSUSED*/
+int
+#ifdef __STDC__
+wctomb(char *s, wchar_t wchar)
+#else
+wctomb(s, wchar)
+       char *s;
+       wchar_t wchar;
+#endif
+{
+       if (s)
+               return -1;
+       return 0;
+}
+
+/*ARGSUSED*/
+size_t
+mbstowcs(pwcs, s, n)
+       wchar_t *pwcs;
+       const char *s;
+       size_t n;
+{
+       if (s && n && *s)
+               return -1;
+       return 0;
+}
+
+/*ARGSUSED*/
+size_t
+wcstombs(s, pwcs, n)
+       char *s;
+       const wchar_t *pwcs;
+       size_t n;
+{
+       if (pwcs && n && *pwcs)
+               return -1;
+       return 0;
+}
diff --git a/usr/src/lib/libc/stdlib/putenv.c b/usr/src/lib/libc/stdlib/putenv.c
new file mode 100644 (file)
index 0000000..2a9728e
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putenv.c   5.4 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <string.h>
+
+int
+putenv(str)
+       const char *str;
+{
+       register char *p, *equal;
+       int rval;
+
+       if (!(p = strdup(str)))
+               return(1);
+       if (!(equal = index(p, '='))) {
+               (void)free(p);
+               return(1);
+       }
+       *equal = '\0';
+       rval = setenv(p, equal + 1, 1);
+       (void)free(p);
+       return(rval);
+}
diff --git a/usr/src/lib/libc/stdlib/qsort.c b/usr/src/lib/libc/stdlib/qsort.c
new file mode 100644 (file)
index 0000000..44a86d0
--- /dev/null
@@ -0,0 +1,275 @@
+/*-
+ * Copyright (c) 1980, 1983, 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)qsort.c    5.9 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+/*
+ * MTHRESH is the smallest partition for which we compare for a median
+ * value instead of using the middle value.
+ */
+#define        MTHRESH 6
+
+/*
+ * THRESH is the minimum number of entries in a partition for continued
+ * partitioning.
+ */
+#define        THRESH  4
+
+void
+qsort(bot, nmemb, size, compar)
+       void *bot;
+       size_t nmemb, size;
+       int (*compar) __P((const void *, const void *));
+{
+       static void insertion_sort(), quick_sort();
+
+       if (nmemb <= 1)
+               return;
+
+       if (nmemb >= THRESH)
+               quick_sort(bot, nmemb, size, compar);
+       else
+               insertion_sort(bot, nmemb, size, compar);
+}
+
+/*
+ * Swap two areas of size number of bytes.  Although qsort(3) permits random
+ * blocks of memory to be sorted, sorting pointers is almost certainly the
+ * common case (and, were it not, could easily be made so).  Regardless, it
+ * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
+ * arithmetic gets lost in the time required for comparison function calls.
+ */
+#define        SWAP(a, b) { \
+       cnt = size; \
+       do { \
+               ch = *a; \
+               *a++ = *b; \
+               *b++ = ch; \
+       } while (--cnt); \
+}
+
+/*
+ * Knuth, Vol. 3, page 116, Algorithm Q, step b, argues that a single pass
+ * of straight insertion sort after partitioning is complete is better than
+ * sorting each small partition as it is created.  This isn't correct in this
+ * implementation because comparisons require at least one (and often two)
+ * function calls and are likely to be the dominating expense of the sort.
+ * Doing a final insertion sort does more comparisons than are necessary
+ * because it compares the "edges" and medians of the partitions which are
+ * known to be already sorted.
+ *
+ * This is also the reasoning behind selecting a small THRESH value (see
+ * Knuth, page 122, equation 26), since the quicksort algorithm does less
+ * comparisons than the insertion sort.
+ */
+#define        SORT(bot, n) { \
+       if (n > 1) \
+               if (n == 2) { \
+                       t1 = bot + size; \
+                       if (compar(t1, bot) < 0) \
+                               SWAP(t1, bot); \
+               } else \
+                       insertion_sort(bot, n, size, compar); \
+}
+
+static void
+quick_sort(bot, nmemb, size, compar)
+       register char *bot;
+       register int size;
+       int nmemb, (*compar)();
+{
+       register int cnt;
+       register u_char ch;
+       register char *top, *mid, *t1, *t2;
+       register int n1, n2;
+       char *bsv;
+       static void insertion_sort();
+
+       /* bot and nmemb must already be set. */
+partition:
+
+       /* find mid and top elements */
+       mid = bot + size * (nmemb >> 1);
+       top = bot + (nmemb - 1) * size;
+
+       /*
+        * Find the median of the first, last and middle element (see Knuth,
+        * Vol. 3, page 123, Eq. 28).  This test order gets the equalities
+        * right.
+        */
+       if (nmemb >= MTHRESH) {
+               n1 = compar(bot, mid);
+               n2 = compar(mid, top);
+               if (n1 < 0 && n2 > 0)
+                       t1 = compar(bot, top) < 0 ? top : bot;
+               else if (n1 > 0 && n2 < 0)
+                       t1 = compar(bot, top) > 0 ? top : bot;
+               else
+                       t1 = mid;
+
+               /* if mid element not selected, swap selection there */
+               if (t1 != mid) {
+                       SWAP(t1, mid);
+                       mid -= size;
+               }
+       }
+
+       /* Standard quicksort, Knuth, Vol. 3, page 116, Algorithm Q. */
+#define        didswap n1
+#define        newbot  t1
+#define        replace t2
+       didswap = 0;
+       for (bsv = bot;;) {
+               for (; bot < mid && compar(bot, mid) <= 0; bot += size);
+               while (top > mid) {
+                       if (compar(mid, top) <= 0) {
+                               top -= size;
+                               continue;
+                       }
+                       newbot = bot + size;    /* value of bot after swap */
+                       if (bot == mid)         /* top <-> mid, mid == top */
+                               replace = mid = top;
+                       else {                  /* bot <-> top */
+                               replace = top;
+                               top -= size;
+                       }
+                       goto swap;
+               }
+               if (bot == mid)
+                       break;
+
+               /* bot <-> mid, mid == bot */
+               replace = mid;
+               newbot = mid = bot;             /* value of bot after swap */
+               top -= size;
+
+swap:          SWAP(bot, replace);
+               bot = newbot;
+               didswap = 1;
+       }
+
+       /*
+        * Quicksort behaves badly in the presence of data which is already
+        * sorted (see Knuth, Vol. 3, page 119) going from O N lg N to O N^2.
+        * To avoid this worst case behavior, if a re-partitioning occurs
+        * without swapping any elements, it is not further partitioned and
+        * is insert sorted.  This wins big with almost sorted data sets and
+        * only loses if the data set is very strangely partitioned.  A fix
+        * for those data sets would be to return prematurely if the insertion
+        * sort routine is forced to make an excessive number of swaps, and
+        * continue the partitioning.
+        */
+       if (!didswap) {
+               insertion_sort(bsv, nmemb, size, compar);
+               return;
+       }
+
+       /*
+        * Re-partition or sort as necessary.  Note that the mid element
+        * itself is correctly positioned and can be ignored.
+        */
+#define        nlower  n1
+#define        nupper  n2
+       bot = bsv;
+       nlower = (mid - bot) / size;    /* size of lower partition */
+       mid += size;
+       nupper = nmemb - nlower - 1;    /* size of upper partition */
+
+       /*
+        * If must call recursively, do it on the smaller partition; this
+        * bounds the stack to lg N entries.
+        */
+       if (nlower > nupper) {
+               if (nupper >= THRESH)
+                       quick_sort(mid, nupper, size, compar);
+               else {
+                       SORT(mid, nupper);
+                       if (nlower < THRESH) {
+                               SORT(bot, nlower);
+                               return;
+                       }
+               }
+               nmemb = nlower;
+       } else {
+               if (nlower >= THRESH)
+                       quick_sort(bot, nlower, size, compar);
+               else {
+                       SORT(bot, nlower);
+                       if (nupper < THRESH) {
+                               SORT(mid, nupper);
+                               return;
+                       }
+               }
+               bot = mid;
+               nmemb = nupper;
+       }
+       goto partition;
+       /* NOTREACHED */
+}
+
+static void
+insertion_sort(bot, nmemb, size, compar)
+       char *bot;
+       register int size;
+       int nmemb, (*compar)();
+{
+       register int cnt;
+       register u_char ch;
+       register char *s1, *s2, *t1, *t2, *top;
+
+       /*
+        * A simple insertion sort (see Knuth, Vol. 3, page 81, Algorithm
+        * S).  Insertion sort has the same worst case as most simple sorts
+        * (O N^2).  It gets used here because it is (O N) in the case of
+        * sorted data.
+        */
+       top = bot + nmemb * size;
+       for (t1 = bot + size; t1 < top;) {
+               for (t2 = t1; (t2 -= size) >= bot && compar(t1, t2) < 0;);
+               if (t1 != (t2 += size)) {
+                       /* Bubble bytes up through each element. */
+                       for (cnt = size; cnt--; ++t1) {
+                               ch = *t1;
+                               for (s1 = s2 = t1; (s2 -= size) >= t2; s1 = s2)
+                                       *s1 = *s2;
+                               *s1 = ch;
+                       }
+               } else
+                       t1 += size;
+       }
+}
diff --git a/usr/src/lib/libc/stdlib/radixsort.3 b/usr/src/lib/libc/stdlib/radixsort.3
new file mode 100644 (file)
index 0000000..0575ec7
--- /dev/null
@@ -0,0 +1,143 @@
+.\" Copyright (c) 1990, 1991 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.
+.\"
+.\"     @(#)radixsort.3        5.5 (Berkeley) 4/19/91
+.\"
+.Dd April 19, 1991
+.Dt RADIXSORT 3
+.Os
+.Sh NAME
+.Nm radixsort
+.Nd radix sort
+.Sh SYNOPSIS
+.Fd #include <limits.h>
+.Fd #include <stdlib.h>
+.Ft int
+.Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_char endbyte"
+.Sh DESCRIPTION
+The
+.Fn radixsort
+function
+is a modified radix sort.
+.Pp
+The
+.Fn radixsort
+function sorts an array of
+.Fa nmemb
+pointers to byte strings, the initial member of which is referenced
+by
+.Fa base .
+The byte strings may contain any values; the end of each string
+is denoted by the user-specified value
+.Fa endbyte .
+The contents of the array are sorted in ascending order according
+to the
+.Tn ASCII
+order of the byte strings they reference.
+.Pp
+Applications may specify a sort order by providing the
+.Fa table
+argument.
+If
+.Pf non- Dv NULL , 
+.Fa table
+must reference an array of
+.Dv UCHAR_MAX
++ 1 bytes which contains the sort
+weight of each possible byte value.
+The end-of-string byte must have a sort weight of 0.
+More than one byte may have the same sort weight.
+The
+.Fa table
+argument
+is useful for applications which wish to sort different characters
+equally; for example, providing a table with the same weights
+for A-Z as for a-z will result in a case-insensitive sort.
+.Pp
+The
+.Fn radixsort
+function
+is stable, that is, if two elements compare as equal, their order in
+the sorted array is unchanged.
+.Pp
+The
+.Fn radixsort
+function
+is a variant of most-significant-byte radix sorting; in particular, see
+D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
+The
+.Fn radixsort
+function
+takes linear time relative to the number of bytes in the strings.
+.Sh RETURN VALUES
+Upon successful completion 0 is returned.
+Otherwise, \-1 is returned and the global variable 
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn radixsort
+function
+may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr sort 1 ,
+.Xr qsort 3
+.Pp
+.Rs
+.%A Knuth, D.E.
+.%D 1968
+.%B "The Art of Computer Programming"
+.%T "Sorting and Searching"
+.%V Vol. 3
+.%P pp. 170-178
+.Re
+.Rs
+.%A Paige, R.
+.%D 1987
+.%T "Three Partition Refinement Algorithms"
+.%J "SIAM J. Comput."
+.%V Vol. 16
+.%N No. 6
+.Re
+.Sh HISTORY
+The
+.Fn radixsort
+function is
+.Ud .
+.Sh BUGS
+The
+.Fa nmemb
+argument
+must be less than the maximum integer,
+.Dv INT_MAX .
diff --git a/usr/src/lib/libc/stdlib/radixsort.c b/usr/src/lib/libc/stdlib/radixsort.c
new file mode 100644 (file)
index 0000000..5ba4818
--- /dev/null
@@ -0,0 +1,289 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)radixsort.c        5.7 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+/*
+ * __rspartition is the cutoff point for a further partitioning instead
+ * of a shellsort.  If it changes check __rsshell_increments.  Both of
+ * these are exported, as the best values are data dependent.
+ */
+#define        NPARTITION      40
+int __rspartition = NPARTITION;
+int __rsshell_increments[] = { 4, 1, 0, 0, 0, 0, 0, 0 };
+
+/*
+ * Stackp points to context structures, where each structure schedules a
+ * partitioning.  Radixsort exits when the stack is empty.
+ *
+ * If the buckets are placed on the stack randomly, the worst case is when
+ * all the buckets but one contain (npartitions + 1) elements and the bucket
+ * pushed on the stack last contains the rest of the elements.  In this case,
+ * stack growth is bounded by:
+ *
+ *     limit = (nelements / (npartitions + 1)) - 1;
+ *
+ * This is a very large number, 52,377,648 for the maximum 32-bit signed int.
+ *
+ * By forcing the largest bucket to be pushed on the stack first, the worst
+ * case is when all but two buckets each contain (npartitions + 1) elements,
+ * with the remaining elements split equally between the first and last
+ * buckets pushed on the stack.  In this case, stack growth is bounded when:
+ *
+ *     for (partition_cnt = 0; nelements > npartitions; ++partition_cnt)
+ *             nelements =
+ *                 (nelements - (npartitions + 1) * (nbuckets - 2)) / 2;
+ * The bound is:
+ *
+ *     limit = partition_cnt * (nbuckets - 1);
+ *
+ * This is a much smaller number, 4590 for the maximum 32-bit signed int.
+ */
+#define        NBUCKETS        (UCHAR_MAX + 1)
+
+typedef struct _stack {
+       const u_char **bot;
+       int indx, nmemb;
+} CONTEXT;
+
+#define        STACKPUSH { \
+       stackp->bot = p; \
+       stackp->nmemb = nmemb; \
+       stackp->indx = indx; \
+       ++stackp; \
+}
+#define        STACKPOP { \
+       if (stackp == stack) \
+               break; \
+       --stackp; \
+       bot = stackp->bot; \
+       nmemb = stackp->nmemb; \
+       indx = stackp->indx; \
+}
+
+/*
+ * A variant of MSD radix sorting; see Knuth Vol. 3, page 177, and 5.2.5,
+ * Ex. 10 and 12.  Also, "Three Partition Refinement Algorithms, Paige
+ * and Tarjan, SIAM J. Comput. Vol. 16, No. 6, December 1987.
+ *
+ * This uses a simple sort as soon as a bucket crosses a cutoff point,
+ * rather than sorting the entire list after partitioning is finished.
+ * This should be an advantage.
+ *
+ * This is pure MSD instead of LSD of some number of MSD, switching to
+ * the simple sort as soon as possible.  Takes linear time relative to
+ * the number of bytes in the strings.
+ */
+int
+#if __STDC__
+radixsort(const u_char **l1, int nmemb, const u_char *tab, u_char endbyte)
+#else
+radixsort(l1, nmemb, tab, endbyte)
+       const u_char **l1;
+       register int nmemb;
+       const u_char *tab;
+       u_char endbyte;
+#endif
+{
+       register int i, indx, t1, t2;
+       register const u_char **l2;
+       register const u_char **p;
+       register const u_char **bot;
+       register const u_char *tr;
+       CONTEXT *stack, *stackp;
+       int c[NBUCKETS + 1], max;
+       u_char ltab[NBUCKETS];
+       static void shellsort();
+
+       if (nmemb <= 1)
+               return(0);
+
+       /*
+        * T1 is the constant part of the equation, the number of elements
+        * represented on the stack between the top and bottom entries.
+        * It doesn't get rounded as the divide by 2 rounds down (correct
+        * for a value being subtracted).  T2, the nelem value, has to be
+        * rounded up before each divide because we want an upper bound;
+        * this could overflow if nmemb is the maximum int.
+        */
+       t1 = ((__rspartition + 1) * (NBUCKETS - 2)) >> 1;
+       for (i = 0, t2 = nmemb; t2 > __rspartition; i += NBUCKETS - 1)
+               t2 = ((t2 + 1) >> 1) - t1;
+       if (i) {
+               if (!(stack = stackp = (CONTEXT *)malloc(i * sizeof(CONTEXT))))
+                       return(-1);
+       } else
+               stack = stackp = NULL;
+
+       /*
+        * There are two arrays, one provided by the user (l1), and the
+        * temporary one (l2).  The data is sorted to the temporary stack,
+        * and then copied back.  The speedup of using index to determine
+        * which stack the data is on and simply swapping stacks back and
+        * forth, thus avoiding the copy every iteration, turns out to not
+        * be any faster than the current implementation.
+        */
+       if (!(l2 = (const u_char **)malloc(sizeof(u_char *) * nmemb)))
+               return(-1);
+
+       /*
+        * Tr references a table of sort weights; multiple entries may
+        * map to the same weight; EOS char must have the lowest weight.
+        */
+       if (tab)
+               tr = tab;
+       else {
+               for (t1 = 0, t2 = endbyte; t1 < t2; ++t1)
+                       ltab[t1] = t1 + 1;
+               ltab[t2] = 0;
+               for (t1 = endbyte + 1; t1 < NBUCKETS; ++t1)
+                       ltab[t1] = t1;
+               tr = ltab;
+       }
+
+       /* First sort is entire stack */
+       bot = l1;
+       indx = 0;
+
+       for (;;) {
+               /* Clear bucket count array */
+               bzero((char *)c, sizeof(c));
+
+               /*
+                * Compute number of items that sort to the same bucket
+                * for this index.
+                */
+               for (p = bot, i = nmemb; --i >= 0;)
+                       ++c[tr[(*p++)[indx]]];
+
+               /*
+                * Sum the number of characters into c, dividing the temp
+                * stack into the right number of buckets for this bucket,
+                * this index.  C contains the cumulative total of keys
+                * before and included in this bucket, and will later be
+                * used as an index to the bucket.  c[NBUCKETS] contains
+                * the total number of elements, for determining how many
+                * elements the last bucket contains.  At the same time
+                * find the largest bucket so it gets pushed first.
+                */
+               for (i = max = t1 = 0, t2 = __rspartition; i <= NBUCKETS; ++i) {
+                       if (c[i] > t2) {
+                               t2 = c[i];
+                               max = i;
+                       }
+                       t1 = c[i] += t1;
+               }
+
+               /*
+                * Partition the elements into buckets; c decrements through
+                * the bucket, and ends up pointing to the first element of
+                * the bucket.
+                */
+               for (i = nmemb; --i >= 0;) {
+                       --p;
+                       l2[--c[tr[(*p)[indx]]]] = *p;
+               }
+
+               /* Copy the partitioned elements back to user stack */
+               bcopy(l2, bot, nmemb * sizeof(u_char *));
+
+               ++indx;
+               /*
+                * Sort buckets as necessary; don't sort c[0], it's the
+                * EOS character bucket, and nothing can follow EOS.
+                */
+               for (i = max; i; --i) {
+                       if ((nmemb = c[i + 1] - (t1 = c[i])) < 2)
+                               continue;
+                       p = bot + t1;
+                       if (nmemb > __rspartition)
+                               STACKPUSH
+                       else
+                               shellsort(p, indx, nmemb, tr);
+               }
+               for (i = max + 1; i < NBUCKETS; ++i) {
+                       if ((nmemb = c[i + 1] - (t1 = c[i])) < 2)
+                               continue;
+                       p = bot + t1;
+                       if (nmemb > __rspartition)
+                               STACKPUSH
+                       else
+                               shellsort(p, indx, nmemb, tr);
+               }
+               /* Break out when stack is empty */
+               STACKPOP
+       }
+
+       free((char *)l2);
+       free((char *)stack);
+       return(0);
+}
+
+/*
+ * Shellsort (diminishing increment sort) from Data Structures and
+ * Algorithms, Aho, Hopcraft and Ullman, 1983 Edition, page 290;
+ * see also Knuth Vol. 3, page 84.  The increments are selected from
+ * formula (8), page 95.  Roughly O(N^3/2).
+ */
+static void
+shellsort(p, indx, nmemb, tr)
+       register u_char **p, *tr;
+       register int indx, nmemb;
+{
+       register u_char ch, *s1, *s2;
+       register int incr, *incrp, t1, t2;
+
+       for (incrp = __rsshell_increments; incr = *incrp++;)
+               for (t1 = incr; t1 < nmemb; ++t1)
+                       for (t2 = t1 - incr; t2 >= 0;) {
+                               s1 = p[t2] + indx;
+                               s2 = p[t2 + incr] + indx;
+                               while ((ch = tr[*s1++]) == tr[*s2] && ch)
+                                       ++s2;
+                               if (ch > tr[*s2]) {
+                                       s1 = p[t2];
+                                       p[t2] = p[t2 + incr];
+                                       p[t2 + incr] = s1;
+                                       t2 -= incr;
+                               } else
+                                       break;
+                       }
+}
diff --git a/usr/src/lib/libc/stdlib/random.3 b/usr/src/lib/libc/stdlib/random.3
new file mode 100644 (file)
index 0000000..872983c
--- /dev/null
@@ -0,0 +1,166 @@
+.\" Copyright (c) 1983, 1991 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.
+.\"
+.\"     @(#)random.3   6.5 (Berkeley) 4/19/91
+.\"
+.Dd April 19, 1991
+.Dt RANDOM 3
+.Os BSD 4.2
+.Sh NAME
+.Nm random ,
+.Nm srandom ,
+.Nm initstate ,
+.Nm setstate
+.Nd better random number generator; routines for changing generators
+.Sh SYNOPSIS
+.Fd #include <stdlib>
+.Ft long 
+.Fn random void
+.Ft void
+.Fn srandom "unsigned seed"
+.Ft char *
+.Fn initstate "unsigned seed" "char *state" "int n"
+.Ft char *
+.Fn setstate "char *state"
+.Sh DESCRIPTION
+The
+.Fn random
+function
+uses a non-linear additive feedback random number generator employing a
+default table of size 31 long integers to return successive pseudo-random
+numbers in the range from 0 to
+.if t 2\u\s731\s10\d\(mi1.
+.if n (2**31)\(mi1.
+The period of this random number generator is very large, approximately
+.if t 16\(mu(2\u\s731\s10\d\(mi1).
+.if n 16*((2**31)\(mi1).
+.Pp
+The
+.Fn random Ns / Fn srandom
+have (almost) the same calling sequence and initialization properties as
+.Xr rand 3 Ns / Xr srand 3 .
+The difference is that
+.Xr rand
+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
+.Fn random
+are usable.  For example,
+.Sq Li random()&01
+will produce a random binary
+value.
+.Pp
+Unlike
+.Xr srand ,
+.Fn srandom
+does not return the old seed; the reason for this is that the amount of
+state information used is much more than a single word.  (Two other
+routines are provided to deal with restarting/changing random
+number generators).  Like
+.Xr rand 3 ,
+however,
+.Fn random
+will by default produce a sequence of numbers that can be duplicated
+by calling
+.Fn srandom
+with 
+.Ql 1
+as the seed.
+.Pp
+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
+.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 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.
+The
+.Fn initstate
+function
+returns a pointer to the previous state information array.
+.Pp
+Once a state has been initialized, the
+.Fn setstate
+routine provides for rapid switching between states.
+The
+.Fn setstate
+function
+returns a pointer to the previous state array; its
+argument state array is used for further random number generation
+until the next call to
+.Fn initstate
+or
+.Fn setstate .
+.Pp
+Once a state array has been initialized, it may be restarted at a
+different point either by calling
+.Fn initstate
+(with the desired seed, the state array, and its size) or by calling
+both
+.Fn setstate
+(with the state array) and
+.Fn srandom
+(with the desired seed).
+The advantage of calling both
+.Fn setstate
+and
+.Fn srandom
+is that the size of the state array does not have to be remembered after
+it is initialized.
+.Pp
+With 256 bytes of state information, the period of the random number
+generator is greater than
+.if t 2\u\s769\s10\d,
+.if n 2**69
+which should be sufficient for most purposes.
+.Sh AUTHOR
+Earl T. Cohen
+.Sh DIAGNOSTICS
+If
+.Fn initstate
+is called with less than 8 bytes of state information, or if
+.Fn setstate
+detects that the state information has been garbled, error
+messages are printed on the standard error output.
+.Sh SEE ALSO
+.Xr rand 3
+.Sh HISTORY
+These
+functions appeared in 
+.Bx 4.2 .
+.Sh BUGS
+About 2/3 the speed of
+.Xr rand 3 .
diff --git a/usr/src/lib/libc/stdlib/random.c b/usr/src/lib/libc/stdlib/random.c
new file mode 100644 (file)
index 0000000..74c5c36
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)random.c   5.9 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * random.c:
+ *
+ * An improved random number generation package.  In addition to the standard
+ * rand()/srand() like interface, this package also has a special state info
+ * interface.  The initstate() routine is called with a seed, an array of
+ * bytes, and a count of how many bytes are being passed in; this array is
+ * then initialized to contain information for random number generation with
+ * that much state information.  Good sizes for the amount of state
+ * information are 32, 64, 128, and 256 bytes.  The state can be switched by
+ * calling the setstate() routine with the same array as was initiallized
+ * with initstate().  By default, the package runs with 128 bytes of state
+ * information and generates far better random numbers than a linear
+ * 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 longs; 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 longs worth of
+ * state information, which will allow a degree seven polynomial.  (Note:
+ * the zeroeth word of state information also has some other information
+ * stored in it -- see setstate() for details).
+ * 
+ * The random number generation technique is a linear feedback shift register
+ * approach, employing trinomials (since there are fewer terms to sum up that
+ * way).  In this approach, the least significant bit of all the numbers in
+ * the state table will act as a linear feedback shift register, and will
+ * have period 2^deg - 1 (where deg is the degree of the polynomial being
+ * used, assuming that the polynomial is irreducible and primitive).  The
+ * higher order bits will have longer periods, since their values are also
+ * influenced by pseudo-random carries out of the lower bits.  The total
+ * 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.
+ * With deg equal to seven, the period is actually much longer than the
+ * 7*(2**7 - 1) predicted by this formula.
+ */
+
+/*
+ * For each of the currently supported random number generators, we have a
+ * break value on the amount of state information (you need at least this
+ * many bytes of state info to support this random number generator), a degree
+ * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ * the separation between the two lower order coefficients of the trinomial.
+ */
+#define        TYPE_0          0               /* linear congruential */
+#define        BREAK_0         8
+#define        DEG_0           0
+#define        SEP_0           0
+
+#define        TYPE_1          1               /* x**7 + x**3 + 1 */
+#define        BREAK_1         32
+#define        DEG_1           7
+#define        SEP_1           3
+
+#define        TYPE_2          2               /* x**15 + x + 1 */
+#define        BREAK_2         64
+#define        DEG_2           15
+#define        SEP_2           1
+
+#define        TYPE_3          3               /* x**31 + x**3 + 1 */
+#define        BREAK_3         128
+#define        DEG_3           31
+#define        SEP_3           3
+
+#define        TYPE_4          4               /* x**63 + x + 1 */
+#define        BREAK_4         256
+#define        DEG_4           63
+#define        SEP_4           1
+
+/*
+ * Array versions of the above information to make code run faster --
+ * relies on fact that TYPE_i == i.
+ */
+#define        MAX_TYPES       5               /* max number of types above */
+
+static int degrees[MAX_TYPES] =        { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static int seps [MAX_TYPES] =  { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+/*
+ * Initially, everything is set up as if from:
+ *
+ *     initstate(1, &randtbl, 128);
+ *
+ * Note that this initialization takes advantage of the fact that srandom()
+ * advances the front and rear pointers 10*rand_deg times, and hence the
+ * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ * element of the state information, which contains info about the current
+ * position of the rear pointer is just
+ *
+ *     MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
+ */
+
+static long randtbl[DEG_3 + 1] = {
+       TYPE_3,
+       0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
+       0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
+       0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
+       0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+       0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
+       0x27fb47b9,
+};
+
+/*
+ * fptr and rptr are two pointers into the state info, a front and a rear
+ * pointer.  These two pointers are always rand_sep places aparts, as they
+ * cycle cyclically through the state information.  (Yes, this does mean we
+ * could get away with just one pointer, but the code for random() is more
+ * efficient this way).  The pointers are left positioned as they would be
+ * from the call
+ *
+ *     initstate(1, randtbl, 128);
+ *
+ * (The position of the rear pointer, rptr, is really 0 (as explained above
+ * in the initialization of randtbl) because the state table pointer is set
+ * to point to randtbl[1] (as explained below).
+ */
+static long *fptr = &randtbl[SEP_3 + 1];
+static long *rptr = &randtbl[1];
+
+/*
+ * The following things are the pointer to the state information table, the
+ * type of the current generator, the degree of the current polynomial being
+ * used, and the separation between the two pointers.  Note that for efficiency
+ * of random(), we remember the first location of the state information, not
+ * the zeroeth.  Hence it is valid to access state[-1], which is used to
+ * store the type of the R.N.G.  Also, we remember the last location, since
+ * this is more efficient than indexing every time to find the address of
+ * the last element to see if the front and rear pointers have wrapped.
+ */
+static long *state = &randtbl[1];
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+static long *end_ptr = &randtbl[DEG_3 + 1];
+
+/*
+ * srandom:
+ *
+ * Initialize the random number generator based on the given seed.  If the
+ * type is the trivial no-state-information type, just remember the seed.
+ * Otherwise, initializes state[] based on the given "seed" via a linear
+ * congruential generator.  Then, the pointers are set to known locations
+ * that are exactly rand_sep places apart.  Lastly, it cycles the state
+ * information a given number of times to get rid of any initial dependencies
+ * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
+ * for default usage relies on values produced by this routine.
+ */
+void
+srandom(x)
+       u_int x;
+{
+       register int i, j;
+
+       if (rand_type == TYPE_0)
+               state[0] = x;
+       else {
+               j = 1;
+               state[0] = x;
+               for (i = 1; i < rand_deg; i++)
+                       state[i] = 1103515245 * state[i - 1] + 12345;
+               fptr = &state[rand_sep];
+               rptr = &state[0];
+               for (i = 0; i < 10 * rand_deg; i++)
+                       (void)random();
+       }
+}
+
+/*
+ * initstate:
+ *
+ * Initialize the state information in the given array of n bytes for future
+ * random number generation.  Based on the number of bytes we are given, and
+ * the break values for the different R.N.G.'s, we choose the best (largest)
+ * one we can and set things up for it.  srandom() is then called to
+ * initialize the state information.
+ * 
+ * Note that on return from srandom(), we set state[-1] to be the type
+ * multiplexed with the current value of the rear pointer; this is so
+ * successive calls to initstate() won't lose this information and will be
+ * able to restart with setstate().
+ * 
+ * Note: the first thing we do is save the current state, if any, just like
+ * setstate() so that it doesn't matter when initstate is called.
+ *
+ * Returns a pointer to the old state.
+ */
+char *
+initstate(seed, arg_state, n)
+       u_int seed;                     /* seed for R.N.G. */
+       char *arg_state;                /* pointer to state array */
+       int n;                          /* # bytes of state info */
+{
+       register char *ostate = (char *)(&state[-1]);
+
+       if (rand_type == TYPE_0)
+               state[-1] = rand_type;
+       else
+               state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+       if (n < BREAK_0) {
+               (void)fprintf(stderr,
+                   "random: not enough state (%d bytes); ignored.\n", n);
+               return(0);
+       }
+       if (n < BREAK_1) {
+               rand_type = TYPE_0;
+               rand_deg = DEG_0;
+               rand_sep = SEP_0;
+       } else if (n < BREAK_2) {
+               rand_type = TYPE_1;
+               rand_deg = DEG_1;
+               rand_sep = SEP_1;
+       } else if (n < BREAK_3) {
+               rand_type = TYPE_2;
+               rand_deg = DEG_2;
+               rand_sep = SEP_2;
+       } else if (n < BREAK_4) {
+               rand_type = TYPE_3;
+               rand_deg = DEG_3;
+               rand_sep = SEP_3;
+       } else {
+               rand_type = TYPE_4;
+               rand_deg = DEG_4;
+               rand_sep = SEP_4;
+       }
+       state = &(((long *)arg_state)[1]);      /* first location */
+       end_ptr = &state[rand_deg];     /* must set end_ptr before srandom */
+       srandom(seed);
+       if (rand_type == TYPE_0)
+               state[-1] = rand_type;
+       else
+               state[-1] = MAX_TYPES*(rptr - state) + rand_type;
+       return(ostate);
+}
+
+/*
+ * setstate:
+ *
+ * Restore the state from the given state array.
+ *
+ * Note: it is important that we also remember the locations of the pointers
+ * in the current state information, and restore the locations of the pointers
+ * from the old state information.  This is done by multiplexing the pointer
+ * location into the zeroeth word of the state information.
+ *
+ * Note that due to the order in which things are done, it is OK to call
+ * setstate() with the same state as the current state.
+ *
+ * Returns a pointer to the old state information.
+ */
+char *
+setstate(arg_state)
+       char *arg_state;
+{
+       register long *new_state = (long *)arg_state;
+       register int type = new_state[0] % MAX_TYPES;
+       register int rear = new_state[0] / MAX_TYPES;
+       char *ostate = (char *)(&state[-1]);
+
+       if (rand_type == TYPE_0)
+               state[-1] = rand_type;
+       else
+               state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+       switch(type) {
+       case TYPE_0:
+       case TYPE_1:
+       case TYPE_2:
+       case TYPE_3:
+       case TYPE_4:
+               rand_type = type;
+               rand_deg = degrees[type];
+               rand_sep = seps[type];
+               break;
+       default:
+               (void)fprintf(stderr,
+                   "random: state info corrupted; not changed.\n");
+       }
+       state = &new_state[1];
+       if (rand_type != TYPE_0) {
+               rptr = &state[rear];
+               fptr = &state[(rear + rand_sep) % rand_deg];
+       }
+       end_ptr = &state[rand_deg];             /* set end_ptr too */
+       return(ostate);
+}
+
+/*
+ * random:
+ *
+ * If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is
+ * the same in all the other cases due to all the global variables that have
+ * been set up.  The basic operation is to add the number at the rear pointer
+ * into the one at the front pointer.  Then both pointers are advanced to
+ * the next location cyclically in the table.  The value returned is the sum
+ * generated, reduced to 31 bits by throwing away the "least random" low bit.
+ *
+ * Note: the code takes advantage of the fact that both the front and
+ * rear pointers can't wrap on the same call by not testing the rear
+ * pointer if the front one has wrapped.
+ *
+ * Returns a 31-bit random number.
+ */
+long
+random()
+{
+       long i;
+
+       if (rand_type == TYPE_0)
+               i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
+       else {
+               *fptr += *rptr;
+               i = (*fptr >> 1) & 0x7fffffff;  /* chucking least random bit */
+               if (++fptr >= end_ptr) {
+                       fptr = state;
+                       ++rptr;
+               } else if (++rptr >= end_ptr)
+                       rptr = state;
+       }
+       return(i);
+}
diff --git a/usr/src/lib/libc/stdlib/strtol.c b/usr/src/lib/libc/stdlib/strtol.c
new file mode 100644 (file)
index 0000000..000d876
--- /dev/null
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c   5.4 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(nptr, endptr, base)
+       const char *nptr;
+       char **endptr;
+       register int base;
+{
+       register const char *s = nptr;
+       register unsigned long acc;
+       register int c;
+       register unsigned long cutoff;
+       register int neg = 0, any, cutlim;
+
+       /*
+        * Skip white space and pick up leading +/- sign if any.
+        * If base is 0, allow 0x for hex and 0 for octal, else
+        * assume decimal; if base is already 16, allow 0x.
+        */
+       do {
+               c = *s++;
+       } while (isspace(c));
+       if (c == '-') {
+               neg = 1;
+               c = *s++;
+       } else if (c == '+')
+               c = *s++;
+       if ((base == 0 || base == 16) &&
+           c == '0' && (*s == 'x' || *s == 'X')) {
+               c = s[1];
+               s += 2;
+               base = 16;
+       }
+       if (base == 0)
+               base = c == '0' ? 8 : 10;
+
+       /*
+        * Compute the cutoff value between legal numbers and illegal
+        * numbers.  That is the largest legal value, divided by the
+        * base.  An input number that is greater than this value, if
+        * followed by a legal input character, is too big.  One that
+        * is equal to this value may be valid or not; the limit
+        * between valid and invalid numbers is then based on the last
+        * digit.  For instance, if the range for longs is
+        * [-2147483648..2147483647] and the input base is 10,
+        * cutoff will be set to 214748364 and cutlim to either
+        * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+        * a value > 214748364, or equal but the next digit is > 7 (or 8),
+        * the number is too big, and we will return a range error.
+        *
+        * Set any if any `digits' consumed; make it negative to indicate
+        * overflow.
+        */
+       cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+       cutlim = cutoff % (unsigned long)base;
+       cutoff /= (unsigned long)base;
+       for (acc = 0, any = 0;; c = *s++) {
+               if (isdigit(c))
+                       c -= '0';
+               else if (isalpha(c))
+                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+               else
+                       break;
+               if (c >= base)
+                       break;
+               if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+                       any = -1;
+               else {
+                       any = 1;
+                       acc *= base;
+                       acc += c;
+               }
+       }
+       if (any < 0) {
+               acc = neg ? LONG_MIN : LONG_MAX;
+               errno = ERANGE;
+       } else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = any ? s - 1 : (char *)nptr;
+       return (acc);
+}
diff --git a/usr/src/lib/libc/stdlib/strtoul.c b/usr/src/lib/libc/stdlib/strtoul.c
new file mode 100644 (file)
index 0000000..ed8c108
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoul.c  5.3 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(nptr, endptr, base)
+       const char *nptr;
+       char **endptr;
+       register int base;
+{
+       register const char *s = nptr;
+       register unsigned long acc;
+       register int c;
+       register unsigned long cutoff;
+       register int neg = 0, any, cutlim;
+
+       /*
+        * See strtol for comments as to the logic used.
+        */
+       do {
+               c = *s++;
+       } while (isspace(c));
+       if (c == '-') {
+               neg = 1;
+               c = *s++;
+       } else if (c == '+')
+               c = *s++;
+       if ((base == 0 || base == 16) &&
+           c == '0' && (*s == 'x' || *s == 'X')) {
+               c = s[1];
+               s += 2;
+               base = 16;
+       }
+       if (base == 0)
+               base = c == '0' ? 8 : 10;
+       cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+       cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+       for (acc = 0, any = 0;; c = *s++) {
+               if (isdigit(c))
+                       c -= '0';
+               else if (isalpha(c))
+                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+               else
+                       break;
+               if (c >= base)
+                       break;
+               if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+                       any = -1;
+               else {
+                       any = 1;
+                       acc *= base;
+                       acc += c;
+               }
+       }
+       if (any < 0) {
+               acc = ULONG_MAX;
+               errno = ERANGE;
+       } else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = any ? s - 1 : (char *)nptr;
+       return (acc);
+}
diff --git a/usr/src/lib/libc/stdlib/system.c b/usr/src/lib/libc/stdlib/system.c
new file mode 100644 (file)
index 0000000..f8c3a23
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)system.c   5.10 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <paths.h>
+
+system(command)
+       const char *command;
+{
+       union wait pstat;
+       pid_t pid;
+       int omask;
+       sig_t intsave, quitsave;
+
+       if (!command)           /* just checking... */
+               return(1);
+
+       omask = sigblock(sigmask(SIGCHLD));
+       switch(pid = vfork()) {
+       case -1:                        /* error */
+               (void)sigsetmask(omask);
+               pstat.w_status = 0;
+               pstat.w_retcode = 127;
+               return(pstat.w_status);
+       case 0:                         /* child */
+               (void)sigsetmask(omask);
+               execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
+               _exit(127);
+       }
+       intsave = signal(SIGINT, SIG_IGN);
+       quitsave = signal(SIGQUIT, SIG_IGN);
+       pid = waitpid(pid, (int *)&pstat, 0);
+       (void)sigsetmask(omask);
+       (void)signal(SIGINT, intsave);
+       (void)signal(SIGQUIT, quitsave);
+       return(pid == -1 ? -1 : pstat.w_status);
+}