diff options
| author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 |
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 |
| commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
| tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /lib | |
| parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
Diffstat (limited to 'lib')
689 files changed, 37661 insertions, 21317 deletions
diff --git a/lib/Makefile b/lib/Makefile index 8995044c55d5..29043c1fd223 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,7 +1,7 @@ # @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91 -SUBDIR= csu.${MACHINE} libc libcurses libm \ - libresolv librpc librpcsvc libtelnet libterm libutil liby +SUBDIR= csu.${MACHINE} libc libcurses libm libpthread \ + libresolv librpcsvc libtelnet libterm libutil liby .if exists(libcrypt) .if !defined(NOCRYPT) @@ -9,4 +9,10 @@ SUBDIR+= libcrypt .endif .endif +.if !defined(SPLIT_F2C) +SUBDIR+= libf2c +.else +SUBDIR+= libI77 libF77 +.endif + .include <bsd.subdir.mk> diff --git a/lib/Makefile.inc b/lib/Makefile.inc new file mode 100644 index 000000000000..8e9d1e78a221 --- /dev/null +++ b/lib/Makefile.inc @@ -0,0 +1,3 @@ +# Default version for system libs (override in <lib>/Makefile if necessary) +SHLIB_MAJOR?= 1 +SHLIB_MINOR?= 0 diff --git a/lib/csu.i386/Makefile b/lib/csu.i386/Makefile index aeb328edc755..503ad9753294 100644 --- a/lib/csu.i386/Makefile +++ b/lib/csu.i386/Makefile @@ -1,16 +1,22 @@ -# @(#)Makefile 5.6 (Berkeley) 5/22/91 +# from: @(#)Makefile 5.6 (Berkeley) 5/22/91 +# $Id: Makefile,v 1.8 1993/12/24 02:11:37 jkh Exp $ -CFLAGS= -O -DLIBC_SCCS -OBJS= crt0.o gcrt0.o +CFLAGS+= -DLIBC_SCCS -DDYNAMIC +OBJS= crt0.o gcrt0.o crt1.so CLEANFILES+= gmon.o moncrt0.o core a.out all: ${OBJS} crt0.o: crt0.c - ${CC} ${CFLAGS} -c -DCRT0 ${.ALLSRC} + ${CC} ${CFLAGS} -c -DCRT0 ${.ALLSRC} -o ${.TARGET} ${LD} -x -r ${.TARGET} mv a.out ${.TARGET} +crt1.so: crt1.c + ${CC} ${CFLAGS} -fpic -c ${.ALLSRC} -o ${.TARGET} + ${LD} -X -r ${.TARGET} + @mv a.out ${.TARGET} + moncrt0.o: crt0.c ${CC} ${CFLAGS} -c -DMCRT0 ${.ALLSRC} -o ${.TARGET} ${LD} -x -r ${.TARGET} @@ -20,7 +26,7 @@ gcrt0.o: moncrt0.o gmon.o ${LD} -x -r -o ${.TARGET} moncrt0.o gmon.o gmon.o: gmon.c gmon.h - ${CC} -c ${DEFS} ${.IMPSRC} + ${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${LD} -x -r ${.TARGET} mv a.out ${.TARGET} diff --git a/lib/csu.i386/crt0.c b/lib/csu.i386/crt0.c index 7c3cef10e6d6..93bb1e1ff7fb 100644 --- a/lib/csu.i386/crt0.c +++ b/lib/csu.i386/crt0.c @@ -1,5 +1,5 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. +/* + * Copyright (c) 1993 Paul Kranenburg * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -12,61 +12,105 @@ * 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 product includes software developed by Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * 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. + * $Id: crt0.c,v 1.9 1994/02/16 19:26:39 nate Exp $ */ + #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)crt0.c 5.7 (Berkeley) 7/3/91"; +static char sccsid[] = "%W% (Erasmus) %G%"; #endif /* LIBC_SCCS and not lint */ +extern void exit(); +int _callmain(); -/* - * C start up routine. - * Robert Henry, UCB, 20 Oct 81 - * - * We make the following (true) assumption: - * 1) The only register variable that we can trust is the frame pointer, - * ebp, which points to the base of the kernel calling frame. - */ +#include <sys/param.h> + +#ifdef DYNAMIC +#include <sys/types.h> +#include <sys/syscall.h> +#include <a.out.h> +#ifndef N_GETMAGIC +#define N_GETMAGIC(x) ((x).a_magic) +#endif +#ifndef N_BSSADDR +#define N_BSSADDR(x) (N_DATADDR(x)+(x).a_data) +#endif +#include <sys/mman.h> +#ifdef sun +#define MAP_COPY MAP_PRIVATE +#define MAP_FILE 0 +#define MAP_ANON 0 +#endif +#include <link.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -char **environ = (char **)0; -static char empty[1]; -char *__progname = empty; -int errno = 0; - -asm(".text"); -asm(".long 0xc000c000"); -#if 1 /* more needed for alignment on i486/gcc-2.3.3 */ -asm(".long 0xc000c000"); -asm(".long 0xc000c000"); -asm(".long 0xc000c000"); +extern struct _dynamic _DYNAMIC; +static struct ld_entry *ld_entry; +static void __do_dynamic_link (); +static char *_getenv(); +static int _strncmp(); + +#ifdef sun +#define LDSO "/usr/lib/ld.so" +#endif +#ifdef BSD +#define LDSO "/usr/libexec/ld.so" #endif +#endif /* DYNAMIC */ + +static char *_strrchr(); + +char **environ; + +#ifdef BSD extern unsigned char etext; extern unsigned char eprol asm ("eprol"); extern start() asm("start"); extern mcount() asm ("mcount"); +int errno; +static char empty[1]; +char *__progname = empty; +#endif + +/* + * We need these system calls, but can't use library stubs + */ +#define _exit(v) __syscall(SYS_exit, (v)) +#define open(name, f, m) __syscall(SYS_open, (name), (f), (m)) +#define close(fd) __syscall(SYS_close, (fd)) +#define read(fd, s, n) __syscall(SYS_read, (fd), (s), (n)) +#define write(fd, s, n) __syscall(SYS_write, (fd), (s), (n)) +#define dup(fd) __syscall(SYS_dup, (fd)) +#define dup2(fd, fdnew) __syscall(SYS_dup2, (fd), (fdnew)) +#ifdef sun +#define mmap(addr, len, prot, flags, fd, off) \ + __syscall(SYS_mmap, (addr), (len), (prot), _MAP_NEW|(flags), (fd), (off)) +#else +#define mmap(addr, len, prot, flags, fd, off) \ + __syscall(SYS_mmap, (addr), (len), (prot), (flags), (fd), (off)) +#endif + +#define _FATAL(str) \ + write(2, str, sizeof(str)), \ + _exit(1); + + start() { struct kframe { @@ -82,44 +126,251 @@ start() register char **targv; register char **argv; extern void _mcleanup(); +#ifdef DYNAMIC + volatile caddr_t x; +#endif #ifdef lint kfp = 0; initcode = initcode = 0; -#else not lint +#else /* not lint */ /* just above the saved frame pointer */ asm ("lea 4(%%ebp), %0" : "=r" (kfp) ); -#endif not lint +#endif /* not lint */ for (argv = targv = &kfp->kargv[0]; *targv++; /* void */) /* void */ ; if (targv >= (char **)(*argv)) --targv; environ = targv; + + if (argv[0]) + if ((__progname = _strrchr(argv[0], '/')) == NULL) + __progname = argv[0]; + else + ++__progname; + +#ifdef DYNAMIC + /* ld(1) convention: if DYNAMIC = 0 then statically linked */ +#ifdef stupid_gcc + if (&_DYNAMIC) + __do_dynamic_link(); +#else + x = (caddr_t)&_DYNAMIC; + if (x) + __do_dynamic_link(); +#endif +#endif /* DYNAMIC */ + asm("eprol:"); #ifdef MCRT0 atexit(_mcleanup); monstartup(&eprol, &etext); #endif MCRT0 - errno = 0; - if (argv[0]) - if ((__progname = strrchr(argv[0], '/')) == NULL) - __progname = argv[0]; - else - ++__progname; + +asm ("__callmain:"); /* Defined for the benefit of debuggers */ exit(main(kfp->kargc, argv, environ)); } -#ifdef CRT0 +#ifdef DYNAMIC +static void +__do_dynamic_link () +{ + struct crt_ldso crt; + struct exec hdr; + char *ldso; + int dupzfd; + int (*entry)(); + +#ifdef DEBUG + /* Provision for alternate ld.so - security risk! */ + if (!(ldso = _getenv("LDSO"))) +#endif + ldso = LDSO; + + crt.crt_ldfd = open(ldso, 0, 0); + if (crt.crt_ldfd == -1) { + _FATAL("No ld.so\n"); + } + + /* Read LDSO exec header */ + if (read(crt.crt_ldfd, &hdr, sizeof hdr) < sizeof hdr) { + _FATAL("Failure reading ld.so\n"); + } + if ((N_GETMAGIC_NET(hdr) != ZMAGIC) && (N_GETMAGIC(hdr) != QMAGIC)) { + _FATAL("Bad magic: ld.so\n"); + } + + /* We use MAP_ANON */ + crt.crt_dzfd = -1; + + /* Map in ld.so */ + crt.crt_ba = mmap(0, hdr.a_text, + PROT_READ|PROT_EXEC, + MAP_FILE|MAP_COPY, + crt.crt_ldfd, N_TXTOFF(hdr)); + if (crt.crt_ba == -1) { + _FATAL("Cannot map ld.so\n"); + } + +#ifdef BSD +/* !!! + * This is gross, ld.so is a ZMAGIC a.out, but has `sizeof(hdr)' for + * an entry point and not at PAGSIZ as the N_*ADDR macros assume. + */ +#undef N_DATADDR +#undef N_BSSADDR +#define N_DATADDR(x) ((x).a_text) +#define N_BSSADDR(x) ((x).a_text + (x).a_data) +#endif + + /* Map in data segment of ld.so writable */ + if (mmap(crt.crt_ba+N_DATADDR(hdr), hdr.a_data, + PROT_READ|PROT_WRITE, + MAP_FIXED|MAP_FILE|MAP_COPY, + crt.crt_ldfd, N_DATOFF(hdr)) == -1) { + _FATAL("Cannot map ld.so\n"); + } + + /* Map bss segment of ld.so zero */ + if (hdr.a_bss && mmap(crt.crt_ba+N_BSSADDR(hdr), hdr.a_bss, + PROT_READ|PROT_WRITE, + MAP_FIXED|MAP_ANON|MAP_COPY, + crt.crt_dzfd, 0) == -1) { + _FATAL("Cannot map ld.so\n"); + } + + crt.crt_dp = &_DYNAMIC; + crt.crt_ep = environ; + crt.crt_bp = (caddr_t)_callmain; + crt.crt_prog = __progname; + + entry = (int (*)())(crt.crt_ba + sizeof hdr); + if ((*entry)(CRT_VERSION_BSD_3, &crt) == -1) { + _FATAL("ld.so failed\n"); + } + + ld_entry = _DYNAMIC.d_entry; + return; +} + /* - * null mcount and moncontrol, - * just in case some routine is compiled for profiling + * DL stubs */ -moncontrol(val) - int val; + +void * +dlopen(name, mode) +char *name; +int mode; +{ + if (ld_entry == NULL) + return NULL; + + return (ld_entry->dlopen)(name, mode); +} + +int +dlclose(fd) +void *fd; +{ + if (ld_entry == NULL) + return -1; + + return (ld_entry->dlclose)(fd); +} + +void * +dlsym(fd, name) +void *fd; +char *name; +{ + if (ld_entry == NULL) + return NULL; + + return (ld_entry->dlsym)(fd, name); +} + +int +dlctl(fd, cmd, arg) +void *fd, *arg; +int cmd; { + if (ld_entry == NULL) + return -1; + return (ld_entry->dlctl)(fd, cmd, arg); } -mcount() { } -#endif CRT0 +/* + * Support routines + */ + +static int +_strncmp(s1, s2, n) + register char *s1, *s2; + register n; +{ + + if (n == 0) + return (0); + do { + if (*s1 != *s2++) + return (*(unsigned char *)s1 - *(unsigned char *)--s2); + if (*s1++ == 0) + break; + } while (--n != 0); + return (0); +} + +static char * +_getenv(name) + register char *name; +{ + 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) == '=') { + return(++C); + } + return (char *)0; +} + + asm(" ___syscall:"); + asm(" popl %ecx"); + asm(" popl %eax"); + asm(" pushl %ecx"); + asm(" .byte 0x9a"); + asm(" .long 0"); + asm(" .word 7"); + asm(" pushl %ecx"); + asm(" jc 1f"); + asm(" ret"); + asm(" 1:"); + asm(" movl $-1,%eax"); + asm(" ret"); + +#endif /* DYNAMIC */ + +static char * +_strrchr(p, ch) +register char *p, ch; +{ + register char *save; + + for (save = NULL;; ++p) { + if (*p == ch) + save = (char *)p; + if (!*p) + return(save); + } +/* NOTREACHED */ +} + +#ifdef MCRT0 +asm (" .text"); +asm ("_eprol:"); +#endif diff --git a/lib/csu.i386/crt1.c b/lib/csu.i386/crt1.c new file mode 100644 index 000000000000..bee2d1b6fb67 --- /dev/null +++ b/lib/csu.i386/crt1.c @@ -0,0 +1,47 @@ +typedef void (*func_ptr) (void); + +func_ptr __CTOR_LIST__[2]; +func_ptr __DTOR_LIST__[2]; + +/* Run all the global destructors on exit from the program. */ + +static void +__do_global_dtors () +{ + unsigned nptrs = (unsigned long) __DTOR_LIST__[0]; + unsigned i; + + /* Some systems place the number of pointers + in the first word of the table. + On other systems, that word is -1. + In all cases, the table is null-terminated. */ + + /* If the length is not recorded, count up to the null. */ + if (nptrs == -1) + for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++); + + /* GNU LD format. */ + for (i = nptrs; i >= 1; i--) + __DTOR_LIST__[i] (); + +} + +static void +__do_global_ctors () +{ + func_ptr *p; + + for (p = __CTOR_LIST__ + 1; *p; ) + (*p++)(); + atexit (__do_global_dtors); +} + +__init() +{ + static int initialized = 0; + if (! initialized) { + initialized = 1; + __do_global_ctors (); + } + +} diff --git a/lib/csu.i386/gmon.c b/lib/csu.i386/gmon.c index 55486881e133..852edba3ff27 100644 --- a/lib/csu.i386/gmon.c +++ b/lib/csu.i386/gmon.c @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91"; +/*static char sccsid[] = "from: @(#)gmon.c 5.3 (Berkeley) 5/22/91";*/ +static char rcsid[] = "$Id: gmon.c,v 1.2 1993/11/04 01:09:15 paul Exp $"; #endif /* LIBC_SCCS and not lint */ diff --git a/lib/csu.i386/gmon.h b/lib/csu.i386/gmon.h index c89a721972bd..0dd05738220a 100644 --- a/lib/csu.i386/gmon.h +++ b/lib/csu.i386/gmon.h @@ -30,7 +30,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)gmon.h 5.2 (Berkeley) 5/6/91 + * from: @(#)gmon.h 5.2 (Berkeley) 5/6/91 + * $Id: gmon.h,v 1.2 1993/11/04 01:09:18 paul Exp $ */ struct phdr { diff --git a/lib/libF77/Makefile b/lib/libF77/Makefile new file mode 100644 index 000000000000..9a790d656664 --- /dev/null +++ b/lib/libF77/Makefile @@ -0,0 +1,30 @@ +LIB=F77 +CFLAGS+= -DSkip_f2c_Undefs -DIEEE_drem + +MISC = Version.c main.c s_rnge.c abort_.c getarg_.c iargc_.c getenv_.c\ + signal_.c s_stop.c s_paus.c system_.c cabs.c\ + derf_.c derfc_.c erf_.c erfc_.c sig_die.c +POW = pow_ci.c pow_dd.c pow_di.c pow_hh.c pow_ii.c pow_ri.c pow_zi.c pow_zz.c +CX = c_abs.c c_cos.c c_div.c c_exp.c c_log.c c_sin.c c_sqrt.c +DCX = z_cos.c z_div.c z_exp.c z_log.c z_sin.c z_sqrt.c +REAL = r_abs.c r_acos.c r_asin.c r_atan.c r_atn2.c r_cnjg.c r_cos.c\ + r_cosh.c r_dim.c r_exp.c r_imag.c r_int.c\ + r_lg10.c r_log.c r_mod.c r_nint.c r_sign.c\ + r_sin.c r_sinh.c r_sqrt.c r_tan.c r_tanh.c +DBL = d_abs.c d_acos.c d_asin.c d_atan.c d_atn2.c\ + d_cnjg.c d_cos.c d_cosh.c d_dim.c d_exp.c\ + d_imag.c d_int.c d_lg10.c d_log.c d_mod.c\ + d_nint.c d_prod.c d_sign.c d_sin.c d_sinh.c\ + d_sqrt.c d_tan.c d_tanh.c +INT = i_abs.c i_dim.c i_dnnt.c i_indx.c i_len.c i_mod.c i_nint.c i_sign.c +HALF = h_abs.c h_dim.c h_dnnt.c h_indx.c h_len.c h_mod.c h_nint.c h_sign.c +CMP = l_ge.c l_gt.c l_le.c l_lt.c hl_ge.c hl_gt.c hl_le.c hl_lt.c +EFL = ef1asc_.c ef1cmc_.c +CHAR = s_cat.c s_cmp.c s_copy.c + +F77SRCS= $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ + $(HALF) $(CMP) $(EFL) $(CHAR) + +SRCS= ${F77SRCS} ${I77SRCS} + +.include <bsd.lib.mk> diff --git a/lib/libF77/Notice b/lib/libF77/Notice new file mode 100644 index 000000000000..64af9f12dc4e --- /dev/null +++ b/lib/libF77/Notice @@ -0,0 +1,23 @@ +/**************************************************************** +Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +Bellcore or any of their entities not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. +****************************************************************/ + diff --git a/lib/libF77/README b/lib/libF77/README new file mode 100644 index 000000000000..4bf21f998d5b --- /dev/null +++ b/lib/libF77/README @@ -0,0 +1,86 @@ +If your compiler does not recognize ANSI C headers, +compile with KR_headers defined: either add -DKR_headers +to the definition of CFLAGS in the makefile, or insert + +#define KR_headers + +at the top of f2c.h , cabs.c , main.c , and sig_die.c . + + +If you have a really ancient K&R C compiler that does not understand +void, add -Dvoid=int to the definition of CFLAGS in the makefile. + +If you use a C++ compiler, first create a local f2c.h by appending +f2ch.add to the usual f2c.h, e.g., by issuing the command + make f2c.h +which assumes f2c.h is installed in /usr/include . + +If your system lacks onexit() and you are not using an ANSI C +compiler, then you should compile main.c with NO_ONEXIT defined. +See the comments about onexit in the makefile. + +If your system has a double drem() function such that drem(a,b) +is the IEEE remainder function (with double a, b), then you may +wish to compile r_mod.c and d_mod.c with IEEE_drem defined. +On some systems, you may also need to compile with -Ddrem=remainder . + +To check for transmission errors, issue the command + make check +This assumes you have the xsum program whose source, xsum.c, +is distributed as part of "all from f2c/src". If you do not +have xsum, you can obtain xsum.c by sending the following E-mail +message to netlib@research.att.com + send xsum.c from f2c/src + +The makefile assumes you have installed f2c.h in a standard +place (and does not cause recompilation when f2c.h is changed); +f2c.h comes with "all from f2c" (the source for f2c) and is +available separately ("f2c.h from f2c"). + +Most of the routines in libF77 are support routines for Fortran +intrinsic functions or for operations that f2c chooses not +to do "in line". There are a few exceptions, summarized below -- +functions and subroutines that appear to your program as ordinary +external Fortran routines. + +1. CALL ABORT prints a message and causes a core dump. + +2. ERF(r) and DERF(d) and the REAL and DOUBLE PRECISION + error functions (with x REAL and d DOUBLE PRECISION); + DERF must be declared DOUBLE PRECISION in your program. + Both ERF and DERF assume your C library provides the + underlying erf() function (which not all systems do). + +3. ERFC(r) and DERFC(d) are the complementary error functions: + ERFC(r) = 1 - ERF(r) and DERFC(d) = 1.d0 - DERFC(d) + (except that their results may be more accurate than + explicitly evaluating the above formulae would give). + Again, ERFC and r are REAL, and DERFC and d are DOUBLE + PRECISION (and must be declared as such in your program), + and ERFC and DERFC rely on your system's erfc(). + +4. CALL GETARG(n,s), where n is an INTEGER and s is a CHARACTER + variable, sets s to the n-th command-line argument (or to + all blanks if there are fewer than n command-line arguments); + CALL GETARG(0,s) sets s to the name of the program (on systems + that support this feature). See IARGC below. + +5. CALL GETENV(name, value), where name and value are of type + CHARACTER, sets value to the environment value, $name, of + name (or to blanks if $name has not been set). + +6. NARGS = IARGC() sets NARGS to the number of command-line + arguments (an INTEGER value). + +7. CALL SIGNAL(n,func), where n is an INTEGER and func is an + EXTERNAL procedure, arranges for func to be invoked when + signal n occurs (on systems where this makes sense). + +8. CALL SYSTEM(cmd), where cmd is of type CHARACTER, passes + cmd to the system's command processor (on systems where + this can be done). + +The makefile does not attempt to compile pow_qq.c, which is meant +for use with INTEGER*8. To use it, you must modify f2c.h to +declare longint appropriately; then add pow_qq.o to the POW = +line in the makefile. diff --git a/lib/libF77/Version.c b/lib/libF77/Version.c new file mode 100644 index 000000000000..e6b99cfe1e9d --- /dev/null +++ b/lib/libF77/Version.c @@ -0,0 +1,27 @@ +static char junk[] = "\n@(#)LIBF77 VERSION 2.01 12 March 1993\n"; + +/* +2.00 11 June 1980. File version.c added to library. +2.01 31 May 1988. s_paus() flushes stderr; names of hl_* fixed + [ d]erf[c ] added + 8 Aug. 1989: #ifdefs for f2c -i2 added to s_cat.c + 29 Nov. 1989: s_cmp returns long (for f2c) + 30 Nov. 1989: arg types from f2c.h + 12 Dec. 1989: s_rnge allows long names + 19 Dec. 1989: getenv_ allows unsorted environment + 28 Mar. 1990: add exit(0) to end of main() + 2 Oct. 1990: test signal(...) == SIG_IGN rather than & 01 in main + 17 Oct. 1990: abort() calls changed to sig_die(...,1) + 22 Oct. 1990: separate sig_die from main + 25 Apr. 1991: minor, theoretically invisible tweaks to s_cat, sig_die + 31 May 1991: make system_ return status + 18 Dec. 1991: change long to ftnlen (for -i2) many places + 28 Feb. 1992: repair z_sqrt.c (scribbled on input, gave wrong answer) + 18 July 1992: for n < 0, repair handling of 0**n in pow_[dr]i.c + and m**n in pow_hh.c and pow_ii.c; + catch SIGTRAP in main() for error msg before abort + 23 July 1992: switch to ANSI prototypes unless KR_headers is #defined + 23 Oct. 1992: fix botch in signal_.c (erroneous deref of 2nd arg); + change Cabs to f__cabs. + 12 March 1993: various tweaks for C++. +*/ diff --git a/lib/libF77/abort_.c b/lib/libF77/abort_.c new file mode 100644 index 000000000000..9d4a0568ec74 --- /dev/null +++ b/lib/libF77/abort_.c @@ -0,0 +1,18 @@ +#include "stdio.h" +#include "f2c.h" + +#ifdef KR_headers +extern VOID sig_die(); + +int abort_() +#else +extern void sig_die(char*,int); + +int abort_(void) +#endif +{ +sig_die("Fortran abort routine called", 1); +#ifdef __cplusplus +return 0; +#endif +} diff --git a/lib/libF77/c_abs.c b/lib/libF77/c_abs.c new file mode 100644 index 000000000000..041fbd3d8bb0 --- /dev/null +++ b/lib/libF77/c_abs.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double f__cabs(); + +double c_abs(z) complex *z; +#else +extern double f__cabs(double, double); + +double c_abs(complex *z) +#endif +{ +return( f__cabs( z->r, z->i ) ); +} diff --git a/lib/libF77/c_cos.c b/lib/libF77/c_cos.c new file mode 100644 index 000000000000..d5fadd43b18e --- /dev/null +++ b/lib/libF77/c_cos.c @@ -0,0 +1,16 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double sin(), cos(), sinh(), cosh(); + +VOID c_cos(r, z) complex *r, *z; +#else +#undef abs +#include "math.h" + +void c_cos(complex *r, complex *z) +#endif +{ +r->r = cos(z->r) * cosh(z->i); +r->i = - sin(z->r) * sinh(z->i); +} diff --git a/lib/libF77/c_div.c b/lib/libF77/c_div.c new file mode 100644 index 000000000000..0bb56b485e1e --- /dev/null +++ b/lib/libF77/c_div.c @@ -0,0 +1,36 @@ +#include "f2c.h" + +#ifdef KR_headers +extern VOID sig_die(); +VOID c_div(c, a, b) +complex *a, *b, *c; +#else +extern void sig_die(char*,int); +void c_div(complex *c, complex *a, complex *b) +#endif +{ +double ratio, den; +double abr, abi; + +if( (abr = b->r) < 0.) + abr = - abr; +if( (abi = b->i) < 0.) + abi = - abi; +if( abr <= abi ) + { + if(abi == 0) + sig_die("complex division by zero", 1); + ratio = (double)b->r / b->i ; + den = b->i * (1 + ratio*ratio); + c->r = (a->r*ratio + a->i) / den; + c->i = (a->i*ratio - a->r) / den; + } + +else + { + ratio = (double)b->i / b->r ; + den = b->r * (1 + ratio*ratio); + c->r = (a->r + a->i*ratio) / den; + c->i = (a->i - a->r*ratio) / den; + } +} diff --git a/lib/libF77/c_exp.c b/lib/libF77/c_exp.c new file mode 100644 index 000000000000..8252c7f7012b --- /dev/null +++ b/lib/libF77/c_exp.c @@ -0,0 +1,19 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double exp(), cos(), sin(); + + VOID c_exp(r, z) complex *r, *z; +#else +#undef abs +#include "math.h" + +void c_exp(complex *r, complex *z) +#endif +{ +double expx; + +expx = exp(z->r); +r->r = expx * cos(z->i); +r->i = expx * sin(z->i); +} diff --git a/lib/libF77/c_log.c b/lib/libF77/c_log.c new file mode 100644 index 000000000000..a77521aee548 --- /dev/null +++ b/lib/libF77/c_log.c @@ -0,0 +1,16 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double log(), f__cabs(), atan2(); +VOID c_log(r, z) complex *r, *z; +#else +#undef abs +#include "math.h" +extern double f__cabs(double, double); + +void c_log(complex *r, complex *z) +#endif +{ +r->i = atan2(z->i, z->r); +r->r = log( f__cabs(z->r, z->i) ); +} diff --git a/lib/libF77/c_sin.c b/lib/libF77/c_sin.c new file mode 100644 index 000000000000..ffdef1d171fc --- /dev/null +++ b/lib/libF77/c_sin.c @@ -0,0 +1,16 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double sin(), cos(), sinh(), cosh(); + +VOID c_sin(r, z) complex *r, *z; +#else +#undef abs +#include "math.h" + +void c_sin(complex *r, complex *z) +#endif +{ +r->r = sin(z->r) * cosh(z->i); +r->i = cos(z->r) * sinh(z->i); +} diff --git a/lib/libF77/c_sqrt.c b/lib/libF77/c_sqrt.c new file mode 100644 index 000000000000..3b7342f4a49f --- /dev/null +++ b/lib/libF77/c_sqrt.c @@ -0,0 +1,34 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double sqrt(), f__cabs(); + +VOID c_sqrt(r, z) complex *r, *z; +#else +#undef abs +#include "math.h" +extern double f__cabs(double, double); + +void c_sqrt(complex *r, complex *z) +#endif +{ +double mag, t; + +if( (mag = f__cabs(z->r, z->i)) == 0.) + r->r = r->i = 0.; +else if(z->r > 0) + { + r->r = t = sqrt(0.5 * (mag + z->r) ); + t = z->i / t; + r->i = 0.5 * t; + } +else + { + t = sqrt(0.5 * (mag - z->r) ); + if(z->i < 0) + t = -t; + r->i = t; + t = z->i / t; + r->r = 0.5 * t; + } +} diff --git a/lib/libF77/cabs.c b/lib/libF77/cabs.c new file mode 100644 index 000000000000..8c14afd15ca2 --- /dev/null +++ b/lib/libF77/cabs.c @@ -0,0 +1,14 @@ +#ifdef KR_headers +extern double sqrt(); +double f__cabs(real, imag) double real, imag; +#else +#undef abs +#include "math.h" +double f__cabs(double real, double imag) +#endif +{ +struct {double x, y;} z; +z.x = real; +z.y = imag; +return cabs(z); +} diff --git a/lib/libF77/d_abs.c b/lib/libF77/d_abs.c new file mode 100644 index 000000000000..cb157e067b73 --- /dev/null +++ b/lib/libF77/d_abs.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_abs(x) doublereal *x; +#else +double d_abs(doublereal *x) +#endif +{ +if(*x >= 0) + return(*x); +return(- *x); +} diff --git a/lib/libF77/d_acos.c b/lib/libF77/d_acos.c new file mode 100644 index 000000000000..ecb56e87f540 --- /dev/null +++ b/lib/libF77/d_acos.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double acos(); +double d_acos(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_acos(doublereal *x) +#endif +{ +return( acos(*x) ); +} diff --git a/lib/libF77/d_asin.c b/lib/libF77/d_asin.c new file mode 100644 index 000000000000..045e73301c81 --- /dev/null +++ b/lib/libF77/d_asin.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double asin(); +double d_asin(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_asin(doublereal *x) +#endif +{ +return( asin(*x) ); +} diff --git a/lib/libF77/d_atan.c b/lib/libF77/d_atan.c new file mode 100644 index 000000000000..03530a1857c3 --- /dev/null +++ b/lib/libF77/d_atan.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double atan(); +double d_atan(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_atan(doublereal *x) +#endif +{ +return( atan(*x) ); +} diff --git a/lib/libF77/d_atn2.c b/lib/libF77/d_atn2.c new file mode 100644 index 000000000000..7c25ac046081 --- /dev/null +++ b/lib/libF77/d_atn2.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double atan2(); +double d_atn2(x,y) doublereal *x, *y; +#else +#undef abs +#include "math.h" +double d_atn2(doublereal *x, doublereal *y) +#endif +{ +return( atan2(*x,*y) ); +} diff --git a/lib/libF77/d_cnjg.c b/lib/libF77/d_cnjg.c new file mode 100644 index 000000000000..c778c38758cb --- /dev/null +++ b/lib/libF77/d_cnjg.c @@ -0,0 +1,12 @@ +#include "f2c.h" + + VOID +#ifdef KR_headers +d_cnjg(r, z) doublecomplex *r, *z; +#else +d_cnjg(doublecomplex *r, doublecomplex *z) +#endif +{ +r->r = z->r; +r->i = - z->i; +} diff --git a/lib/libF77/d_cos.c b/lib/libF77/d_cos.c new file mode 100644 index 000000000000..45c4838baee7 --- /dev/null +++ b/lib/libF77/d_cos.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double cos(); +double d_cos(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_cos(doublereal *x) +#endif +{ +return( cos(*x) ); +} diff --git a/lib/libF77/d_cosh.c b/lib/libF77/d_cosh.c new file mode 100644 index 000000000000..1181833cc1fa --- /dev/null +++ b/lib/libF77/d_cosh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double cosh(); +double d_cosh(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_cosh(doublereal *x) +#endif +{ +return( cosh(*x) ); +} diff --git a/lib/libF77/d_dim.c b/lib/libF77/d_dim.c new file mode 100644 index 000000000000..1d0ecb7bbb64 --- /dev/null +++ b/lib/libF77/d_dim.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_dim(a,b) doublereal *a, *b; +#else +double d_dim(doublereal *a, doublereal *b) +#endif +{ +return( *a > *b ? *a - *b : 0); +} diff --git a/lib/libF77/d_exp.c b/lib/libF77/d_exp.c new file mode 100644 index 000000000000..3f2b6ffcc45e --- /dev/null +++ b/lib/libF77/d_exp.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double exp(); +double d_exp(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_exp(doublereal *x) +#endif +{ +return( exp(*x) ); +} diff --git a/lib/libF77/d_imag.c b/lib/libF77/d_imag.c new file mode 100644 index 000000000000..793a3f9c4059 --- /dev/null +++ b/lib/libF77/d_imag.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_imag(z) doublecomplex *z; +#else +double d_imag(doublecomplex *z) +#endif +{ +return(z->i); +} diff --git a/lib/libF77/d_int.c b/lib/libF77/d_int.c new file mode 100644 index 000000000000..6c0e64215d8d --- /dev/null +++ b/lib/libF77/d_int.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +double d_int(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_int(doublereal *x) +#endif +{ +return( (*x>0) ? floor(*x) : -floor(- *x) ); +} diff --git a/lib/libF77/d_lg10.c b/lib/libF77/d_lg10.c new file mode 100644 index 000000000000..f03ff0043f86 --- /dev/null +++ b/lib/libF77/d_lg10.c @@ -0,0 +1,15 @@ +#include "f2c.h" + +#define log10e 0.43429448190325182765 + +#ifdef KR_headers +double log(); +double d_lg10(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_lg10(doublereal *x) +#endif +{ +return( log10e * log(*x) ); +} diff --git a/lib/libF77/d_log.c b/lib/libF77/d_log.c new file mode 100644 index 000000000000..d7a1941d56a5 --- /dev/null +++ b/lib/libF77/d_log.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double log(); +double d_log(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_log(doublereal *x) +#endif +{ +return( log(*x) ); +} diff --git a/lib/libF77/d_mod.c b/lib/libF77/d_mod.c new file mode 100644 index 000000000000..0d3ffbff9eb5 --- /dev/null +++ b/lib/libF77/d_mod.c @@ -0,0 +1,40 @@ +#include "f2c.h" + +#ifdef KR_headers +#ifdef IEEE_drem +double drem(); +#else +double floor(); +#endif +double d_mod(x,y) doublereal *x, *y; +#else +#ifdef IEEE_drem +double drem(double, double); +#else +#undef abs +#include "math.h" +#endif +double d_mod(doublereal *x, doublereal *y) +#endif +{ +#ifdef IEEE_drem + double xa, ya, z; + if ((ya = *y) < 0.) + ya = -ya; + z = drem(xa = *x, ya); + if (xa > 0) { + if (z < 0) + z += ya; + } + else if (z > 0) + z -= ya; + return z; +#else + double quotient; + if( (quotient = *x / *y) >= 0) + quotient = floor(quotient); + else + quotient = -floor(-quotient); + return(*x - (*y) * quotient ); +#endif +} diff --git a/lib/libF77/d_nint.c b/lib/libF77/d_nint.c new file mode 100644 index 000000000000..2ead3df200ae --- /dev/null +++ b/lib/libF77/d_nint.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +double d_nint(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_nint(doublereal *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/d_prod.c b/lib/libF77/d_prod.c new file mode 100644 index 000000000000..3d4cef7835c2 --- /dev/null +++ b/lib/libF77/d_prod.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_prod(x,y) real *x, *y; +#else +double d_prod(real *x, real *y) +#endif +{ +return( (*x) * (*y) ); +} diff --git a/lib/libF77/d_sign.c b/lib/libF77/d_sign.c new file mode 100644 index 000000000000..514ff0bbff82 --- /dev/null +++ b/lib/libF77/d_sign.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_sign(a,b) doublereal *a, *b; +#else +double d_sign(doublereal *a, doublereal *b) +#endif +{ +double x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} diff --git a/lib/libF77/d_sin.c b/lib/libF77/d_sin.c new file mode 100644 index 000000000000..0013af03496f --- /dev/null +++ b/lib/libF77/d_sin.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sin(); +double d_sin(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_sin(doublereal *x) +#endif +{ +return( sin(*x) ); +} diff --git a/lib/libF77/d_sinh.c b/lib/libF77/d_sinh.c new file mode 100644 index 000000000000..1ccd02ead97e --- /dev/null +++ b/lib/libF77/d_sinh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sinh(); +double d_sinh(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_sinh(doublereal *x) +#endif +{ +return( sinh(*x) ); +} diff --git a/lib/libF77/d_sqrt.c b/lib/libF77/d_sqrt.c new file mode 100644 index 000000000000..bee10a3a551f --- /dev/null +++ b/lib/libF77/d_sqrt.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sqrt(); +double d_sqrt(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_sqrt(doublereal *x) +#endif +{ +return( sqrt(*x) ); +} diff --git a/lib/libF77/d_tan.c b/lib/libF77/d_tan.c new file mode 100644 index 000000000000..23fa423188e3 --- /dev/null +++ b/lib/libF77/d_tan.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double tan(); +double d_tan(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_tan(doublereal *x) +#endif +{ +return( tan(*x) ); +} diff --git a/lib/libF77/d_tanh.c b/lib/libF77/d_tanh.c new file mode 100644 index 000000000000..0363a49b1be3 --- /dev/null +++ b/lib/libF77/d_tanh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double tanh(); +double d_tanh(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_tanh(doublereal *x) +#endif +{ +return( tanh(*x) ); +} diff --git a/lib/libF77/derf_.c b/lib/libF77/derf_.c new file mode 100644 index 000000000000..6afaccdaa3ed --- /dev/null +++ b/lib/libF77/derf_.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double erf(); +double derf_(x) doublereal *x; +#else +extern double erf(double); +double derf_(doublereal *x) +#endif +{ +return( erf(*x) ); +} diff --git a/lib/libF77/derfc_.c b/lib/libF77/derfc_.c new file mode 100644 index 000000000000..e199f916058e --- /dev/null +++ b/lib/libF77/derfc_.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +extern double erfc(); + +double derfc_(x) doublereal *x; +#else +extern double erfc(double); + +double derfc_(doublereal *x) +#endif +{ +return( erfc(*x) ); +} diff --git a/lib/libF77/disclaimer b/lib/libF77/disclaimer new file mode 100644 index 000000000000..59db1ecf42fd --- /dev/null +++ b/lib/libF77/disclaimer @@ -0,0 +1,15 @@ +f2c is a Fortran to C converter under development by + David Gay (AT&T Bell Labs) + Stu Feldman (Bellcore) + Mark Maimone (Carnegie-Mellon University) + Norm Schryer (AT&T Bell Labs) +Please send bug reports to dmg@research.att.com or uunet!research!dmg. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. diff --git a/lib/libF77/ef1asc_.c b/lib/libF77/ef1asc_.c new file mode 100644 index 000000000000..b2b8d72a7811 --- /dev/null +++ b/lib/libF77/ef1asc_.c @@ -0,0 +1,21 @@ +/* EFL support routine to copy string b to string a */ + +#include "f2c.h" + + +#define M ( (long) (sizeof(long) - 1) ) +#define EVEN(x) ( ( (x)+ M) & (~M) ) + +#ifdef KR_headers +extern VOID s_copy(); +ef1asc_(a, la, b, lb) ftnint *a, *b; ftnlen *la, *lb; +#else +extern void s_copy(char*,char*,ftnlen,ftnlen); +int ef1asc_(ftnint *a, ftnlen *la, ftnint *b, ftnlen *lb) +#endif +{ +s_copy( (char *)a, (char *)b, EVEN(*la), *lb ); +#ifdef __cplusplus +return 0; +#endif +} diff --git a/lib/libF77/ef1cmc_.c b/lib/libF77/ef1cmc_.c new file mode 100644 index 000000000000..8239a6ba2e1f --- /dev/null +++ b/lib/libF77/ef1cmc_.c @@ -0,0 +1,14 @@ +/* EFL support routine to compare two character strings */ + +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +integer ef1cmc_(a, la, b, lb) ftnint *a, *b; ftnlen *la, *lb; +#else +extern integer s_cmp(char*,char*,ftnlen,ftnlen); +integer ef1cmc_(ftnint *a, ftnlen *la, ftnint *b, ftnlen *lb) +#endif +{ +return( s_cmp( (char *)a, (char *)b, *la, *lb) ); +} diff --git a/lib/libF77/erf_.c b/lib/libF77/erf_.c new file mode 100644 index 000000000000..f7565ae6ae39 --- /dev/null +++ b/lib/libF77/erf_.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double erf(); +double erf_(x) real *x; +#else +extern double erf(double); +double erf_(real *x) +#endif +{ +return( erf(*x) ); +} diff --git a/lib/libF77/erfc_.c b/lib/libF77/erfc_.c new file mode 100644 index 000000000000..56adb2f910b7 --- /dev/null +++ b/lib/libF77/erfc_.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double erfc(); +double erfc_(x) real *x; +#else +extern double erfc(double); +double erfc_(real *x) +#endif +{ +return( erfc(*x) ); +} diff --git a/lib/libF77/f2ch.add b/lib/libF77/f2ch.add new file mode 100644 index 000000000000..4ab0d8078c65 --- /dev/null +++ b/lib/libF77/f2ch.add @@ -0,0 +1,162 @@ +/* If you are using a C++ compiler, append the following to f2c.h + for compiling libF77 and libI77. */ + +#ifdef __cplusplus +extern "C" { +extern int abort_(void); +extern double c_abs(complex *); +extern void c_cos(complex *, complex *); +extern void c_div(complex *, complex *, complex *); +extern void c_exp(complex *, complex *); +extern void c_log(complex *, complex *); +extern void c_sin(complex *, complex *); +extern void c_sqrt(complex *, complex *); +extern double d_abs(double *); +extern double d_acos(double *); +extern double d_asin(double *); +extern double d_atan(double *); +extern double d_atn2(double *, double *); +extern void d_cnjg(doublecomplex *, doublecomplex *); +extern double d_cos(double *); +extern double d_cosh(double *); +extern double d_dim(double *, double *); +extern double d_exp(double *); +extern double d_imag(doublecomplex *); +extern double d_int(double *); +extern double d_lg10(double *); +extern double d_log(double *); +extern double d_mod(double *, double *); +extern double d_nint(double *); +extern double d_prod(float *, float *); +extern double d_sign(double *, double *); +extern double d_sin(double *); +extern double d_sinh(double *); +extern double d_sqrt(double *); +extern double d_tan(double *); +extern double d_tanh(double *); +extern double derf_(double *); +extern double derfc_(double *); +extern integer do_fio(ftnint *, char *, ftnlen); +extern integer do_lio(ftnint *, ftnint *, char *, ftnlen); +extern integer do_uio(ftnint *, char *, ftnlen); +extern integer e_rdfe(void); +extern integer e_rdue(void); +extern integer e_rsfe(void); +extern integer e_rsfi(void); +extern integer e_rsle(void); +extern integer e_rsli(void); +extern integer e_rsue(void); +extern integer e_wdfe(void); +extern integer e_wdue(void); +extern integer e_wsfe(void); +extern integer e_wsfi(void); +extern integer e_wsle(void); +extern integer e_wsli(void); +extern integer e_wsue(void); +extern int ef1asc_(ftnint *, ftnlen *, ftnint *, ftnlen *); +extern integer ef1cmc_(ftnint *, ftnlen *, ftnint *, ftnlen *); +extern double erf(double); +extern double erf_(float *); +extern double erfc(double); +extern double erfc_(float *); +extern integer f_back(alist *); +extern integer f_clos(cllist *); +extern integer f_end(alist *); +extern void f_exit(void); +extern integer f_inqu(inlist *); +extern integer f_open(olist *); +extern integer f_rew(alist *); +extern int flush_(void); +extern void getarg_(integer *, char *, ftnlen); +extern void getenv_(char *, char *, ftnlen, ftnlen); +extern short h_abs(short *); +extern short h_dim(short *, short *); +extern short h_dnnt(double *); +extern short h_indx(char *, char *, ftnlen, ftnlen); +extern short h_len(char *, ftnlen); +extern short h_mod(short *, short *); +extern short h_nint(float *); +extern short h_sign(short *, short *); +extern short hl_ge(char *, char *, ftnlen, ftnlen); +extern short hl_gt(char *, char *, ftnlen, ftnlen); +extern short hl_le(char *, char *, ftnlen, ftnlen); +extern short hl_lt(char *, char *, ftnlen, ftnlen); +extern integer i_abs(integer *); +extern integer i_dim(integer *, integer *); +extern integer i_dnnt(double *); +extern integer i_indx(char *, char *, ftnlen, ftnlen); +extern integer i_len(char *, ftnlen); +extern integer i_mod(integer *, integer *); +extern integer i_nint(float *); +extern integer i_sign(integer *, integer *); +extern integer iargc_(void); +extern ftnlen l_ge(char *, char *, ftnlen, ftnlen); +extern ftnlen l_gt(char *, char *, ftnlen, ftnlen); +extern ftnlen l_le(char *, char *, ftnlen, ftnlen); +extern ftnlen l_lt(char *, char *, ftnlen, ftnlen); +extern void pow_ci(complex *, complex *, integer *); +extern double pow_dd(double *, double *); +extern double pow_di(double *, integer *); +extern short pow_hh(short *, shortint *); +extern integer pow_ii(integer *, integer *); +extern double pow_ri(float *, integer *); +extern void pow_zi(doublecomplex *, doublecomplex *, integer *); +extern void pow_zz(doublecomplex *, doublecomplex *, doublecomplex *); +extern double r_abs(float *); +extern double r_acos(float *); +extern double r_asin(float *); +extern double r_atan(float *); +extern double r_atn2(float *, float *); +extern void r_cnjg(complex *, complex *); +extern double r_cos(float *); +extern double r_cosh(float *); +extern double r_dim(float *, float *); +extern double r_exp(float *); +extern double r_imag(complex *); +extern double r_int(float *); +extern double r_lg10(float *); +extern double r_log(float *); +extern double r_mod(float *, float *); +extern double r_nint(float *); +extern double r_sign(float *, float *); +extern double r_sin(float *); +extern double r_sinh(float *); +extern double r_sqrt(float *); +extern double r_tan(float *); +extern double r_tanh(float *); +extern void s_cat(char *, char **, integer *, integer *, ftnlen); +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +extern void s_copy(char *, char *, ftnlen, ftnlen); +extern int s_paus(char *, ftnlen); +extern integer s_rdfe(cilist *); +extern integer s_rdue(cilist *); +extern integer s_rnge(char *, integer, char *, integer); +extern integer s_rsfe(cilist *); +extern integer s_rsfi(icilist *); +extern integer s_rsle(cilist *); +extern integer s_rsli(icilist *); +extern integer s_rsne(cilist *); +extern integer s_rsni(icilist *); +extern integer s_rsue(cilist *); +extern int s_stop(char *, ftnlen); +extern integer s_wdfe(cilist *); +extern integer s_wdue(cilist *); +extern integer s_wsfe(cilist *); +extern integer s_wsfi(icilist *); +extern integer s_wsle(cilist *); +extern integer s_wsli(icilist *); +extern integer s_wsne(cilist *); +extern integer s_wsni(icilist *); +extern integer s_wsue(cilist *); +extern void sig_die(char *, int); +extern integer signal_(integer *, void (*)(int)); +extern int system_(char *, ftnlen); +extern double z_abs(doublecomplex *); +extern void z_cos(doublecomplex *, doublecomplex *); +extern void z_div(doublecomplex *, doublecomplex *, doublecomplex *); +extern void z_exp(doublecomplex *, doublecomplex *); +extern void z_log(doublecomplex *, doublecomplex *); +extern void z_sin(doublecomplex *, doublecomplex *); +extern void z_sqrt(doublecomplex *, doublecomplex *); + } +#endif diff --git a/lib/libF77/getarg_.c b/lib/libF77/getarg_.c new file mode 100644 index 000000000000..fef0da7b1d5f --- /dev/null +++ b/lib/libF77/getarg_.c @@ -0,0 +1,28 @@ +#include "f2c.h" + +/* + * subroutine getarg(k, c) + * returns the kth unix command argument in fortran character + * variable argument c +*/ + +#ifdef KR_headers +VOID getarg_(n, s, ls) ftnint *n; register char *s; ftnlen ls; +#else +void getarg_(ftnint *n, register char *s, ftnlen ls) +#endif +{ +extern int xargc; +extern char **xargv; +register char *t; +register int i; + +if(*n>=0 && *n<xargc) + t = xargv[*n]; +else + t = ""; +for(i = 0; i<ls && *t!='\0' ; ++i) + *s++ = *t++; +for( ; i<ls ; ++i) + *s++ = ' '; +} diff --git a/lib/libF77/getenv_.c b/lib/libF77/getenv_.c new file mode 100644 index 000000000000..2a035ea9a6bb --- /dev/null +++ b/lib/libF77/getenv_.c @@ -0,0 +1,51 @@ +#include "f2c.h" + +/* + * getenv - f77 subroutine to return environment variables + * + * called by: + * call getenv (ENV_NAME, char_var) + * where: + * ENV_NAME is the name of an environment variable + * char_var is a character variable which will receive + * the current value of ENV_NAME, or all blanks + * if ENV_NAME is not defined + */ + +#ifdef KR_headers +VOID getenv_(fname, value, flen, vlen) char *value, *fname; ftnlen vlen, flen; +#else +void getenv_(char *fname, char *value, ftnlen flen, ftnlen vlen) +#endif +{ +extern char **environ; +register char *ep, *fp, *flast; +register char **env = environ; + +flast = fname + flen; +for(fp = fname ; fp < flast ; ++fp) + if(*fp == ' ') + { + flast = fp; + break; + } + +while (ep = *env++) + { + for(fp = fname; fp<flast ; ) + if(*fp++ != *ep++) + goto endloop; + + if(*ep++ == '=') { /* copy right hand side */ + while( *ep && --vlen>=0 ) + *value++ = *ep++; + + goto blank; + } +endloop: ; + } + +blank: + while( --vlen >= 0 ) + *value++ = ' '; +} diff --git a/lib/libF77/h_abs.c b/lib/libF77/h_abs.c new file mode 100644 index 000000000000..73b82151ac1d --- /dev/null +++ b/lib/libF77/h_abs.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_abs(x) shortint *x; +#else +shortint h_abs(shortint *x) +#endif +{ +if(*x >= 0) + return(*x); +return(- *x); +} diff --git a/lib/libF77/h_dim.c b/lib/libF77/h_dim.c new file mode 100644 index 000000000000..ceff660e26cd --- /dev/null +++ b/lib/libF77/h_dim.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_dim(a,b) shortint *a, *b; +#else +shortint h_dim(shortint *a, shortint *b) +#endif +{ +return( *a > *b ? *a - *b : 0); +} diff --git a/lib/libF77/h_dnnt.c b/lib/libF77/h_dnnt.c new file mode 100644 index 000000000000..9fbeb5ce6244 --- /dev/null +++ b/lib/libF77/h_dnnt.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +shortint h_dnnt(x) doublereal *x; +#else +#undef abs +#include "math.h" +shortint h_dnnt(doublereal *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/h_indx.c b/lib/libF77/h_indx.c new file mode 100644 index 000000000000..a211cc7fa0fb --- /dev/null +++ b/lib/libF77/h_indx.c @@ -0,0 +1,26 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_indx(a, b, la, lb) char *a, *b; ftnlen la, lb; +#else +shortint h_indx(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +ftnlen i, n; +char *s, *t, *bend; + +n = la - lb + 1; +bend = b + lb; + +for(i = 0 ; i < n ; ++i) + { + s = a + i; + t = b; + while(t < bend) + if(*s++ != *t++) + goto no; + return((shortint)i+1); + no: ; + } +return(0); +} diff --git a/lib/libF77/h_len.c b/lib/libF77/h_len.c new file mode 100644 index 000000000000..00a2151bfa11 --- /dev/null +++ b/lib/libF77/h_len.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_len(s, n) char *s; ftnlen n; +#else +shortint h_len(char *s, ftnlen n) +#endif +{ +return(n); +} diff --git a/lib/libF77/h_mod.c b/lib/libF77/h_mod.c new file mode 100644 index 000000000000..43431c1c503c --- /dev/null +++ b/lib/libF77/h_mod.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_mod(a,b) short *a, *b; +#else +shortint h_mod(short *a, short *b) +#endif +{ +return( *a % *b); +} diff --git a/lib/libF77/h_nint.c b/lib/libF77/h_nint.c new file mode 100644 index 000000000000..bf63df128d89 --- /dev/null +++ b/lib/libF77/h_nint.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +shortint h_nint(x) real *x; +#else +#undef abs +#include "math.h" +shortint h_nint(real *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/h_sign.c b/lib/libF77/h_sign.c new file mode 100644 index 000000000000..7b06c157a74e --- /dev/null +++ b/lib/libF77/h_sign.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint h_sign(a,b) shortint *a, *b; +#else +shortint h_sign(shortint *a, shortint *b) +#endif +{ +shortint x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} diff --git a/lib/libF77/hl_ge.c b/lib/libF77/hl_ge.c new file mode 100644 index 000000000000..4c29527065a2 --- /dev/null +++ b/lib/libF77/hl_ge.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +shortlogical hl_ge(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +shortlogical hl_ge(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) >= 0); +} diff --git a/lib/libF77/hl_gt.c b/lib/libF77/hl_gt.c new file mode 100644 index 000000000000..c4f345a0859e --- /dev/null +++ b/lib/libF77/hl_gt.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +shortlogical hl_gt(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +shortlogical hl_gt(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) > 0); +} diff --git a/lib/libF77/hl_le.c b/lib/libF77/hl_le.c new file mode 100644 index 000000000000..a9cce596c715 --- /dev/null +++ b/lib/libF77/hl_le.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +shortlogical hl_le(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +shortlogical hl_le(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) <= 0); +} diff --git a/lib/libF77/hl_lt.c b/lib/libF77/hl_lt.c new file mode 100644 index 000000000000..162d919c3b48 --- /dev/null +++ b/lib/libF77/hl_lt.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +shortlogical hl_lt(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +shortlogical hl_lt(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) < 0); +} diff --git a/lib/libF77/i_abs.c b/lib/libF77/i_abs.c new file mode 100644 index 000000000000..be21295aaa12 --- /dev/null +++ b/lib/libF77/i_abs.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_abs(x) integer *x; +#else +integer i_abs(integer *x) +#endif +{ +if(*x >= 0) + return(*x); +return(- *x); +} diff --git a/lib/libF77/i_dim.c b/lib/libF77/i_dim.c new file mode 100644 index 000000000000..6e1b1707b555 --- /dev/null +++ b/lib/libF77/i_dim.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_dim(a,b) integer *a, *b; +#else +integer i_dim(integer *a, integer *b) +#endif +{ +return( *a > *b ? *a - *b : 0); +} diff --git a/lib/libF77/i_dnnt.c b/lib/libF77/i_dnnt.c new file mode 100644 index 000000000000..9d46c4b6ad9d --- /dev/null +++ b/lib/libF77/i_dnnt.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +integer i_dnnt(x) doublereal *x; +#else +#undef abs +#include "math.h" +integer i_dnnt(doublereal *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/i_indx.c b/lib/libF77/i_indx.c new file mode 100644 index 000000000000..96e7bc51ba85 --- /dev/null +++ b/lib/libF77/i_indx.c @@ -0,0 +1,26 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_indx(a, b, la, lb) char *a, *b; ftnlen la, lb; +#else +integer i_indx(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +ftnlen i, n; +char *s, *t, *bend; + +n = la - lb + 1; +bend = b + lb; + +for(i = 0 ; i < n ; ++i) + { + s = a + i; + t = b; + while(t < bend) + if(*s++ != *t++) + goto no; + return(i+1); + no: ; + } +return(0); +} diff --git a/lib/libF77/i_len.c b/lib/libF77/i_len.c new file mode 100644 index 000000000000..4020fee46183 --- /dev/null +++ b/lib/libF77/i_len.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_len(s, n) char *s; ftnlen n; +#else +integer i_len(char *s, ftnlen n) +#endif +{ +return(n); +} diff --git a/lib/libF77/i_mod.c b/lib/libF77/i_mod.c new file mode 100644 index 000000000000..6937c4213570 --- /dev/null +++ b/lib/libF77/i_mod.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_mod(a,b) integer *a, *b; +#else +integer i_mod(integer *a, integer *b) +#endif +{ +return( *a % *b); +} diff --git a/lib/libF77/i_nint.c b/lib/libF77/i_nint.c new file mode 100644 index 000000000000..ccde78548880 --- /dev/null +++ b/lib/libF77/i_nint.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +integer i_nint(x) real *x; +#else +#undef abs +#include "math.h" +integer i_nint(real *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/i_sign.c b/lib/libF77/i_sign.c new file mode 100644 index 000000000000..94009b86e6fa --- /dev/null +++ b/lib/libF77/i_sign.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +integer i_sign(a,b) integer *a, *b; +#else +integer i_sign(integer *a, integer *b) +#endif +{ +integer x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} diff --git a/lib/libF77/iargc_.c b/lib/libF77/iargc_.c new file mode 100644 index 000000000000..29614ec6595d --- /dev/null +++ b/lib/libF77/iargc_.c @@ -0,0 +1,11 @@ +#include "f2c.h" + +#ifdef KR_headers +ftnint iargc_() +#else +ftnint iargc_(void) +#endif +{ +extern int xargc; +return ( xargc - 1 ); +} diff --git a/lib/libF77/l_ge.c b/lib/libF77/l_ge.c new file mode 100644 index 000000000000..86b4a1f5a7f5 --- /dev/null +++ b/lib/libF77/l_ge.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +logical l_ge(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +logical l_ge(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) >= 0); +} diff --git a/lib/libF77/l_gt.c b/lib/libF77/l_gt.c new file mode 100644 index 000000000000..c4b52f5bf7dd --- /dev/null +++ b/lib/libF77/l_gt.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +logical l_gt(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +logical l_gt(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) > 0); +} diff --git a/lib/libF77/l_le.c b/lib/libF77/l_le.c new file mode 100644 index 000000000000..f2740a238143 --- /dev/null +++ b/lib/libF77/l_le.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +logical l_le(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +logical l_le(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) <= 0); +} diff --git a/lib/libF77/l_lt.c b/lib/libF77/l_lt.c new file mode 100644 index 000000000000..c48dc946f9a7 --- /dev/null +++ b/lib/libF77/l_lt.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +extern integer s_cmp(); +logical l_lt(a,b,la,lb) char *a, *b; ftnlen la, lb; +#else +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +logical l_lt(char *a, char *b, ftnlen la, ftnlen lb) +#endif +{ +return(s_cmp(a,b,la,lb) < 0); +} diff --git a/lib/libF77/main.c b/lib/libF77/main.c new file mode 100644 index 000000000000..d7f71bd36fdd --- /dev/null +++ b/lib/libF77/main.c @@ -0,0 +1,124 @@ +/* STARTUP PROCEDURE FOR UNIX FORTRAN PROGRAMS */ + +#include "stdio.h" +#include "signal.h" + +#ifndef SIGIOT +#define SIGIOT SIGABRT +#endif + +#ifndef KR_headers +#include "stdlib.h" +#endif +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO__STDC +#define ONEXIT onexit +extern void f_exit(); +#else +#ifndef KR_headers +extern void f_exit(void); +#ifndef NO_ONEXIT +#define ONEXIT atexit +extern int atexit(void (*)(void)); +#endif +#else +#ifndef NO_ONEXIT +#define ONEXIT onexit +extern void f_exit(); +#endif +#endif +#endif + +#ifdef KR_headers +extern void f_init(), sig_die(); +extern int MAIN__(); +#define Int /* int */ +#else +extern void f_init(void), sig_die(char*, int); +extern int MAIN__(void); +#define Int int +#endif + +static void sigfdie(Int n) +{ +sig_die("Floating Exception", 1); +} + + +static void sigidie(Int n) +{ +sig_die("IOT Trap", 1); +} + +#ifdef SIGQUIT +static void sigqdie(Int n) +{ +sig_die("Quit signal", 1); +} +#endif + + +static void sigindie(Int n) +{ +sig_die("Interrupt", 0); +} + +static void sigtdie(Int n) +{ +sig_die("Killed", 0); +} + +#ifdef SIGTRAP +static void sigtrdie(Int n) +{ +sig_die("Trace trap", 1); +} +#endif + + +int xargc; +char **xargv; + +#ifdef KR_headers +main(argc, argv) int argc; char **argv; +#else +main(int argc, char **argv) +#endif +{ +xargc = argc; +xargv = argv; +signal(SIGFPE, sigfdie); /* ignore underflow, enable overflow */ +signal(SIGIOT, sigidie); +#ifdef SIGTRAP +signal(SIGTRAP, sigtrdie); +#endif +#ifdef SIGQUIT +if(signal(SIGQUIT,sigqdie) == SIG_IGN) + signal(SIGQUIT, SIG_IGN); +#endif +if(signal(SIGINT, sigindie) == SIG_IGN) + signal(SIGINT, SIG_IGN); +signal(SIGTERM,sigtdie); + +#ifdef pdp11 + ldfps(01200); /* detect overflow as an exception */ +#endif + +f_init(); +#ifndef NO_ONEXIT +ONEXIT(f_exit); +#endif +MAIN__(); +#ifdef NO_ONEXIT +f_exit(); +#endif +exit(0); /* exit(0) rather than return(0) to bypass Cray bug */ +return 0; /* For compilers that complain of missing return values; */ + /* others will complain that this is unreachable code. */ +} +#ifdef __cplusplus + } +#endif diff --git a/lib/libF77/permission b/lib/libF77/permission new file mode 100644 index 000000000000..20d431ed6dc9 --- /dev/null +++ b/lib/libF77/permission @@ -0,0 +1,41 @@ +From ches Tue Mar 6 09:06:22 EST 1990 +It think it probably is. I am told the line is 89% utilized. But the throughpu +t +is shared, so I wouldn't worry about it. +>From ehg Tue Mar 6 08:16 EST 1990 +Received: by coma; Tue Mar 6 08:17:21 1990 +From: pyxis!ehg +Date: Tue, 6 Mar 90 08:16 EST +To: coma!ches + +Thanks. Is it reasonable for people to ask for the 600KB f2c source over +uunet's dedicated line? I'm just trying to find out if there's a problem +before there's a disaster. +>From ches Tue Mar 6 07:16:18 EST 1990 +Inet has no dialers. All its calls go through the internet. The mcsun addresse +s +were uunet.uu.net!mcsun!..., which will travel to uunet via Internet and +then across the ocean on uunet's dedicated line. +/**************************************************************** +Copyright 1990 by AT&T Bell Laboratories and Bellcore. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +Bellcore or any of their entities not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. +****************************************************************/ + diff --git a/lib/libF77/pow_ci.c b/lib/libF77/pow_ci.c new file mode 100644 index 000000000000..37e2ce0f2eb9 --- /dev/null +++ b/lib/libF77/pow_ci.c @@ -0,0 +1,20 @@ +#include "f2c.h" + +#ifdef KR_headers +VOID pow_ci(p, a, b) /* p = a**b */ + complex *p, *a; integer *b; +#else +extern void pow_zi(doublecomplex*, doublecomplex*, integer*); +void pow_ci(complex *p, complex *a, integer *b) /* p = a**b */ +#endif +{ +doublecomplex p1, a1; + +a1.r = a->r; +a1.i = a->i; + +pow_zi(&p1, &a1, b); + +p->r = p1.r; +p->i = p1.i; +} diff --git a/lib/libF77/pow_dd.c b/lib/libF77/pow_dd.c new file mode 100644 index 000000000000..d2bb0e39bfdc --- /dev/null +++ b/lib/libF77/pow_dd.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double pow(); +double pow_dd(ap, bp) doublereal *ap, *bp; +#else +#undef abs +#include "math.h" +double pow_dd(doublereal *ap, doublereal *bp) +#endif +{ +return(pow(*ap, *bp) ); +} diff --git a/lib/libF77/pow_di.c b/lib/libF77/pow_di.c new file mode 100644 index 000000000000..7af69a71259b --- /dev/null +++ b/lib/libF77/pow_di.c @@ -0,0 +1,34 @@ +#include "f2c.h" + +#ifdef KR_headers +double pow_di(ap, bp) doublereal *ap; integer *bp; +#else +double pow_di(doublereal *ap, integer *bp) +#endif +{ +double pow, x; +integer n; + +pow = 1; +x = *ap; +n = *bp; + +if(n != 0) + { + if(n < 0) + { + n = -n; + x = 1/x; + } + for( ; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + } +return(pow); +} diff --git a/lib/libF77/pow_hh.c b/lib/libF77/pow_hh.c new file mode 100644 index 000000000000..e1a503c5ca82 --- /dev/null +++ b/lib/libF77/pow_hh.c @@ -0,0 +1,31 @@ +#include "f2c.h" + +#ifdef KR_headers +shortint pow_hh(ap, bp) shortint *ap, *bp; +#else +shortint pow_hh(shortint *ap, shortint *bp) +#endif +{ + shortint pow, x, n; + + x = *ap; + n = *bp; + + if (n <= 0) { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return x == 0 ? 1/x : 0; + n = -n; + } + for(pow = 1; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + return(pow); + } diff --git a/lib/libF77/pow_ii.c b/lib/libF77/pow_ii.c new file mode 100644 index 000000000000..e7948776e6c7 --- /dev/null +++ b/lib/libF77/pow_ii.c @@ -0,0 +1,31 @@ +#include "f2c.h" + +#ifdef KR_headers +integer pow_ii(ap, bp) integer *ap, *bp; +#else +integer pow_ii(integer *ap, integer *bp) +#endif +{ + integer pow, x, n; + + x = *ap; + n = *bp; + + if (n <= 0) { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return x == 0 ? 1/x : 0; + n = -n; + } + for(pow = 1; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + return(pow); + } diff --git a/lib/libF77/pow_qq.c b/lib/libF77/pow_qq.c new file mode 100644 index 000000000000..d80c40a9a697 --- /dev/null +++ b/lib/libF77/pow_qq.c @@ -0,0 +1,31 @@ +#include "f2c.h" + +#ifdef KR_headers +longint pow_qq(ap, bp) longint *ap, *bp; +#else +longint pow_qq(longint *ap, longint *bp) +#endif +{ + longint pow, x, n; + + x = *ap; + n = *bp; + + if (n <= 0) { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return x == 0 ? 1/x : 0; + n = -n; + } + for(pow = 1; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + return(pow); + } diff --git a/lib/libF77/pow_ri.c b/lib/libF77/pow_ri.c new file mode 100644 index 000000000000..3a3c4cf1ca4e --- /dev/null +++ b/lib/libF77/pow_ri.c @@ -0,0 +1,34 @@ +#include "f2c.h" + +#ifdef KR_headers +double pow_ri(ap, bp) real *ap; integer *bp; +#else +double pow_ri(real *ap, integer *bp) +#endif +{ +double pow, x; +integer n; + +pow = 1; +x = *ap; +n = *bp; + +if(n != 0) + { + if(n < 0) + { + n = -n; + x = 1/x; + } + for( ; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + } +return(pow); +} diff --git a/lib/libF77/pow_zi.c b/lib/libF77/pow_zi.c new file mode 100644 index 000000000000..8dd60069bfe0 --- /dev/null +++ b/lib/libF77/pow_zi.c @@ -0,0 +1,50 @@ +#include "f2c.h" + +#ifdef KR_headers +VOID pow_zi(p, a, b) /* p = a**b */ + doublecomplex *p, *a; integer *b; +#else +extern void z_div(doublecomplex*, doublecomplex*, doublecomplex*); +void pow_zi(doublecomplex *p, doublecomplex *a, integer *b) /* p = a**b */ +#endif +{ +integer n; +double t; +doublecomplex x; +static doublecomplex one = {1.0, 0.0}; + +n = *b; +p->r = 1; +p->i = 0; + +if(n == 0) + return; +if(n < 0) + { + n = -n; + z_div(&x, &one, a); + } +else + { + x.r = a->r; + x.i = a->i; + } + +for( ; ; ) + { + if(n & 01) + { + t = p->r * x.r - p->i * x.i; + p->i = p->r * x.i + p->i * x.r; + p->r = t; + } + if(n >>= 1) + { + t = x.r * x.r - x.i * x.i; + x.i = 2 * x.r * x.i; + x.r = t; + } + else + break; + } +} diff --git a/lib/libF77/pow_zz.c b/lib/libF77/pow_zz.c new file mode 100644 index 000000000000..55785dffbe6b --- /dev/null +++ b/lib/libF77/pow_zz.c @@ -0,0 +1,23 @@ +#include "f2c.h" + +#ifdef KR_headers +double log(), exp(), cos(), sin(), atan2(), f__cabs(); +VOID pow_zz(r,a,b) doublecomplex *r, *a, *b; +#else +#undef abs +#include "math.h" +extern double f__cabs(double,double); +void pow_zz(doublecomplex *r, doublecomplex *a, doublecomplex *b) +#endif +{ +double logr, logi, x, y; + +logr = log( f__cabs(a->r, a->i) ); +logi = atan2(a->i, a->r); + +x = exp( logr * b->r - logi * b->i ); +y = logr * b->i + logi * b->r; + +r->r = x * cos(y); +r->i = x * sin(y); +} diff --git a/lib/libF77/r_abs.c b/lib/libF77/r_abs.c new file mode 100644 index 000000000000..7b222961d16d --- /dev/null +++ b/lib/libF77/r_abs.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double r_abs(x) real *x; +#else +double r_abs(real *x) +#endif +{ +if(*x >= 0) + return(*x); +return(- *x); +} diff --git a/lib/libF77/r_acos.c b/lib/libF77/r_acos.c new file mode 100644 index 000000000000..328812ab6aa2 --- /dev/null +++ b/lib/libF77/r_acos.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double acos(); +double r_acos(x) real *x; +#else +#undef abs +#include "math.h" +double r_acos(real *x) +#endif +{ +return( acos(*x) ); +} diff --git a/lib/libF77/r_asin.c b/lib/libF77/r_asin.c new file mode 100644 index 000000000000..a30c6706b06d --- /dev/null +++ b/lib/libF77/r_asin.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double asin(); +double r_asin(x) real *x; +#else +#undef abs +#include "math.h" +double r_asin(real *x) +#endif +{ +return( asin(*x) ); +} diff --git a/lib/libF77/r_atan.c b/lib/libF77/r_atan.c new file mode 100644 index 000000000000..1e3817bdf661 --- /dev/null +++ b/lib/libF77/r_atan.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double atan(); +double r_atan(x) real *x; +#else +#undef abs +#include "math.h" +double r_atan(real *x) +#endif +{ +return( atan(*x) ); +} diff --git a/lib/libF77/r_atn2.c b/lib/libF77/r_atn2.c new file mode 100644 index 000000000000..3832a27f3e3c --- /dev/null +++ b/lib/libF77/r_atn2.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double atan2(); +double r_atn2(x,y) real *x, *y; +#else +#undef abs +#include "math.h" +double r_atn2(real *x, real *y) +#endif +{ +return( atan2(*x,*y) ); +} diff --git a/lib/libF77/r_cnjg.c b/lib/libF77/r_cnjg.c new file mode 100644 index 000000000000..e127ca969c4f --- /dev/null +++ b/lib/libF77/r_cnjg.c @@ -0,0 +1,11 @@ +#include "f2c.h" + +#ifdef KR_headers +VOID r_cnjg(r, z) complex *r, *z; +#else +VOID r_cnjg(complex *r, complex *z) +#endif +{ +r->r = z->r; +r->i = - z->i; +} diff --git a/lib/libF77/r_cos.c b/lib/libF77/r_cos.c new file mode 100644 index 000000000000..cf5c8eb4af29 --- /dev/null +++ b/lib/libF77/r_cos.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double cos(); +double r_cos(x) real *x; +#else +#undef abs +#include "math.h" +double r_cos(real *x) +#endif +{ +return( cos(*x) ); +} diff --git a/lib/libF77/r_cosh.c b/lib/libF77/r_cosh.c new file mode 100644 index 000000000000..5756c172427b --- /dev/null +++ b/lib/libF77/r_cosh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double cosh(); +double r_cosh(x) real *x; +#else +#undef abs +#include "math.h" +double r_cosh(real *x) +#endif +{ +return( cosh(*x) ); +} diff --git a/lib/libF77/r_dim.c b/lib/libF77/r_dim.c new file mode 100644 index 000000000000..baca95cd9e47 --- /dev/null +++ b/lib/libF77/r_dim.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +double r_dim(a,b) real *a, *b; +#else +double r_dim(real *a, real *b) +#endif +{ +return( *a > *b ? *a - *b : 0); +} diff --git a/lib/libF77/r_exp.c b/lib/libF77/r_exp.c new file mode 100644 index 000000000000..a95f4bc7f2b2 --- /dev/null +++ b/lib/libF77/r_exp.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double exp(); +double r_exp(x) real *x; +#else +#undef abs +#include "math.h" +double r_exp(real *x) +#endif +{ +return( exp(*x) ); +} diff --git a/lib/libF77/r_imag.c b/lib/libF77/r_imag.c new file mode 100644 index 000000000000..d51252bbb791 --- /dev/null +++ b/lib/libF77/r_imag.c @@ -0,0 +1,10 @@ +#include "f2c.h" + +#ifdef KR_headers +double r_imag(z) complex *z; +#else +double r_imag(complex *z) +#endif +{ +return(z->i); +} diff --git a/lib/libF77/r_int.c b/lib/libF77/r_int.c new file mode 100644 index 000000000000..11264bf19247 --- /dev/null +++ b/lib/libF77/r_int.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +double r_int(x) real *x; +#else +#undef abs +#include "math.h" +double r_int(real *x) +#endif +{ +return( (*x>0) ? floor(*x) : -floor(- *x) ); +} diff --git a/lib/libF77/r_lg10.c b/lib/libF77/r_lg10.c new file mode 100644 index 000000000000..4ea02f451003 --- /dev/null +++ b/lib/libF77/r_lg10.c @@ -0,0 +1,15 @@ +#include "f2c.h" + +#define log10e 0.43429448190325182765 + +#ifdef KR_headers +double log(); +double r_lg10(x) real *x; +#else +#undef abs +#include "math.h" +double r_lg10(real *x) +#endif +{ +return( log10e * log(*x) ); +} diff --git a/lib/libF77/r_log.c b/lib/libF77/r_log.c new file mode 100644 index 000000000000..aec6726ef5b6 --- /dev/null +++ b/lib/libF77/r_log.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double log(); +double r_log(x) real *x; +#else +#undef abs +#include "math.h" +double r_log(real *x) +#endif +{ +return( log(*x) ); +} diff --git a/lib/libF77/r_mod.c b/lib/libF77/r_mod.c new file mode 100644 index 000000000000..7adb44cdbec0 --- /dev/null +++ b/lib/libF77/r_mod.c @@ -0,0 +1,40 @@ +#include "f2c.h" + +#ifdef KR_headers +#ifdef IEEE_drem +double drem(); +#else +double floor(); +#endif +double r_mod(x,y) real *x, *y; +#else +#ifdef IEEE_drem +double drem(double, double); +#else +#undef abs +#include "math.h" +#endif +double r_mod(real *x, real *y) +#endif +{ +#ifdef IEEE_drem + double xa, ya, z; + if ((ya = *y) < 0.) + ya = -ya; + z = drem(xa = *x, ya); + if (xa > 0) { + if (z < 0) + z += ya; + } + else if (z > 0) + z -= ya; + return z; +#else + double quotient; + if( (quotient = (double)*x / *y) >= 0) + quotient = floor(quotient); + else + quotient = -floor(-quotient); + return(*x - (*y) * quotient ); +#endif +} diff --git a/lib/libF77/r_nint.c b/lib/libF77/r_nint.c new file mode 100644 index 000000000000..c45bac6458f0 --- /dev/null +++ b/lib/libF77/r_nint.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +double r_nint(x) real *x; +#else +#undef abs +#include "math.h" +double r_nint(real *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/lib/libF77/r_sign.c b/lib/libF77/r_sign.c new file mode 100644 index 000000000000..df6d02af00a7 --- /dev/null +++ b/lib/libF77/r_sign.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double r_sign(a,b) real *a, *b; +#else +double r_sign(real *a, real *b) +#endif +{ +double x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} diff --git a/lib/libF77/r_sin.c b/lib/libF77/r_sin.c new file mode 100644 index 000000000000..d2a3dac8581e --- /dev/null +++ b/lib/libF77/r_sin.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sin(); +double r_sin(x) real *x; +#else +#undef abs +#include "math.h" +double r_sin(real *x) +#endif +{ +return( sin(*x) ); +} diff --git a/lib/libF77/r_sinh.c b/lib/libF77/r_sinh.c new file mode 100644 index 000000000000..00cba0cb07f9 --- /dev/null +++ b/lib/libF77/r_sinh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sinh(); +double r_sinh(x) real *x; +#else +#undef abs +#include "math.h" +double r_sinh(real *x) +#endif +{ +return( sinh(*x) ); +} diff --git a/lib/libF77/r_sqrt.c b/lib/libF77/r_sqrt.c new file mode 100644 index 000000000000..26b45458aac9 --- /dev/null +++ b/lib/libF77/r_sqrt.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double sqrt(); +double r_sqrt(x) real *x; +#else +#undef abs +#include "math.h" +double r_sqrt(real *x) +#endif +{ +return( sqrt(*x) ); +} diff --git a/lib/libF77/r_tan.c b/lib/libF77/r_tan.c new file mode 100644 index 000000000000..736b37893c44 --- /dev/null +++ b/lib/libF77/r_tan.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double tan(); +double r_tan(x) real *x; +#else +#undef abs +#include "math.h" +double r_tan(real *x) +#endif +{ +return( tan(*x) ); +} diff --git a/lib/libF77/r_tanh.c b/lib/libF77/r_tanh.c new file mode 100644 index 000000000000..044255a08cc0 --- /dev/null +++ b/lib/libF77/r_tanh.c @@ -0,0 +1,13 @@ +#include "f2c.h" + +#ifdef KR_headers +double tanh(); +double r_tanh(x) real *x; +#else +#undef abs +#include "math.h" +double r_tanh(real *x) +#endif +{ +return( tanh(*x) ); +} diff --git a/lib/libF77/s_cat.c b/lib/libF77/s_cat.c new file mode 100644 index 000000000000..e9e29cf5d46a --- /dev/null +++ b/lib/libF77/s_cat.c @@ -0,0 +1,25 @@ +#include "f2c.h" + +#ifdef KR_headers +VOID s_cat(lp, rpp, rnp, np, ll) char *lp, *rpp[]; ftnlen rnp[], *np, ll; +#else +VOID s_cat(char *lp, char *rpp[], ftnlen rnp[], ftnlen *np, ftnlen ll) +#endif +{ +ftnlen i, n, nc; +char *f__rp; + +n = (int)*np; +for(i = 0 ; i < n ; ++i) + { + nc = ll; + if(rnp[i] < nc) + nc = rnp[i]; + ll -= nc; + f__rp = rpp[i]; + while(--nc >= 0) + *lp++ = *f__rp++; + } +while(--ll >= 0) + *lp++ = ' '; +} diff --git a/lib/libF77/s_cmp.c b/lib/libF77/s_cmp.c new file mode 100644 index 000000000000..9e4c12619a2f --- /dev/null +++ b/lib/libF77/s_cmp.c @@ -0,0 +1,42 @@ +#include "f2c.h" + +/* compare two strings */ + +#ifdef KR_headers +integer s_cmp(a, b, la, lb) register char *a, *b; ftnlen la, lb; +#else +integer s_cmp(register char *a, register char *b, ftnlen la, ftnlen lb) +#endif +{ +register char *aend, *bend; +aend = a + la; +bend = b + lb; + +if(la <= lb) + { + while(a < aend) + if(*a != *b) + return( *a - *b ); + else + { ++a; ++b; } + + while(b < bend) + if(*b != ' ') + return( ' ' - *b ); + else ++b; + } + +else + { + while(b < bend) + if(*a == *b) + { ++a; ++b; } + else + return( *a - *b ); + while(a < aend) + if(*a != ' ') + return(*a - ' '); + else ++a; + } +return(0); +} diff --git a/lib/libF77/s_copy.c b/lib/libF77/s_copy.c new file mode 100644 index 000000000000..989f5dded9b0 --- /dev/null +++ b/lib/libF77/s_copy.c @@ -0,0 +1,27 @@ +#include "f2c.h" + +/* assign strings: a = b */ + +#ifdef KR_headers +VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb; +#else +void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb) +#endif +{ +register char *aend, *bend; + +aend = a + la; + +if(la <= lb) + while(a < aend) + *a++ = *b++; + +else + { + bend = b + lb; + while(b < bend) + *a++ = *b++; + while(a < aend) + *a++ = ' '; + } +} diff --git a/lib/libF77/s_paus.c b/lib/libF77/s_paus.c new file mode 100644 index 000000000000..35107d880734 --- /dev/null +++ b/lib/libF77/s_paus.c @@ -0,0 +1,64 @@ +#include "stdio.h" +#include "f2c.h" +#define PAUSESIG 15 + +#ifdef KR_headers +#define Void /* void */ +#define Int /* int */ +#else +#define Void void +#define Int int +#undef abs +#include "stdlib.h" +#include "signal.h" +#ifdef __cplusplus +extern "C" { +#endif +extern int getpid(void), isatty(int), pause(void); +#endif + +extern VOID f_exit(Void); + +static VOID waitpause(Int n) +{ +return; +} + +#ifdef KR_headers +int s_paus(s, n) char *s; ftnlen n; +#else +int s_paus(char *s, ftnlen n) +#endif +{ +int i; + +fprintf(stderr, "PAUSE "); +if(n > 0) + for(i = 0; i<n ; ++i) + putc(*s++, stderr); +fprintf(stderr, " statement executed\n"); +if( isatty(fileno(stdin)) ) + { + fprintf(stderr, "To resume execution, type go. Any other input will terminate job.\n"); + fflush(stderr); + if( getchar()!='g' || getchar()!='o' || getchar()!='\n' ) + { + fprintf(stderr, "STOP\n"); + f_exit(); + exit(0); + } + } +else + { + fprintf(stderr, "To resume execution, execute a kill -%d %d command\n", + PAUSESIG, getpid() ); + signal(PAUSESIG, waitpause); + fflush(stderr); + pause(); + } +fprintf(stderr, "Execution resumes after PAUSE.\n"); +#ifdef __cplusplus +return 0; /* NOT REACHED */ +} +#endif +} diff --git a/lib/libF77/s_rnge.c b/lib/libF77/s_rnge.c new file mode 100644 index 000000000000..b200fce1bf34 --- /dev/null +++ b/lib/libF77/s_rnge.c @@ -0,0 +1,26 @@ +#include "stdio.h" +#include "f2c.h" + +/* called when a subscript is out of range */ + +#ifdef KR_headers +extern VOID sig_die(); +integer s_rnge(varn, offset, procn, line) char *varn, *procn; ftnint offset, line; +#else +extern VOID sig_die(char*,int); +integer s_rnge(char *varn, ftnint offset, char *procn, ftnint line) +#endif +{ +register int i; + +fprintf(stderr, "Subscript out of range on file line %ld, procedure ", line); +while((i = *procn) && i != '_' && i != ' ') + putc(*procn++, stderr); +fprintf(stderr, ".\nAttempt to access the %ld-th element of variable ", offset+1); +while((i = *varn) && i != ' ') + putc(*varn++, stderr); +sig_die(".", 1); +#ifdef __cplusplus +return 0; +#endif +} diff --git a/lib/libF77/s_stop.c b/lib/libF77/s_stop.c new file mode 100644 index 000000000000..7a3b4aa75431 --- /dev/null +++ b/lib/libF77/s_stop.c @@ -0,0 +1,33 @@ +#include "stdio.h" +#include "f2c.h" + +#ifdef KR_headers +extern void f_exit(); +VOID s_stop(s, n) char *s; ftnlen n; +#else +#undef abs +#include "stdlib.h" +#ifdef __cplusplus +extern "C" { +#endif +void f_exit(void); + +int s_stop(char *s, ftnlen n) +#endif +{ +int i; + +if(n > 0) + { + fprintf(stderr, "STOP "); + for(i = 0; i<n ; ++i) + putc(*s++, stderr); + fprintf(stderr, " statement executed\n"); + } +f_exit(); +exit(0); +#ifdef __cplusplus +return 0; /* NOT REACHED */ +} +#endif +} diff --git a/lib/libF77/sig_die.c b/lib/libF77/sig_die.c new file mode 100644 index 000000000000..91638b0ad473 --- /dev/null +++ b/lib/libF77/sig_die.c @@ -0,0 +1,37 @@ +#include "stdio.h" +#include "signal.h" + +#ifndef SIGIOT +#define SIGIOT SIGABRT +#endif + +#ifdef KR_headers +void sig_die(s, kill) register char *s; int kill; +#else +#include "stdlib.h" +#ifdef __cplusplus +extern "C" { +#endif + extern void f_exit(void); + +void sig_die(register char *s, int kill) +#endif +{ + /* print error message, then clear buffers */ + fprintf(stderr, "%s\n", s); + fflush(stderr); + f_exit(); + fflush(stderr); + + if(kill) + { + /* now get a core */ + signal(SIGIOT, SIG_DFL); + abort(); + } + else + exit(1); + } +#ifdef __cplusplus +} +#endif diff --git a/lib/libF77/signal_.c b/lib/libF77/signal_.c new file mode 100644 index 000000000000..90ec7ea39af2 --- /dev/null +++ b/lib/libF77/signal_.c @@ -0,0 +1,19 @@ +#include "f2c.h" + +#ifdef KR_headers +typedef int (*sig_type)(); +extern sig_type signal(); + +ftnint signal_(sigp, proc) integer *sigp; sig_type proc; +#else +#include "signal.h" +typedef void (*sig_type)(int); + +ftnint signal_(integer *sigp, sig_type proc) +#endif +{ + int sig; + sig = (int)*sigp; + + return (ftnint)signal(sig, proc); + } diff --git a/lib/libF77/system_.c b/lib/libF77/system_.c new file mode 100644 index 000000000000..181850b51b13 --- /dev/null +++ b/lib/libF77/system_.c @@ -0,0 +1,22 @@ +/* f77 interface to system routine */ + +#include "f2c.h" + +#ifdef KR_headers +system_(s, n) register char *s; ftnlen n; +#else +#undef abs +#include "stdlib.h" +system_(register char *s, ftnlen n) +#endif +{ +char buff[1000]; +register char *bp, *blast; + +blast = buff + (n < 1000 ? n : 1000); + +for(bp = buff ; bp<blast && *s!='\0' ; ) + *bp++ = *s++; +*bp = '\0'; +return system(buff); +} diff --git a/lib/libF77/z_abs.c.obsolete b/lib/libF77/z_abs.c.obsolete new file mode 100644 index 000000000000..7e67ad2957fb --- /dev/null +++ b/lib/libF77/z_abs.c.obsolete @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double f__cabs(); +double z_abs(z) doublecomplex *z; +#else +double f__cabs(double, double); +double z_abs(doublecomplex *z) +#endif +{ +return( f__cabs( z->r, z->i ) ); +} diff --git a/lib/libF77/z_cos.c b/lib/libF77/z_cos.c new file mode 100644 index 000000000000..bc9e23e18a72 --- /dev/null +++ b/lib/libF77/z_cos.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double sin(), cos(), sinh(), cosh(); +VOID z_cos(r, z) doublecomplex *r, *z; +#else +#undef abs +#include "math.h" +void z_cos(doublecomplex *r, doublecomplex *z) +#endif +{ +r->r = cos(z->r) * cosh(z->i); +r->i = - sin(z->r) * sinh(z->i); +} diff --git a/lib/libF77/z_div.c b/lib/libF77/z_div.c new file mode 100644 index 000000000000..fd53733e8827 --- /dev/null +++ b/lib/libF77/z_div.c @@ -0,0 +1,36 @@ +#include "f2c.h" + +#ifdef KR_headers +extern void sig_die(); +VOID z_div(c, a, b) doublecomplex *a, *b, *c; +#else +extern void sig_die(char*, int); +void z_div(doublecomplex *c, doublecomplex *a, doublecomplex *b) +#endif +{ +double ratio, den; +double abr, abi; + +if( (abr = b->r) < 0.) + abr = - abr; +if( (abi = b->i) < 0.) + abi = - abi; +if( abr <= abi ) + { + if(abi == 0) + sig_die("complex division by zero", 1); + ratio = b->r / b->i ; + den = b->i * (1 + ratio*ratio); + c->r = (a->r*ratio + a->i) / den; + c->i = (a->i*ratio - a->r) / den; + } + +else + { + ratio = b->i / b->r ; + den = b->r * (1 + ratio*ratio); + c->r = (a->r + a->i*ratio) / den; + c->i = (a->i - a->r*ratio) / den; + } + +} diff --git a/lib/libF77/z_exp.c b/lib/libF77/z_exp.c new file mode 100644 index 000000000000..56138f3d34b4 --- /dev/null +++ b/lib/libF77/z_exp.c @@ -0,0 +1,17 @@ +#include "f2c.h" + +#ifdef KR_headers +double exp(), cos(), sin(); +VOID z_exp(r, z) doublecomplex *r, *z; +#else +#undef abs +#include "math.h" +void z_exp(doublecomplex *r, doublecomplex *z) +#endif +{ +double expx; + +expx = exp(z->r); +r->r = expx * cos(z->i); +r->i = expx * sin(z->i); +} diff --git a/lib/libF77/z_log.c b/lib/libF77/z_log.c new file mode 100644 index 000000000000..fa1ac803eb3a --- /dev/null +++ b/lib/libF77/z_log.c @@ -0,0 +1,16 @@ +#include "f2c.h" + +#ifdef KR_headers +double log(), f__cabs(), atan2(); +VOID z_log(r, z) doublecomplex *r, *z; +#else +#undef abs +#include "math.h" +extern double f__cabs(double, double); +void z_log(doublecomplex *r, doublecomplex *z) +#endif +{ + +r->i = atan2(z->i, z->r); +r->r = log( f__cabs( z->r, z->i ) ); +} diff --git a/lib/libF77/z_sin.c b/lib/libF77/z_sin.c new file mode 100644 index 000000000000..bd908046f394 --- /dev/null +++ b/lib/libF77/z_sin.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double sin(), cos(), sinh(), cosh(); +VOID z_sin(r, z) doublecomplex *r, *z; +#else +#undef abs +#include "math.h" +void z_sin(doublecomplex *r, doublecomplex *z) +#endif +{ +r->r = sin(z->r) * cosh(z->i); +r->i = cos(z->r) * sinh(z->i); +} diff --git a/lib/libF77/z_sqrt.c b/lib/libF77/z_sqrt.c new file mode 100644 index 000000000000..eed38d0cef85 --- /dev/null +++ b/lib/libF77/z_sqrt.c @@ -0,0 +1,29 @@ +#include "f2c.h" + +#ifdef KR_headers +double sqrt(), f__cabs(); +VOID z_sqrt(r, z) doublecomplex *r, *z; +#else +#undef abs +#include "math.h" +extern double f__cabs(double, double); +void z_sqrt(doublecomplex *r, doublecomplex *z) +#endif +{ +double mag; + +if( (mag = f__cabs(z->r, z->i)) == 0.) + r->r = r->i = 0.; +else if(z->r > 0) + { + r->r = sqrt(0.5 * (mag + z->r) ); + r->i = z->i / r->r / 2; + } +else + { + r->i = sqrt(0.5 * (mag - z->r) ); + if(z->i < 0) + r->i = - r->i; + r->r = z->i / r->i / 2; + } +} diff --git a/lib/libI77/Makefile b/lib/libI77/Makefile new file mode 100644 index 000000000000..6c76a9dc9f56 --- /dev/null +++ b/lib/libI77/Makefile @@ -0,0 +1,14 @@ +SHLIB_MAJOR= 1 +SHLIB_MINOR= 0 + +LIB=I77 +CFLAGS+= -DSkip_f2c_Undefs -DNON_ANSI_RW_MODES + +I77SRCS = Version.c backspace.c close.c dfe.c dolio.c due.c endfile.c err.c \ + fmt.c fmtlib.c iio.c ilnw.c inquire.c lread.c lwrite.c open.c \ + rdfmt.c rewind.c rsfe.c rsli.c rsne.c sfe.c sue.c typesize.c uio.c \ + util.c wref.c wrtfmt.c wsfe.c wsle.c wsne.c xwsne.c + +SRCS= ${I77SRCS} + +.include <bsd.lib.mk> diff --git a/lib/libI77/Notice b/lib/libI77/Notice new file mode 100644 index 000000000000..64af9f12dc4e --- /dev/null +++ b/lib/libI77/Notice @@ -0,0 +1,23 @@ +/**************************************************************** +Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +Bellcore or any of their entities not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. +****************************************************************/ + diff --git a/lib/libI77/README b/lib/libI77/README new file mode 100644 index 000000000000..86132a794552 --- /dev/null +++ b/lib/libI77/README @@ -0,0 +1,155 @@ +If your compiler does not recognize ANSI C headers, +compile with KR_headers defined: either add -DKR_headers +to the definition of CFLAGS in the makefile, or insert + +#define KR_headers + +at the top of f2c.h and fmtlib.c . + + +If you have a really ancient K&R C compiler that does not understand +void, add -Dvoid=int to the definition of CFLAGS in the makefile. + +If you use a C++ compiler, first create a local f2c.h by appending +f2ch.add to the usual f2c.h, e.g., by issuing the command + make f2c.h +which assumes f2c.h is installed in /usr/include . + +If your system lacks /usr/include/local.h , +then you should create an appropriate local.h in +this directory. An appropriate local.h may simply +be empty, or it may #define VAX or #define CRAY +(or whatever else you must do to make fp.h work right). +Alternatively, edit fp.h to suite your machine. + +If your system lacks /usr/include/fcntl.h , then you +should simply create an empty fcntl.h in this directory. +If your compiler then complains about creat and open not +having a prototype, compile with OPEN_DECL defined. +On many systems, open and creat are declared in fcntl.h . + +If your system has /usr/include/fcntl.h, you may need to add +-D_POSIX_SOURCE to the makefile's definition of CFLAGS. + +If your system's sprintf does not work the way ANSI C +specifies -- specifically, if it does not return the +number of characters transmitted -- then insert the line + +#define USE_STRLEN + +at the end of fmt.h . This is necessary with +at least some versions of Sun software. + +If your system's fopen does not like the ANSI binary +reading and writing modes "rb" and "wb", then you should +compile open.c with NON_ANSI_RW_MODES #defined. + +If you get error messages about references to cf->_ptr +and cf->_base when compiling wrtfmt.c and wsfe.c or to +stderr->_flag when compiling err.c, then insert the line + +#define NON_UNIX_STDIO + +at the beginning of fio.h, and recompile everything (or +at least those modules that contain NON_UNIX_STDIO). + +Unformatted sequential records consist of a length of record +contents, the record contents themselves, and the length of +record contents again (for backspace). Prior to 17 Oct. 1991, +the length was of type int; now it is of type long, but you +can change it back to int by inserting + +#define UIOLEN_int + +at the beginning of fio.h. This affects only sue.c and uio.c . + +You may need to supply the following non-ANSI routines: + + fstat(int fileds, struct stat *buf) is similar +to stat(char *name, struct stat *buf), except that +the first argument, fileds, is the file descriptor +returned by open rather than the name of the file. +fstat is used in the system-dependent routine +canseek (in the libI77 source file err.c), which +is supposed to return 1 if it's possible to issue +seeks on the file in question, 0 if it's not; you may +need to suitably modify err.c . On non-UNIX systems, +you can avoid references to fstat and stat by compiling +with NON_UNIX_STDIO defined; in that case, you may need +to supply access(char *Name,0), which is supposed to +return 0 if file Name exists, nonzero otherwise. + + char * mktemp(char *buf) is supposed to replace the +6 trailing X's in buf with a unique number and then +return buf. The idea is to get a unique name for +a temporary file. + +On non-UNIX systems, you may need to change a few other, +e.g.: the form of name computed by mktemp() in endfile.c and +open.c; the use of the open(), close(), and creat() system +calls in endfile.c, err.c, open.c; and the modes in calls on +fopen() and fdopen() (and perhaps the use of fdopen() itself +-- it's supposed to return a FILE* corresponding to a given +an integer file descriptor) in err.c and open.c (component ufmt +of struct unit is 1 for formatted I/O -- text mode on some systems +-- and 0 for unformatted I/O -- binary mode on some systems). +Compiling with -DNON_UNIX_STDIO omits all references to creat() +and almost all references to open() and close(), the exception +being in the function f__isdev() (in open.c). + +For Turbo C++, in particular, you need to adjust the mktemp +invocations and should compile all of libI77 with -DMSDOS . +You also need to #undef ungetc in lread.c and rsne.c . + +If you want to be able to load against libI77 but not libF77, +then you will need to add sig_die.o (from libF77) to libI77. + +If you wish to use translated Fortran that has funny notions +of record length for direct unformatted I/O (i.e., that assumes +RECL= values in OPEN statements are not bytes but rather counts +of some other units -- e.g., 4-character words for VMS), then you +should insert an appropriate #define for url_Adjust at the +beginning of open.c . For VMS Fortran, for example, +#define url_Adjust(x) x *= 4 +would suffice. + +To check for transmission errors, issue the command + make check +This assumes you have the xsum program whose source, xsum.c, +is distributed as part of "all from f2c/src". If you do not +have xsum, you can obtain xsum.c by sending the following E-mail +message to netlib@research.att.com + send xsum.c from f2c/src + +The makefile assumes you have installed f2c.h in a standard +place (and does not cause recompilation when f2c.h is changed); +f2c.h comes with "all from f2c" (the source for f2c) and is +available separately ("f2c.h from f2c"). + +By default, Fortran I/O units 5, 6, and 0 are pre-connected to +stdin, stdout, and stderr, respectively. You can change this +behavior by changing f_init() in err.c to suit your needs. +Note that f2c assumes READ(*... means READ(5... and WRITE(*... +means WRITE(6... . Moreover, an OPEN(n,... statement that does +not specify a file name (and does not specify STATUS='SCRATCH') +assumes FILE='fort.n' . You can change this by editing open.c +and endfile.c suitably. + +Lines protected from compilation by #ifdef Allow_TYQUAD +are for a possible extension to 64-bit integers in which +integer = int = 32 bits and longint = long = 64 bits. + +Extensions (Feb. 1993) to NAMELIST processing: + 1. Reading a ? instead of &name (the start of a namelist) causes +the namelist being sought to be written to stdout (unit 6); +to omit this feature, compile rsne.c with -DNo_Namelist_Questions. + 2. Reading the wrong namelist name now leads to an error message +and an attempt to skip input until the right namelist name is found; +to omit this feature, compile rsne.c with -DNo_Bad_Namelist_Skip. + 3. Namelist writes now insert newlines before each variable; to omit +this feature, compile xwsne.c with -DNo_Extra_Namelist_Newlines. + +Nonstandard extension (Feb. 1993) to open: for sequential files, +ACCESS='APPEND' (or access='anything else starting with "A" or "a"') +causes the file to be positioned at end-of-file, so a write will +append to the file. diff --git a/lib/libI77/Version.c b/lib/libI77/Version.c new file mode 100644 index 000000000000..04edb5a1c2ec --- /dev/null +++ b/lib/libI77/Version.c @@ -0,0 +1,176 @@ +static char junk[] = "\n@(#) LIBI77 VERSION pjw,dmg-mods 8 Dec. 1993\n"; + +/* +2.01 $ format added +2.02 Coding bug in open.c repaired +2.03 fixed bugs in lread.c (read * with negative f-format) and lio.c + and lio.h (e-format conforming to spec) +2.04 changed open.c and err.c (fopen and freopen respectively) to + update to new c-library (append mode) +2.05 added namelist capability +2.06 allow internal list and namelist I/O +*/ + +/* +close.c: + allow upper-case STATUS= values +endfile.c + create fort.nnn if unit nnn not open; + else if (file length == 0) use creat() rather than copy; + use local copy() rather than forking /bin/cp; + rewind, fseek to clear buffer (for no reading past EOF) +err.c + use neither setbuf nor setvbuf; make stderr buffered +fio.h + #define _bufend +inquire.c + upper case responses; + omit byfile test from SEQUENTIAL= + answer "YES" to DIRECT= for unopened file (open to debate) +lio.c + flush stderr, stdout at end of each stmt + space before character strings in list output only at line start +lio.h + adjust LEW, LED consistent with old libI77 +lread.c + use atof() + allow "nnn*," when reading complex constants +open.c + try opening for writing when open for read fails, with + special uwrt value (2) delaying creat() to first write; + set curunit so error messages don't drop core; + no file name ==> fort.nnn except for STATUS='SCRATCH' +rdfmt.c + use atof(); trust EOF == end-of-file (so don't read past + end-of-file after endfile stmt) +sfe.c + flush stderr, stdout at end of each stmt +wrtfmt.c: + use upper case + put wrt_E and wrt_F into wref.c, use sprintf() + rather than ecvt() and fcvt() [more accurate on VAX] +*/ + +/* 16 Oct. 1988: uwrt = 3 after write, rewind, so close won't zap the file. */ + +/* 10 July 1989: change _bufend to buf_end in fio.h, wsfe.c, wrtfmt.c */ + +/* 28 Nov. 1989: corrections for IEEE and Cray arithmetic */ +/* 29 Nov. 1989: change various int return types to long for f2c */ +/* 30 Nov. 1989: various types from f2c.h */ +/* 6 Dec. 1989: types corrected various places */ +/* 19 Dec. 1989: make iostat= work right for internal I/O */ +/* 8 Jan. 1990: add rsne, wsne -- routines for handling NAMELIST */ +/* 28 Jan. 1990: have NAMELIST read treat $ as &, general white + space as blank */ +/* 27 Mar. 1990: change an = to == in rd_L(rdfmt.c) so formatted reads + of logical values reject letters other than fFtT; + have nowwriting reset cf */ +/* 14 Aug. 1990: adjust lread.c to treat tabs as spaces in list input */ +/* 17 Aug. 1990: adjust open.c to recognize blank='Z...' as well as + blank='z...' when reopening an open file */ +/* 30 Aug. 1990: prevent embedded blanks in list output of complex values; + omit exponent field in list output of values of + magnitude between 10 and 1e8; prevent writing stdin + and reading stdout or stderr; don't close stdin, stdout, + or stderr when reopening units 5, 6, 0. */ +/* 18 Sep. 1990: add component udev to unit and consider old == new file + iff uinode and udev values agree; use stat rather than + access to check existence of file (when STATUS='OLD')*/ +/* 2 Oct. 1990: adjust rewind.c so two successive rewinds after a write + don't clobber the file. */ +/* 9 Oct. 1990: add #include "fcntl.h" to endfile.c, err.c, open.c; + adjust g_char in util.c for segmented memories. */ +/* 17 Oct. 1990: replace abort() and _cleanup() with calls on + sig_die(...,1) (defined in main.c). */ +/* 5 Nov. 1990: changes to open.c: complain if new= is specified and the + file already exists; allow file= to be omitted in open stmts + and allow status='replace' (Fortran 90 extensions). */ +/* 11 Dec. 1990: adjustments for POSIX. */ +/* 15 Jan. 1991: tweak i_ungetc in rsli.c to allow reading from + strings in read-only memory. */ +/* 25 Apr. 1991: adjust namelist stuff to work with f2c -i2 */ +/* 26 Apr. 1991: fix some bugs with NAMELIST read of multi-dim. arrays */ +/* 16 May 1991: increase LEFBL in lio.h to bypass NeXT bug */ +/* 17 Oct. 1991: change type of length field in sequential unformatted + records from int to long (for systems where sizeof(int) + can vary, depending on the compiler or compiler options). */ +/* 14 Nov. 1991: change uint to Uint in fmt.h, rdfmt.c, wrtfmt.c. +/* 25 Nov. 1991: change uint to Uint in lwrite.c; change sizeof(int) to + sizeof(uioint) in fseeks in sue.c (missed on 17 Oct.). */ +/* 1 Dec. 1991: uio.c: add test for read failure (seq. unformatted reads); + adjust an error return from EOF to off end of record */ +/* 12 Dec. 1991: rsli.c: fix bug with internal list input that caused + the last character of each record to be ignored. + iio.c: adjust error message in internal formatted + input from "end-of-file" to "off end of record" if + the format specifies more characters than the + record contains. */ +/* 17 Jan. 1992: lread.c, rsne.c: in list and namelist input, + treat "r* ," and "r*," alike (where r is a + positive integer constant), and fix a bug in + handling null values following items with repeat + counts (e.g., 2*1,,3); for namelist reading + of a numeric array, allow a new name-value subsequence + to terminate the current one (as though the current + one ended with the right number of null values). + lio.h, lwrite.c: omit insignificant zeros in + list and namelist output. To get the old + behavior, compile with -DOld_list_output . */ +/* 18 Jan. 1992: make list output consistent with F format by + printing .1 rather than 0.1 (introduced yesterday). */ +/* 3 Feb. 1992: rsne.c: fix namelist read bug that caused the + character following a comma to be ignored. */ +/* 19 May 1992: adjust iio.c, ilnw.c, rdfmt.c and rsli.c to make err= + work with internal list and formatted I/O. */ +/* 18 July 1992: adjust rsne.c to allow namelist input to stop at + an & (e.g. &end). */ +/* 23 July 1992: switch to ANSI prototypes unless KR_headers is #defined ; + recognize Z format (assuming 8-bit bytes). */ +/* 14 Aug. 1992: tweak wrt_E in wref.c to avoid -NaN */ +/* 23 Oct. 1992: Supply missing l_eof = 0 assignment to s_rsne() in rsne.c + (so end-of-file on other files won't confuse namelist + reads of external files). Prepend f__ to external + names that are only of internal interest to lib[FI]77. */ +/* 1 Feb. 1993: backspace.c: fix bug that bit when last char of 2nd + buffer == '\n'. + endfile.c: guard against tiny L_tmpnam; close and reopen + files in t_runc(). + lio.h: lengthen LINTW (buffer size in lwrite.c). + err.c, open.c: more prepending of f__ (to [rw]_mode). */ +/* 5 Feb. 1993: tweaks to NAMELIST: rsne.c: ? prints the namelist being + sought; namelists of the wrong name are skipped (after + an error message; xwsne.c: namelist writes have a + newline before each new variable. + open.c: ACCESS='APPEND' positions sequential files + at EOF (nonstandard extension -- that doesn't require + changing data structures). */ +/* 9 Feb. 1993: Change some #ifdef MSDOS lines to #ifdef NON_UNIZ_STDIO. + err.c: under NON_UNIX_STDIO, avoid close(creat(name,0666)) + when the unit has another file descriptor for name. */ +/* 4 March 1993: err.c, open.c: take declaration of fdopen from rawio.h; + open.c: always give f__w_mode[] 4 elements for use + in t_runc (in endfile.c -- for change of 1 Feb. 1993). */ +/* 6 March 1993: uio.c: adjust off-end-of-record test for sequential + unformatted reads to respond to err= rather than end=. */ +/* 12 March 1993: various tweaks for C++ */ +/* 6 April 1993: adjust error returns for formatted inputs to flush + the current input line when err=label is specified. + To restore the old behavior (input left mid-line), + either adjust the #definition of errfl in fio.h or + omit the invocation of f__doend in err__fl (in err.c). */ +/* 23 June 1993: iio.c: fix bug in format reversions for internal writes. */ +/* 5 Aug. 1993: lread.c: fix bug in handling repetition counts for + logical data (during list or namelist input). + Change struct f__syl to struct syl (for buggy compilers). */ +/* 7 Aug. 1993: lread.c: fix bug in namelist reading of incomplete + logical arrays. */ +/* 9 Aug. 1993: lread.c: fix bug in namelist reading of an incomplete + array of numeric data followed by another namelist + item whose name starts with 'd', 'D', 'e', or 'E'. */ +/* 8 Sept. 1993: open.c: protect #include "sys/..." with + #ifndef NON_UNIX_STDIO; Version date not changed. */ +/* 10 Nov. 1993: backspace.c: add nonsense for #ifdef MSDOS */ +/* 8 Dec. 1993: iio.c: adjust internal formatted reads to treat + short records as though padded with blanks + (rather than causing an "off end of record" error). */ diff --git a/lib/libI77/backspace.c b/lib/libI77/backspace.c new file mode 100644 index 000000000000..421342485fec --- /dev/null +++ b/lib/libI77/backspace.c @@ -0,0 +1,96 @@ +#include "f2c.h" +#include "fio.h" +#ifdef KR_headers +integer f_back(a) alist *a; +#else +integer f_back(alist *a) +#endif +{ unit *b; + int i, n, ndec; +#ifdef MSDOS + int j, k; + long w, z; +#endif + long x, y; + char buf[32]; + if(a->aunit >= MXUNIT || a->aunit < 0) + err(a->aerr,101,"backspace") + b= &f__units[a->aunit]; + if(b->useek==0) err(a->aerr,106,"backspace") + if(b->ufd==NULL) { + fk_open(1, 1, a->aunit); + return(0); + } + if(b->uend==1) + { b->uend=0; + return(0); + } + if(b->uwrt) { + (void) t_runc(a); + if (f__nowreading(b)) + err(a->aerr,errno,"backspace") + } + if(b->url>0) + { + x=ftell(b->ufd); + y = x % b->url; + if(y == 0) x--; + x /= b->url; + x *= b->url; + (void) fseek(b->ufd,x,SEEK_SET); + return(0); + } + + if(b->ufmt==0) + { (void) fseek(b->ufd,-(long)sizeof(int),SEEK_CUR); + (void) fread((char *)&n,sizeof(int),1,b->ufd); + (void) fseek(b->ufd,-(long)n-2*sizeof(int),SEEK_CUR); + return(0); + } +#ifdef MSDOS + w = -1; +#endif + for(ndec = 2;; ndec = 1) + { + y = x=ftell(b->ufd); + if(x<sizeof(buf)) x=0; + else x -= sizeof(buf); + (void) fseek(b->ufd,x,SEEK_SET); + n=fread(buf,1,(int)(y-x), b->ufd); + for(i=n-ndec;i>=0;i--) + { + if(buf[i]!='\n') continue; +#ifdef MSDOS + for(j = k = 0; j <= i; j++) + if (buf[j] == '\n') + k++; + fseek(b->ufd,x,SEEK_SET); + do { + if (getc(b->ufd) == '\n') { + --k; + if ((z = ftell(b->ufd)) >= y) { + if (w == -1) + goto break2; + break; + } + w = z; + } + } while(k > 0); + fseek(b->ufd, w, SEEK_SET); +#else + fseek(b->ufd,(long)(i+1-n),SEEK_CUR); +#endif + return(0); + } +#ifdef MSDOS + break2: +#endif + if(x==0) + { + (void) fseek(b->ufd, 0L, SEEK_SET); + return(0); + } + else if(n<=0) err(a->aerr,(EOF),"backspace") + (void) fseek(b->ufd, x, SEEK_SET); + } +} diff --git a/lib/libI77/close.c b/lib/libI77/close.c new file mode 100644 index 000000000000..29a7af54c1f8 --- /dev/null +++ b/lib/libI77/close.c @@ -0,0 +1,95 @@ +#include "f2c.h" +#include "fio.h" +#ifdef KR_headers +integer f_clos(a) cllist *a; +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +#ifdef NON_UNIX_STDIO +#ifndef unlink +#define unlink remove +#endif +#else +#ifdef MSDOS +#include "io.h" +#else +#ifdef __cplusplus +extern "C" int unlink(const char*); +#else +extern int unlink(const char*); +#endif +#endif +#endif + +integer f_clos(cllist *a) +#endif +{ unit *b; + + if(a->cunit >= MXUNIT) return(0); + b= &f__units[a->cunit]; + if(b->ufd==NULL) + goto done; + if (!a->csta) + if (b->uscrtch == 1) + goto Delete; + else + goto Keep; + switch(*a->csta) { + default: + Keep: + case 'k': + case 'K': + if(b->uwrt == 1) + t_runc((alist *)a); + if(b->ufnm) { + fclose(b->ufd); + free(b->ufnm); + } + break; + case 'd': + case 'D': + Delete: + if(b->ufnm) { + fclose(b->ufd); + unlink(b->ufnm); /*SYSDEP*/ + free(b->ufnm); + } + } + b->ufd=NULL; + done: + b->uend=0; + b->ufnm=NULL; + return(0); + } + void +#ifdef KR_headers +f_exit() +#else +f_exit(void) +#endif +{ int i; + static cllist xx; + if (!xx.cerr) { + xx.cerr=1; + xx.csta=NULL; + for(i=0;i<MXUNIT;i++) + { + xx.cunit=i; + (void) f_clos(&xx); + } + } +} + int +#ifdef KR_headers +flush_() +#else +flush_(void) +#endif +{ int i; + for(i=0;i<MXUNIT;i++) + if(f__units[i].ufd != NULL && f__units[i].uwrt) + fflush(f__units[i].ufd); +return 0; +} diff --git a/lib/libI77/dfe.c b/lib/libI77/dfe.c new file mode 100644 index 000000000000..669c3bd8b1db --- /dev/null +++ b/lib/libI77/dfe.c @@ -0,0 +1,157 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" + +y_rsk(Void) +{ + if(f__curunit->uend || f__curunit->url <= f__recpos + || f__curunit->url == 1) return 0; + do { + getc(f__cf); + } while(++f__recpos < f__curunit->url); + return 0; +} +y_getc(Void) +{ + int ch; + if(f__curunit->uend) return(-1); + if((ch=getc(f__cf))!=EOF) + { + f__recpos++; + if(f__curunit->url>=f__recpos || + f__curunit->url==1) + return(ch); + else return(' '); + } + if(feof(f__cf)) + { + f__curunit->uend=1; + errno=0; + return(-1); + } + err(f__elist->cierr,errno,"readingd"); +#ifdef __cplusplus + return 0; +#endif +} +#ifdef KR_headers +y_putc(c) +#else +y_putc(int c) +#endif +{ + f__recpos++; + if(f__recpos <= f__curunit->url || f__curunit->url==1) + putc(c,f__cf); + else + err(f__elist->cierr,110,"dout"); + return(0); +} +y_rev(Void) +{ /*what about work done?*/ + if(f__curunit->url==1 || f__recpos==f__curunit->url) + return(0); + while(f__recpos<f__curunit->url) + (*f__putn)(' '); + f__recpos=0; + return(0); +} +y_err(Void) +{ + err(f__elist->cierr, 110, "dfe"); +#ifdef __cplusplus + return 0; +#endif +} + +y_newrec(Void) +{ + if(f__curunit->url == 1 || f__recpos == f__curunit->url) { + f__hiwater = f__recpos = f__cursor = 0; + return(1); + } + if(f__hiwater > f__recpos) + f__recpos = f__hiwater; + y_rev(); + f__hiwater = f__cursor = 0; + return(1); +} + +#ifdef KR_headers +c_dfe(a) cilist *a; +#else +c_dfe(cilist *a) +#endif +{ + f__sequential=0; + f__formatted=f__external=1; + f__elist=a; + f__cursor=f__scale=f__recpos=0; + if(a->ciunit>MXUNIT || a->ciunit<0) + err(a->cierr,101,"startchk"); + f__curunit = &f__units[a->ciunit]; + if(f__curunit->ufd==NULL && fk_open(DIR,FMT,a->ciunit)) + err(a->cierr,104,"dfe"); + f__cf=f__curunit->ufd; + if(!f__curunit->ufmt) err(a->cierr,102,"dfe") + if(!f__curunit->useek) err(a->cierr,104,"dfe") + f__fmtbuf=a->cifmt; + (void) fseek(f__cf,(long)f__curunit->url * (a->cirec-1),SEEK_SET); + f__curunit->uend = 0; + return(0); +} +#ifdef KR_headers +integer s_rdfe(a) cilist *a; +#else +integer s_rdfe(cilist *a) +#endif +{ + int n; + if(!f__init) f_init(); + if(n=c_dfe(a))return(n); + f__reading=1; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr,errno,"read start"); + f__getn = y_getc; + f__doed = rd_ed; + f__doned = rd_ned; + f__dorevert = f__donewrec = y_err; + f__doend = y_rsk; + if(pars_f(f__fmtbuf)<0) + err(a->cierr,100,"read start"); + fmt_bg(); + return(0); +} +#ifdef KR_headers +integer s_wdfe(a) cilist *a; +#else +integer s_wdfe(cilist *a) +#endif +{ + int n; + if(!f__init) f_init(); + if(n=c_dfe(a)) return(n); + f__reading=0; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr,errno,"startwrt"); + f__putn = y_putc; + f__doed = w_ed; + f__doned= w_ned; + f__dorevert = y_err; + f__donewrec = y_newrec; + f__doend = y_rev; + if(pars_f(f__fmtbuf)<0) + err(a->cierr,100,"startwrt"); + fmt_bg(); + return(0); +} +integer e_rdfe(Void) +{ + (void) en_fio(); + return(0); +} +integer e_wdfe(Void) +{ + (void) en_fio(); + return(0); +} diff --git a/lib/libI77/disclaimer b/lib/libI77/disclaimer new file mode 100644 index 000000000000..59db1ecf42fd --- /dev/null +++ b/lib/libI77/disclaimer @@ -0,0 +1,15 @@ +f2c is a Fortran to C converter under development by + David Gay (AT&T Bell Labs) + Stu Feldman (Bellcore) + Mark Maimone (Carnegie-Mellon University) + Norm Schryer (AT&T Bell Labs) +Please send bug reports to dmg@research.att.com or uunet!research!dmg. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. diff --git a/lib/libI77/dolio.c b/lib/libI77/dolio.c new file mode 100644 index 000000000000..4b5a2ca6588c --- /dev/null +++ b/lib/libI77/dolio.c @@ -0,0 +1,20 @@ +#include "f2c.h" + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef KR_headers +extern int (*f__lioproc)(); + +integer do_lio(type,number,ptr,len) ftnint *number,*type; char *ptr; ftnlen len; +#else +extern int (*f__lioproc)(ftnint*, char*, ftnlen, ftnint); + +integer do_lio(ftnint *type, ftnint *number, char *ptr, ftnlen len) +#endif +{ + return((*f__lioproc)(number,ptr,len,*type)); +} +#ifdef __cplusplus + } +#endif diff --git a/lib/libI77/due.c b/lib/libI77/due.c new file mode 100644 index 000000000000..33ee02c3cd29 --- /dev/null +++ b/lib/libI77/due.c @@ -0,0 +1,64 @@ +#include "f2c.h" +#include "fio.h" + +#ifdef KR_headers +c_due(a) cilist *a; +#else +c_due(cilist *a) +#endif +{ + if(!f__init) f_init(); + if(a->ciunit>=MXUNIT || a->ciunit<0) + err(a->cierr,101,"startio"); + f__sequential=f__formatted=f__recpos=0; + f__external=1; + f__curunit = &f__units[a->ciunit]; + f__elist=a; + if(f__curunit->ufd==NULL && fk_open(DIR,UNF,a->ciunit) ) err(a->cierr,104,"due"); + f__cf=f__curunit->ufd; + if(f__curunit->ufmt) err(a->cierr,102,"cdue") + if(!f__curunit->useek) err(a->cierr,104,"cdue") + if(f__curunit->ufd==NULL) err(a->cierr,114,"cdue") + (void) fseek(f__cf,(long)(a->cirec-1)*f__curunit->url,SEEK_SET); + f__curunit->uend = 0; + return(0); +} +#ifdef KR_headers +integer s_rdue(a) cilist *a; +#else +integer s_rdue(cilist *a) +#endif +{ + int n; + if(n=c_due(a)) return(n); + f__reading=1; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr,errno,"read start"); + return(0); +} +#ifdef KR_headers +integer s_wdue(a) cilist *a; +#else +integer s_wdue(cilist *a) +#endif +{ + int n; + if(n=c_due(a)) return(n); + f__reading=0; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr,errno,"write start"); + return(0); +} +integer e_rdue(Void) +{ + if(f__curunit->url==1 || f__recpos==f__curunit->url) + return(0); + (void) fseek(f__cf,(long)(f__curunit->url-f__recpos),SEEK_CUR); + if(ftell(f__cf)%f__curunit->url) + err(f__elist->cierr,200,"syserr"); + return(0); +} +integer e_wdue(Void) +{ + return(e_rdue()); +} diff --git a/lib/libI77/endfile.c b/lib/libI77/endfile.c new file mode 100644 index 000000000000..68e1f2f3fa0b --- /dev/null +++ b/lib/libI77/endfile.c @@ -0,0 +1,195 @@ +#include "f2c.h" +#include "fio.h" +#ifndef NON_UNIX_STDIO +#include "sys/types.h" +#endif +#include "rawio.h" + +#ifdef KR_headers +extern char *strcpy(); +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +#include "string.h" +#endif + +#ifdef NON_UNIX_STDIO +#ifndef unlink +#define unlink remove +#endif +#else +#ifdef MSDOS +#include "io.h" +#endif +#endif + +#ifdef NON_UNIX_STDIO +extern char *f__r_mode[], *f__w_mode[]; +#endif + +#ifdef KR_headers +integer f_end(a) alist *a; +#else +integer f_end(alist *a) +#endif +{ + unit *b; + if(a->aunit>=MXUNIT || a->aunit<0) err(a->aerr,101,"endfile"); + b = &f__units[a->aunit]; + if(b->ufd==NULL) { + char nbuf[10]; + (void) sprintf(nbuf,"fort.%ld",a->aunit); +#ifdef NON_UNIX_STDIO + { FILE *tf; + if (tf = fopen(nbuf, f__w_mode[0])) + fclose(tf); + } +#else + close(creat(nbuf, 0666)); +#endif + return(0); + } + b->uend=1; + return(b->useek ? t_runc(a) : 0); +} + + static int +#ifdef NON_UNIX_STDIO +#ifdef KR_headers +copy(from, len, to) char *from, *to; register long len; +#else +copy(FILE *from, register long len, FILE *to) +#endif +{ + int k, len1; + char buf[BUFSIZ]; + + while(fread(buf, len1 = len > BUFSIZ ? BUFSIZ : (int)len, 1, from)) { + if (!fwrite(buf, len1, 1, to)) + return 1; + if ((len -= len1) <= 0) + break; + } + return 0; + } +#else +#ifdef KR_headers +copy(from, len, to) char *from, *to; register long len; +#else +copy(char *from, register long len, char *to) +#endif +{ + register int n; + int k, rc = 0, tmp; + char buf[BUFSIZ]; + + if ((k = open(from, O_RDONLY)) < 0) + return 1; + if ((tmp = creat(to,0666)) < 0) + return 1; + while((n = read(k, buf, len > BUFSIZ ? BUFSIZ : (int)len)) > 0) { + if (write(tmp, buf, n) != n) + { rc = 1; break; } + if ((len -= n) <= 0) + break; + } + close(k); + close(tmp); + return n < 0 ? 1 : rc; + } +#endif + +#ifndef L_tmpnam +#define L_tmpnam 16 +#endif + + int +#ifdef KR_headers +t_runc(a) alist *a; +#else +t_runc(alist *a) +#endif +{ + char nm[L_tmpnam+12]; /* extra space in case L_tmpnam is tiny */ + long loc, len; + unit *b; +#ifdef NON_UNIX_STDIO + FILE *bf, *tf; +#else + FILE *bf; +#endif + int rc = 0; + + b = &f__units[a->aunit]; + if(b->url) + return(0); /*don't truncate direct files*/ + loc=ftell(bf = b->ufd); + fseek(bf,0L,SEEK_END); + len=ftell(bf); + if (loc >= len || b->useek == 0 || b->ufnm == NULL) + return(0); +#ifdef NON_UNIX_STDIO + fclose(b->ufd); +#else + rewind(b->ufd); /* empty buffer */ +#endif + if (!loc) { +#ifdef NON_UNIX_STDIO + if (!(bf = fopen(b->ufnm, f__w_mode[b->ufmt]))) +#else + if (close(creat(b->ufnm,0666))) +#endif + rc = 1; + if (b->uwrt) + b->uwrt = 1; + goto done; + } +#ifdef _POSIX_SOURCE + tmpnam(nm); +#else + strcpy(nm,"tmp.FXXXXXX"); + mktemp(nm); +#endif +#ifdef NON_UNIX_STDIO + if (!(bf = fopen(b->ufnm, f__r_mode[0]))) { + bad: + rc = 1; + goto done; + } + if (!(tf = fopen(nm, f__w_mode[0]))) + goto bad; + if (copy(bf, loc, tf)) { + bad1: + rc = 1; + goto done1; + } + if (!(bf = freopen(b->ufnm, f__w_mode[0], bf))) + goto bad1; + if (!(tf = freopen(nm, f__r_mode[0], tf))) + goto bad1; + if (copy(tf, loc, bf)) + goto bad1; + if (f__w_mode[0] != f__w_mode[b->ufmt]) { + if (!(bf = freopen(b->ufnm, f__w_mode[b->ufmt+2], bf))) + goto bad1; + fseek(bf, loc, SEEK_SET); + } +done1: + fclose(tf); + unlink(nm); +done: + f__cf = b->ufd = bf; +#else + if (copy(b->ufnm, loc, nm) + || copy(nm, loc, b->ufnm)) + rc = 1; + unlink(nm); + fseek(b->ufd, loc, SEEK_SET); +done: +#endif + if (rc) + err(a->aerr,111,"endfile"); + return 0; + } diff --git a/lib/libI77/err.c b/lib/libI77/err.c new file mode 100644 index 000000000000..85966261d8a4 --- /dev/null +++ b/lib/libI77/err.c @@ -0,0 +1,275 @@ +#ifndef NON_UNIX_STDIO +#include "sys/types.h" +#include "sys/stat.h" +#endif +#include "f2c.h" +#include "fio.h" +#include "fmt.h" /* for struct syl */ +#include "rawio.h" /* for fcntl.h, fdopen */ +#include "local.h" +#ifdef NON_UNIX_STDIO +#ifdef KR_headers +extern char *malloc(); +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +#endif +#endif + +/*global definitions*/ +unit f__units[MXUNIT]; /*unit table*/ +flag f__init; /*0 on entry, 1 after initializations*/ +cilist *f__elist; /*active external io list*/ +flag f__reading; /*1 if reading, 0 if writing*/ +flag f__cplus,f__cblank; +char *f__fmtbuf; +flag f__external; /*1 if external io, 0 if internal */ +#ifdef KR_headers +int (*f__doed)(),(*f__doned)(); +int (*f__doend)(),(*f__donewrec)(),(*f__dorevert)(); +int (*f__getn)(),(*f__putn)(); /*for formatted io*/ +#else +int (*f__getn)(void),(*f__putn)(int); /*for formatted io*/ +int (*f__doed)(struct syl*, char*, ftnlen),(*f__doned)(struct syl*); +int (*f__dorevert)(void),(*f__donewrec)(void),(*f__doend)(void); +#endif +flag f__sequential; /*1 if sequential io, 0 if direct*/ +flag f__formatted; /*1 if formatted io, 0 if unformatted*/ +FILE *f__cf; /*current file*/ +unit *f__curunit; /*current unit*/ +int f__recpos; /*place in current record*/ +int f__cursor,f__scale; + +/*error messages*/ +char *F_err[] = +{ + "error in format", /* 100 */ + "illegal unit number", /* 101 */ + "formatted io not allowed", /* 102 */ + "unformatted io not allowed", /* 103 */ + "direct io not allowed", /* 104 */ + "sequential io not allowed", /* 105 */ + "can't backspace file", /* 106 */ + "null file name", /* 107 */ + "can't stat file", /* 108 */ + "unit not connected", /* 109 */ + "off end of record", /* 110 */ + "truncation failed in endfile", /* 111 */ + "incomprehensible list input", /* 112 */ + "out of free space", /* 113 */ + "unit not connected", /* 114 */ + "read unexpected character", /* 115 */ + "bad logical input field", /* 116 */ + "bad variable type", /* 117 */ + "bad namelist name", /* 118 */ + "variable not in namelist", /* 119 */ + "no end record", /* 120 */ + "variable count incorrect", /* 121 */ + "subscript for scalar variable", /* 122 */ + "invalid array section", /* 123 */ + "substring out of bounds", /* 124 */ + "subscript out of bounds", /* 125 */ + "can't read file", /* 126 */ + "can't write file", /* 127 */ + "'new' file exists", /* 128 */ + "can't append to file" /* 129 */ +}; +#define MAXERR (sizeof(F_err)/sizeof(char *)+100) + +#ifdef KR_headers +f__canseek(f) FILE *f; /*SYSDEP*/ +#else +f__canseek(FILE *f) /*SYSDEP*/ +#endif +{ +#ifdef NON_UNIX_STDIO + return !isatty(fileno(f)); +#else + struct stat x; + + if (fstat(fileno(f),&x) < 0) + return(0); +#ifdef S_IFMT + switch(x.st_mode & S_IFMT) { + case S_IFDIR: + case S_IFREG: + if(x.st_nlink > 0) /* !pipe */ + return(1); + else + return(0); + case S_IFCHR: + if(isatty(fileno(f))) + return(0); + return(1); +#ifdef S_IFBLK + case S_IFBLK: + return(1); +#endif + } +#else +#ifdef S_ISDIR + /* POSIX version */ + if (S_ISREG(x.st_mode) || S_ISDIR(x.st_mode)) { + if(x.st_nlink > 0) /* !pipe */ + return(1); + else + return(0); + } + if (S_ISCHR(x.st_mode)) { + if(isatty(fileno(f))) + return(0); + return(1); + } + if (S_ISBLK(x.st_mode)) + return(1); +#else + Help! How does fstat work on this system? +#endif +#endif + return(0); /* who knows what it is? */ +#endif +} + + void +#ifdef KR_headers +f__fatal(n,s) char *s; +#else +f__fatal(int n, char *s) +#endif +{ + if(n<100 && n>=0) perror(s); /*SYSDEP*/ + else if(n >= (int)MAXERR || n < -1) + { fprintf(stderr,"%s: illegal error number %d\n",s,n); + } + else if(n == -1) fprintf(stderr,"%s: end of file\n",s); + else + fprintf(stderr,"%s: %s\n",s,F_err[n-100]); + if (f__curunit) { + fprintf(stderr,"apparent state: unit %d ",f__curunit-f__units); + fprintf(stderr, f__curunit->ufnm ? "named %s\n" : "(unnamed)\n", + f__curunit->ufnm); + } + else + fprintf(stderr,"apparent state: internal I/O\n"); + if (f__fmtbuf) + fprintf(stderr,"last format: %s\n",f__fmtbuf); + fprintf(stderr,"lately %s %s %s %s",f__reading?"reading":"writing", + f__sequential?"sequential":"direct",f__formatted?"formatted":"unformatted", + f__external?"external":"internal"); + sig_die(" IO", 1); +} +/*initialization routine*/ + VOID +f_init(Void) +{ unit *p; + + f__init=1; + p= &f__units[0]; + p->ufd=stderr; + p->useek=f__canseek(stderr); +#ifdef NON_UNIX_STDIO + setbuf(stderr, (char *)malloc(BUFSIZ)); +#else + stderr->_flag &= ~_IONBF; +#endif + p->ufmt=1; + p->uwrt=1; + p = &f__units[5]; + p->ufd=stdin; + p->useek=f__canseek(stdin); + p->ufmt=1; + p->uwrt=0; + p= &f__units[6]; + p->ufd=stdout; + p->useek=f__canseek(stdout); + /* IOLBUF and setvbuf only in system 5+ */ +#ifdef COMMENTED_OUT + if(isatty(fileno(stdout))) { + extern char _sobuf[]; + setbuf(stdout, _sobuf); + /* setvbuf(stdout, _IOLBF, 0, 0); /* the buf arg in setvbuf? */ + p->useek = 1; /* only within a record no bigger than BUFSIZ */ + } +#endif + p->ufmt=1; + p->uwrt=1; +} +#ifdef KR_headers +f__nowreading(x) unit *x; +#else +f__nowreading(unit *x) +#endif +{ + long loc; + extern char *f__r_mode[]; + if (!x->ufnm) + goto cantread; + loc=ftell(x->ufd); + if(freopen(x->ufnm,f__r_mode[x->ufmt],x->ufd) == NULL) { + cantread: + errno = 126; + return(1); + } + x->uwrt=0; + (void) fseek(x->ufd,loc,SEEK_SET); + return(0); +} +#ifdef KR_headers +f__nowwriting(x) unit *x; +#else +f__nowwriting(unit *x) +#endif +{ + long loc; + int k; + extern char *f__w_mode[]; + + if (!x->ufnm) + goto cantwrite; + if (x->uwrt == 3) { /* just did write, rewind */ +#ifdef NON_UNIX_STDIO + if (!(f__cf = x->ufd = + freopen(x->ufnm,f__w_mode[x->ufmt],x->ufd))) +#else + if (close(creat(x->ufnm,0666))) +#endif + goto cantwrite; + } + else { + loc=ftell(x->ufd); +#ifdef NON_UNIX_STDIO + if (!(f__cf = x->ufd = + freopen(x->ufnm, f__w_mode[x->ufmt+2], x->ufd))) +#else + if (fclose(x->ufd) < 0 + || (k = x->uwrt == 2 ? creat(x->ufnm,0666) + : open(x->ufnm,O_WRONLY)) < 0 + || (f__cf = x->ufd = fdopen(k,f__w_mode[x->ufmt])) == NULL) +#endif + { + x->ufd = NULL; + cantwrite: + errno = 127; + return(1); + } + (void) fseek(x->ufd,loc,SEEK_SET); + } + x->uwrt = 1; + return(0); +} + + int +#ifdef KR_headers +err__fl(f, m, s) int f, m; char *s; +#else +err__fl(int f, int m, char *s) +#endif +{ + if (!f) + f__fatal(m, s); + if (f__doend) + (*f__doend)(); + return errno = m; + } diff --git a/lib/libI77/f2ch.add b/lib/libI77/f2ch.add new file mode 100644 index 000000000000..4ab0d8078c65 --- /dev/null +++ b/lib/libI77/f2ch.add @@ -0,0 +1,162 @@ +/* If you are using a C++ compiler, append the following to f2c.h + for compiling libF77 and libI77. */ + +#ifdef __cplusplus +extern "C" { +extern int abort_(void); +extern double c_abs(complex *); +extern void c_cos(complex *, complex *); +extern void c_div(complex *, complex *, complex *); +extern void c_exp(complex *, complex *); +extern void c_log(complex *, complex *); +extern void c_sin(complex *, complex *); +extern void c_sqrt(complex *, complex *); +extern double d_abs(double *); +extern double d_acos(double *); +extern double d_asin(double *); +extern double d_atan(double *); +extern double d_atn2(double *, double *); +extern void d_cnjg(doublecomplex *, doublecomplex *); +extern double d_cos(double *); +extern double d_cosh(double *); +extern double d_dim(double *, double *); +extern double d_exp(double *); +extern double d_imag(doublecomplex *); +extern double d_int(double *); +extern double d_lg10(double *); +extern double d_log(double *); +extern double d_mod(double *, double *); +extern double d_nint(double *); +extern double d_prod(float *, float *); +extern double d_sign(double *, double *); +extern double d_sin(double *); +extern double d_sinh(double *); +extern double d_sqrt(double *); +extern double d_tan(double *); +extern double d_tanh(double *); +extern double derf_(double *); +extern double derfc_(double *); +extern integer do_fio(ftnint *, char *, ftnlen); +extern integer do_lio(ftnint *, ftnint *, char *, ftnlen); +extern integer do_uio(ftnint *, char *, ftnlen); +extern integer e_rdfe(void); +extern integer e_rdue(void); +extern integer e_rsfe(void); +extern integer e_rsfi(void); +extern integer e_rsle(void); +extern integer e_rsli(void); +extern integer e_rsue(void); +extern integer e_wdfe(void); +extern integer e_wdue(void); +extern integer e_wsfe(void); +extern integer e_wsfi(void); +extern integer e_wsle(void); +extern integer e_wsli(void); +extern integer e_wsue(void); +extern int ef1asc_(ftnint *, ftnlen *, ftnint *, ftnlen *); +extern integer ef1cmc_(ftnint *, ftnlen *, ftnint *, ftnlen *); +extern double erf(double); +extern double erf_(float *); +extern double erfc(double); +extern double erfc_(float *); +extern integer f_back(alist *); +extern integer f_clos(cllist *); +extern integer f_end(alist *); +extern void f_exit(void); +extern integer f_inqu(inlist *); +extern integer f_open(olist *); +extern integer f_rew(alist *); +extern int flush_(void); +extern void getarg_(integer *, char *, ftnlen); +extern void getenv_(char *, char *, ftnlen, ftnlen); +extern short h_abs(short *); +extern short h_dim(short *, short *); +extern short h_dnnt(double *); +extern short h_indx(char *, char *, ftnlen, ftnlen); +extern short h_len(char *, ftnlen); +extern short h_mod(short *, short *); +extern short h_nint(float *); +extern short h_sign(short *, short *); +extern short hl_ge(char *, char *, ftnlen, ftnlen); +extern short hl_gt(char *, char *, ftnlen, ftnlen); +extern short hl_le(char *, char *, ftnlen, ftnlen); +extern short hl_lt(char *, char *, ftnlen, ftnlen); +extern integer i_abs(integer *); +extern integer i_dim(integer *, integer *); +extern integer i_dnnt(double *); +extern integer i_indx(char *, char *, ftnlen, ftnlen); +extern integer i_len(char *, ftnlen); +extern integer i_mod(integer *, integer *); +extern integer i_nint(float *); +extern integer i_sign(integer *, integer *); +extern integer iargc_(void); +extern ftnlen l_ge(char *, char *, ftnlen, ftnlen); +extern ftnlen l_gt(char *, char *, ftnlen, ftnlen); +extern ftnlen l_le(char *, char *, ftnlen, ftnlen); +extern ftnlen l_lt(char *, char *, ftnlen, ftnlen); +extern void pow_ci(complex *, complex *, integer *); +extern double pow_dd(double *, double *); +extern double pow_di(double *, integer *); +extern short pow_hh(short *, shortint *); +extern integer pow_ii(integer *, integer *); +extern double pow_ri(float *, integer *); +extern void pow_zi(doublecomplex *, doublecomplex *, integer *); +extern void pow_zz(doublecomplex *, doublecomplex *, doublecomplex *); +extern double r_abs(float *); +extern double r_acos(float *); +extern double r_asin(float *); +extern double r_atan(float *); +extern double r_atn2(float *, float *); +extern void r_cnjg(complex *, complex *); +extern double r_cos(float *); +extern double r_cosh(float *); +extern double r_dim(float *, float *); +extern double r_exp(float *); +extern double r_imag(complex *); +extern double r_int(float *); +extern double r_lg10(float *); +extern double r_log(float *); +extern double r_mod(float *, float *); +extern double r_nint(float *); +extern double r_sign(float *, float *); +extern double r_sin(float *); +extern double r_sinh(float *); +extern double r_sqrt(float *); +extern double r_tan(float *); +extern double r_tanh(float *); +extern void s_cat(char *, char **, integer *, integer *, ftnlen); +extern integer s_cmp(char *, char *, ftnlen, ftnlen); +extern void s_copy(char *, char *, ftnlen, ftnlen); +extern int s_paus(char *, ftnlen); +extern integer s_rdfe(cilist *); +extern integer s_rdue(cilist *); +extern integer s_rnge(char *, integer, char *, integer); +extern integer s_rsfe(cilist *); +extern integer s_rsfi(icilist *); +extern integer s_rsle(cilist *); +extern integer s_rsli(icilist *); +extern integer s_rsne(cilist *); +extern integer s_rsni(icilist *); +extern integer s_rsue(cilist *); +extern int s_stop(char *, ftnlen); +extern integer s_wdfe(cilist *); +extern integer s_wdue(cilist *); +extern integer s_wsfe(cilist *); +extern integer s_wsfi(icilist *); +extern integer s_wsle(cilist *); +extern integer s_wsli(icilist *); +extern integer s_wsne(cilist *); +extern integer s_wsni(icilist *); +extern integer s_wsue(cilist *); +extern void sig_die(char *, int); +extern integer signal_(integer *, void (*)(int)); +extern int system_(char *, ftnlen); +extern double z_abs(doublecomplex *); +extern void z_cos(doublecomplex *, doublecomplex *); +extern void z_div(doublecomplex *, doublecomplex *, doublecomplex *); +extern void z_exp(doublecomplex *, doublecomplex *); +extern void z_log(doublecomplex *, doublecomplex *); +extern void z_sin(doublecomplex *, doublecomplex *); +extern void z_sqrt(doublecomplex *, doublecomplex *); + } +#endif diff --git a/lib/libI77/fio.h b/lib/libI77/fio.h new file mode 100644 index 000000000000..370942108a11 --- /dev/null +++ b/lib/libI77/fio.h @@ -0,0 +1,102 @@ +#include "stdio.h" +#include "errno.h" +#ifndef NULL +/* ANSI C */ +#include "stddef.h" +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifdef MSDOS +#ifndef NON_UNIX_STDIO +#define NON_UNIX_STDIO +#endif +#endif + +#ifdef UIOLEN_int +typedef int uiolen; +#else +typedef long uiolen; +#endif + +/*units*/ +typedef struct +{ FILE *ufd; /*0=unconnected*/ + char *ufnm; +#ifndef MSDOS + long uinode; + int udev; +#endif + int url; /*0=sequential*/ + flag useek; /*true=can backspace, use dir, ...*/ + flag ufmt; + flag uprnt; + flag ublnk; + flag uend; + flag uwrt; /*last io was write*/ + flag uscrtch; +} unit; + +extern flag f__init; +extern cilist *f__elist; /*active external io list*/ +extern flag f__reading,f__external,f__sequential,f__formatted; +#undef Void +#ifdef KR_headers +#define Void /*void*/ +extern int (*f__getn)(),(*f__putn)(); /*for formatted io*/ +extern long f__inode(); +extern VOID sig_die(); +extern int (*f__donewrec)(), t_putc(), x_wSL(); +extern int c_sfe(), err_fl(), xrd_SL(); +#else +#define Void void +#ifdef __cplusplus +extern "C" { +#endif +extern int (*f__getn)(void),(*f__putn)(int); /*for formatted io*/ +extern long f__inode(char*,int*); +extern void sig_die(char*,int); +extern void f__fatal(int,char*); +extern int t_runc(alist*); +extern int f__nowreading(unit*), f__nowwriting(unit*); +extern int fk_open(int,int,ftnint); +extern int en_fio(void); +extern void f_init(void); +extern int (*f__donewrec)(void), t_putc(int), x_wSL(void); +extern void b_char(char*,char*,ftnlen), g_char(char*,ftnlen,char*); +extern int c_sfe(cilist*), z_rnew(void); +extern int isatty(int); +extern int err__fl(int,int,char*); +extern int xrd_SL(void); +#ifdef __cplusplus + } +#endif +#endif +extern int (*f__doend)(Void); +extern FILE *f__cf; /*current file*/ +extern unit *f__curunit; /*current unit*/ +extern unit f__units[]; +#define err(f,m,s) {if(f) errno= m; else f__fatal(m,s); return(m);} +#define errfl(f,m,s) return err__fl(f,m,s) + +/*Table sizes*/ +#define MXUNIT 100 + +extern int f__recpos; /*position in current record*/ +extern int f__cursor; /* offset to move to */ +extern int f__hiwater; /* so TL doesn't confuse us */ + +#define WRITE 1 +#define READ 2 +#define SEQ 3 +#define DIR 4 +#define FMT 5 +#define UNF 6 +#define EXT 7 +#define INT 8 + +#define buf_end(x) (x->_flag & _IONBF ? x->_ptr : x->_base + BUFSIZ) diff --git a/lib/libI77/fmt.c b/lib/libI77/fmt.c new file mode 100644 index 000000000000..12792fcf1ddb --- /dev/null +++ b/lib/libI77/fmt.c @@ -0,0 +1,488 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#define skip(s) while(*s==' ') s++ +#ifdef interdata +#define SYLMX 300 +#endif +#ifdef pdp11 +#define SYLMX 300 +#endif +#ifdef vax +#define SYLMX 300 +#endif +#ifndef SYLMX +#define SYLMX 300 +#endif +#define GLITCH '\2' + /* special quote character for stu */ +extern int f__cursor,f__scale; +extern flag f__cblank,f__cplus; /*blanks in I and compulsory plus*/ +struct syl f__syl[SYLMX]; +int f__parenlvl,f__pc,f__revloc; + +#ifdef KR_headers +char *ap_end(s) char *s; +#else +char *ap_end(char *s) +#endif +{ char quote; + quote= *s++; + for(;*s;s++) + { if(*s!=quote) continue; + if(*++s!=quote) return(s); + } + if(f__elist->cierr) { + errno = 100; + return(NULL); + } + f__fatal(100, "bad string"); + /*NOTREACHED*/ return 0; +} +#ifdef KR_headers +op_gen(a,b,c,d) +#else +op_gen(int a, int b, int c, int d) +#endif +{ struct syl *p= &f__syl[f__pc]; + if(f__pc>=SYLMX) + { fprintf(stderr,"format too complicated:\n"); + sig_die(f__fmtbuf, 1); + } + p->op=a; + p->p1=b; + p->p2=c; + p->p3=d; + return(f__pc++); +} +#ifdef KR_headers +char *f_list(); +char *gt_num(s,n) char *s; int *n; +#else +char *f_list(char*); +char *gt_num(char *s, int *n) +#endif +{ int m=0,f__cnt=0; + char c; + for(c= *s;;c = *s) + { if(c==' ') + { s++; + continue; + } + if(c>'9' || c<'0') break; + m=10*m+c-'0'; + f__cnt++; + s++; + } + if(f__cnt==0) *n=1; + else *n=m; + return(s); +} +#ifdef KR_headers +char *f_s(s,curloc) char *s; +#else +char *f_s(char *s, int curloc) +#endif +{ + skip(s); + if(*s++!='(') + { + return(NULL); + } + if(f__parenlvl++ ==1) f__revloc=curloc; + if(op_gen(RET1,curloc,0,0)<0 || + (s=f_list(s))==NULL) + { + return(NULL); + } + skip(s); + return(s); +} +#ifdef KR_headers +ne_d(s,p) char *s,**p; +#else +ne_d(char *s, char **p) +#endif +{ int n,x,sign=0; + struct syl *sp; + switch(*s) + { + default: + return(0); + case ':': (void) op_gen(COLON,0,0,0); break; + case '$': + (void) op_gen(NONL, 0, 0, 0); break; + case 'B': + case 'b': + if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0); + else (void) op_gen(BN,0,0,0); + break; + case 'S': + case 's': + if(*(s+1)=='s' || *(s+1) == 'S') + { x=SS; + s++; + } + else if(*(s+1)=='p' || *(s+1) == 'P') + { x=SP; + s++; + } + else x=S; + (void) op_gen(x,0,0,0); + break; + case '/': (void) op_gen(SLASH,0,0,0); break; + case '-': sign=1; + case '+': s++; /*OUTRAGEOUS CODING TRICK*/ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + s=gt_num(s,&n); + switch(*s) + { + default: + return(0); + case 'P': + case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break; + case 'X': + case 'x': (void) op_gen(X,n,0,0); break; + case 'H': + case 'h': + sp = &f__syl[op_gen(H,n,0,0)]; + *(char **)&sp->p2 = s + 1; + s+=n; + break; + } + break; + case GLITCH: + case '"': + case '\'': + sp = &f__syl[op_gen(APOS,0,0,0)]; + *(char **)&sp->p2 = s; + if((*p = ap_end(s)) == NULL) + return(0); + return(1); + case 'T': + case 't': + if(*(s+1)=='l' || *(s+1) == 'L') + { x=TL; + s++; + } + else if(*(s+1)=='r'|| *(s+1) == 'R') + { x=TR; + s++; + } + else x=T; + s=gt_num(s+1,&n); + s--; + (void) op_gen(x,n,0,0); + break; + case 'X': + case 'x': (void) op_gen(X,1,0,0); break; + case 'P': + case 'p': (void) op_gen(P,1,0,0); break; + } + s++; + *p=s; + return(1); +} +#ifdef KR_headers +e_d(s,p) char *s,**p; +#else +e_d(char *s, char **p) +#endif +{ int i,im,n,w,d,e,found=0,x=0; + char *sv=s; + s=gt_num(s,&n); + (void) op_gen(STACK,n,0,0); + switch(*s++) + { + default: break; + case 'E': + case 'e': x=1; + case 'G': + case 'g': + found=1; + s=gt_num(s,&w); + if(w==0) break; + if(*s=='.') + { s++; + s=gt_num(s,&d); + } + else d=0; + if(*s!='E' && *s != 'e') + (void) op_gen(x==1?E:G,w,d,0); /* default is Ew.dE2 */ + else + { s++; + s=gt_num(s,&e); + (void) op_gen(x==1?EE:GE,w,d,e); + } + break; + case 'O': + case 'o': + i = O; + im = OM; + goto finish_I; + case 'Z': + case 'z': + i = Z; + im = ZM; + goto finish_I; + case 'L': + case 'l': + found=1; + s=gt_num(s,&w); + if(w==0) break; + (void) op_gen(L,w,0,0); + break; + case 'A': + case 'a': + found=1; + skip(s); + if(*s>='0' && *s<='9') + { s=gt_num(s,&w); + if(w==0) break; + (void) op_gen(AW,w,0,0); + break; + } + (void) op_gen(A,0,0,0); + break; + case 'F': + case 'f': + found=1; + s=gt_num(s,&w); + if(w==0) break; + if(*s=='.') + { s++; + s=gt_num(s,&d); + } + else d=0; + (void) op_gen(F,w,d,0); + break; + case 'D': + case 'd': + found=1; + s=gt_num(s,&w); + if(w==0) break; + if(*s=='.') + { s++; + s=gt_num(s,&d); + } + else d=0; + (void) op_gen(D,w,d,0); + break; + case 'I': + case 'i': + i = I; + im = IM; + finish_I: + found=1; + s=gt_num(s,&w); + if(w==0) break; + if(*s!='.') + { (void) op_gen(i,w,0,0); + break; + } + s++; + s=gt_num(s,&d); + (void) op_gen(im,w,d,0); + break; + } + if(found==0) + { f__pc--; /*unSTACK*/ + *p=sv; + return(0); + } + *p=s; + return(1); +} +#ifdef KR_headers +char *i_tem(s) char *s; +#else +char *i_tem(char *s) +#endif +{ char *t; + int n,curloc; + if(*s==')') return(s); + if(ne_d(s,&t)) return(t); + if(e_d(s,&t)) return(t); + s=gt_num(s,&n); + if((curloc=op_gen(STACK,n,0,0))<0) return(NULL); + return(f_s(s,curloc)); +} +#ifdef KR_headers +char *f_list(s) char *s; +#else +char *f_list(char *s) +#endif +{ + for(;*s!=0;) + { skip(s); + if((s=i_tem(s))==NULL) return(NULL); + skip(s); + if(*s==',') s++; + else if(*s==')') + { if(--f__parenlvl==0) + { + (void) op_gen(REVERT,f__revloc,0,0); + return(++s); + } + (void) op_gen(GOTO,0,0,0); + return(++s); + } + } + return(NULL); +} + +#ifdef KR_headers +pars_f(s) char *s; +#else +pars_f(char *s) +#endif +{ + f__parenlvl=f__revloc=f__pc=0; + if(f_s(s,0) == NULL) + { + return(-1); + } + return(0); +} +#define STKSZ 10 +int f__cnt[STKSZ],f__ret[STKSZ],f__cp,f__rp; +flag f__workdone, f__nonl; + +#ifdef KR_headers +type_f(n) +#else +type_f(int n) +#endif +{ + switch(n) + { + default: + return(n); + case RET1: + return(RET1); + case REVERT: return(REVERT); + case GOTO: return(GOTO); + case STACK: return(STACK); + case X: + case SLASH: + case APOS: case H: + case T: case TL: case TR: + return(NED); + case F: + case I: + case IM: + case A: case AW: + case O: case OM: + case L: + case E: case EE: case D: + case G: case GE: + case Z: case ZM: + return(ED); + } +} +#ifdef KR_headers +integer do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr; +#else +integer do_fio(ftnint *number, char *ptr, ftnlen len) +#endif +{ struct syl *p; + int n,i; + for(i=0;i<*number;i++,ptr+=len) + { +loop: switch(type_f((p= &f__syl[f__pc])->op)) + { + default: + fprintf(stderr,"unknown code in do_fio: %d\n%s\n", + p->op,f__fmtbuf); + err(f__elist->cierr,100,"do_fio"); + case NED: + if((*f__doned)(p)) + { f__pc++; + goto loop; + } + f__pc++; + continue; + case ED: + if(f__cnt[f__cp]<=0) + { f__cp--; + f__pc++; + goto loop; + } + if(ptr==NULL) + return((*f__doend)()); + f__cnt[f__cp]--; + f__workdone=1; + if((n=(*f__doed)(p,ptr,len))>0) + errfl(f__elist->cierr,errno,"fmt"); + if(n<0) + err(f__elist->ciend,(EOF),"fmt"); + continue; + case STACK: + f__cnt[++f__cp]=p->p1; + f__pc++; + goto loop; + case RET1: + f__ret[++f__rp]=p->p1; + f__pc++; + goto loop; + case GOTO: + if(--f__cnt[f__cp]<=0) + { f__cp--; + f__rp--; + f__pc++; + goto loop; + } + f__pc=1+f__ret[f__rp--]; + goto loop; + case REVERT: + f__rp=f__cp=0; + f__pc = p->p1; + if(ptr==NULL) + return((*f__doend)()); + if(!f__workdone) return(0); + if((n=(*f__dorevert)()) != 0) return(n); + goto loop; + case COLON: + if(ptr==NULL) + return((*f__doend)()); + f__pc++; + goto loop; + case NONL: + f__nonl = 1; + f__pc++; + goto loop; + case S: + case SS: + f__cplus=0; + f__pc++; + goto loop; + case SP: + f__cplus = 1; + f__pc++; + goto loop; + case P: f__scale=p->p1; + f__pc++; + goto loop; + case BN: + f__cblank=0; + f__pc++; + goto loop; + case BZ: + f__cblank=1; + f__pc++; + goto loop; + } + } + return(0); +} +en_fio(Void) +{ ftnint one=1; + return(do_fio(&one,(char *)NULL,(ftnint)0)); +} + VOID +fmt_bg(Void) +{ + f__workdone=f__cp=f__rp=f__pc=f__cursor=0; + f__cnt[0]=f__ret[0]=0; +} diff --git a/lib/libI77/fmt.h b/lib/libI77/fmt.h new file mode 100644 index 000000000000..d4810a15e82a --- /dev/null +++ b/lib/libI77/fmt.h @@ -0,0 +1,82 @@ +struct syl +{ int op,p1,p2,p3; +}; +#define RET1 1 +#define REVERT 2 +#define GOTO 3 +#define X 4 +#define SLASH 5 +#define STACK 6 +#define I 7 +#define ED 8 +#define NED 9 +#define IM 10 +#define APOS 11 +#define H 12 +#define TL 13 +#define TR 14 +#define T 15 +#define COLON 16 +#define S 17 +#define SP 18 +#define SS 19 +#define P 20 +#define BN 21 +#define BZ 22 +#define F 23 +#define E 24 +#define EE 25 +#define D 26 +#define G 27 +#define GE 28 +#define L 29 +#define A 30 +#define AW 31 +#define O 32 +#define NONL 33 +#define OM 34 +#define Z 35 +#define ZM 36 +extern struct syl f__syl[]; +extern int f__pc,f__parenlvl,f__revloc; +typedef union +{ real pf; + doublereal pd; +} ufloat; +typedef union +{ short is; + char ic; + integer il; +#ifdef Allow_TYQUAD + longint ili; +#endif +} Uint; +#ifdef KR_headers +extern int (*f__doed)(),(*f__doned)(); +extern int (*f__dorevert)(); +extern int rd_ed(),rd_ned(); +extern int w_ed(),w_ned(); +#else +#ifdef __cplusplus +extern "C" { +#endif +extern int (*f__doed)(struct syl*, char*, ftnlen),(*f__doned)(struct syl*); +extern int (*f__dorevert)(void); +extern void fmt_bg(void); +extern int pars_f(char*); +extern int rd_ed(struct syl*, char*, ftnlen),rd_ned(struct syl*); +extern int w_ed(struct syl*, char*, ftnlen),w_ned(struct syl*); +extern int wrt_E(ufloat*, int, int, int, ftnlen); +extern int wrt_F(ufloat*, int, int, ftnlen); +extern int wrt_L(Uint*, int, ftnlen); +#ifdef __cplusplus + } +#endif +#endif +extern flag f__cblank,f__cplus,f__workdone, f__nonl; +extern char *f__fmtbuf; +extern int f__scale; +#define GET(x) if((x=(*f__getn)())<0) return(x) +#define VAL(x) (x!='\n'?x:' ') +#define PUT(x) (*f__putn)(x) +extern int f__cursor; diff --git a/lib/libI77/fmtlib.c b/lib/libI77/fmtlib.c new file mode 100644 index 000000000000..37a4cc5f1d5a --- /dev/null +++ b/lib/libI77/fmtlib.c @@ -0,0 +1,28 @@ +/* @(#)fmtlib.c 1.2 */ +#define MAXINTLENGTH 23 +#ifdef KR_headers +char *f__icvt(value,ndigit,sign, base) long value; int *ndigit,*sign; + register int base; +#else +char *f__icvt(long value, int *ndigit, int *sign, int base) +#endif +{ static char buf[MAXINTLENGTH+1]; + register int i; + if(value>0) *sign=0; + else if(value<0) + { value = -value; + *sign= 1; + } + else + { *sign=0; + *ndigit=1; + buf[MAXINTLENGTH]='0'; + return(&buf[MAXINTLENGTH]); + } + for(i=MAXINTLENGTH-1;value>0;i--) + { *(buf+i)=(int)(value%base)+'0'; + value /= base; + } + *ndigit=MAXINTLENGTH-1-i; + return(&buf[i+1]); +} diff --git a/lib/libI77/fp.h b/lib/libI77/fp.h new file mode 100644 index 000000000000..033cb03f272f --- /dev/null +++ b/lib/libI77/fp.h @@ -0,0 +1,26 @@ +#define FMAX 40 +#define EXPMAXDIGS 8 +#define EXPMAX 99999999 +/* FMAX = max number of nonzero digits passed to atof() */ +/* EXPMAX = 10^EXPMAXDIGS - 1 = largest allowed exponent absolute value */ + +#include "local.h" + +/* MAXFRACDIGS and MAXINTDIGS are for wrt_F -- bounds (not necessarily + tight) on the maximum number of digits to the right and left of + * the decimal point. + */ + +#ifdef VAX +#define MAXFRACDIGS 56 +#define MAXINTDIGS 38 +#else +#ifdef CRAY +#define MAXFRACDIGS 9880 +#define MAXINTDIGS 9864 +#else +/* values that suffice for IEEE double */ +#define MAXFRACDIGS 344 +#define MAXINTDIGS 308 +#endif +#endif diff --git a/lib/libI77/iio.c b/lib/libI77/iio.c new file mode 100644 index 000000000000..b747826f4b88 --- /dev/null +++ b/lib/libI77/iio.c @@ -0,0 +1,138 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +extern char *f__icptr; +char *f__icend; +extern icilist *f__svic; +int f__icnum; +extern int f__hiwater; +z_getc(Void) +{ + if(f__recpos++ < f__svic->icirlen) { + if(f__icptr >= f__icend) err(f__svic->iciend,(EOF),"endfile"); + return(*f__icptr++); + } + return '\n'; +} +#ifdef KR_headers +z_putc(c) +#else +z_putc(int c) +#endif +{ + if(f__icptr >= f__icend) err(f__svic->icierr,110,"inwrite"); + if(f__recpos++ < f__svic->icirlen) + *f__icptr++ = c; + else err(f__svic->icierr,110,"recend"); + return 0; +} +z_rnew(Void) +{ + f__icptr = f__svic->iciunit + (++f__icnum)*f__svic->icirlen; + f__recpos = 0; + f__cursor = 0; + f__hiwater = 0; + return 1; +} + + static int +z_endp(Void) +{ + (*f__donewrec)(); + return 0; + } + +#ifdef KR_headers +c_si(a) icilist *a; +#else +c_si(icilist *a) +#endif +{ + f__elist = (cilist *)a; + f__fmtbuf=a->icifmt; + if(pars_f(f__fmtbuf)<0) + err(a->icierr,100,"startint"); + fmt_bg(); + f__sequential=f__formatted=1; + f__external=0; + f__cblank=f__cplus=f__scale=0; + f__svic=a; + f__icnum=f__recpos=0; + f__cursor = 0; + f__hiwater = 0; + f__icptr = a->iciunit; + f__icend = f__icptr + a->icirlen*a->icirnum; + f__curunit = 0; + f__cf = 0; + return(0); +} + + int +iw_rev(Void) +{ + if(f__workdone) + z_endp(); + f__hiwater = f__recpos = f__cursor = 0; + return(f__workdone=0); + } + +#ifdef KR_headers +integer s_rsfi(a) icilist *a; +#else +integer s_rsfi(icilist *a) +#endif +{ int n; + if(n=c_si(a)) return(n); + f__reading=1; + f__doed=rd_ed; + f__doned=rd_ned; + f__getn=z_getc; + f__dorevert = z_endp; + f__donewrec = z_rnew; + f__doend = z_endp; + return(0); +} + +z_wnew(Void) +{ + while(f__recpos++ < f__svic->icirlen) + *f__icptr++ = ' '; + f__recpos = 0; + f__cursor = 0; + f__hiwater = 0; + f__icnum++; + return 1; +} +#ifdef KR_headers +integer s_wsfi(a) icilist *a; +#else +integer s_wsfi(icilist *a) +#endif +{ int n; + if(n=c_si(a)) return(n); + f__reading=0; + f__doed=w_ed; + f__doned=w_ned; + f__putn=z_putc; + f__dorevert = iw_rev; + f__donewrec = z_wnew; + f__doend = z_endp; + return(0); +} +integer e_rsfi(Void) +{ int n; + n = en_fio(); + f__fmtbuf = NULL; + return(n); +} +integer e_wsfi(Void) +{ + int n; + n = en_fio(); + f__fmtbuf = NULL; + if(f__icnum >= f__svic->icirnum) + return(n); + while(f__recpos++ < f__svic->icirlen) + *f__icptr++ = ' '; + return(n); +} diff --git a/lib/libI77/ilnw.c b/lib/libI77/ilnw.c new file mode 100644 index 000000000000..b4156861eeb8 --- /dev/null +++ b/lib/libI77/ilnw.c @@ -0,0 +1,77 @@ +#include "f2c.h" +#include "fio.h" +#include "lio.h" +extern char *f__icptr; +extern char *f__icend; +extern icilist *f__svic; +extern int f__icnum; +#ifdef KR_headers +extern int z_putc(); +#else +extern int z_putc(int); +#endif + + static int +z_wSL(Void) +{ + while(f__recpos < f__svic->icirlen) + z_putc(' '); + return z_rnew(); + } + + VOID +#ifdef KR_headers +c_liw(a) icilist *a; +#else +c_liw(icilist *a) +#endif +{ + f__reading = 0; + f__external = 0; + f__formatted = 1; + f__putn = z_putc; + L_len = a->icirlen; + f__donewrec = z_wSL; + f__svic = a; + f__icnum = f__recpos = 0; + f__cursor = 0; + f__cf = 0; + f__curunit = 0; + f__icptr = a->iciunit; + f__icend = f__icptr + a->icirlen*a->icirnum; + f__elist = (cilist *)a; + } + + integer +#ifdef KR_headers +s_wsni(a) icilist *a; +#else +s_wsni(icilist *a) +#endif +{ + cilist ca; + + c_liw(a); + ca.cifmt = a->icifmt; + x_wsne(&ca); + z_wSL(); + return 0; + } + + integer +#ifdef KR_headers +s_wsli(a) icilist *a; +#else +s_wsli(icilist *a) +#endif +{ + f__lioproc = l_write; + c_liw(a); + return(0); + } + +integer e_wsli(Void) +{ + z_wSL(); + return(0); + } diff --git a/lib/libI77/inquire.c b/lib/libI77/inquire.c new file mode 100644 index 000000000000..ec98b22f8401 --- /dev/null +++ b/lib/libI77/inquire.c @@ -0,0 +1,106 @@ +#include "f2c.h" +#include "fio.h" +#ifdef KR_headers +integer f_inqu(a) inlist *a; +#else +#ifdef MSDOS +#undef abs +#undef min +#undef max +#include "string.h" +#include "io.h" +#endif +integer f_inqu(inlist *a) +#endif +{ flag byfile; + int i, n; + unit *p; + char buf[256]; + long x; + if(a->infile!=NULL) + { byfile=1; + g_char(a->infile,a->infilen,buf); +#ifdef NON_UNIX_STDIO + x = access(buf,0) ? -1 : 0; + for(i=0,p=NULL;i<MXUNIT;i++) + if(f__units[i].ufd != NULL + && f__units[i].ufnm != NULL + && !strcmp(f__units[i].ufnm,buf)) { + p = &f__units[i]; + break; + } +#else + x=f__inode(buf, &n); + for(i=0,p=NULL;i<MXUNIT;i++) + if(f__units[i].uinode==x + && f__units[i].ufd!=NULL + && f__units[i].udev == n) { + p = &f__units[i]; + break; + } +#endif + } + else + { + byfile=0; + if(a->inunit<MXUNIT && a->inunit>=0) + { + p= &f__units[a->inunit]; + } + else + { + p=NULL; + } + } + if(a->inex!=NULL) + if(byfile && x != -1 || !byfile && p!=NULL) + *a->inex=1; + else *a->inex=0; + if(a->inopen!=NULL) + if(byfile) *a->inopen=(p!=NULL); + else *a->inopen=(p!=NULL && p->ufd!=NULL); + if(a->innum!=NULL) *a->innum= p-f__units; + if(a->innamed!=NULL) + if(byfile || p!=NULL && p->ufnm!=NULL) + *a->innamed=1; + else *a->innamed=0; + if(a->inname!=NULL) + if(byfile) + b_char(buf,a->inname,a->innamlen); + else if(p!=NULL && p->ufnm!=NULL) + b_char(p->ufnm,a->inname,a->innamlen); + if(a->inacc!=NULL && p!=NULL && p->ufd!=NULL) + if(p->url) + b_char("DIRECT",a->inacc,a->inacclen); + else b_char("SEQUENTIAL",a->inacc,a->inacclen); + if(a->inseq!=NULL) + if(p!=NULL && p->url) + b_char("NO",a->inseq,a->inseqlen); + else b_char("YES",a->inseq,a->inseqlen); + if(a->indir!=NULL) + if(p==NULL || p->url) + b_char("YES",a->indir,a->indirlen); + else b_char("NO",a->indir,a->indirlen); + if(a->infmt!=NULL) + if(p!=NULL && p->ufmt==0) + b_char("UNFORMATTED",a->infmt,a->infmtlen); + else b_char("FORMATTED",a->infmt,a->infmtlen); + if(a->inform!=NULL) + if(p!=NULL && p->ufmt==0) + b_char("NO",a->inform,a->informlen); + else b_char("YES",a->inform,a->informlen); + if(a->inunf) + if(p!=NULL && p->ufmt==0) + b_char("YES",a->inunf,a->inunflen); + else if (p!=NULL) b_char("NO",a->inunf,a->inunflen); + else b_char("UNKNOWN",a->inunf,a->inunflen); + if(a->inrecl!=NULL && p!=NULL) + *a->inrecl=p->url; + if(a->innrec!=NULL && p!=NULL && p->url>0) + *a->innrec=ftell(p->ufd)/p->url+1; + if(a->inblank && p!=NULL && p->ufmt) + if(p->ublnk) + b_char("ZERO",a->inblank,a->inblanklen); + else b_char("NULL",a->inblank,a->inblanklen); + return(0); +} diff --git a/lib/libI77/lio.h b/lib/libI77/lio.h new file mode 100644 index 000000000000..5af9fc45e66f --- /dev/null +++ b/lib/libI77/lio.h @@ -0,0 +1,73 @@ +/* copy of ftypes from the compiler */ +/* variable types + * numeric assumptions: + * int < reals < complexes + * TYDREAL-TYREAL = TYDCOMPLEX-TYCOMPLEX + */ + +/* 0-10 retain their old (pre LOGICAL*1, etc.) */ +/* values to allow mixing old and new objects. */ + +#define TYUNKNOWN 0 +#define TYADDR 1 +#define TYSHORT 2 +#define TYLONG 3 +#define TYREAL 4 +#define TYDREAL 5 +#define TYCOMPLEX 6 +#define TYDCOMPLEX 7 +#define TYLOGICAL 8 +#define TYCHAR 9 +#define TYSUBR 10 +#define TYINT1 11 +#define TYLOGICAL1 12 +#define TYLOGICAL2 13 +#ifdef Allow_TYQUAD +#define TYQUAD 14 +#endif + +#define LINTW 24 +#define LINE 80 +#define LLOGW 2 +#ifdef Old_list_output +#define LLOW 1.0 +#define LHIGH 1.e9 +#define LEFMT " %# .8E" +#define LFFMT " %# .9g" +#else +#define LGFMT "%.9G" +#endif +/* LEFBL 20 should suffice; 24 overcomes a NeXT bug. */ +#define LEFBL 24 + +typedef union +{ + char flchar; + short flshort; + ftnint flint; +#ifdef Allow_TYQUAD + longint fllongint; +#endif + real flreal; + doublereal fldouble; +} flex; +extern int f__scale; +#ifdef KR_headers +extern int (*f__lioproc)(), (*l_getc)(), (*l_ungetc)(); +extern int l_read(), l_write(); +#else +#ifdef __cplusplus +extern "C" { +#endif +extern int (*f__lioproc)(ftnint*, char*, ftnlen, ftnint); +extern int l_write(ftnint*, char*, ftnlen, ftnint); +extern void x_wsne(cilist*); +extern int c_le(cilist*), (*l_getc)(void), (*l_ungetc)(int,FILE*); +extern int l_read(ftnint*,char*,ftnlen,ftnint); +extern integer e_rsle(void), e_wsle(void), s_wsne(cilist*); +extern int z_rnew(void); +#ifdef __cplusplus + } +#endif +#endif +extern ftnint L_len; diff --git a/lib/libI77/local.h b/lib/libI77/local.h new file mode 100644 index 000000000000..a26b7c1a4964 --- /dev/null +++ b/lib/libI77/local.h @@ -0,0 +1,6 @@ +/* Use + -DNON_ANSI_RW_MODES in libI77/makefile and + -DIEEE_drem in libF77/makefile. Rich */ +#define _base _bf._base +#define _flag _flags +#define _ptr _p diff --git a/lib/libI77/lread.c b/lib/libI77/lread.c new file mode 100644 index 000000000000..dacb9a8f9e5a --- /dev/null +++ b/lib/libI77/lread.c @@ -0,0 +1,611 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "lio.h" +#include "ctype.h" +#include "fp.h" + +extern char *f__fmtbuf; +#ifdef KR_headers +extern double atof(); +extern char *malloc(), *realloc(); +int (*f__lioproc)(), (*l_getc)(), (*l_ungetc)(); +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +int (*f__lioproc)(ftnint*, char*, ftnlen, ftnint), (*l_getc)(void), + (*l_ungetc)(int,FILE*); +#endif +int l_eof; + +#define isblnk(x) (f__ltab[x+1]&B) +#define issep(x) (f__ltab[x+1]&SX) +#define isapos(x) (f__ltab[x+1]&AX) +#define isexp(x) (f__ltab[x+1]&EX) +#define issign(x) (f__ltab[x+1]&SG) +#define iswhit(x) (f__ltab[x+1]&WH) +#define SX 1 +#define B 2 +#define AX 4 +#define EX 8 +#define SG 16 +#define WH 32 +char f__ltab[128+1] = { /* offset one for EOF */ + 0, + 0,0,AX,0,0,0,0,0,0,WH|B,SX|WH,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + SX|B|WH,0,AX,0,0,0,0,AX,0,0,0,SG,SX,SG,0,SX, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + AX,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +#ifdef ungetc + static int +#ifdef KR_headers +un_getc(x,f__cf) int x; FILE *f__cf; +#else +un_getc(int x, FILE *f__cf) +#endif +{ return ungetc(x,f__cf); } +#else +#define un_getc ungetc +#ifdef KR_headers + extern int ungetc(); +#endif +#endif + +t_getc(Void) +{ int ch; + if(f__curunit->uend) return(EOF); + if((ch=getc(f__cf))!=EOF) return(ch); + if(feof(f__cf)) + f__curunit->uend = l_eof = 1; + return(EOF); +} +integer e_rsle(Void) +{ + int ch; + if(f__curunit->uend) return(0); + while((ch=t_getc())!='\n' && ch!=EOF); + return(0); +} + +flag f__lquit; +int f__lcount,f__ltype,nml_read; +char *f__lchar; +double f__lx,f__ly; +#define ERR(x) if(n=(x)) return(n) +#define GETC(x) (x=(*l_getc)()) +#define Ungetc(x,y) (*l_ungetc)(x,y) + +#ifdef KR_headers +l_R(poststar) int poststar; +#else +l_R(int poststar) +#endif +{ + char s[FMAX+EXPMAXDIGS+4]; + register int ch; + register char *sp, *spe, *sp1; + long e, exp; + int havenum, havestar, se; + + if (!poststar) { + if (f__lcount > 0) + return(0); + f__lcount = 1; + } + f__ltype = 0; + exp = 0; + havestar = 0; +retry: + sp1 = sp = s; + spe = sp + FMAX; + havenum = 0; + + switch(GETC(ch)) { + case '-': *sp++ = ch; sp1++; spe++; + case '+': + GETC(ch); + } + while(ch == '0') { + ++havenum; + GETC(ch); + } + while(isdigit(ch)) { + if (sp < spe) *sp++ = ch; + else ++exp; + GETC(ch); + } + if (ch == '*' && !poststar) { + if (sp == sp1 || exp || *s == '-') { + errfl(f__elist->cierr,112,"bad repetition count"); + } + poststar = havestar = 1; + *sp = 0; + f__lcount = atoi(s); + goto retry; + } + if (ch == '.') { + GETC(ch); + if (sp == sp1) + while(ch == '0') { + ++havenum; + --exp; + GETC(ch); + } + while(isdigit(ch)) { + if (sp < spe) + { *sp++ = ch; --exp; } + GETC(ch); + } + } + havenum += sp - sp1; + se = 0; + if (issign(ch)) + goto signonly; + if (havenum && isexp(ch)) { + GETC(ch); + if (issign(ch)) { +signonly: + if (ch == '-') se = 1; + GETC(ch); + } + if (!isdigit(ch)) { +bad: + errfl(f__elist->cierr,112,"exponent field"); + } + + e = ch - '0'; + while(isdigit(GETC(ch))) { + e = 10*e + ch - '0'; + if (e > EXPMAX) + goto bad; + } + if (se) + exp -= e; + else + exp += e; + } + (void) Ungetc(ch, f__cf); + if (sp > sp1) { + ++havenum; + while(*--sp == '0') + ++exp; + if (exp) + sprintf(sp+1, "e%ld", exp); + else + sp[1] = 0; + f__lx = atof(s); + } + else + f__lx = 0.; + if (havenum) + f__ltype = TYLONG; + else + switch(ch) { + case ',': + case '/': + break; + default: + if (havestar && ( ch == ' ' + ||ch == '\t' + ||ch == '\n')) + break; + if (nml_read > 1) { + f__lquit = 2; + return 0; + } + errfl(f__elist->cierr,112,"invalid number"); + } + return 0; + } + + static int +#ifdef KR_headers +rd_count(ch) register int ch; +#else +rd_count(register int ch) +#endif +{ + if (ch < '0' || ch > '9') + return 1; + f__lcount = ch - '0'; + while(GETC(ch) >= '0' && ch <= '9') + f__lcount = 10*f__lcount + ch - '0'; + Ungetc(ch,f__cf); + return f__lcount <= 0; + } + +l_C(Void) +{ int ch, nml_save; + double lz; + if(f__lcount>0) return(0); + f__ltype=0; + GETC(ch); + if(ch!='(') + { + if (nml_read > 1 && (ch < '0' || ch > '9')) { + Ungetc(ch,f__cf); + f__lquit = 2; + return 0; + } + if (rd_count(ch)) + if(!f__cf || !feof(f__cf)) + errfl(f__elist->cierr,112,"complex format"); + else + err(f__elist->cierr,(EOF),"lread"); + if(GETC(ch)!='*') + { + if(!f__cf || !feof(f__cf)) + errfl(f__elist->cierr,112,"no star"); + else + err(f__elist->cierr,(EOF),"lread"); + } + if(GETC(ch)!='(') + { Ungetc(ch,f__cf); + return(0); + } + } + else + f__lcount = 1; + while(iswhit(GETC(ch))); + Ungetc(ch,f__cf); + nml_save = nml_read; + nml_read = 0; + if (ch = l_R(1)) + return ch; + if (!f__ltype) + errfl(f__elist->cierr,112,"no real part"); + lz = f__lx; + while(iswhit(GETC(ch))); + if(ch!=',') + { (void) Ungetc(ch,f__cf); + errfl(f__elist->cierr,112,"no comma"); + } + while(iswhit(GETC(ch))); + (void) Ungetc(ch,f__cf); + if (ch = l_R(1)) + return ch; + if (!f__ltype) + errfl(f__elist->cierr,112,"no imaginary part"); + while(iswhit(GETC(ch))); + if(ch!=')') errfl(f__elist->cierr,112,"no )"); + f__ly = f__lx; + f__lx = lz; + nml_read = nml_save; + return(0); +} +l_L(Void) +{ + int ch; + if(f__lcount>0) return(0); + f__lcount = 1; + f__ltype=0; + GETC(ch); + if(isdigit(ch)) + { + rd_count(ch); + if(GETC(ch)!='*') + if(!f__cf || !feof(f__cf)) + errfl(f__elist->cierr,112,"no star"); + else + err(f__elist->cierr,(EOF),"lread"); + GETC(ch); + } + if(ch == '.') GETC(ch); + switch(ch) + { + case 't': + case 'T': + f__lx=1; + break; + case 'f': + case 'F': + f__lx=0; + break; + default: + if(isblnk(ch) || issep(ch) || ch==EOF) + { (void) Ungetc(ch,f__cf); + return(0); + } + if (nml_read > 1) { + Ungetc(ch,f__cf); + f__lquit = 2; + return 0; + } + errfl(f__elist->cierr,112,"logical"); + } + f__ltype=TYLONG; + while(!issep(GETC(ch)) && ch!=EOF); + (void) Ungetc(ch, f__cf); + return(0); +} +#define BUFSIZE 128 +l_CHAR(Void) +{ int ch,size,i; + char quote,*p; + if(f__lcount>0) return(0); + f__ltype=0; + if(f__lchar!=NULL) free(f__lchar); + size=BUFSIZE; + p=f__lchar = (char *)malloc((unsigned int)size); + if(f__lchar == NULL) + errfl(f__elist->cierr,113,"no space"); + + GETC(ch); + if(isdigit(ch)) { + /* allow Fortran 8x-style unquoted string... */ + /* either find a repetition count or the string */ + f__lcount = ch - '0'; + *p++ = ch; + for(i = 1;;) { + switch(GETC(ch)) { + case '*': + if (f__lcount == 0) { + f__lcount = 1; + goto noquote; + } + p = f__lchar; + goto have_lcount; + case ',': + case ' ': + case '\t': + case '\n': + case '/': + Ungetc(ch,f__cf); + /* no break */ + case EOF: + f__lcount = 1; + f__ltype = TYCHAR; + return *p = 0; + } + if (!isdigit(ch)) { + f__lcount = 1; + goto noquote; + } + *p++ = ch; + f__lcount = 10*f__lcount + ch - '0'; + if (++i == size) { + f__lchar = (char *)realloc(f__lchar, + (unsigned int)(size += BUFSIZE)); + p = f__lchar + i; + } + } + } + else (void) Ungetc(ch,f__cf); + have_lcount: + if(GETC(ch)=='\'' || ch=='"') quote=ch; + else if(isblnk(ch) || (issep(ch) && ch != '\n') || ch==EOF) + { (void) Ungetc(ch,f__cf); + return(0); + } + else { + /* Fortran 8x-style unquoted string */ + *p++ = ch; + for(i = 1;;) { + switch(GETC(ch)) { + case ',': + case ' ': + case '\t': + case '\n': + case '/': + Ungetc(ch,f__cf); + /* no break */ + case EOF: + f__ltype = TYCHAR; + return *p = 0; + } + noquote: + *p++ = ch; + if (++i == size) { + f__lchar = (char *)realloc(f__lchar, + (unsigned int)(size += BUFSIZE)); + p = f__lchar + i; + } + } + } + f__ltype=TYCHAR; + for(i=0;;) + { while(GETC(ch)!=quote && ch!='\n' + && ch!=EOF && ++i<size) *p++ = ch; + if(i==size) + { + newone: + f__lchar= (char *)realloc(f__lchar, + (unsigned int)(size += BUFSIZE)); + p=f__lchar+i-1; + *p++ = ch; + } + else if(ch==EOF) return(EOF); + else if(ch=='\n') + { if(*(p-1) != '\\') continue; + i--; + p--; + if(++i<size) *p++ = ch; + else goto newone; + } + else if(GETC(ch)==quote) + { if(++i<size) *p++ = ch; + else goto newone; + } + else + { (void) Ungetc(ch,f__cf); + *p = 0; + return(0); + } + } +} +#ifdef KR_headers +c_le(a) cilist *a; +#else +c_le(cilist *a) +#endif +{ + f__fmtbuf="list io"; + if(a->ciunit>=MXUNIT || a->ciunit<0) + err(a->cierr,101,"stler"); + f__scale=f__recpos=0; + f__elist=a; + f__curunit = &f__units[a->ciunit]; + if(f__curunit->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) + err(a->cierr,102,"lio"); + f__cf=f__curunit->ufd; + if(!f__curunit->ufmt) err(a->cierr,103,"lio") + return(0); +} +#ifdef KR_headers +l_read(number,ptr,len,type) ftnint *number,type; char *ptr; ftnlen len; +#else +l_read(ftnint *number, char *ptr, ftnlen len, ftnint type) +#endif +{ +#define Ptr ((flex *)ptr) + int i,n,ch; + doublereal *yy; + real *xx; + for(i=0;i<*number;i++) + { + if(f__lquit) return(0); + if(l_eof) + err(f__elist->ciend, EOF, "list in") + if(f__lcount == 0) { + f__ltype = 0; + for(;;) { + GETC(ch); + switch(ch) { + case EOF: + goto loopend; + case ' ': + case '\t': + case '\n': + continue; + case '/': + f__lquit = 1; + goto loopend; + case ',': + f__lcount = 1; + goto loopend; + default: + (void) Ungetc(ch, f__cf); + goto rddata; + } + } + } + rddata: + switch((int)type) + { + case TYINT1: + case TYSHORT: + case TYLONG: +#ifdef TYQUAD + case TYQUAD: +#endif + case TYREAL: + case TYDREAL: + ERR(l_R(0)); + break; + case TYCOMPLEX: + case TYDCOMPLEX: + ERR(l_C()); + break; + case TYLOGICAL1: + case TYLOGICAL2: + case TYLOGICAL: + ERR(l_L()); + break; + case TYCHAR: + ERR(l_CHAR()); + break; + } + while (GETC(ch) == ' ' || ch == '\t'); + if (ch != ',' || f__lcount > 1) + Ungetc(ch,f__cf); + loopend: + if(f__lquit) return(0); + if(f__cf) { + if (feof(f__cf)) + err(f__elist->ciend,(EOF),"list in") + else if(ferror(f__cf)) { + clearerr(f__cf); + errfl(f__elist->cierr,errno,"list in"); + } + } + if(f__ltype==0) goto bump; + switch((int)type) + { + case TYINT1: + case TYLOGICAL1: + Ptr->flchar = (char)f__lx; + break; + case TYLOGICAL2: + case TYSHORT: + Ptr->flshort = (short)f__lx; + break; + case TYLOGICAL: + case TYLONG: + Ptr->flint=f__lx; + break; +#ifdef TYQUAD + case TYQUAD: + Ptr->fllongint = f__lx; + break; +#endif + case TYREAL: + Ptr->flreal=f__lx; + break; + case TYDREAL: + Ptr->fldouble=f__lx; + break; + case TYCOMPLEX: + xx=(real *)ptr; + *xx++ = f__lx; + *xx = f__ly; + break; + case TYDCOMPLEX: + yy=(doublereal *)ptr; + *yy++ = f__lx; + *yy = f__ly; + break; + case TYCHAR: + b_char(f__lchar,ptr,len); + break; + } + bump: + if(f__lcount>0) f__lcount--; + ptr += len; + if (nml_read) + nml_read++; + } + return(0); +#undef Ptr +} +#ifdef KR_headers +integer s_rsle(a) cilist *a; +#else +integer s_rsle(cilist *a) +#endif +{ + int n; + + if(!f__init) f_init(); + if(n=c_le(a)) return(n); + f__reading=1; + f__external=1; + f__formatted=1; + f__lioproc = l_read; + f__lquit = 0; + f__lcount = 0; + l_eof = 0; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr,errno,"read start"); + l_getc = t_getc; + l_ungetc = un_getc; + f__doend = xrd_SL; + return(0); +} diff --git a/lib/libI77/lwrite.c b/lib/libI77/lwrite.c new file mode 100644 index 000000000000..6c630d3a0955 --- /dev/null +++ b/lib/libI77/lwrite.c @@ -0,0 +1,250 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "lio.h" +ftnint L_len; + +#ifdef KR_headers +t_putc(c) +#else +t_putc(int c) +#endif +{ + f__recpos++; + putc(c,f__cf); + return(0); +} + static VOID +#ifdef KR_headers +lwrt_I(n) long n; +#else +lwrt_I(long n) +#endif +{ + char buf[LINTW],*p; +#ifdef USE_STRLEN + (void) sprintf(buf," %ld",n); + if(f__recpos+strlen(buf)>=L_len) +#else + if(f__recpos + sprintf(buf," %ld",n) >= L_len) +#endif + (*f__donewrec)(); + for(p=buf;*p;PUT(*p++)); +} + static VOID +#ifdef KR_headers +lwrt_L(n, len) ftnint n; ftnlen len; +#else +lwrt_L(ftnint n, ftnlen len) +#endif +{ + if(f__recpos+LLOGW>=L_len) + (*f__donewrec)(); + wrt_L((Uint *)&n,LLOGW, len); +} + static VOID +#ifdef KR_headers +lwrt_A(p,len) char *p; ftnlen len; +#else +lwrt_A(char *p, ftnlen len) +#endif +{ + int i; + if(f__recpos+len>=L_len) + (*f__donewrec)(); + if (!f__recpos) + { PUT(' '); ++f__recpos; } + for(i=0;i<len;i++) PUT(*p++); +} + + static int +#ifdef KR_headers +l_g(buf, n) char *buf; double n; +#else +l_g(char *buf, double n) +#endif +{ +#ifdef Old_list_output + doublereal absn; + char *fmt; + + absn = n; + if (absn < 0) + absn = -absn; + fmt = LLOW <= absn && absn < LHIGH ? LFFMT : LEFMT; +#ifdef USE_STRLEN + sprintf(buf, fmt, n); + return strlen(buf); +#else + return sprintf(buf, fmt, n); +#endif + +#else + register char *b, c, c1; + + b = buf; + *b++ = ' '; + if (n < 0) { + *b++ = '-'; + n = -n; + } + else + *b++ = ' '; + if (n == 0) { + *b++ = '0'; + *b++ = '.'; + *b = 0; + goto f__ret; + } + sprintf(b, LGFMT, n); + if (*b == '0') { + while(b[0] = b[1]) + b++; + } + /* Fortran 77 insists on having a decimal point... */ + else for(;; b++) + switch(*b) { + case 0: + *b++ = '.'; + *b = 0; + goto f__ret; + case '.': + while(*++b); + goto f__ret; + case 'E': + for(c1 = '.', c = 'E'; *b = c1; + c1 = c, c = *++b); + goto f__ret; + } + f__ret: + return b - buf; +#endif + } + + static VOID +#ifdef KR_headers +l_put(s) register char *s; +#else +l_put(register char *s) +#endif +{ +#ifdef KR_headers + register int c, (*pn)() = f__putn; +#else + register int c, (*pn)(int) = f__putn; +#endif + while(c = *s++) + (*pn)(c); + } + + static VOID +#ifdef KR_headers +lwrt_F(n) double n; +#else +lwrt_F(double n) +#endif +{ + char buf[LEFBL]; + + if(f__recpos + l_g(buf,n) >= L_len) + (*f__donewrec)(); + l_put(buf); +} + static VOID +#ifdef KR_headers +lwrt_C(a,b) double a,b; +#else +lwrt_C(double a, double b) +#endif +{ + char *ba, *bb, bufa[LEFBL], bufb[LEFBL]; + int al, bl; + + al = l_g(bufa, a); + for(ba = bufa; *ba == ' '; ba++) + --al; + bl = l_g(bufb, b) + 1; /* intentionally high by 1 */ + for(bb = bufb; *bb == ' '; bb++) + --bl; + if(f__recpos + al + bl + 3 >= L_len && f__recpos) + (*f__donewrec)(); + PUT(' '); + PUT('('); + l_put(ba); + PUT(','); + if (f__recpos + bl >= L_len) { + (*f__donewrec)(); + PUT(' '); + } + l_put(bb); + PUT(')'); +} +#ifdef KR_headers +l_write(number,ptr,len,type) ftnint *number,type; char *ptr; ftnlen len; +#else +l_write(ftnint *number, char *ptr, ftnlen len, ftnint type) +#endif +{ +#define Ptr ((flex *)ptr) + int i; + long x; + double y,z; + real *xx; + doublereal *yy; + for(i=0;i< *number; i++) + { + switch((int)type) + { + default: f__fatal(204,"unknown type in lio"); + case TYINT1: + x = Ptr->flchar; + goto xint; + case TYSHORT: + x=Ptr->flshort; + goto xint; +#ifdef TYQUAD + case TYQUAD: + x = Ptr->fllongint; + goto xint; +#endif + case TYLONG: + x=Ptr->flint; + xint: lwrt_I(x); + break; + case TYREAL: + y=Ptr->flreal; + goto xfloat; + case TYDREAL: + y=Ptr->fldouble; + xfloat: lwrt_F(y); + break; + case TYCOMPLEX: + xx= &Ptr->flreal; + y = *xx++; + z = *xx; + goto xcomplex; + case TYDCOMPLEX: + yy = &Ptr->fldouble; + y= *yy++; + z = *yy; + xcomplex: + lwrt_C(y,z); + break; + case TYLOGICAL1: + x = Ptr->flchar; + goto xlog; + case TYLOGICAL2: + x = Ptr->flshort; + goto xlog; + case TYLOGICAL: + x = Ptr->flint; + xlog: lwrt_L(Ptr->flint, len); + break; + case TYCHAR: + lwrt_A(ptr,len); + break; + } + ptr += len; + } + return(0); +} diff --git a/lib/libI77/open.c b/lib/libI77/open.c new file mode 100644 index 000000000000..514d76f83b1b --- /dev/null +++ b/lib/libI77/open.c @@ -0,0 +1,231 @@ +#ifndef NON_UNIX_STDIO +#include "sys/types.h" +#include "sys/stat.h" +#endif +#include "f2c.h" +#include "fio.h" +#include "string.h" +#include "rawio.h" + +#ifdef KR_headers +extern char *malloc(), *mktemp(); +extern integer f_clos(); +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +extern int f__canseek(FILE*); +extern integer f_clos(cllist*); +#endif + +#ifdef NON_ANSI_RW_MODES +char *f__r_mode[2] = {"r", "r"}; +char *f__w_mode[4] = {"w", "w", "r+w", "r+w"}; +#else +char *f__r_mode[2] = {"rb", "r"}; +char *f__w_mode[4] = {"wb", "w", "r+b", "r+"}; +#endif + +#ifdef KR_headers +f__isdev(s) char *s; +#else +f__isdev(char *s) +#endif +{ +#ifdef NON_UNIX_STDIO + int i, j; + + i = open(s,O_RDONLY); + if (i == -1) + return 0; + j = isatty(i); + close(i); + return j; +#else + struct stat x; + + if(stat(s, &x) == -1) return(0); +#ifdef S_IFMT + switch(x.st_mode&S_IFMT) { + case S_IFREG: + case S_IFDIR: + return(0); + } +#else +#ifdef S_ISREG + /* POSIX version */ + if(S_ISREG(x.st_mode) || S_ISDIR(x.st_mode)) + return(0); + else +#else + Help! How does stat work on this system? +#endif +#endif + return(1); +#endif +} +#ifdef KR_headers +integer f_open(a) olist *a; +#else +integer f_open(olist *a) +#endif +{ unit *b; + integer rv; + char buf[256], *s; + cllist x; +#ifdef NON_UNIX_STDIO + FILE *tf; +#else + int n; + struct stat stb; +#endif + if(a->ounit>=MXUNIT || a->ounit<0) + err(a->oerr,101,"open") + f__curunit = b = &f__units[a->ounit]; + if(b->ufd) { + if(a->ofnm==0) + { + same: if (a->oblnk) + b->ublnk = *a->oblnk == 'z' || *a->oblnk == 'Z'; + return(0); + } +#ifdef NON_UNIX_STDIO + if (b->ufnm + && strlen(b->ufnm) == a->ofnmlen + && !strncmp(b->ufnm, b->ufnm, (unsigned)a->ofnmlen)) + goto same; +#else + g_char(a->ofnm,a->ofnmlen,buf); + if (f__inode(buf,&n) == b->uinode && n == b->udev) + goto same; +#endif + x.cunit=a->ounit; + x.csta=0; + x.cerr=a->oerr; + if ((rv = f_clos(&x)) != 0) + return rv; + } + b->url = (int)a->orl; + b->ublnk = a->oblnk && (*a->oblnk == 'z' || *a->oblnk == 'Z'); + if(a->ofm==0) + { if(b->url>0) b->ufmt=0; + else b->ufmt=1; + } + else if(*a->ofm=='f' || *a->ofm == 'F') b->ufmt=1; + else b->ufmt=0; +#ifdef url_Adjust + if (b->url && !b->ufmt) + url_Adjust(b->url); +#endif + if (a->ofnm) { + g_char(a->ofnm,a->ofnmlen,buf); + if (!buf[0]) + err(a->oerr,107,"open") + } + else + sprintf(buf, "fort.%ld", a->ounit); + b->uscrtch = 0; + switch(a->osta ? *a->osta : 'u') + { + case 'o': + case 'O': +#ifdef NON_UNIX_STDIO + if(access(buf,0)) +#else + if(stat(buf,&stb)) +#endif + err(a->oerr,errno,"open") + break; + case 's': + case 'S': + b->uscrtch=1; +#ifdef _POSIX_SOURCE + tmpnam(buf); +#else + (void) strcpy(buf,"tmp.FXXXXXX"); + (void) mktemp(buf); +#endif + goto replace; + case 'n': + case 'N': +#ifdef NON_UNIX_STDIO + if(!access(buf,0)) +#else + if(!stat(buf,&stb)) +#endif + err(a->oerr,128,"open") + /* no break */ + case 'r': /* Fortran 90 replace option */ + case 'R': + replace: +#ifdef NON_UNIX_STDIO + if (tf = fopen(buf,f__w_mode[0])) + fclose(tf); +#else + (void) close(creat(buf, 0666)); +#endif + } + + b->ufnm=(char *) malloc((unsigned int)(strlen(buf)+1)); + if(b->ufnm==NULL) err(a->oerr,113,"no space"); + (void) strcpy(b->ufnm,buf); + b->uend=0; + b->uwrt = 0; + if(f__isdev(buf)) + { b->ufd = fopen(buf,f__r_mode[b->ufmt]); + if(b->ufd==NULL) err(a->oerr,errno,buf) + } + else { + if(!(b->ufd = fopen(buf, f__r_mode[b->ufmt]))) { +#ifdef NON_UNIX_STDIO + if (b->ufd = fopen(buf, f__w_mode[b->ufmt+2])) + b->uwrt = 2; + else if (b->ufd = fopen(buf, f__w_mode[b->ufmt])) + b->uwrt = 1; + else +#else + if ((n = open(buf,O_WRONLY)) >= 0) + b->uwrt = 2; + else { + n = creat(buf, 0666); + b->uwrt = 1; + } + if (n < 0 + || (b->ufd = fdopen(n, f__w_mode[b->ufmt])) == NULL) +#endif + err(a->oerr, errno, "open"); + } + } + b->useek=f__canseek(b->ufd); +#ifndef NON_UNIX_STDIO + if((b->uinode=f__inode(buf,&b->udev))==-1) + err(a->oerr,108,"open") +#endif + if(b->useek) + if (a->orl) + rewind(b->ufd); + else if ((s = a->oacc) && (*s == 'a' || *s == 'A') + && fseek(b->ufd, 0L, SEEK_END)) + err(a->oerr,129,"open"); + return(0); +} +#ifdef KR_headers +fk_open(seq,fmt,n) ftnint n; +#else +fk_open(int seq, int fmt, ftnint n) +#endif +{ char nbuf[10]; + olist a; + (void) sprintf(nbuf,"fort.%ld",n); + a.oerr=1; + a.ounit=n; + a.ofnm=nbuf; + a.ofnmlen=strlen(nbuf); + a.osta=NULL; + a.oacc= seq==SEQ?"s":"d"; + a.ofm = fmt==FMT?"f":"u"; + a.orl = seq==DIR?1:0; + a.oblnk=NULL; + return(f_open(&a)); +} diff --git a/lib/libI77/permission b/lib/libI77/permission new file mode 100644 index 000000000000..20d431ed6dc9 --- /dev/null +++ b/lib/libI77/permission @@ -0,0 +1,41 @@ +From ches Tue Mar 6 09:06:22 EST 1990 +It think it probably is. I am told the line is 89% utilized. But the throughpu +t +is shared, so I wouldn't worry about it. +>From ehg Tue Mar 6 08:16 EST 1990 +Received: by coma; Tue Mar 6 08:17:21 1990 +From: pyxis!ehg +Date: Tue, 6 Mar 90 08:16 EST +To: coma!ches + +Thanks. Is it reasonable for people to ask for the 600KB f2c source over +uunet's dedicated line? I'm just trying to find out if there's a problem +before there's a disaster. +>From ches Tue Mar 6 07:16:18 EST 1990 +Inet has no dialers. All its calls go through the internet. The mcsun addresse +s +were uunet.uu.net!mcsun!..., which will travel to uunet via Internet and +then across the ocean on uunet's dedicated line. +/**************************************************************** +Copyright 1990 by AT&T Bell Laboratories and Bellcore. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +Bellcore or any of their entities not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. +****************************************************************/ + diff --git a/lib/libI77/rawio.h b/lib/libI77/rawio.h new file mode 100644 index 000000000000..59181d759f8d --- /dev/null +++ b/lib/libI77/rawio.h @@ -0,0 +1,41 @@ +#ifdef KR_headers +extern FILE *fdopen(); +#else +#ifdef MSDOS +#include "io.h" +#define close _close +#define creat _creat +#define open _open +#define read _read +#define write _write +#endif +#ifdef __cplusplus +extern "C" { +#endif +#ifndef MSDOS +#ifdef OPEN_DECL +extern int creat(const char*,int), open(const char*,int); +#endif +extern int close(int); +extern int read(int,void*,size_t), write(int,void*,size_t); +extern int unlink(const char*); +#ifndef _POSIX_SOURCE +#ifndef NON_UNIX_STDIO +extern FILE *fdopen(int, const char*); +#endif +#endif +#endif + +extern char *mktemp(char*); + +#ifdef __cplusplus + } +#endif +#endif + +#include "fcntl.h" + +#ifndef O_WRONLY +#define O_RDONLY 0 +#define O_WRONLY 1 +#endif diff --git a/lib/libI77/rdfmt.c b/lib/libI77/rdfmt.c new file mode 100644 index 000000000000..9fd854515b65 --- /dev/null +++ b/lib/libI77/rdfmt.c @@ -0,0 +1,476 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "fp.h" + +extern int f__cursor; +#ifdef KR_headers +extern double atof(); +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +#endif + + static int +#ifdef KR_headers +rd_Z(n,w,len) Uint *n; ftnlen len; +#else +rd_Z(Uint *n, int w, ftnlen len) +#endif +{ + long x[9]; + char *s, *s0, *s1, *se, *t; + int ch, i, w1, w2; + static char hex[256]; + static int one = 1; + int bad = 0; + + if (!hex['0']) { + s = "0123456789"; + while(ch = *s++) + hex[ch] = ch - '0' + 1; + s = "ABCDEF"; + while(ch = *s++) + hex[ch] = hex[ch + 'a' - 'A'] = ch - 'A' + 11; + } + s = s0 = (char *)x; + s1 = (char *)&x[4]; + se = (char *)&x[8]; + if (len > 4*sizeof(long)) + return errno = 117; + while (w) { + GET(ch); + if (ch==',' || ch=='\n') + break; + w--; + if (ch > ' ') { + if (!hex[ch & 0xff]) + bad++; + *s++ = ch; + if (s == se) { + /* discard excess characters */ + for(t = s0, s = s1; t < s1;) + *t++ = *s++; + s = s1; + } + } + } + if (bad) + return errno = 115; + w = (int)len; + w1 = s - s0; + w2 = w1+1 >> 1; + t = (char *)n; + if (*(char *)&one) { + /* little endian */ + t += w - 1; + i = -1; + } + else + i = 1; + for(; w > w2; t += i, --w) + *t = 0; + if (!w) + return 0; + if (w < w2) + s0 = s - (w << 1); + else if (w1 & 1) { + *t = hex[*s0++ & 0xff] - 1; + if (!--w) + return 0; + t += i; + } + do { + *t = hex[*s0 & 0xff]-1 << 4 | hex[s0[1] & 0xff]-1; + t += i; + s0 += 2; + } + while(--w); + return 0; + } + + static int +#ifdef KR_headers +rd_I(n,w,len, base) Uint *n; int w; ftnlen len; register int base; +#else +rd_I(Uint *n, int w, ftnlen len, register int base) +#endif +{ long x; + int sign,ch; + char s[84], *ps; + ps=s; x=0; + while (w) + { + GET(ch); + if (ch==',' || ch=='\n') break; + *ps=ch; ps++; w--; + } + *ps='\0'; + ps=s; + while (*ps==' ') ps++; + if (*ps=='-') { sign=1; ps++; } + else { sign=0; if (*ps=='+') ps++; } +loop: while (*ps>='0' && *ps<='9') { x=x*base+(*ps-'0'); ps++; } + if (*ps==' ') {if (f__cblank) x *= base; ps++; goto loop;} + if(sign) x = -x; + if(len==sizeof(integer)) n->il=x; + else if(len == sizeof(char)) n->ic = (char)x; +#ifdef Allow_TYQUAD + else if (len == sizeof(longint)) n->ili = x; +#endif + else n->is = (short)x; + if (*ps) return(errno=115); else return(0); +} + static int +#ifdef KR_headers +rd_L(n,w,len) ftnint *n; ftnlen len; +#else +rd_L(ftnint *n, int w, ftnlen len) +#endif +{ int ch, lv; + char s[84], *ps; + ps=s; + while (w) { + GET(ch); + if (ch==','||ch=='\n') break; + *ps=ch; + ps++; w--; + } + *ps='\0'; + ps=s; while (*ps==' ') ps++; + if (*ps=='.') ps++; + if (*ps=='t' || *ps == 'T') + lv = 1; + else if (*ps == 'f' || *ps == 'F') + lv = 0; + else return(errno=116); + switch(len) { + case sizeof(char): *(char *)n = (char)lv; break; + case sizeof(short): *(short *)n = (short)lv; break; + default: *n = lv; + } + return 0; +} + +#include "ctype.h" + + static int +#ifdef KR_headers +rd_F(p, w, d, len) ufloat *p; ftnlen len; +#else +rd_F(ufloat *p, int w, int d, ftnlen len) +#endif +{ + char s[FMAX+EXPMAXDIGS+4]; + register int ch; + register char *sp, *spe, *sp1; + double x; + int scale1, se; + long e, exp; + + sp1 = sp = s; + spe = sp + FMAX; + exp = -d; + x = 0.; + + do { + GET(ch); + w--; + } while (ch == ' ' && w); + switch(ch) { + case '-': *sp++ = ch; sp1++; spe++; + case '+': + if (!w) goto zero; + --w; + GET(ch); + } + while(ch == ' ') { +blankdrop: + if (!w--) goto zero; GET(ch); } + while(ch == '0') + { if (!w--) goto zero; GET(ch); } + if (ch == ' ' && f__cblank) + goto blankdrop; + scale1 = f__scale; + while(isdigit(ch)) { +digloop1: + if (sp < spe) *sp++ = ch; + else ++exp; +digloop1e: + if (!w--) goto done; + GET(ch); + } + if (ch == ' ') { + if (f__cblank) + { ch = '0'; goto digloop1; } + goto digloop1e; + } + if (ch == '.') { + exp += d; + if (!w--) goto done; + GET(ch); + if (sp == sp1) { /* no digits yet */ + while(ch == '0') { +skip01: + --exp; +skip0: + if (!w--) goto done; + GET(ch); + } + if (ch == ' ') { + if (f__cblank) goto skip01; + goto skip0; + } + } + while(isdigit(ch)) { +digloop2: + if (sp < spe) + { *sp++ = ch; --exp; } +digloop2e: + if (!w--) goto done; + GET(ch); + } + if (ch == ' ') { + if (f__cblank) + { ch = '0'; goto digloop2; } + goto digloop2e; + } + } + switch(ch) { + default: + break; + case '-': se = 1; goto signonly; + case '+': se = 0; goto signonly; + case 'e': + case 'E': + case 'd': + case 'D': + if (!w--) + goto bad; + GET(ch); + while(ch == ' ') { + if (!w--) + goto bad; + GET(ch); + } + se = 0; + switch(ch) { + case '-': se = 1; + case '+': +signonly: + if (!w--) + goto bad; + GET(ch); + } + while(ch == ' ') { + if (!w--) + goto bad; + GET(ch); + } + if (!isdigit(ch)) + goto bad; + + e = ch - '0'; + for(;;) { + if (!w--) + { ch = '\n'; break; } + GET(ch); + if (!isdigit(ch)) { + if (ch == ' ') { + if (f__cblank) + ch = '0'; + else continue; + } + else + break; + } + e = 10*e + ch - '0'; + if (e > EXPMAX && sp > sp1) + goto bad; + } + if (se) + exp -= e; + else + exp += e; + scale1 = 0; + } + switch(ch) { + case '\n': + case ',': + break; + default: +bad: + return (errno = 115); + } +done: + if (sp > sp1) { + while(*--sp == '0') + ++exp; + if (exp -= scale1) + sprintf(sp+1, "e%ld", exp); + else + sp[1] = 0; + x = atof(s); + } +zero: + if (len == sizeof(real)) + p->pf = x; + else + p->pd = x; + return(0); + } + + + static int +#ifdef KR_headers +rd_A(p,len) char *p; ftnlen len; +#else +rd_A(char *p, ftnlen len) +#endif +{ int i,ch; + for(i=0;i<len;i++) + { GET(ch); + *p++=VAL(ch); + } + return(0); +} + static int +#ifdef KR_headers +rd_AW(p,w,len) char *p; ftnlen len; +#else +rd_AW(char *p, int w, ftnlen len) +#endif +{ int i,ch; + if(w>=len) + { for(i=0;i<w-len;i++) + GET(ch); + for(i=0;i<len;i++) + { GET(ch); + *p++=VAL(ch); + } + return(0); + } + for(i=0;i<w;i++) + { GET(ch); + *p++=VAL(ch); + } + for(i=0;i<len-w;i++) *p++=' '; + return(0); +} + static int +#ifdef KR_headers +rd_H(n,s) char *s; +#else +rd_H(int n, char *s) +#endif +{ int i,ch; + for(i=0;i<n;i++) + if((ch=(*f__getn)())<0) return(ch); + else *s++ = ch=='\n'?' ':ch; + return(1); +} + static int +#ifdef KR_headers +rd_POS(s) char *s; +#else +rd_POS(char *s) +#endif +{ char quote; + int ch; + quote= *s++; + for(;*s;s++) + if(*s==quote && *(s+1)!=quote) break; + else if((ch=(*f__getn)())<0) return(ch); + else *s = ch=='\n'?' ':ch; + return(1); +} +#ifdef KR_headers +rd_ed(p,ptr,len) struct syl *p; char *ptr; ftnlen len; +#else +rd_ed(struct syl *p, char *ptr, ftnlen len) +#endif +{ int ch; + for(;f__cursor>0;f__cursor--) if((ch=(*f__getn)())<0) return(ch); + if(f__cursor<0) + { if(f__recpos+f__cursor < 0) /*err(elist->cierr,110,"fmt")*/ + f__cursor = -f__recpos; /* is this in the standard? */ + if(f__external == 0) { + extern char *f__icptr; + f__icptr += f__cursor; + } + else if(f__curunit && f__curunit->useek) + (void) fseek(f__cf,(long) f__cursor,SEEK_CUR); + else + err(f__elist->cierr,106,"fmt"); + f__recpos += f__cursor; + f__cursor=0; + } + switch(p->op) + { + default: fprintf(stderr,"rd_ed, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case IM: + case I: ch = rd_I((Uint *)ptr,p->p1,len, 10); + break; + + /* O and OM don't work right for character, double, complex, */ + /* or doublecomplex, and they differ from Fortran 90 in */ + /* showing a minus sign for negative values. */ + + case OM: + case O: ch = rd_I((Uint *)ptr, p->p1, len, 8); + break; + case L: ch = rd_L((ftnint *)ptr,p->p1,len); + break; + case A: ch = rd_A(ptr,len); + break; + case AW: + ch = rd_AW(ptr,p->p1,len); + break; + case E: case EE: + case D: + case G: + case GE: + case F: ch = rd_F((ufloat *)ptr,p->p1,p->p2,len); + break; + + /* Z and ZM assume 8-bit bytes. */ + + case ZM: + case Z: + ch = rd_Z((Uint *)ptr, p->p1, len); + break; + } + if(ch == 0) return(ch); + else if(ch == EOF) return(EOF); + if (f__cf) + clearerr(f__cf); + return(errno); +} +#ifdef KR_headers +rd_ned(p) struct syl *p; +#else +rd_ned(struct syl *p) +#endif +{ + switch(p->op) + { + default: fprintf(stderr,"rd_ned, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case APOS: + return(rd_POS(*(char **)&p->p2)); + case H: return(rd_H(p->p1,*(char **)&p->p2)); + case SLASH: return((*f__donewrec)()); + case TR: + case X: f__cursor += p->p1; + return(1); + case T: f__cursor=p->p1-f__recpos - 1; + return(1); + case TL: f__cursor -= p->p1; + if(f__cursor < -f__recpos) /* TL1000, 1X */ + f__cursor = -f__recpos; + return(1); + } +} diff --git a/lib/libI77/rewind.c b/lib/libI77/rewind.c new file mode 100644 index 000000000000..e58daad7b8a2 --- /dev/null +++ b/lib/libI77/rewind.c @@ -0,0 +1,24 @@ +#include "f2c.h" +#include "fio.h" +#ifdef KR_headers +integer f_rew(a) alist *a; +#else +integer f_rew(alist *a) +#endif +{ + unit *b; + if(a->aunit>=MXUNIT || a->aunit<0) + err(a->aerr,101,"rewind"); + b = &f__units[a->aunit]; + if(b->ufd == NULL || b->uwrt == 3) + return(0); + if(!b->useek) + err(a->aerr,106,"rewind") + if(b->uwrt) { + (void) t_runc(a); + b->uwrt = 3; + } + rewind(b->ufd); + b->uend=0; + return(0); +} diff --git a/lib/libI77/rsfe.c b/lib/libI77/rsfe.c new file mode 100644 index 000000000000..5d29bee6847e --- /dev/null +++ b/lib/libI77/rsfe.c @@ -0,0 +1,73 @@ +/* read sequential formatted external */ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" + +xrd_SL(Void) +{ int ch; + if(!f__curunit->uend) + while((ch=getc(f__cf))!='\n' && ch!=EOF); + f__cursor=f__recpos=0; + return(1); +} +x_getc(Void) +{ int ch; + if(f__curunit->uend) return(EOF); + ch = getc(f__cf); + if(ch!=EOF && ch!='\n') + { f__recpos++; + return(ch); + } + if(ch=='\n') + { (void) ungetc(ch,f__cf); + return(ch); + } + if(f__curunit->uend || feof(f__cf)) + { errno=0; + f__curunit->uend=1; + return(-1); + } + return(-1); +} +x_endp(Void) +{ + (void) xrd_SL(); + return(0); +} +x_rev(Void) +{ + (void) xrd_SL(); + return(0); +} +#ifdef KR_headers +integer s_rsfe(a) cilist *a; /* start */ +#else +integer s_rsfe(cilist *a) /* start */ +#endif +{ int n; + if(!f__init) f_init(); + if(n=c_sfe(a)) return(n); + f__reading=1; + f__sequential=1; + f__formatted=1; + f__external=1; + f__elist=a; + f__cursor=f__recpos=0; + f__scale=0; + f__fmtbuf=a->cifmt; + f__curunit= &f__units[a->ciunit]; + f__cf=f__curunit->ufd; + if(pars_f(f__fmtbuf)<0) err(a->cierr,100,"startio"); + f__getn= x_getc; + f__doed= rd_ed; + f__doned= rd_ned; + fmt_bg(); + f__doend=x_endp; + f__donewrec=xrd_SL; + f__dorevert=x_rev; + f__cblank=f__curunit->ublnk; + f__cplus=0; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr,errno,"read start"); + return(0); +} diff --git a/lib/libI77/rsli.c b/lib/libI77/rsli.c new file mode 100644 index 000000000000..b016d1e0ea44 --- /dev/null +++ b/lib/libI77/rsli.c @@ -0,0 +1,98 @@ +#include "f2c.h" +#include "fio.h" +#include "lio.h" +#include "fmt.h" /* for f__doend */ + +extern flag f__lquit; +extern int f__lcount; +extern char *f__icptr; +extern char *f__icend; +extern icilist *f__svic; +extern int f__icnum, f__recpos; + +static int i_getc(Void) +{ + if(f__recpos >= f__svic->icirlen) { + if (f__recpos++ == f__svic->icirlen) + return '\n'; + z_rnew(); + } + f__recpos++; + if(f__icptr >= f__icend) err(f__svic->iciend,(EOF),"internal read"); + return(*f__icptr++); + } + + static +#ifdef KR_headers +int i_ungetc(ch, f) int ch; FILE *f; +#else +int i_ungetc(int ch, FILE *f) +#endif +{ + if (--f__recpos == f__svic->icirlen) + return '\n'; + if (f__recpos < -1) + err(f__svic->icierr,110,"recend"); + /* *--icptr == ch, and icptr may point to read-only memory */ + return *--f__icptr /* = ch */; + } + + static void +#ifdef KR_headers +c_lir(a) icilist *a; +#else +c_lir(icilist *a) +#endif +{ + extern int l_eof; + f__reading = 1; + f__external = 0; + f__formatted = 1; + f__svic = a; + L_len = a->icirlen; + f__recpos = -1; + f__icnum = f__recpos = 0; + f__cursor = 0; + l_getc = i_getc; + l_ungetc = i_ungetc; + l_eof = 0; + f__icptr = a->iciunit; + f__icend = f__icptr + a->icirlen*a->icirnum; + f__cf = 0; + f__curunit = 0; + f__elist = (cilist *)a; + } + + +#ifdef KR_headers +integer s_rsli(a) icilist *a; +#else +integer s_rsli(icilist *a) +#endif +{ + f__lioproc = l_read; + f__lquit = 0; + f__lcount = 0; + c_lir(a); + f__doend = 0; + return(0); + } + +integer e_rsli(Void) +{ return 0; } + +#ifdef KR_headers +integer s_rsni(a) icilist *a; +#else +extern int x_rsne(cilist*); + +integer s_rsni(icilist *a) +#endif +{ + cilist ca; + ca.ciend = a->iciend; + ca.cierr = a->icierr; + ca.cifmt = a->icifmt; + c_lir(a); + return x_rsne(&ca); + } diff --git a/lib/libI77/rsne.c b/lib/libI77/rsne.c new file mode 100644 index 000000000000..4064fd2badad --- /dev/null +++ b/lib/libI77/rsne.c @@ -0,0 +1,565 @@ +#include "f2c.h" +#include "fio.h" +#include "lio.h" + +#define MAX_NL_CACHE 3 /* maximum number of namelist hash tables to cache */ +#define MAXDIM 20 /* maximum number of subscripts */ + + struct dimen { + ftnlen extent; + ftnlen curval; + ftnlen delta; + ftnlen stride; + }; + typedef struct dimen dimen; + + struct hashentry { + struct hashentry *next; + char *name; + Vardesc *vd; + }; + typedef struct hashentry hashentry; + + struct hashtab { + struct hashtab *next; + Namelist *nl; + int htsize; + hashentry *tab[1]; + }; + typedef struct hashtab hashtab; + + static hashtab *nl_cache; + static n_nlcache; + static hashentry **zot; + extern ftnlen f__typesize[]; + + extern flag f__lquit; + extern int f__lcount, nml_read; + extern t_getc(Void); + +#ifdef KR_headers + extern char *malloc(), *memset(); + +#ifdef ungetc + static int +un_getc(x,f__cf) int x; FILE *f__cf; +{ return ungetc(x,f__cf); } +#else +#define un_getc ungetc + extern int ungetc(); +#endif + +#else +#undef abs +#undef min +#undef max +#include "stdlib.h" +#include "string.h" + +#ifdef ungetc + static int +un_getc(int x, FILE *f__cf) +{ return ungetc(x,f__cf); } +#else +#define un_getc ungetc +#endif +#endif + + static Vardesc * +#ifdef KR_headers +hash(ht, s) hashtab *ht; register char *s; +#else +hash(hashtab *ht, register char *s) +#endif +{ + register int c, x; + register hashentry *h; + char *s0 = s; + + for(x = 0; c = *s++; x = x & 0x4000 ? ((x << 1) & 0x7fff) + 1 : x << 1) + x += c; + for(h = *(zot = ht->tab + x % ht->htsize); h; h = h->next) + if (!strcmp(s0, h->name)) + return h->vd; + return 0; + } + + hashtab * +#ifdef KR_headers +mk_hashtab(nl) Namelist *nl; +#else +mk_hashtab(Namelist *nl) +#endif +{ + int nht, nv; + hashtab *ht; + Vardesc *v, **vd, **vde; + hashentry *he; + + hashtab **x, **x0, *y; + for(x = &nl_cache; y = *x; x0 = x, x = &y->next) + if (nl == y->nl) + return y; + if (n_nlcache >= MAX_NL_CACHE) { + /* discard least recently used namelist hash table */ + y = *x0; + free((char *)y->next); + y->next = 0; + } + else + n_nlcache++; + nv = nl->nvars; + if (nv >= 0x4000) + nht = 0x7fff; + else { + for(nht = 1; nht < nv; nht <<= 1); + nht += nht - 1; + } + ht = (hashtab *)malloc(sizeof(hashtab) + (nht-1)*sizeof(hashentry *) + + nv*sizeof(hashentry)); + if (!ht) + return 0; + he = (hashentry *)&ht->tab[nht]; + ht->nl = nl; + ht->htsize = nht; + ht->next = nl_cache; + nl_cache = ht; + memset((char *)ht->tab, 0, nht*sizeof(hashentry *)); + vd = nl->vars; + vde = vd + nv; + while(vd < vde) { + v = *vd++; + if (!hash(ht, v->name)) { + he->next = *zot; + *zot = he; + he->name = v->name; + he->vd = v; + he++; + } + } + return ht; + } + +static char Alpha[256], Alphanum[256]; + + static VOID +nl_init(Void) { + register char *s; + register int c; + + if(!f__init) + f_init(); + for(s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; c = *s++; ) + Alpha[c] + = Alphanum[c] + = Alpha[c + 'a' - 'A'] + = Alphanum[c + 'a' - 'A'] + = c; + for(s = "0123456789_"; c = *s++; ) + Alphanum[c] = c; + } + +#define GETC(x) (x=(*l_getc)()) +#define Ungetc(x,y) (*l_ungetc)(x,y) + + static int +#ifdef KR_headers +getname(s, slen) register char *s; int slen; +#else +getname(register char *s, int slen) +#endif +{ + register char *se = s + slen - 1; + register int ch; + + GETC(ch); + if (!(*s++ = Alpha[ch & 0xff])) { + if (ch != EOF) + ch = 115; + errfl(f__elist->cierr, ch, "namelist read"); + } + while(*s = Alphanum[GETC(ch) & 0xff]) + if (s < se) + s++; + if (ch == EOF) + err(f__elist->cierr, EOF, "namelist read"); + if (ch > ' ') + Ungetc(ch,f__cf); + return *s = 0; + } + + static int +#ifdef KR_headers +getnum(chp, val) int *chp; ftnlen *val; +#else +getnum(int *chp, ftnlen *val) +#endif +{ + register int ch, sign; + register ftnlen x; + + while(GETC(ch) <= ' ' && ch >= 0); + if (ch == '-') { + sign = 1; + GETC(ch); + } + else { + sign = 0; + if (ch == '+') + GETC(ch); + } + x = ch - '0'; + if (x < 0 || x > 9) + return 115; + while(GETC(ch) >= '0' && ch <= '9') + x = 10*x + ch - '0'; + while(ch <= ' ' && ch >= 0) + GETC(ch); + if (ch == EOF) + return EOF; + *val = sign ? -x : x; + *chp = ch; + return 0; + } + + static int +#ifdef KR_headers +getdimen(chp, d, delta, extent, x1) + int *chp; dimen *d; ftnlen delta, extent, *x1; +#else +getdimen(int *chp, dimen *d, ftnlen delta, ftnlen extent, ftnlen *x1) +#endif +{ + register int k; + ftnlen x2, x3; + + if (k = getnum(chp, x1)) + return k; + x3 = 1; + if (*chp == ':') { + if (k = getnum(chp, &x2)) + return k; + x2 -= *x1; + if (*chp == ':') { + if (k = getnum(chp, &x3)) + return k; + if (!x3) + return 123; + x2 /= x3; + } + if (x2 < 0 || x2 >= extent) + return 123; + d->extent = x2 + 1; + } + else + d->extent = 1; + d->curval = 0; + d->delta = delta; + d->stride = x3; + return 0; + } + +#ifndef No_Namelist_Questions + static Void +#ifdef KR_headers +print_ne(a) cilist *a; +#else +print_ne(cilist *a) +#endif +{ + flag intext = f__external; + int rpsave = f__recpos; + FILE *cfsave = f__cf; + unit *usave = f__curunit; + cilist t; + t = *a; + t.ciunit = 6; + s_wsne(&t); + fflush(f__cf); + f__external = intext; + f__reading = 1; + f__recpos = rpsave; + f__cf = cfsave; + f__curunit = usave; + f__elist = a; + } +#endif + + static char where0[] = "namelist read start "; + +#ifdef KR_headers +x_rsne(a) cilist *a; +#else +x_rsne(cilist *a) +#endif +{ + int ch, got1, k, n, nd, quote; + Namelist *nl; + static char where[] = "namelist read"; + char buf[64]; + hashtab *ht; + Vardesc *v; + dimen *dn, *dn0, *dn1; + ftnlen *dims, *dims1; + ftnlen b, b0, b1, ex, no, no1, nomax, size, span; + ftnint type; + char *vaddr; + long iva, ivae; + dimen dimens[MAXDIM], substr; + + if (!Alpha['a']) + nl_init(); + f__reading=1; + f__formatted=1; + got1 = 0; + top: + for(;;) switch(GETC(ch)) { + case EOF: + err(a->ciend,(EOF),where0); + case '&': + case '$': + goto have_amp; +#ifndef No_Namelist_Questions + case '?': + print_ne(a); + continue; +#endif + default: + if (ch <= ' ' && ch >= 0) + continue; + errfl(a->cierr, 115, where0); + } + have_amp: + if (ch = getname(buf,sizeof(buf))) + return ch; + nl = (Namelist *)a->cifmt; + if (strcmp(buf, nl->name)) +#ifdef No_Bad_Namelist_Skip + errfl(a->cierr, 118, where0); +#else + { + fprintf(stderr, + "Skipping namelist \"%s\": seeking namelist \"%s\".\n", + buf, nl->name); + fflush(stderr); + for(;;) switch(GETC(ch)) { + case EOF: + err(a->ciend, EOF, where0); + case '/': + case '&': + case '$': + if (f__external) + e_rsle(); + else + z_rnew(); + goto top; + case '"': + case '\'': + quote = ch; + more_quoted: + while(GETC(ch) != quote) + if (ch == EOF) + err(a->ciend, EOF, where0); + if (GETC(ch) == quote) + goto more_quoted; + Ungetc(ch,f__cf); + default: + continue; + } + } +#endif + ht = mk_hashtab(nl); + if (!ht) + errfl(f__elist->cierr, 113, where0); + for(;;) { + for(;;) switch(GETC(ch)) { + case EOF: + if (got1) + return 0; + err(a->ciend, EOF, where0); + case '/': + case '$': + case '&': + return 0; + default: + if (ch <= ' ' && ch >= 0 || ch == ',') + continue; + Ungetc(ch,f__cf); + if (ch = getname(buf,sizeof(buf))) + return ch; + goto havename; + } + havename: + v = hash(ht,buf); + if (!v) + errfl(a->cierr, 119, where); + while(GETC(ch) <= ' ' && ch >= 0); + vaddr = v->addr; + type = v->type; + if (type < 0) { + size = -type; + type = TYCHAR; + } + else + size = f__typesize[type]; + ivae = size; + iva = 0; + if (ch == '(' /*)*/ ) { + dn = dimens; + if (!(dims = v->dims)) { + if (type != TYCHAR) + errfl(a->cierr, 122, where); + if (k = getdimen(&ch, dn, (ftnlen)size, + (ftnlen)size, &b)) + errfl(a->cierr, k, where); + if (ch != ')') + errfl(a->cierr, 115, where); + b1 = dn->extent; + if (--b < 0 || b + b1 > size) + return 124; + iva += b; + size = b1; + while(GETC(ch) <= ' ' && ch >= 0); + goto scalar; + } + nd = (int)dims[0]; + nomax = span = dims[1]; + ivae = iva + size*nomax; + if (k = getdimen(&ch, dn, size, nomax, &b)) + errfl(a->cierr, k, where); + no = dn->extent; + b0 = dims[2]; + dims1 = dims += 3; + ex = 1; + for(n = 1; n++ < nd; dims++) { + if (ch != ',') + errfl(a->cierr, 115, where); + dn1 = dn + 1; + span /= *dims; + if (k = getdimen(&ch, dn1, dn->delta**dims, + span, &b1)) + errfl(a->cierr, k, where); + ex *= *dims; + b += b1*ex; + no *= dn1->extent; + dn = dn1; + } + if (ch != ')') + errfl(a->cierr, 115, where); + b -= b0; + if (b < 0 || b >= nomax) + errfl(a->cierr, 125, where); + iva += size * b; + dims = dims1; + while(GETC(ch) <= ' ' && ch >= 0); + no1 = 1; + dn0 = dimens; + if (type == TYCHAR && ch == '(' /*)*/) { + if (k = getdimen(&ch, &substr, size, size, &b)) + errfl(a->cierr, k, where); + if (ch != ')') + errfl(a->cierr, 115, where); + b1 = substr.extent; + if (--b < 0 || b + b1 > size) + return 124; + iva += b; + b0 = size; + size = b1; + while(GETC(ch) <= ' ' && ch >= 0); + if (b1 < b0) + goto delta_adj; + } + for(; dn0 < dn; dn0++) { + if (dn0->extent != *dims++ || dn0->stride != 1) + break; + no1 *= dn0->extent; + } + if (dn0 == dimens && dimens[0].stride == 1) { + no1 = dimens[0].extent; + dn0++; + } + delta_adj: + ex = 0; + for(dn1 = dn0; dn1 <= dn; dn1++) + ex += (dn1->extent-1) + * (dn1->delta *= dn1->stride); + for(dn1 = dn; dn1 > dn0; dn1--) { + ex -= (dn1->extent - 1) * dn1->delta; + dn1->delta -= ex; + } + } + else if (dims = v->dims) { + no = no1 = dims[1]; + ivae = iva + no*size; + } + else + scalar: + no = no1 = 1; + if (ch != '=') + errfl(a->cierr, 115, where); + got1 = nml_read = 1; + f__lcount = 0; + readloop: + for(;;) { + if (iva >= ivae || iva < 0) { + f__lquit = 1; + goto mustend; + } + else if (iva + no1*size > ivae) + no1 = (ivae - iva)/size; + f__lquit = 0; + if (k = l_read(&no1, vaddr + iva, size, type)) + return k; + if (f__lquit == 1) + return 0; + mustend: + if (GETC(ch) == '/' || ch == '$' || ch == '&') { + f__lquit = 1; + return 0; + } + else if (f__lquit) { + while(ch <= ' ' && ch >= 0) + GETC(ch); + Ungetc(ch,f__cf); + if (!Alpha[ch & 0xff] && ch >= 0) + errfl(a->cierr, 125, where); + break; + } + Ungetc(ch,f__cf); + if ((no -= no1) <= 0) + break; + for(dn1 = dn0; dn1 <= dn; dn1++) { + if (++dn1->curval < dn1->extent) { + iva += dn1->delta; + goto readloop; + } + dn1->curval = 0; + } + break; + } + } + } + + integer +#ifdef KR_headers +s_rsne(a) cilist *a; +#else +s_rsne(cilist *a) +#endif +{ + extern int l_eof; + int n; + + f__external=1; + l_eof = 0; + if(n = c_le(a)) + return n; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr,errno,where0); + l_getc = t_getc; + l_ungetc = un_getc; + f__doend = xrd_SL; + if (n = x_rsne(a)) + return n; + return e_rsle(); + } diff --git a/lib/libI77/sfe.c b/lib/libI77/sfe.c new file mode 100644 index 000000000000..6dea23af40fe --- /dev/null +++ b/lib/libI77/sfe.c @@ -0,0 +1,32 @@ +/* sequential formatted external common routines*/ +#include "f2c.h" +#include "fio.h" + +extern char *f__fmtbuf; + +integer e_rsfe(Void) +{ int n; + n=en_fio(); + if (f__cf == stdout) + fflush(stdout); + else if (f__cf == stderr) + fflush(stderr); + f__fmtbuf=NULL; + return(n); +} +#ifdef KR_headers +c_sfe(a) cilist *a; /* check */ +#else +c_sfe(cilist *a) /* check */ +#endif +{ unit *p; + if(a->ciunit >= MXUNIT || a->ciunit<0) + err(a->cierr,101,"startio"); + p = &f__units[a->ciunit]; + if(p->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) err(a->cierr,114,"sfe") + if(!p->ufmt) err(a->cierr,102,"sfe") + return(0); +} +integer e_wsfe(Void) +{ return(e_rsfe()); +} diff --git a/lib/libI77/sue.c b/lib/libI77/sue.c new file mode 100644 index 000000000000..21f30bf76f12 --- /dev/null +++ b/lib/libI77/sue.c @@ -0,0 +1,79 @@ +#include "f2c.h" +#include "fio.h" +extern uiolen f__reclen; +long f__recloc; + +#ifdef KR_headers +c_sue(a) cilist *a; +#else +c_sue(cilist *a) +#endif +{ + if(a->ciunit >= MXUNIT || a->ciunit < 0) + err(a->cierr,101,"startio"); + f__external=f__sequential=1; + f__formatted=0; + f__curunit = &f__units[a->ciunit]; + f__elist=a; + if(f__curunit->ufd==NULL && fk_open(SEQ,UNF,a->ciunit)) + err(a->cierr,114,"sue"); + f__cf=f__curunit->ufd; + if(f__curunit->ufmt) err(a->cierr,103,"sue") + if(!f__curunit->useek) err(a->cierr,103,"sue") + return(0); +} +#ifdef KR_headers +integer s_rsue(a) cilist *a; +#else +integer s_rsue(cilist *a) +#endif +{ + int n; + if(!f__init) f_init(); + f__reading=1; + if(n=c_sue(a)) return(n); + f__recpos=0; + if(f__curunit->uwrt && f__nowreading(f__curunit)) + err(a->cierr, errno, "read start"); + if(fread((char *)&f__reclen,sizeof(uiolen),1,f__cf) + != 1) + { if(feof(f__cf)) + { f__curunit->uend = 1; + err(a->ciend, EOF, "start"); + } + clearerr(f__cf); + err(a->cierr, errno, "start"); + } + return(0); +} +#ifdef KR_headers +integer s_wsue(a) cilist *a; +#else +integer s_wsue(cilist *a) +#endif +{ + int n; + if(!f__init) f_init(); + if(n=c_sue(a)) return(n); + f__reading=0; + f__reclen=0; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr, errno, "write start"); + f__recloc=ftell(f__cf); + (void) fseek(f__cf,(long)sizeof(uiolen),SEEK_CUR); + return(0); +} +integer e_wsue(Void) +{ long loc; + (void) fwrite((char *)&f__reclen,sizeof(uiolen),1,f__cf); + loc=ftell(f__cf); + (void) fseek(f__cf,f__recloc,SEEK_SET); + (void) fwrite((char *)&f__reclen,sizeof(uiolen),1,f__cf); + (void) fseek(f__cf,loc,SEEK_SET); + return(0); +} +integer e_rsue(Void) +{ + (void) fseek(f__cf,(long)(f__reclen-f__recpos+sizeof(uiolen)),SEEK_CUR); + return(0); +} diff --git a/lib/libI77/typesize.c b/lib/libI77/typesize.c new file mode 100644 index 000000000000..1a1f4f796254 --- /dev/null +++ b/lib/libI77/typesize.c @@ -0,0 +1,6 @@ +#include "f2c.h" + +ftnlen f__typesize[] = { 0, 0, sizeof(shortint), sizeof(integer), + sizeof(real), sizeof(doublereal), + sizeof(complex), sizeof(doublecomplex), + sizeof(logical), sizeof(char) }; diff --git a/lib/libI77/uio.c b/lib/libI77/uio.c new file mode 100644 index 000000000000..4277dc95c70f --- /dev/null +++ b/lib/libI77/uio.c @@ -0,0 +1,54 @@ +#include "f2c.h" +#include "fio.h" +uiolen f__reclen; + +#ifdef KR_headers +do_us(number,ptr,len) ftnint *number; char *ptr; ftnlen len; +#else +do_us(ftnint *number, char *ptr, ftnlen len) +#endif +{ + if(f__reading) + { + f__recpos += (int)(*number * len); + if(f__recpos>f__reclen) + err(f__elist->cierr, 110, "do_us"); + if (fread(ptr,(int)len,(int)(*number),f__cf) != *number) + err(f__elist->ciend, EOF, "do_us"); + return(0); + } + else + { + f__reclen += *number * len; + (void) fwrite(ptr,(int)len,(int)(*number),f__cf); + return(0); + } +} +#ifdef KR_headers +integer do_ud(number,ptr,len) ftnint *number; char *ptr; ftnlen len; +#else +integer do_ud(ftnint *number, char *ptr, ftnlen len) +#endif +{ + f__recpos += (int)(*number * len); + if(f__recpos > f__curunit->url && f__curunit->url!=1) + err(f__elist->cierr,110,"do_ud"); + if(f__reading) + { + if(fread(ptr,(int)len,(int)(*number),f__cf) != *number) + err(f__elist->cierr,EOF,"do_ud") + else return(0); + } + (void) fwrite(ptr,(int)len,(int)(*number),f__cf); + return(0); +} +#ifdef KR_headers +integer do_uio(number,ptr,len) ftnint *number; char *ptr; ftnlen len; +#else +integer do_uio(ftnint *number, char *ptr, ftnlen len) +#endif +{ + if(f__sequential) + return(do_us(number,ptr,len)); + else return(do_ud(number,ptr,len)); +} diff --git a/lib/libI77/util.c b/lib/libI77/util.c new file mode 100644 index 000000000000..af068b0a23c5 --- /dev/null +++ b/lib/libI77/util.c @@ -0,0 +1,72 @@ +#ifndef NON_UNIX_STDIO +#include "sys/types.h" +#include "sys/stat.h" +#endif +#include "f2c.h" +#include "fio.h" + + VOID +#ifdef KR_headers +g_char(a,alen,b) char *a,*b; ftnlen alen; +#else +g_char(char *a, ftnlen alen, char *b) +#endif +{ + char *x = a + alen, *y = b + alen; + + for(;; y--) { + if (x <= a) { + *b = 0; + return; + } + if (*--x != ' ') + break; + } + *y-- = 0; + do *y-- = *x; + while(x-- > a); + } + + VOID +#ifdef KR_headers +b_char(a,b,blen) char *a,*b; ftnlen blen; +#else +b_char(char *a, char *b, ftnlen blen) +#endif +{ int i; + for(i=0;i<blen && *a!=0;i++) *b++= *a++; + for(;i<blen;i++) *b++=' '; +} +#ifndef NON_UNIX_STDIO +#ifdef KR_headers +long f__inode(a, dev) char *a; int *dev; +#else +long f__inode(char *a, int *dev) +#endif +{ struct stat x; + if(stat(a,&x)<0) return(-1); + *dev = x.st_dev; + return(x.st_ino); +} +#endif + +#define INTBOUND sizeof(int)-1 + VOID +#ifdef KR_headers +f__mvgbt(n,len,a,b) char *a,*b; +#else +f__mvgbt(int n, int len, char *a, char *b) +#endif +{ register int num=n*len; + if( ((int)a&INTBOUND)==0 && ((int)b&INTBOUND)==0 && (num&INTBOUND)==0 ) + { register int *x=(int *)a,*y=(int *)b; + num /= sizeof(int); + if(x>y) for(;num>0;num--) *y++= *x++; + else for(num--;num>=0;num--) *(y+num)= *(x+num); + } + else + { register char *x=a,*y=b; + if(x>y) for(;num>0;num--) *y++= *x++; + else for(num--;num>=0;num--) *(y+num)= *(x+num); + } +} diff --git a/lib/libI77/wref.c b/lib/libI77/wref.c new file mode 100644 index 000000000000..f58faf2562a6 --- /dev/null +++ b/lib/libI77/wref.c @@ -0,0 +1,245 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "fp.h" +#ifndef VAX +#include "ctype.h" +#endif + +#ifndef KR_headers +#undef abs +#undef min +#undef max +#include "stdlib.h" +#include "string.h" +#endif + +#ifdef KR_headers +wrt_E(p,w,d,e,len) ufloat *p; ftnlen len; +#else +wrt_E(ufloat *p, int w, int d, int e, ftnlen len) +#endif +{ + char buf[FMAX+EXPMAXDIGS+4], *s, *se; + int d1, delta, e1, i, sign, signspace; + double dd; +#ifndef VAX + int e0 = e; +#endif + + if(e <= 0) + e = 2; + if(f__scale) { + if(f__scale >= d + 2 || f__scale <= -d) + goto nogood; + } + if(f__scale <= 0) + --d; + if (len == sizeof(real)) + dd = p->pf; + else + dd = p->pd; + if (dd < 0.) { + signspace = sign = 1; + dd = -dd; + } + else { + sign = 0; + signspace = (int)f__cplus; +#ifndef VAX + if (!dd) + dd = 0.; /* avoid -0 */ +#endif + } + delta = w - (2 /* for the . and the d adjustment above */ + + 2 /* for the E+ */ + signspace + d + e); + if (delta < 0) { +nogood: + while(--w >= 0) + PUT('*'); + return(0); + } + if (f__scale < 0) + d += f__scale; + if (d > FMAX) { + d1 = d - FMAX; + d = FMAX; + } + else + d1 = 0; + sprintf(buf,"%#.*E", d, dd); +#ifndef VAX + /* check for NaN, Infinity */ + if (!isdigit(buf[0])) { + switch(buf[0]) { + case 'n': + case 'N': + signspace = 0; /* no sign for NaNs */ + } + delta = w - strlen(buf) - signspace; + if (delta < 0) + goto nogood; + while(--delta >= 0) + PUT(' '); + if (signspace) + PUT(sign ? '-' : '+'); + for(s = buf; *s; s++) + PUT(*s); + return 0; + } +#endif + se = buf + d + 3; + if (f__scale != 1 && dd) + sprintf(se, "%+.2d", atoi(se) + 1 - f__scale); + s = ++se; + if (e < 2) { + if (*s != '0') + goto nogood; + } +#ifndef VAX + /* accommodate 3 significant digits in exponent */ + if (s[2]) { +#ifdef Pedantic + if (!e0 && !s[3]) + for(s -= 2, e1 = 2; s[0] = s[1]; s++); + + /* Pedantic gives the behavior that Fortran 77 specifies, */ + /* i.e., requires that E be specified for exponent fields */ + /* of more than 3 digits. With Pedantic undefined, we get */ + /* the behavior that Cray displays -- you get a bigger */ + /* exponent field if it fits. */ +#else + if (!e0) { + for(s -= 2, e1 = 2; s[0] = s[1]; s++) +#ifdef CRAY + delta--; + if ((delta += 4) < 0) + goto nogood +#endif + ; + } +#endif + else if (e0 >= 0) + goto shift; + else + e1 = e; + } + else + shift: +#endif + for(s += 2, e1 = 2; *s; ++e1, ++s) + if (e1 >= e) + goto nogood; + while(--delta >= 0) + PUT(' '); + if (signspace) + PUT(sign ? '-' : '+'); + s = buf; + i = f__scale; + if (f__scale <= 0) { + PUT('.'); + for(; i < 0; ++i) + PUT('0'); + PUT(*s); + s += 2; + } + else if (f__scale > 1) { + PUT(*s); + s += 2; + while(--i > 0) + PUT(*s++); + PUT('.'); + } + if (d1) { + se -= 2; + while(s < se) PUT(*s++); + se += 2; + do PUT('0'); while(--d1 > 0); + } + while(s < se) + PUT(*s++); + if (e < 2) + PUT(s[1]); + else { + while(++e1 <= e) + PUT('0'); + while(*s) + PUT(*s++); + } + return 0; + } + +#ifdef KR_headers +wrt_F(p,w,d,len) ufloat *p; ftnlen len; +#else +wrt_F(ufloat *p, int w, int d, ftnlen len) +#endif +{ + int d1, sign, n; + double x; + char *b, buf[MAXINTDIGS+MAXFRACDIGS+4], *s; + + x= (len==sizeof(real)?p->pf:p->pd); + if (d < MAXFRACDIGS) + d1 = 0; + else { + d1 = d - MAXFRACDIGS; + d = MAXFRACDIGS; + } + if (x < 0.) + { x = -x; sign = 1; } + else { + sign = 0; +#ifndef VAX + if (!x) + x = 0.; +#endif + } + + if (n = f__scale) + if (n > 0) + do x *= 10.; while(--n > 0); + else + do x *= 0.1; while(++n < 0); + +#ifdef USE_STRLEN + sprintf(b = buf, "%#.*f", d, x); + n = strlen(b) + d1; +#else + n = sprintf(b = buf, "%#.*f", d, x) + d1; +#endif + + if (buf[0] == '0' && d) + { ++b; --n; } + if (sign) { + /* check for all zeros */ + for(s = b;;) { + while(*s == '0') s++; + switch(*s) { + case '.': + s++; continue; + case 0: + sign = 0; + } + break; + } + } + if (sign || f__cplus) + ++n; + if (n > w) { + while(--w >= 0) + PUT('*'); + return 0; + } + for(w -= n; --w >= 0; ) + PUT(' '); + if (sign) + PUT('-'); + else if (f__cplus) + PUT('+'); + while(n = *b++) + PUT(n); + while(--d1 >= 0) + PUT('0'); + return 0; + } diff --git a/lib/libI77/wrtfmt.c b/lib/libI77/wrtfmt.c new file mode 100644 index 000000000000..ab6bdde1a004 --- /dev/null +++ b/lib/libI77/wrtfmt.c @@ -0,0 +1,372 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "local.h" +extern int f__cursor; +#ifdef KR_headers +extern char *f__icvt(); +#else +extern char *f__icvt(long, int*, int*, int); +#endif +int f__hiwater; +icilist *f__svic; +char *f__icptr; +mv_cur(Void) /* shouldn't use fseek because it insists on calling fflush */ + /* instead we know too much about stdio */ +{ + if(f__external == 0) { + if(f__cursor < 0) { + if(f__hiwater < f__recpos) + f__hiwater = f__recpos; + f__recpos += f__cursor; + f__icptr += f__cursor; + f__cursor = 0; + if(f__recpos < 0) + err(f__elist->cierr, 110, "left off"); + } + else if(f__cursor > 0) { + if(f__recpos + f__cursor >= f__svic->icirlen) + err(f__elist->cierr, 110, "recend"); + if(f__hiwater <= f__recpos) + for(; f__cursor > 0; f__cursor--) + (*f__putn)(' '); + else if(f__hiwater <= f__recpos + f__cursor) { + f__cursor -= f__hiwater - f__recpos; + f__icptr += f__hiwater - f__recpos; + f__recpos = f__hiwater; + for(; f__cursor > 0; f__cursor--) + (*f__putn)(' '); + } + else { + f__icptr += f__cursor; + f__recpos += f__cursor; + } + f__cursor = 0; + } + return(0); + } + if(f__cursor > 0) { + if(f__hiwater <= f__recpos) + for(;f__cursor>0;f__cursor--) (*f__putn)(' '); + else if(f__hiwater <= f__recpos + f__cursor) { +#ifndef NON_UNIX_STDIO + if(f__cf->_ptr + f__hiwater - f__recpos < buf_end(f__cf)) + f__cf->_ptr += f__hiwater - f__recpos; + else +#endif + (void) fseek(f__cf, (long) (f__hiwater - f__recpos), SEEK_CUR); + f__cursor -= f__hiwater - f__recpos; + f__recpos = f__hiwater; + for(; f__cursor > 0; f__cursor--) + (*f__putn)(' '); + } + else { +#ifndef NON_UNIX_STDIO + if(f__cf->_ptr + f__cursor < buf_end(f__cf)) + f__cf->_ptr += f__cursor; + else +#endif + (void) fseek(f__cf, (long)f__cursor, SEEK_CUR); + f__recpos += f__cursor; + } + } + if(f__cursor<0) + { + if(f__cursor+f__recpos<0) err(f__elist->cierr,110,"left off"); +#ifndef NON_UNIX_STDIO + if(f__cf->_ptr + f__cursor >= f__cf->_base) + f__cf->_ptr += f__cursor; + else +#endif + if(f__curunit && f__curunit->useek) + (void) fseek(f__cf,(long)f__cursor,SEEK_CUR); + else + err(f__elist->cierr,106,"fmt"); + if(f__hiwater < f__recpos) + f__hiwater = f__recpos; + f__recpos += f__cursor; + f__cursor=0; + } + return(0); +} + + static int +#ifdef KR_headers +wrt_Z(n,w,minlen,len) Uint *n; int w, minlen; ftnlen len; +#else +wrt_Z(Uint *n, int w, int minlen, ftnlen len) +#endif +{ + register char *s, *se; + register i, w1; + static int one = 1; + static char hex[] = "0123456789ABCDEF"; + s = (char *)n; + --len; + if (*(char *)&one) { + /* little endian */ + se = s; + s += len; + i = -1; + } + else { + se = s + len; + i = 1; + } + for(;; s += i) + if (s == se || *s) + break; + w1 = (i*(se-s) << 1) + 1; + if (*s & 0xf0) + w1++; + if (w1 > w) + for(i = 0; i < w; i++) + (*f__putn)('*'); + else { + if ((minlen -= w1) > 0) + w1 += minlen; + while(--w >= w1) + (*f__putn)(' '); + while(--minlen >= 0) + (*f__putn)('0'); + if (!(*s & 0xf0)) { + (*f__putn)(hex[*s & 0xf]); + if (s == se) + return 0; + s += i; + } + for(;; s += i) { + (*f__putn)(hex[*s >> 4 & 0xf]); + (*f__putn)(hex[*s & 0xf]); + if (s == se) + break; + } + } + return 0; + } + + static int +#ifdef KR_headers +wrt_I(n,w,len, base) Uint *n; ftnlen len; register int base; +#else +wrt_I(Uint *n, int w, ftnlen len, register int base) +#endif +{ int ndigit,sign,spare,i; + long x; + char *ans; + if(len==sizeof(integer)) x=n->il; + else if(len == sizeof(char)) x = n->ic; +#ifdef Allow_TYQUAD + else if (len == sizeof(longint)) x = n->ili; +#endif + else x=n->is; + ans=f__icvt(x,&ndigit,&sign, base); + spare=w-ndigit; + if(sign || f__cplus) spare--; + if(spare<0) + for(i=0;i<w;i++) (*f__putn)('*'); + else + { for(i=0;i<spare;i++) (*f__putn)(' '); + if(sign) (*f__putn)('-'); + else if(f__cplus) (*f__putn)('+'); + for(i=0;i<ndigit;i++) (*f__putn)(*ans++); + } + return(0); +} + static int +#ifdef KR_headers +wrt_IM(n,w,m,len,base) Uint *n; ftnlen len; int base; +#else +wrt_IM(Uint *n, int w, int m, ftnlen len, int base) +#endif +{ int ndigit,sign,spare,i,xsign; + long x; + char *ans; + if(sizeof(integer)==len) x=n->il; + else if(len == sizeof(char)) x = n->ic; + else x=n->is; + ans=f__icvt(x,&ndigit,&sign, base); + if(sign || f__cplus) xsign=1; + else xsign=0; + if(ndigit+xsign>w || m+xsign>w) + { for(i=0;i<w;i++) (*f__putn)('*'); + return(0); + } + if(x==0 && m==0) + { for(i=0;i<w;i++) (*f__putn)(' '); + return(0); + } + if(ndigit>=m) + spare=w-ndigit-xsign; + else + spare=w-m-xsign; + for(i=0;i<spare;i++) (*f__putn)(' '); + if(sign) (*f__putn)('-'); + else if(f__cplus) (*f__putn)('+'); + for(i=0;i<m-ndigit;i++) (*f__putn)('0'); + for(i=0;i<ndigit;i++) (*f__putn)(*ans++); + return(0); +} + static int +#ifdef KR_headers +wrt_AP(s) char *s; +#else +wrt_AP(char *s) +#endif +{ char quote; + if(f__cursor && mv_cur()) return(mv_cur()); + quote = *s++; + for(;*s;s++) + { if(*s!=quote) (*f__putn)(*s); + else if(*++s==quote) (*f__putn)(*s); + else return(1); + } + return(1); +} + static int +#ifdef KR_headers +wrt_H(a,s) char *s; +#else +wrt_H(int a, char *s) +#endif +{ + if(f__cursor && mv_cur()) return(mv_cur()); + while(a--) (*f__putn)(*s++); + return(1); +} +#ifdef KR_headers +wrt_L(n,len, sz) Uint *n; ftnlen sz; +#else +wrt_L(Uint *n, int len, ftnlen sz) +#endif +{ int i; + long x; + if(sizeof(long)==sz) x=n->il; + else if(sz == sizeof(char)) x = n->ic; + else x=n->is; + for(i=0;i<len-1;i++) + (*f__putn)(' '); + if(x) (*f__putn)('T'); + else (*f__putn)('F'); + return(0); +} + static int +#ifdef KR_headers +wrt_A(p,len) char *p; ftnlen len; +#else +wrt_A(char *p, ftnlen len) +#endif +{ + while(len-- > 0) (*f__putn)(*p++); + return(0); +} + static int +#ifdef KR_headers +wrt_AW(p,w,len) char * p; ftnlen len; +#else +wrt_AW(char * p, int w, ftnlen len) +#endif +{ + while(w>len) + { w--; + (*f__putn)(' '); + } + while(w-- > 0) + (*f__putn)(*p++); + return(0); +} + + static int +#ifdef KR_headers +wrt_G(p,w,d,e,len) ufloat *p; ftnlen len; +#else +wrt_G(ufloat *p, int w, int d, int e, ftnlen len) +#endif +{ double up = 1,x; + int i,oldscale=f__scale,n,j; + x= len==sizeof(real)?p->pf:p->pd; + if(x < 0 ) x = -x; + if(x<.1) return(wrt_E(p,w,d,e,len)); + for(i=0;i<=d;i++,up*=10) + { if(x>=up) continue; + f__scale=0; + if(e==0) n=4; + else n=e+2; + i=wrt_F(p,w-n,d-i,len); + for(j=0;j<n;j++) (*f__putn)(' '); + f__scale=oldscale; + return(i); + } + return(wrt_E(p,w,d,e,len)); +} +#ifdef KR_headers +w_ed(p,ptr,len) struct syl *p; char *ptr; ftnlen len; +#else +w_ed(struct syl *p, char *ptr, ftnlen len) +#endif +{ + if(f__cursor && mv_cur()) return(mv_cur()); + switch(p->op) + { + default: + fprintf(stderr,"w_ed, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case I: return(wrt_I((Uint *)ptr,p->p1,len, 10)); + case IM: + return(wrt_IM((Uint *)ptr,p->p1,p->p2,len,10)); + + /* O and OM don't work right for character, double, complex, */ + /* or doublecomplex, and they differ from Fortran 90 in */ + /* showing a minus sign for negative values. */ + + case O: return(wrt_I((Uint *)ptr, p->p1, len, 8)); + case OM: + return(wrt_IM((Uint *)ptr,p->p1,p->p2,len,8)); + case L: return(wrt_L((Uint *)ptr,p->p1, len)); + case A: return(wrt_A(ptr,len)); + case AW: + return(wrt_AW(ptr,p->p1,len)); + case D: + case E: + case EE: + return(wrt_E((ufloat *)ptr,p->p1,p->p2,p->p3,len)); + case G: + case GE: + return(wrt_G((ufloat *)ptr,p->p1,p->p2,p->p3,len)); + case F: return(wrt_F((ufloat *)ptr,p->p1,p->p2,len)); + + /* Z and ZM assume 8-bit bytes. */ + + case Z: return(wrt_Z((Uint *)ptr,p->p1,0,len)); + case ZM: + return(wrt_Z((Uint *)ptr,p->p1,p->p2,len)); + } +} +#ifdef KR_headers +w_ned(p) struct syl *p; +#else +w_ned(struct syl *p) +#endif +{ + switch(p->op) + { + default: fprintf(stderr,"w_ned, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case SLASH: + return((*f__donewrec)()); + case T: f__cursor = p->p1-f__recpos - 1; + return(1); + case TL: f__cursor -= p->p1; + if(f__cursor < -f__recpos) /* TL1000, 1X */ + f__cursor = -f__recpos; + return(1); + case TR: + case X: + f__cursor += p->p1; + return(1); + case APOS: + return(wrt_AP(*(char **)&p->p2)); + case H: + return(wrt_H(p->p1,*(char **)&p->p2)); + } +} diff --git a/lib/libI77/wsfe.c b/lib/libI77/wsfe.c new file mode 100644 index 000000000000..2d4051285e17 --- /dev/null +++ b/lib/libI77/wsfe.c @@ -0,0 +1,80 @@ +/*write sequential formatted external*/ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "local.h" +extern int f__hiwater; + +#ifdef KR_headers +x_putc(c) +#else +x_putc(int c) +#endif +{ + /* this uses \n as an indicator of record-end */ + if(c == '\n' && f__recpos < f__hiwater) { /* fseek calls fflush, a loss */ +#ifndef NON_UNIX_STDIO + if(f__cf->_ptr + f__hiwater - f__recpos < buf_end(f__cf)) + f__cf->_ptr += f__hiwater - f__recpos; + else +#endif + (void) fseek(f__cf, (long)(f__hiwater - f__recpos), SEEK_CUR); + } + f__recpos++; + return putc(c,f__cf); +} +x_wSL(Void) +{ + (*f__putn)('\n'); + f__recpos=0; + f__cursor = 0; + f__hiwater = 0; + return(1); +} +xw_end(Void) +{ + if(f__nonl == 0) + (*f__putn)('\n'); + f__hiwater = f__recpos = f__cursor = 0; + return(0); +} +xw_rev(Void) +{ + if(f__workdone) (*f__putn)('\n'); + f__hiwater = f__recpos = f__cursor = 0; + return(f__workdone=0); +} + +#ifdef KR_headers +integer s_wsfe(a) cilist *a; /*start*/ +#else +integer s_wsfe(cilist *a) /*start*/ +#endif +{ int n; + if(!f__init) f_init(); + if(n=c_sfe(a)) return(n); + f__reading=0; + f__sequential=1; + f__formatted=1; + f__external=1; + f__elist=a; + f__hiwater = f__cursor=f__recpos=0; + f__nonl = 0; + f__scale=0; + f__fmtbuf=a->cifmt; + f__curunit = &f__units[a->ciunit]; + f__cf=f__curunit->ufd; + if(pars_f(f__fmtbuf)<0) err(a->cierr,100,"startio"); + f__putn= x_putc; + f__doed= w_ed; + f__doned= w_ned; + f__doend=xw_end; + f__dorevert=xw_rev; + f__donewrec=x_wSL; + fmt_bg(); + f__cplus=0; + f__cblank=f__curunit->ublnk; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr,errno,"write start"); + return(0); +} diff --git a/lib/libI77/wsle.c b/lib/libI77/wsle.c new file mode 100644 index 000000000000..470191be0145 --- /dev/null +++ b/lib/libI77/wsle.c @@ -0,0 +1,36 @@ +#include "f2c.h" +#include "fio.h" +#include "fmt.h" +#include "lio.h" + +#ifdef KR_headers +integer s_wsle(a) cilist *a; +#else +integer s_wsle(cilist *a) +#endif +{ + int n; + if(!f__init) f_init(); + if(n=c_le(a)) return(n); + f__reading=0; + f__external=1; + f__formatted=1; + f__putn = t_putc; + f__lioproc = l_write; + L_len = LINE; + f__donewrec = x_wSL; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr, errno, "list output start"); + return(0); + } + +integer e_wsle(Void) +{ + t_putc('\n'); + f__recpos=0; + if (f__cf == stdout) + fflush(stdout); + else if (f__cf == stderr) + fflush(stderr); + return(0); + } diff --git a/lib/libI77/wsne.c b/lib/libI77/wsne.c new file mode 100644 index 000000000000..c3f06234d3c2 --- /dev/null +++ b/lib/libI77/wsne.c @@ -0,0 +1,28 @@ +#include "f2c.h" +#include "fio.h" +#include "lio.h" + + integer +#ifdef KR_headers +s_wsne(a) cilist *a; +#else +s_wsne(cilist *a) +#endif +{ + int n; + + if(!f__init) + f_init(); + if(n=c_le(a)) + return(n); + f__reading=0; + f__external=1; + f__formatted=1; + f__putn = t_putc; + L_len = LINE; + f__donewrec = x_wSL; + if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr, errno, "namelist output start"); + x_wsne(a); + return e_wsle(); + } diff --git a/lib/libI77/xwsne.c b/lib/libI77/xwsne.c new file mode 100644 index 000000000000..49e6f0ec4596 --- /dev/null +++ b/lib/libI77/xwsne.c @@ -0,0 +1,68 @@ +#include "f2c.h" +#include "fio.h" +#include "lio.h" +#include "fmt.h" + + static VOID +nl_donewrec(Void) +{ + (*f__donewrec)(); + PUT(' '); + } + +#ifdef KR_headers +x_wsne(a) cilist *a; +#else +#include "string.h" + + VOID +x_wsne(cilist *a) +#endif +{ + Namelist *nl; + char *s; + Vardesc *v, **vd, **vde; + ftnint *number, type; + ftnlen *dims; + ftnlen size; + static ftnint one = 1; + extern ftnlen f__typesize[]; + + nl = (Namelist *)a->cifmt; + PUT('&'); + for(s = nl->name; *s; s++) + PUT(*s); + PUT(' '); + vd = nl->vars; + vde = vd + nl->nvars; + while(vd < vde) { + v = *vd++; + s = v->name; +#ifdef No_Extra_Namelist_Newlines + if (f__recpos+strlen(s)+2 >= L_len) +#endif + nl_donewrec(); + while(*s) + PUT(*s++); + PUT(' '); + PUT('='); + number = (dims = v->dims) ? dims + 1 : &one; + type = v->type; + if (type < 0) { + size = -type; + type = TYCHAR; + } + else + size = f__typesize[type]; + l_write(number, v->addr, size, type); + if (vd < vde) { + if (f__recpos+2 >= L_len) + nl_donewrec(); + PUT(','); + PUT(' '); + } + else if (f__recpos+1 >= L_len) + nl_donewrec(); + } + PUT('/'); + } diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 281f23054cf2..319a528c5a54 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -6,17 +6,23 @@ # from CFLAGS below. To remove these strings from just the system call # stubs, remove just -DSYSLIBC_SCCS from CFLAGS. LIB=c -CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS +CFLAGS+= -DYP -DLIBC_SCCS -DSYSLIBC_SCCS AINC= -I${.CURDIR}/${MACHINE} +INSTALL_PIC_ARCHIVE= .include "${.CURDIR}/compat-43/Makefile.inc" .include "${.CURDIR}/db/Makefile.inc" .include "${.CURDIR}/gen/Makefile.inc" .include "${.CURDIR}/locale/Makefile.inc" .include "${.CURDIR}/net/Makefile.inc" +.include "${.CURDIR}/quad/Makefile.inc" .include "${.CURDIR}/stdio/Makefile.inc" .include "${.CURDIR}/stdlib/Makefile.inc" .include "${.CURDIR}/string/Makefile.inc" .include "${.CURDIR}/sys/Makefile.inc" +.include "${.CURDIR}/rpc/Makefile.inc" +.include "${.CURDIR}/regex/Makefile.inc" +.include "${.CURDIR}/yp/Makefile.inc" +.include "${.CURDIR}/${MACHINE}/sys/Makefile.inc" .include <bsd.lib.mk> diff --git a/lib/libc/compat-43/creat.2 b/lib/libc/compat-43/creat.2 index d1e1226bf2ef..23670785e397 100644 --- a/lib/libc/compat-43/creat.2 +++ b/lib/libc/compat-43/creat.2 @@ -55,4 +55,5 @@ open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); .Sh HISTORY The .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/compat-43/sigvec.2 b/lib/libc/compat-43/sigvec.2 index dc4ce5c4c58b..38c9537b09da 100644 --- a/lib/libc/compat-43/sigvec.2 +++ b/lib/libc/compat-43/sigvec.2 @@ -53,7 +53,7 @@ This interface is made obsolete by sigaction(2). .Ef .Pp The system defines a set of signals that may be delivered to a process. -Signal delivery resembles the occurence of a hardware interrupt: +Signal delivery resembles the occurrence of a hardware interrupt: the signal is blocked from further occurrence, the current process context is saved, and a new one is built. A process may specify a .Em handler diff --git a/lib/libc/db/PORT/Makefile b/lib/libc/db/PORT/Makefile deleted file mode 100644 index 9b0b56b4bf56..000000000000 --- a/lib/libc/db/PORT/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/2/93 - -LIBDB= libdb.a -OBJ1= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \ - bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \ - bt_stack.o bt_utils.o -OBJ2= db.o -OBJ3= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \ - hsearch.o ndbm.o -OBJ4= mpool.o -OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \ - rec_seq.o rec_utils.o - -# If you don't have memmove(3), add memmove.o to the MISC line. -# -# If you don't have mktemp(3) or mkstemp(3), add mktemp.o to the MISC line. -# -# If realloc(3) of a NULL pointer on your system isn't the same as -# a malloc(3) call, add realloc.o to the MISC line. -# -# If you don't have snprintf/vsnprintf(3), add snprintf.o to the MISC line. -# Note, this depends you your having vsprintf(3) -- if you don't, there's -# no workaround other than changing the source code to not use the snprintf -# calls. If you have to make that change, check to see if your vsprintf -# returns a length or a char *; if it's the latter, set VSPRINTF_CHARSTAR -# in the include/compat.h file. -MISC= - -${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} - ar cq $@ \ - `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort` - ranlib $@ - -${OBJ1}: - ${CC} -c -O -I. -Iinclude -I../btree ../btree/*.c -${OBJ2}: - ${CC} -c -O -I. -Iinclude -I../db ../db/*.c -${OBJ3}: - ${CC} -c -O -I. -Iinclude -I../hash ../hash/*.c -${OBJ4}: - ${CC} -c -O -I. -Iinclude -I../mpool ../mpool/*.c -${OBJ5}: - ${CC} -c -O -I. -Iinclude -I../recno ../recno/*.c - -memmove.o: - ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c -mktemp.o: - ${CC} -c -O -I. -Iinclude clib/mktemp.c -realloc.o: - ${CC} -c -O -I. -Iinclude clib/realloc.c -snprintf.o: - ${CC} -c -O -I. -Iinclude clib/snprintf.c - -clean: - rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} diff --git a/lib/libc/db/PORT/README b/lib/libc/db/PORT/README deleted file mode 100644 index cbe7f1136241..000000000000 --- a/lib/libc/db/PORT/README +++ /dev/null @@ -1,60 +0,0 @@ -# @(#)README 8.1 (Berkeley) 6/2/93 - -This is the directory to use for creating a library of the dbopen(3) -routines. The Makefile builds the base system. By changing it and -the compat.h file, you should be able to pick and choose the various -things your system needs to make libdb run. - -The knobs that you may have to turn: - -In the Makefile: - If you don't have mktemp(3) or mkstemp(3) on your system, add - "mktemp.o" to the MISC list. - - If you don't have snprintf(3) on your system, add snprintf.o - to the MISC list. - - If you don't have memmove(3), add memmove.o to the MISC list. - -In include/compat.h: - Before attempting to build this library, you should skim through - the compat.h file, and adjust it as necessary for your system. - It's possible to use the #ifndef construct to figure out if a - #ifdef has been set, but C provides no similar method to figure - out if a typedef has been done. All of the typedef's are grouped - at the top of compat.h, your compile errors will tell you which - ones you need. - - Particularly subtle problems can occur if you don't have the - BYTE_ORDER set right or if the realloc define is wrong. - -Some other problems: - You may see warning messages about illegal pointer combinations. - It's because systems prototype malloc, calloc and realloc in - different places. If you want to stop the warnings, find out - where your system prototypes them, and include it in compat.h, - or, just prototype them yourself. - -To install: - Programs using the dbopen(3) interface have to include db.h. - To install the library, you'll need to put db.h (found in the - directory PORT/include) and the library libdb.a in some place - accesible to your program. - -Hints: - SunOS 4.1.2 works with ``MISC=realloc.o snprintf.o memmove.o'' - and the include/compat.h realloc ``#if 0'' changed to ``#if 1''. - SunOS gives a bunch of warning messages on the malloc family - routines. - - Ultrix 4.2A works with ``MISC=realloc.o snprintf.o memmove.o'' - and the include/compat.h realloc ``#if 0'' changed to ``#if 1'' - and BYTE_ORDER changed from BIG_ENDIAN to LITTLE_ENDIAN. - Ultrix does not give warning messages on the malloc family - routines. - - The recno routines require the mmap(2) call. It wouldn't be - difficult to port this package to a system without mmap. Change - rec_open.c to do slightly different initialization and to write - two new routines for rec_get.c that handle regular files using - reads and writes. diff --git a/lib/libc/db/PORT/clib/memmove.c b/lib/libc/db/PORT/clib/memmove.c deleted file mode 100644 index f90b09c9b73f..000000000000 --- a/lib/libc/db/PORT/clib/memmove.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * 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[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/cdefs.h> -#include <string.h> - -/* - * sizeof(word) MUST BE A POWER OF TWO - * SO THAT wmask BELOW IS ALL ONES - */ -typedef int word; /* "word" used for optimal copy speed */ - -#define wsize sizeof(word) -#define wmask (wsize - 1) - -/* - * Copy a block of memory, handling overlap. - * This is the routine that actually implements - * (the portable versions of) bcopy, memcpy, and memmove. - */ -#ifdef MEMCOPY -void * -memcpy(dst0, src0, length) -#else -#ifdef MEMMOVE -void * -memmove(dst0, src0, length) -#else -void -bcopy(src0, dst0, length) -#endif -#endif - void *dst0; - const void *src0; - register size_t length; -{ - register char *dst = dst0; - register const char *src = src0; - register size_t t; - - if (length == 0 || dst == src) /* nothing to do */ - goto done; - - /* - * Macros: loop-t-times; and loop-t-times, t>0 - */ -#define TLOOP(s) if (t) TLOOP1(s) -#define TLOOP1(s) do { s; } while (--t) - - if ((unsigned long)dst < (unsigned long)src) { - /* - * Copy forward. - */ - t = (int)src; /* only need low bits */ - if ((t | (int)dst) & wmask) { - /* - * Try to align operands. This cannot be done - * unless the low bits match. - */ - if ((t ^ (int)dst) & wmask || length < wsize) - t = length; - else - t = wsize - (t & wmask); - length -= t; - TLOOP1(*dst++ = *src++); - } - /* - * Copy whole words, then mop up any trailing bytes. - */ - t = length / wsize; - TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); - t = length & wmask; - TLOOP(*dst++ = *src++); - } else { - /* - * Copy backwards. Otherwise essentially the same. - * Alignment works as before, except that it takes - * (t&wmask) bytes to align, not wsize-(t&wmask). - */ - src += length; - dst += length; - t = (int)src; - if ((t | (int)dst) & wmask) { - if ((t ^ (int)dst) & wmask || length <= wsize) - t = length; - else - t &= wmask; - length -= t; - TLOOP1(*--dst = *--src); - } - t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); - t = length & wmask; - TLOOP(*--dst = *--src); - } -done: -#if defined(MEMCOPY) || defined(MEMMOVE) - return (dst0); -#else - return; -#endif -} diff --git a/lib/libc/db/PORT/clib/realloc.c b/lib/libc/db/PORT/clib/realloc.c deleted file mode 100644 index 11e5cd28c5da..000000000000 --- a/lib/libc/db/PORT/clib/realloc.c +++ /dev/null @@ -1,11 +0,0 @@ -#include <sys/types.h> - -#include <stdlib.h> - -void * -__fix_realloc(p, n) - void *p; - size_t n; -{ - return (p == 0 ? malloc(n) : realloc(p, n)); -} diff --git a/lib/libc/db/PORT/clib/snprintf.c b/lib/libc/db/PORT/clib/snprintf.c deleted file mode 100644 index 2863fa28d62b..000000000000 --- a/lib/libc/db/PORT/clib/snprintf.c +++ /dev/null @@ -1,54 +0,0 @@ -#include <sys/types.h> -#include <sys/cdefs.h> - -#include <compat.h> - -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -int -#ifdef __STDC__ -snprintf(char *str, size_t n, const char *fmt, ...) -#else -snprintf(str, n, fmt, va_alist) - char *str; - size_t n; - const char *fmt; - va_dcl -#endif -{ - va_list ap; - char *rp; - int rval; -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif -#ifdef VSPRINTF_CHARSTAR - rp = vsprintf(str, fmt, ap); - va_end(ap); - return (strlen(rp)); -#else - rval = vsprintf(str, fmt, ap); - va_end(ap); - return (rval); -#endif -} - -int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - va_list ap; -{ -#ifdef VSPRINTF_CHARSTAR - return (strlen(vsprintf(str, fmt, ap))); -#else - return (vsprintf(str, fmt, ap)); -#endif -} diff --git a/lib/libc/db/PORT/include/cdefs.h b/lib/libc/db/PORT/include/cdefs.h deleted file mode 100644 index a04665e30e49..000000000000 --- a/lib/libc/db/PORT/include/cdefs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)cdefs.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _CDEFS_H_ -#define _CDEFS_H_ - -#if defined(__cplusplus) -#define __BEGIN_DECLS extern "C" { -#define __END_DECLS }; -#else -#define __BEGIN_DECLS -#define __END_DECLS -#endif - -/* - * The __CONCAT macro is used to concatenate parts of symbol names, e.g. - * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. - * The __CONCAT macro is a bit tricky -- make sure you don't put spaces - * in between its arguments. __CONCAT can also concatenate double-quoted - * strings produced by the __STRING macro, but this only works with ANSI C. - */ -#if defined(__STDC__) || defined(__cplusplus) -#define __P(protos) protos /* full-blown ANSI C */ -#define __CONCAT(x,y) x ## y -#define __STRING(x) #x - -#else /* !(__STDC__ || __cplusplus) */ -#define __P(protos) () /* traditional C preprocessor */ -#define __CONCAT(x,y) x/**/y -#define __STRING(x) "x" - -#ifdef __GNUC__ -#define const __const /* GCC: ANSI C with -traditional */ -#define inline __inline -#define signed __signed -#define volatile __volatile - -#else /* !__GNUC__ */ -#define const /* delete ANSI C keywords */ -#define inline -#define signed -#define volatile -#endif /* !__GNUC__ */ -#endif /* !(__STDC__ || __cplusplus) */ - -/* - * GCC has extensions for declaring functions as `pure' (always returns - * the same value given the same inputs, i.e., has no external state and - * no side effects) and `dead' (nonreturning). These mainly affect - * optimization and warnings. Unfortunately, GCC complains if these are - * used under strict ANSI mode (`gcc -ansi -pedantic'), hence we need to - * define them only if compiling without this. - */ -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define __dead __volatile -#define __pure __const -#else -#define __dead -#define __pure -#endif - -#endif /* !_CDEFS_H_ */ diff --git a/lib/libc/db/PORT/include/compat.h b/lib/libc/db/PORT/include/compat.h deleted file mode 100644 index bb3f91466731..000000000000 --- a/lib/libc/db/PORT/include/compat.h +++ /dev/null @@ -1,217 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)compat.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _COMPAT_H_ -#define _COMPAT_H_ - -/* - * If your system doesn't typedef u_long, u_short, or u_char, change - * the 0 to a 1. - */ -#if 0 -typedef unsigned long u_long; -typedef unsigned short u_short; -typedef unsigned char u_char; -#endif - -/* If your system doesn't typedef size_t, change the 0 to a 1. */ -#if 0 -typedef unsigned int size_t; -#define SIZE_T_MAX UINT_MAX -#endif - -/* - * If your system doesn't specify a max size for a SIZE_T, check - * to make sure this is the right one. - */ -#ifndef SIZE_T_MAX -#define SIZE_T_MAX UINT_MAX -#endif - -/* - * If your system doesn't have the POSIX type for a signal mask, - * change the 0 to a 1. - */ -#if 0 -typedef unsigned int sigset_t; -#endif - -/* - * If your system's vsprintf returns a char *, not an int, - * change the 0 to a 1. - */ -#if 0 -#define VSPRINTF_CHARSTAR -#endif - -/* - * If you don't have POSIX 1003.1 signals, the signal code surrounding the - * temporary file creation is intended to block all of the possible signals - * long enough to create the file and unlink it. All of this stuff is - * intended to use old-style BSD calls to fake POSIX 1003.1 calls. - */ -#ifdef NO_POSIX_SIGNALS -#define sigemptyset(set) (*(set) = 0) -#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) -#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0) -#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0) -#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0) - -#define SIG_BLOCK 1 -#define SIG_UNBLOCK 2 -#define SIG_SETMASK 3 - -static int __sigtemp; /* For the use of sigprocmask */ - -#define sigprocmask(how,set,oset) \ - ((__sigtemp = (((how) == SIG_BLOCK) ? \ - sigblock(0) | *(set) : (((how) == SIG_UNBLOCK) ? \ - sigblock(0) & ~(*(set)) : ((how) == SIG_SETMASK ? \ - *(set) : sigblock(0))))), ((oset) ? \ - (*(oset) = sigsetmask(__sigtemp)) : sigsetmask(__sigtemp)), 0) -#endif - -/* - * If realloc(3) of a NULL pointer on your system isn't the same as - * a malloc(3) call, change the 0 to a 1, and add realloc.o to the - * MISC line in your Makefile. - */ -#if 0 -#define realloc __fix_realloc -#endif - -/* - * If your system doesn't have an include file with the appropriate - * byte order set, make sure you specify the correct one. - */ -#ifndef BYTE_ORDER -#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ -#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ -#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */ -#endif - -#if defined(SYSV) || defined(SYSTEM5) -#define index(a, b) strchr(a, b) -#define rindex(a, b) strrchr(a, b) -#define bzero(a, b) memset(a, 0, b) -#define bcmp(a, b, n) memcmp(a, b, n) -#define bcopy(a, b, n) memmove(b, a, n) -#endif - -#if defined(BSD) || defined(BSD4_3) -#define strchr(a, b) index(a, b) -#define strrchr(a, b) rindex(a, b) -#define memcmp(a, b, n) bcmp(a, b, n) -#define memmove(a, b, n) bcopy(b, a, n) -#endif - -/* - * 32-bit machine. The db routines are theoretically independent of - * the size of u_shorts and u_longs, but I don't know that anyone has - * ever actually tried it. At a minimum, change the following #define's - * if you are trying to compile on a different type of system. - */ -#ifndef USHRT_MAX -#define USHRT_MAX 0xFFFF -#define ULONG_MAX 0xFFFFFFFF -#endif - -/* POSIX 1003.1 access mode mask. */ -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) -#endif - -/* POSIX 1003.2 RE limit. */ -#ifndef _POSIX2_RE_DUP_MAX -#define _POSIX2_RE_DUP_MAX 255 -#endif - -/* - * If you can't provide lock values in the open(2) call. Note, this - * allows races to happen. - */ -#ifndef O_EXLOCK -#define O_EXLOCK 0 -#endif - -#ifndef O_SHLOCK -#define O_SHLOCK 0 -#endif - -#ifndef EFTYPE -#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */ -#endif - -#ifndef WCOREDUMP /* 4.4BSD extension */ -#define WCOREDUMP(a) 0 -#endif - -#ifndef STDERR_FILENO -#define STDIN_FILENO 0 /* ANSI C #defines */ -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -#endif - -#ifndef SEEK_END -#define SEEK_SET 0 /* POSIX 1003.1 seek values */ -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */ -#define S_ISLNK(m) ((m & 0170000) == 0120000) -#define S_ISSOCK(m) ((m & 0170000) == 0140000) -#endif - -#ifndef _POSIX2_RE_DUP_MAX -#define _POSIX2_RE_DUP_MAX 255 -#endif - -#ifndef NULL /* ANSI C #defines NULL everywhere. */ -#define NULL 0 -#endif - -#ifndef MAX -#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a)) -#endif -#ifndef MIN -#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) -#endif - -#ifndef _BSD_VA_LIST_ -#define _BSD_VA_LIST_ char * -#endif - -#endif /* !_COMPAT_H_ */ diff --git a/lib/libc/db/PORT/include/db.h b/lib/libc/db/PORT/include/db.h deleted file mode 100644 index 2b7de273a517..000000000000 --- a/lib/libc/db/PORT/include/db.h +++ /dev/null @@ -1,194 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)db.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _DB_H_ -#define _DB_H_ - -#include <sys/types.h> -#include <sys/cdefs.h> -#include <machine/endian.h> - -#define RET_ERROR -1 /* Return values. */ -#define RET_SUCCESS 0 -#define RET_SPECIAL 1 - -#define MAX_PAGE_NUMBER ULONG_MAX /* >= # of pages in a file */ -typedef u_long pgno_t; -#define MAX_PAGE_OFFSET USHRT_MAX /* >= # of bytes in a page */ -typedef u_short indx_t; -#define MAX_REC_NUMBER ULONG_MAX /* >= # of records in a tree */ -typedef u_long recno_t; - -/* Key/data structure -- a Data-Base Thang. */ -typedef struct { - void *data; /* data */ - size_t size; /* data length */ -} DBT; - -/* Routine flags. */ -#define R_CURSOR 1 /* del, put, seq */ -#define __R_UNUSED 2 /* UNUSED */ -#define R_FIRST 3 /* seq */ -#define R_IAFTER 4 /* put (RECNO) */ -#define R_IBEFORE 5 /* put (RECNO) */ -#define R_LAST 6 /* seq (BTREE, RECNO) */ -#define R_NEXT 7 /* seq */ -#define R_NOOVERWRITE 8 /* put */ -#define R_PREV 9 /* seq (BTREE, RECNO) */ -#define R_SETCURSOR 10 /* put (RECNO) */ -#define R_RECNOSYNC 11 /* sync (RECNO) */ - -typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; - -#define __USE_OPEN_FLAGS \ - (O_CREAT|O_EXCL|O_EXLOCK|O_RDONLY|O_RDWR|O_SHLOCK|O_TRUNC) - -/* Access method description structure. */ -typedef struct __db { - DBTYPE type; /* underlying db type */ - int (*close) __P((struct __db *)); - int (*del) __P((const struct __db *, const DBT *, u_int)); - int (*fd) __P((const struct __db *)); - int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); - int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); - int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); - int (*sync) __P((const struct __db *, u_int)); - void *internal; /* access method private */ -} DB; - -#define BTREEMAGIC 0x053162 -#define BTREEVERSION 3 - -/* Structure used to pass parameters to the btree routines. */ -typedef struct { -#define R_DUP 0x01 /* duplicate keys */ - u_long flags; - int cachesize; /* bytes to cache */ - int maxkeypage; /* maximum keys per page */ - int minkeypage; /* minimum keys per page */ - int psize; /* page size */ - /* comparison, prefix functions */ - int (*compare) __P((const DBT *, const DBT *)); - int (*prefix) __P((const DBT *, const DBT *)); - int lorder; /* byte order */ -} BTREEINFO; - -#define HASHMAGIC 0x061561 -#define HASHVERSION 2 - -/* Structure used to pass parameters to the hashing routines. */ -typedef struct { - int bsize; /* bucket size */ - int ffactor; /* fill factor */ - int nelem; /* number of elements */ - int cachesize; /* bytes to cache */ - /* hash function */ - int (*hash) __P((const void *, size_t)); - int lorder; /* byte order */ -} HASHINFO; - -/* Structure used to pass parameters to the record routines. */ -typedef struct { -#define R_FIXEDLEN 0x01 /* fixed-length records */ -#define R_NOKEY 0x02 /* key not required */ -#define R_SNAPSHOT 0x04 /* snapshot the input */ - u_long flags; - int cachesize; /* bytes to cache */ - int psize; /* page size */ - int lorder; /* byte order */ - size_t reclen; /* record length (fixed-length records) */ - u_char bval; /* delimiting byte (variable-length records */ - char *bfname; /* btree file name */ -} RECNOINFO; - -/* - * Little endian <==> big endian long swap macros. - * BLSWAP swap a memory location - * BLPSWAP swap a referenced memory location - * BLSWAP_COPY swap from one location to another - */ -#define BLSWAP(a) { \ - u_long _tmp = a; \ - ((char *)&a)[0] = ((char *)&_tmp)[3]; \ - ((char *)&a)[1] = ((char *)&_tmp)[2]; \ - ((char *)&a)[2] = ((char *)&_tmp)[1]; \ - ((char *)&a)[3] = ((char *)&_tmp)[0]; \ -} -#define BLPSWAP(a) { \ - u_long _tmp = *(u_long *)a; \ - ((char *)a)[0] = ((char *)&_tmp)[3]; \ - ((char *)a)[1] = ((char *)&_tmp)[2]; \ - ((char *)a)[2] = ((char *)&_tmp)[1]; \ - ((char *)a)[3] = ((char *)&_tmp)[0]; \ -} -#define BLSWAP_COPY(a, b) { \ - ((char *)&(b))[0] = ((char *)&(a))[3]; \ - ((char *)&(b))[1] = ((char *)&(a))[2]; \ - ((char *)&(b))[2] = ((char *)&(a))[1]; \ - ((char *)&(b))[3] = ((char *)&(a))[0]; \ -} - -/* - * Little endian <==> big endian short swap macros. - * BSSWAP swap a memory location - * BSPSWAP swap a referenced memory location - * BSSWAP_COPY swap from one location to another - */ -#define BSSWAP(a) { \ - u_short _tmp = a; \ - ((char *)&a)[0] = ((char *)&_tmp)[1]; \ - ((char *)&a)[1] = ((char *)&_tmp)[0]; \ -} -#define BSPSWAP(a) { \ - u_short _tmp = *(u_short *)a; \ - ((char *)a)[0] = ((char *)&_tmp)[1]; \ - ((char *)a)[1] = ((char *)&_tmp)[0]; \ -} -#define BSSWAP_COPY(a, b) { \ - ((char *)&(b))[0] = ((char *)&(a))[1]; \ - ((char *)&(b))[1] = ((char *)&(a))[0]; \ -} - -__BEGIN_DECLS -DB *dbopen __P((const char *, int, int, DBTYPE, const void *)); - -#ifdef __DBINTERFACE_PRIVATE -DB *__bt_open __P((const char *, int, int, const BTREEINFO *)); -DB *__hash_open __P((const char *, int, int, const HASHINFO *)); -DB *__rec_open __P((const char *, int, int, const RECNOINFO *)); -void __dbpanic __P((DB *dbp)); -#endif -__END_DECLS -#endif /* !_DB_H_ */ diff --git a/lib/libc/db/PORT/include/mpool.h b/lib/libc/db/PORT/include/mpool.h deleted file mode 100644 index 910e0782aa9d..000000000000 --- a/lib/libc/db/PORT/include/mpool.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mpool.h 8.1 (Berkeley) 6/2/93 - */ - -/* - * The memory pool scheme is a simple one. Each in memory page is referenced - * by a bucket which is threaded in three ways. All active pages are threaded - * on a hash chain (hashed by the page number) and an lru chain. Inactive - * pages are threaded on a free chain. Each reference to a memory pool is - * handed an MPOOL which is the opaque cookie passed to all of the memory - * routines. - */ -#define HASHSIZE 128 -#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE) - -/* The BKT structures are the elements of the lists. */ -typedef struct BKT { - struct BKT *hnext; /* next hash bucket */ - struct BKT *hprev; /* previous hash bucket */ - struct BKT *cnext; /* next free/lru bucket */ - struct BKT *cprev; /* previous free/lru bucket */ - void *page; /* page */ - pgno_t pgno; /* page number */ - -#define MPOOL_DIRTY 0x01 /* page needs to be written */ -#define MPOOL_PINNED 0x02 /* page is pinned into memory */ - unsigned long flags; /* flags */ -} BKT; - -/* The BKTHDR structures are the heads of the lists. */ -typedef struct BKTHDR { - struct BKT *hnext; /* next hash bucket */ - struct BKT *hprev; /* previous hash bucket */ - struct BKT *cnext; /* next free/lru bucket */ - struct BKT *cprev; /* previous free/lru bucket */ -} BKTHDR; - -typedef struct MPOOL { - BKTHDR free; /* The free list. */ - BKTHDR lru; /* The LRU list. */ - BKTHDR hashtable[HASHSIZE]; /* Hashed list by page number. */ - pgno_t curcache; /* Current number of cached pages. */ - pgno_t maxcache; /* Max number of cached pages. */ - pgno_t npages; /* Number of pages in the file. */ - u_long pagesize; /* File page size. */ - int fd; /* File descriptor. */ - /* Page in conversion routine. */ - void (*pgin) __P((void *, pgno_t, void *)); - /* Page out conversion routine. */ - void (*pgout) __P((void *, pgno_t, void *)); - void *pgcookie; /* Cookie for page in/out routines. */ -#ifdef STATISTICS - unsigned long cachehit; - unsigned long cachemiss; - unsigned long pagealloc; - unsigned long pageflush; - unsigned long pageget; - unsigned long pagenew; - unsigned long pageput; - unsigned long pageread; - unsigned long pagewrite; -#endif -} MPOOL; - -#ifdef __MPOOLINTERFACE_PRIVATE -/* Macros to insert/delete into/from hash chain. */ -#define rmhash(bp) { \ - (bp)->hprev->hnext = (bp)->hnext; \ - (bp)->hnext->hprev = (bp)->hprev; \ -} -#define inshash(bp, pg) { \ - hp = &mp->hashtable[HASHKEY(pg)]; \ - (bp)->hnext = hp->hnext; \ - (bp)->hprev = (struct BKT *)hp; \ - hp->hnext->hprev = (bp); \ - hp->hnext = (bp); \ -} - -/* Macros to insert/delete into/from lru and free chains. */ -#define rmchain(bp) { \ - (bp)->cprev->cnext = (bp)->cnext; \ - (bp)->cnext->cprev = (bp)->cprev; \ -} -#define inschain(bp, dp) { \ - (bp)->cnext = (dp)->cnext; \ - (bp)->cprev = (struct BKT *)(dp); \ - (dp)->cnext->cprev = (bp); \ - (dp)->cnext = (bp); \ -} -#endif - -__BEGIN_DECLS -MPOOL *mpool_open __P((DBT *, int, pgno_t, pgno_t)); -void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *), - void (*)(void *, pgno_t, void *), void *)); -void *mpool_new __P((MPOOL *, pgno_t *)); -void *mpool_get __P((MPOOL *, pgno_t, u_int)); -int mpool_put __P((MPOOL *, void *, u_int)); -int mpool_sync __P((MPOOL *)); -int mpool_close __P((MPOOL *)); -#ifdef STATISTICS -void mpool_stat __P((MPOOL *)); -#endif -__END_DECLS diff --git a/lib/libc/db/PORT/sys b/lib/libc/db/PORT/sys deleted file mode 120000 index 2996fba35632..000000000000 --- a/lib/libc/db/PORT/sys +++ /dev/null @@ -1 +0,0 @@ -include
\ No newline at end of file diff --git a/lib/libc/db/README b/lib/libc/db/README deleted file mode 120000 index 974cf28e0083..000000000000 --- a/lib/libc/db/README +++ /dev/null @@ -1 +0,0 @@ -VERSION
\ No newline at end of file diff --git a/lib/libc/db/VERSION b/lib/libc/db/VERSION index ceca0b2061bd..972d3517311a 100644 --- a/lib/libc/db/VERSION +++ b/lib/libc/db/VERSION @@ -1,6 +1,6 @@ -# @(#)VERSION 8.1 (Berkeley) 6/6/93 +# @(#)VERSION 8.8 (Berkeley) 12/19/93 -This is version 1.6 of the Berkeley DB code. +This is version 1.73 of the Berkeley DB code. If your version of the DB code doesn't have a copy of this version file, it's really old, please update it! @@ -8,16 +8,42 @@ this version file, it's really old, please update it! New versions of this software are periodically made available by anonymous ftp from ftp.cs.berkeley.edu, in the file ucb/4bsd/db.tar.Z, or from ftp.uu.net. +If you'd like to get announcements of future releases +of this software, send email to the contact address +below. Email questions may be addressed to Keith Bostic at bostic@cs.berkeley.edu. ============================================ -1.5 -> 1.6 06 Jun 1993 +1.72 -> 1.73 + btree: If enough duplicate records were inserted and then deleted + that internal pages had references to empty pages of the + duplicate keys, the search function ended up on the wrong + page. + +1.7 -> 1.72 12 Oct 1993 + hash: Support NET/2 hash formats. + +1.7 -> 1.71 16 Sep 1993 + btree/recno: + Fix bug in internal search routines that caused + return of invalid pointers. + +1.6 -> 1.7 07 Sep 1993 + hash: Fixed big key overflow bugs. + test: Portability hacks, rewrite test script, Makefile. + btree/recno: + Stop copying non-overflow key/data pairs. + PORT: Break PORT directory up into per architecture/OS + subdirectories. + +1.5 -> 1.6 06 Jun 1993 hash: In PAIRFITS, the first comparison should look at (P)[2]. The hash_realloc function was walking off the end of memory. The overflow page number was wrong when bumping splitpoint. -1.4 -> 1.5 23 May 1993 + +1.4 -> 1.5 23 May 1993 hash: Set hash default fill factor dynamically. recno: Fixed bug in sorted page splits. Add page size parameter support. @@ -30,16 +56,16 @@ bostic@cs.berkeley.edu. Change sync routines to take a flag argument, recno uses this to sync out the underlying btree. -1.3 -> 1.4 10 May 1993 +1.3 -> 1.4 10 May 1993 recno: Delete the R_CURSORLOG flag from the recno interface. Zero-length record fix for non-mmap reads. Try and make SIZE_T_MAX test in open portable. -1.2 -> 1.3 1 May 1993 +1.2 -> 1.3 01 May 1993 btree: Ignore user byte-order setting when reading already existing database. Fixes to byte-order conversions. -1.1 -> 1.2 15 Apr 1993 +1.1 -> 1.2 15 Apr 1993 No bug fixes, only compatibility hacks. ============================================ @@ -50,9 +76,9 @@ Distribution contents: VERSION This file. btree B+tree routines. db Dbopen(3) interface routine. - doc USENIX papers. + doc USENIX papers, formatted man pages. hash Extended linear hashing routines. - man Man pages. + man Unformatted man pages. mpool Memory pool routines. - recno Fixed/variable length routines. + recno Fixed/variable length record routines. test Test package. diff --git a/lib/libc/db/btree/bt_close.c b/lib/libc/db/btree/bt_close.c index 22c739b7b78b..5ff2adff9c8f 100644 --- a/lib/libc/db/btree/bt_close.c +++ b/lib/libc/db/btree/bt_close.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_close.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_close.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -69,6 +69,12 @@ __bt_close(dbp) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + /* * Delete any already deleted record that we've been saving * because the cursor pointed to it. @@ -114,13 +120,20 @@ __bt_sync(dbp, flags) PAGE *h; void *p; + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Sync doesn't currently take any flags. */ if (flags != 0) { errno = EINVAL; return (RET_ERROR); } - t = dbp->internal; - if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED)) return (RET_SUCCESS); diff --git a/lib/libc/db/btree/bt_delete.c b/lib/libc/db/btree/bt_delete.c index 326618b1f609..e512c8423da2 100644 --- a/lib/libc/db/btree/bt_delete.c +++ b/lib/libc/db/btree/bt_delete.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_delete.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_delete.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -70,10 +70,18 @@ __bt_delete(dbp, key, flags) int status; t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + if (ISSET(t, B_RDONLY)) { errno = EPERM; return (RET_ERROR); } + switch(flags) { case 0: status = bt_bdelete(t, key); diff --git a/lib/libc/db/btree/bt_get.c b/lib/libc/db/btree/bt_get.c index 4f473bc4f110..28b2d603dfe5 100644 --- a/lib/libc/db/btree/bt_get.c +++ b/lib/libc/db/btree/bt_get.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_get.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_get.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -70,11 +70,20 @@ __bt_get(dbp, key, data, flags) EPG *e; int exact, status; + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags. */ if (flags) { errno = EINVAL; return (RET_ERROR); } - t = dbp->internal; + if ((e = __bt_search(t, key, &exact)) == NULL) return (RET_ERROR); if (!exact) { @@ -99,7 +108,14 @@ __bt_get(dbp, key, data, flags) } status = __bt_ret(t, e, NULL, data); - mpool_put(t->bt_mp, e->page, 0); + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; return (status); } diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c index f918124042e8..feeffa4c6bf2 100644 --- a/lib/libc/db/btree/bt_open.c +++ b/lib/libc/db/btree/bt_open.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_open.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_open.c 8.3 (Berkeley) 9/16/93"; #endif /* LIBC_SCCS and not lint */ /* @@ -83,9 +83,9 @@ static int tmp __P((void)); * */ DB * -__bt_open(fname, flags, mode, openinfo) +__bt_open(fname, flags, mode, openinfo, dflags) const char *fname; - int flags, mode; + int flags, mode, dflags; const BTREEINFO *openinfo; { BTMETA m; @@ -156,19 +156,17 @@ __bt_open(fname, flags, mode, openinfo) /* Allocate and initialize DB and BTREE structures. */ if ((t = malloc(sizeof(BTREE))) == NULL) goto err; - t->bt_fd = -1; /* Don't close unopened fd on error. */ - if ((t->bt_dbp = dbp = malloc(sizeof(DB))) == NULL) - goto err; + memset(t, 0, sizeof(BTREE)); t->bt_bcursor.pgno = P_INVALID; - t->bt_bcursor.index = 0; - t->bt_stack = NULL; - t->bt_sp = t->bt_maxstack = 0; - t->bt_kbuf = t->bt_dbuf = NULL; - t->bt_kbufsz = t->bt_dbufsz = 0; + t->bt_fd = -1; /* Don't close unopened fd on error. */ t->bt_lorder = b.lorder; t->bt_order = NOT; t->bt_cmp = b.compare; t->bt_pfx = b.prefix; + t->bt_rfd = -1; + + if ((t->bt_dbp = dbp = malloc(sizeof(DB))) == NULL) + goto err; t->bt_flags = 0; if (t->bt_lorder != machine_lorder) SET(t, B_NEEDSWAP); @@ -199,8 +197,7 @@ __bt_open(fname, flags, mode, openinfo) goto einval; } - if ((t->bt_fd = - open(fname, flags & __USE_OPEN_FLAGS, mode)) < 0) + if ((t->bt_fd = open(fname, flags, mode)) < 0) goto err; } else { @@ -314,6 +311,14 @@ __bt_open(fname, flags, mode, openinfo) if (nroot(t) == RET_ERROR) goto err; + /* Global flags. */ + if (dflags & DB_LOCK) + SET(t, B_DB_LOCK); + if (dflags & DB_SHMEM) + SET(t, B_DB_SHMEM); + if (dflags & DB_TXN) + SET(t, B_DB_TXN); + return (dbp); einval: errno = EINVAL; @@ -420,6 +425,13 @@ __bt_fd(dbp) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* In-memory database can't have a file descriptor. */ if (ISSET(t, B_INMEM)) { errno = ENOENT; return (-1); diff --git a/lib/libc/db/btree/bt_put.c b/lib/libc/db/btree/bt_put.c index 2e0918b8f0d8..11a211b15a63 100644 --- a/lib/libc/db/btree/bt_put.c +++ b/lib/libc/db/btree/bt_put.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_put.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_put.c 8.3 (Berkeley) 9/16/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -82,6 +82,12 @@ __bt_put(dbp, key, data, flags) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + switch (flags) { case R_CURSOR: if (!ISSET(t, B_SEQINIT)) @@ -260,7 +266,6 @@ bt_fast(t, key, data, exactp) const DBT *key, *data; int *exactp; { - EPG e; PAGE *h; size_t nbytes; int cmp; @@ -269,8 +274,8 @@ bt_fast(t, key, data, exactp) t->bt_order = NOT; return (NULL); } - e.page = h; - e.index = t->bt_last.index; + t->bt_cur.page = h; + t->bt_cur.index = t->bt_last.index; /* * If won't fit in this page or have too many keys in this page, have @@ -281,19 +286,19 @@ bt_fast(t, key, data, exactp) goto miss; if (t->bt_order == FORWARD) { - if (e.page->nextpg != P_INVALID) + if (t->bt_cur.page->nextpg != P_INVALID) goto miss; - if (e.index != NEXTINDEX(h) - 1) + if (t->bt_cur.index != NEXTINDEX(h) - 1) goto miss; - if ((cmp = __bt_cmp(t, key, &e)) < 0) + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0) goto miss; - t->bt_last.index = cmp ? ++e.index : e.index; + t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index; } else { - if (e.page->prevpg != P_INVALID) + if (t->bt_cur.page->prevpg != P_INVALID) goto miss; - if (e.index != 0) + if (t->bt_cur.index != 0) goto miss; - if ((cmp = __bt_cmp(t, key, &e)) > 0) + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0) goto miss; t->bt_last.index = 0; } @@ -301,7 +306,7 @@ bt_fast(t, key, data, exactp) #ifdef STATISTICS ++bt_cache_hit; #endif - return (&e); + return (&t->bt_cur); miss: #ifdef STATISTICS diff --git a/lib/libc/db/btree/bt_search.c b/lib/libc/db/btree/bt_search.c index 06aba1126bda..a164173d0173 100644 --- a/lib/libc/db/btree/bt_search.c +++ b/lib/libc/db/btree/bt_search.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_search.c 8.4 (Berkeley) 12/10/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -45,6 +45,9 @@ static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93"; #include <db.h> #include "btree.h" +static int bt_snext __P((BTREE *, PAGE *, const DBT *, int *)); +static int bt_sprev __P((BTREE *, PAGE *, const DBT *, int *)); + /* * __BT_SEARCH -- Search a btree for a key. * @@ -54,12 +57,9 @@ static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93"; * exactp: pointer to exact match flag * * Returns: - * EPG for matching record, if any, or the EPG for the location of the - * key, if it were inserted into the tree. - * - * Warnings: - * The EPG returned is in static memory, and will be overwritten by the - * next search of any kind in any tree. + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * the bt_cur field of the tree. A pointer to the field is returned. */ EPG * __bt_search(t, key, exactp) @@ -67,11 +67,10 @@ __bt_search(t, key, exactp) const DBT *key; int *exactp; { - register indx_t index; - register int base, cmp, lim; - register PAGE *h; + PAGE *h, *n; + indx_t index; pgno_t pg; - static EPG e; + int base, cmp, lim; BT_CLR(t); for (pg = P_ROOT;;) { @@ -79,13 +78,13 @@ __bt_search(t, key, exactp) return (NULL); /* Do a binary search on the current page. */ - e.page = h; + t->bt_cur.page = h; for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) { - e.index = index = base + (lim >> 1); - if ((cmp = __bt_cmp(t, key, &e)) == 0) { + t->bt_cur.index = index = base + (lim >> 1); + if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) { if (h->flags & P_BLEAF) { *exactp = 1; - return (&e); + return (&t->bt_cur); } goto next; } @@ -95,11 +94,26 @@ __bt_search(t, key, exactp) } } - /* If it's a leaf page, we're done. */ + /* + * If it's a leaf page, and duplicates aren't allowed, we're + * done. If duplicates are allowed, it's possible that there + * were duplicate keys on duplicate pages, and they were later + * deleted, so we could be on a page with no matches while + * there are matches on other pages. If we're at the start or + * end of a page, check on both sides. + */ if (h->flags & P_BLEAF) { - e.index = base; + t->bt_cur.index = base; *exactp = 0; - return (&e); + if (!ISSET(t, B_NODUPS)) { + if (base == 0 && + bt_sprev(t, h, key, exactp)) + return (&t->bt_cur); + if (base == NEXTINDEX(h) && + bt_snext(t, h, key, exactp)) + return (&t->bt_cur); + } + return (&t->bt_cur); } /* @@ -117,3 +131,105 @@ next: if (__bt_push(t, h->pgno, index) == RET_ERROR) mpool_put(t->bt_mp, h, 0); } } + +/* + * BT_SNEXT -- Check for an exact match after the key. + * + * Parameters: + * t: tree to search + * h: current page. + * key: key to find + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +bt_snext(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + PAGE *tp; + pgno_t pg; + + /* Skip until reach the end of the tree or a key. */ + for (pg = h->nextpg; pg != P_INVALID;) { + if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) { + mpool_put(t->bt_mp, h, 0); + return (NULL); + } + if (NEXTINDEX(tp) != 0) + break; + pg = tp->prevpg; + mpool_put(t->bt_mp, tp, 0); + } + /* + * The key is either an exact match, or not as good as + * the one we already have. + */ + if (pg != P_INVALID) { + e.page = tp; + e.index = NEXTINDEX(tp) - 1; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + } + return (0); +} + +/* + * BT_SPREV -- Check for an exact match before the key. + * + * Parameters: + * t: tree to search + * h: current page. + * key: key to find + * exactp: pointer to exact match flag + * + * Returns: + * If an exact match found. + */ +static int +bt_sprev(t, h, key, exactp) + BTREE *t; + PAGE *h; + const DBT *key; + int *exactp; +{ + EPG e; + PAGE *tp; + pgno_t pg; + + /* Skip until reach the beginning of the tree or a key. */ + for (pg = h->prevpg; pg != P_INVALID;) { + if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) { + mpool_put(t->bt_mp, h, 0); + return (NULL); + } + if (NEXTINDEX(tp) != 0) + break; + pg = tp->prevpg; + mpool_put(t->bt_mp, tp, 0); + } + /* + * The key is either an exact match, or not as good as + * the one we already have. + */ + if (pg != P_INVALID) { + e.page = tp; + e.index = NEXTINDEX(tp) - 1; + if (__bt_cmp(t, key, &e) == 0) { + mpool_put(t->bt_mp, h, 0); + t->bt_cur = e; + *exactp = 1; + return (1); + } + } + return (0); +} diff --git a/lib/libc/db/btree/bt_seq.c b/lib/libc/db/btree/bt_seq.c index 03f8f09a2837..182ef7080d5e 100644 --- a/lib/libc/db/btree/bt_seq.c +++ b/lib/libc/db/btree/bt_seq.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_seq.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_seq.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -86,12 +86,19 @@ __bt_seq(dbp, key, data, flags) EPG e; int status; + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + /* * If scan unitialized as yet, or starting at a specific record, set * the scan to a specific key. Both bt_seqset and bt_seqadv pin the * page the cursor references if they're successful. */ - t = dbp->internal; switch(flags) { case R_NEXT: case R_PREV: @@ -116,7 +123,15 @@ __bt_seq(dbp, key, data, flags) /* Update the actual cursor. */ t->bt_bcursor.pgno = e.page->pgno; t->bt_bcursor.index = e.index; - mpool_put(t->bt_mp, e.page, 0); + + /* + * If the user is doing concurrent access, we copied the + * key/data, toss the page. + */ + if (ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e.page, 0); + else + t->bt_pinned = e.page; SET(t, B_SEQINIT); } return (status); diff --git a/lib/libc/db/btree/bt_utils.c b/lib/libc/db/btree/bt_utils.c index 452eb87e4253..ad8eb97a2f22 100644 --- a/lib/libc/db/btree/bt_utils.c +++ b/lib/libc/db/btree/bt_utils.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bt_utils.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)bt_utils.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -70,11 +70,17 @@ __bt_ret(t, e, key, data) bl = GETBLEAF(e->page, e->index); + /* + * We always copy big keys/data to make them contigous. Otherwise, + * we leave the page pinned and don't copy unless the user specified + * concurrent access. + */ if (bl->flags & P_BIGDATA) { if (__ovfl_get(t, bl->bytes + bl->ksize, &data->size, &t->bt_dbuf, &t->bt_dbufsz)) return (RET_ERROR); - } else { + data->data = t->bt_dbuf; + } else if (ISSET(t, B_DB_LOCK)) { /* Use +1 in case the first record retrieved is 0 length. */ if (bl->dsize + 1 > t->bt_dbufsz) { if ((p = realloc(t->bt_dbuf, bl->dsize + 1)) == NULL) @@ -84,8 +90,11 @@ __bt_ret(t, e, key, data) } memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize); data->size = bl->dsize; + data->data = t->bt_dbuf; + } else { + data->size = bl->dsize; + data->data = bl->bytes + bl->ksize; } - data->data = t->bt_dbuf; if (key == NULL) return (RET_SUCCESS); @@ -94,7 +103,8 @@ __bt_ret(t, e, key, data) if (__ovfl_get(t, bl->bytes, &key->size, &t->bt_kbuf, &t->bt_kbufsz)) return (RET_ERROR); - } else { + key->data = t->bt_kbuf; + } else if (ISSET(t, B_DB_LOCK)) { if (bl->ksize > t->bt_kbufsz) { if ((p = realloc(t->bt_kbuf, bl->ksize)) == NULL) return (RET_ERROR); @@ -103,8 +113,11 @@ __bt_ret(t, e, key, data) } memmove(t->bt_kbuf, bl->bytes, bl->ksize); key->size = bl->ksize; + key->data = t->bt_kbuf; + } else { + key->size = bl->ksize; + key->data = bl->bytes; } - key->data = t->bt_kbuf; return (RET_SUCCESS); } diff --git a/lib/libc/db/btree/btree.h b/lib/libc/db/btree/btree.h index 1e393236b09c..d32e52aa1741 100644 --- a/lib/libc/db/btree/btree.h +++ b/lib/libc/db/btree/btree.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)btree.h 8.1 (Berkeley) 6/4/93 + * @(#)btree.h 8.4 (Berkeley) 12/18/93 */ #include <mpool.h> @@ -59,7 +59,7 @@ * (ANSI C permits random padding.) If your compiler pads randomly you'll have * to do some work to get this package to run. */ -typedef struct PAGE { +typedef struct _page { pgno_t pgno; /* this page's page number */ pgno_t prevpg; /* left sibling */ pgno_t nextpg; /* right sibling */ @@ -111,7 +111,7 @@ typedef struct PAGE { * somewhat special and can cause duplicate internal and leaf page records and * some minor modifications of the above rule. */ -typedef struct BINTERNAL { +typedef struct _binternal { size_t ksize; /* key size */ pgno_t pgno; /* page number stored on */ #define P_BIGDATA 0x01 /* overflow data */ @@ -142,7 +142,7 @@ typedef struct BINTERNAL { * For the recno internal pages, the item is a page number with the number of * keys found on that page and below. */ -typedef struct RINTERNAL { +typedef struct _rinternal { recno_t nrecs; /* number of records */ pgno_t pgno; /* page number stored below */ } RINTERNAL; @@ -163,7 +163,7 @@ typedef struct RINTERNAL { } /* For the btree leaf pages, the item is a key and data pair. */ -typedef struct BLEAF { +typedef struct _bleaf { size_t ksize; /* size of key */ size_t dsize; /* size of data */ u_char flags; /* P_BIGDATA, P_BIGKEY */ @@ -196,7 +196,7 @@ typedef struct BLEAF { } /* For the recno leaf pages, the item is a data entry. */ -typedef struct RLEAF { +typedef struct _rleaf { size_t dsize; /* size of data */ u_char flags; /* P_BIGDATA */ char bytes[1]; @@ -238,12 +238,12 @@ typedef struct RLEAF { * duplicate keys make it impossible. This scheme does require extra work * though, to make sure that we don't perform an operation on a deleted key. */ -typedef struct EPGNO { +typedef struct _epgno { pgno_t pgno; /* the page number */ indx_t index; /* the index on the page */ } EPGNO; -typedef struct EPG { +typedef struct _epg { PAGE *page; /* the (pinned) page */ indx_t index; /* the index on the page */ } EPG; @@ -253,7 +253,7 @@ typedef struct EPG { * This is because the btree doesn't really need it and it requires that every * put or delete call modify the metadata. */ -typedef struct BTMETA { +typedef struct _btmeta { u_long m_magic; /* magic number */ u_long m_version; /* version */ u_long m_psize; /* page size */ @@ -265,11 +265,14 @@ typedef struct BTMETA { } BTMETA; /* The in-memory btree/recno data structure. */ -typedef struct BTREE { +typedef struct _btree { MPOOL *bt_mp; /* memory pool cookie */ DB *bt_dbp; /* pointer to enclosing DB */ + EPG bt_cur; /* current (pinned) page */ + PAGE *bt_pinned; /* page pinned across calls */ + EPGNO bt_bcursor; /* B: btree cursor */ recno_t bt_rcursor; /* R: recno cursor (1-based) */ @@ -291,7 +294,7 @@ typedef struct BTREE { indx_t bt_ovflsize; /* cut-off for key/data overflow */ int bt_lorder; /* byte order */ /* sorted order */ - enum { NOT, BACK, FORWARD, } bt_order; + enum { NOT, BACK, FORWARD } bt_order; EPGNO bt_last; /* last insert */ /* B: key comparison function */ @@ -299,7 +302,7 @@ typedef struct BTREE { /* B: prefix comparison function */ int (*bt_pfx) __P((const DBT *, const DBT *)); /* R: recno input function */ - int (*bt_irec) __P((struct BTREE *, recno_t)); + int (*bt_irec) __P((struct _btree *, recno_t)); FILE *bt_rfp; /* R: record FILE pointer */ int bt_rfd; /* R: record file descriptor */ @@ -324,17 +327,21 @@ typedef struct BTREE { #define B_NEEDSWAP 0x00010 /* if byte order requires swapping */ #define B_NODUPS 0x00020 /* no duplicate keys permitted */ #define B_RDONLY 0x00040 /* read-only tree */ +#define R_RECNO 0x00080 /* record oriented tree */ #define B_SEQINIT 0x00100 /* sequential scan initialized */ #define R_CLOSEFP 0x00200 /* opened a file pointer */ #define R_EOF 0x00400 /* end of input file reached. */ #define R_FIXLEN 0x00800 /* fixed length records */ #define R_MEMMAPPED 0x01000 /* memory mapped file. */ -#define R_RECNO 0x00080 /* record oriented tree */ #define R_INMEM 0x02000 /* in-memory file */ #define R_MODIFIED 0x04000 /* modified file */ #define R_RDONLY 0x08000 /* read-only file */ +#define B_DB_LOCK 0x10000 /* DB_LOCK specified. */ +#define B_DB_SHMEM 0x20000 /* DB_SHMEM specified. */ +#define B_DB_TXN 0x40000 /* DB_TXN specified. */ + u_long bt_flags; /* btree state */ } BTREE; diff --git a/lib/libc/db/btree/extern.h b/lib/libc/db/btree/extern.h index 99b6f31b73e8..bcb10535fccc 100644 --- a/lib/libc/db/btree/extern.h +++ b/lib/libc/db/btree/extern.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)extern.h 8.1 (Berkeley) 6/4/93 + * @(#)extern.h 8.2 (Berkeley) 9/7/93 */ int __bt_close __P((DB *)); @@ -45,7 +45,6 @@ EPG *__bt_first __P((BTREE *, const DBT *, int *)); int __bt_free __P((BTREE *, PAGE *)); int __bt_get __P((const DB *, const DBT *, DBT *, u_int)); PAGE *__bt_new __P((BTREE *, pgno_t *)); -DB *__bt_open __P((const char *, int, int, const BTREEINFO *)); void __bt_pgin __P((void *, pgno_t, void *)); void __bt_pgout __P((void *, pgno_t, void *)); int __bt_push __P((BTREE *, pgno_t, int)); diff --git a/lib/libc/db/db/db.c b/lib/libc/db/db/db.c index e31d48cef418..52e8a363036f 100644 --- a/lib/libc/db/db/db.c +++ b/lib/libc/db/db/db.c @@ -32,12 +32,13 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)db.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)db.c 8.3 (Berkeley) 9/13/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <errno.h> +#include <fcntl.h> #include <stddef.h> #include <stdio.h> @@ -51,14 +52,24 @@ dbopen(fname, flags, mode, type, openinfo) DBTYPE type; const void *openinfo; { - switch (type) { - case DB_BTREE: - return (__bt_open(fname, flags, mode, openinfo)); - case DB_HASH: - return (__hash_open(fname, flags, mode, openinfo)); - case DB_RECNO: - return (__rec_open(fname, flags, mode, openinfo)); - } + +#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN) +#define USE_OPEN_FLAGS \ + (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \ + O_RDWR | O_SHLOCK | O_TRUNC) + + if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0) + switch (type) { + case DB_BTREE: + return (__bt_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_HASH: + return (__hash_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + case DB_RECNO: + return (__rec_open(fname, flags & USE_OPEN_FLAGS, + mode, openinfo, flags & DB_FLAGS)); + } errno = EINVAL; return (NULL); } diff --git a/lib/libc/db/doc/btree.3.ps b/lib/libc/db/doc/btree.3.ps deleted file mode 100644 index 7ae6af965b44..000000000000 --- a/lib/libc/db/doc/btree.3.ps +++ /dev/null @@ -1,364 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.08 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Bold -%%+ font Times-Italic -%%DocumentSuppliedResources: procset grops 1.08 0 -%%Pages: 2 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.08 0 -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}bind def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/FL{ -currentgray exch setgray fill setgray -}bind def -/BL/fill load def -/LW/setlinewidth load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -}bind def -/PEND{ -clear -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE -/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 378.84(BTREE\(3\) BTREE\(3\))72 48 R/F1 9/Times-Bold@0 -SF -.18(NA)72 84 S(ME).18 E F0(btree \255 btree database access method)108 96 Q -F1(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q -(#include <db)108 136.8 Q(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 .198 -(The routine)108 165.6 R/F3 10/Times-Italic@0 SF(dbopen)2.698 E F0 .198 -(is the library interf)2.698 F .198(ace to database \214les.)-.1 F .198 -(One of the supported \214le formats is btree \214les.)5.198 F .974 -(The general description of the database access methods is in)108 177.6 R F3 -(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F -(the btree speci\214c information.)108 189.6 Q(The btree data structure is a s\ -orted, balanced tree structure storing associated k)108 206.4 Q -.15(ey)-.1 G -(/data pairs.).15 E .504(The btree access method speci\214c data structure pro) -108 223.2 R .504(vided to)-.15 F F3(dbopen)3.004 E F0 .503 -(is de\214ned in the <db)3.003 F .503(.h> include \214le as)-.4 F(follo)108 -235.2 Q(ws:)-.25 E(typedef struct {)108 252 Q(u_long \215ags;)144 264 Q -(u_int cachesize;)144 276 Q(inde)144 288 Q(x_t psize;)-.15 E(int lorder;)144 -300 Q(int mink)144 312 Q -.15(ey)-.1 G(page;).15 E -(int \(*compare\)\(const DBT *k)144 324 Q -.15(ey)-.1 G(1, const DBT *k).15 E --.15(ey)-.1 G(2\);).15 E(int \(*pre\214x\)\(const DBT *k)144 336 Q -.15(ey)-.1 -G(1, const DBT *k).15 E -.15(ey)-.1 G(2\);).15 E 2.5(}B)108 348 S(TREEINFO;) -121.97 348 Q(The elements of this structure are as follo)108 364.8 Q(ws:)-.25 E -14.61(\215ags The)108 381.6 R(\215ag v)2.5 E(alue is speci\214ed by)-.25 E F3 -(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5(ft)313.2 381.6 S(he follo)321.81 -381.6 Q(wing v)-.25 E(alues:)-.25 E(R_DUP)144 398.4 Q 1.296(Permit duplicate k) -180 410.4 R -.15(ey)-.1 G 3.796(si).15 G 3.796(nt)275.578 410.4 S 1.296 -(he tree, i.e. permit insertion if the k)287.154 410.4 R 1.596 -.15(ey t)-.1 H -3.796(ob).15 G 3.796(ei)466.878 410.4 S 1.296(nserted already)477.894 410.4 R --.15(ex)180 422.4 S 1.935(ists in the tree.).15 F 1.935(The def)6.935 F 1.935 -(ault beha)-.1 F(vior)-.2 E 4.435(,a)-.4 G 4.435(sd)358.215 422.4 S 1.935 -(escribed in)371.54 422.4 R F3(dbopen)4.435 E F0 1.935(\(3\), is to o).24 F --.15(ve)-.15 G 1.935(rwrite a).15 F .148(matching k)180 434.4 R .448 -.15(ey w) --.1 H .148(hen inserting a ne).15 F 2.649(wk)-.25 G .449 -.15(ey o)329.709 -434.4 T 2.649(rt).15 G 2.649(of)355.407 434.4 S .149(ail if the R_NOO)366.286 -434.4 R(VER)-.5 E .149(WRITE \215ag is speci-)-.55 F 5.972(\214ed. The)180 -446.4 R 3.472(R_DUP \215ag is o)5.972 F -.15(ve)-.15 G 3.472 -(rridden by the R_NOO).15 F(VER)-.5 E 3.471(WRITE \215ag, and if the)-.55 F -(R_NOO)180 458.4 Q(VER)-.5 E .781 -(WRITE \215ag is speci\214ed, attempts to insert duplicate k)-.55 F -.15(ey)-.1 -G 3.282(si).15 G .782(nto the tree will)474.604 458.4 R -.1(fa)180 470.4 S(il.) -.1 E 1.13(If the database contains duplicate k)180 487.2 R -.15(ey)-.1 G 1.129 -(s, the order of retrie).15 F -.25(va)-.25 G 3.629(lo).25 G 3.629(fk)439.644 -487.2 S -.15(ey)451.503 487.2 S 1.129(/data pairs is unde-).15 F .837 -(\214ned if the)180 499.2 R F3 -.1(ge)3.337 G(t).1 E F0 .837 -(routine is used, ho)3.337 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G F3(seq)3.737 -E F0 .838(routine calls with the R_CURSOR \215ag set)3.337 F(will al)180 511.2 -Q -.1(wa)-.1 G(ys return the logical `).1 E(`\214rst')-.74 E 2.5('o)-.74 G 2.5 -(fa)333.85 511.2 S .3 -.15(ny g)344.12 511.2 T(roup of duplicate k).15 E -.15 -(ey)-.1 G(s.).15 E(cachesize)108 528 Q 3.056(As)144 540 S .556 -(uggested maximum size \(in bytes\) of the memory cache.)158.166 540 R .555 -(This v)5.556 F .555(alue is)-.25 F F2(only)3.055 E F0(advisory)3.055 E 3.055 -(,a)-.65 G .555(nd the)514.725 540 R .759 -(access method will allocate more memory rather than f)144 552 R 3.259 -(ail. Since)-.1 F -2.15 -.25(ev e)3.259 H .76(ry search e).25 F .76 -(xamines the root)-.15 F .055 -(page of the tree, caching the most recently used pages substantially impro)144 -564 R -.15(ve)-.15 G 2.554(sa).15 G .054(ccess time.)459.578 564 R .054 -(In addi-)5.054 F .661(tion, ph)144 576 R .662(ysical writes are delayed as lo\ -ng as possible, so a moderate cache can reduce the number)-.05 F .601 -(of I/O operations signi\214cantly)144 588 R 5.601(.O)-.65 G -.15(bv)280.744 -588 S(iously).15 E 3.101(,u)-.65 G .601(sing a cache increases \(b)324.995 588 -R .6(ut only increases\) the lik)-.2 F(eli-)-.1 E .19(hood of corruption or lo\ -st data if the system crashes while a tree is being modi\214ed.)144 600 R(If) -5.191 E F3(cac)2.691 E(hesize)-.15 E F0(is)2.691 E 2.5(0\()144 612 S -(no size is speci\214ed\) a def)154.83 612 Q(ault cache is used.)-.1 E 12.95 -(psize P)108 628.8 R .45 -(age size is the size \(in bytes\) of the pages used for nodes in the tree.) --.15 F .449(The minimum page size is)5.449 F .442 -(512 bytes and the maximum page size is 64K.)144 640.8 R(If)5.442 E F3(psize) -2.942 E F0 .442(is 0 \(no page size is speci\214ed\) a page size)2.942 F -(is chosen based on the underlying \214le system I/O block size.)144 652.8 Q -9.62(lorder The)108 669.6 R 1.597(byte order for inte)4.097 F 1.596 -(gers in the stored database metadata.)-.15 F 1.596 -(The number should represent the)6.596 F .688(order as an inte)144 681.6 R .689 -(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 -(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689 -(is 0 \(no)3.189 F(order is speci\214ed\) the current host order is used.)144 -693.6 Q(1)535 768 Q EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 378.84(BTREE\(3\) BTREE\(3\))72 48 R(mink)108 84 Q -.15 -(ey)-.1 G(page).15 E 1.423(The minimum number of k)144 96 R -.15(ey)-.1 G 3.923 -(sw).15 G 1.422(hich will be stored on an)282.245 96 R 3.922(ys)-.15 G 1.422 -(ingle page.)400.618 96 R 1.422(This v)6.422 F 1.422(alue is used to)-.25 F -.257(determine which k)144 108 R -.15(ey)-.1 G 2.757(sw).15 G .257 -(ill be stored on o)242.001 108 R -.15(ve)-.15 G(r\215o).15 E 2.757(wp)-.25 G -.257(ages, i.e. if a k)348.006 108 R .558 -.15(ey o)-.1 H 2.758(rd).15 G .258 -(ata item is longer than the)435.11 108 R 1.102(pagesize di)144 120 R 1.102 -(vided by the mink)-.25 F -.15(ey)-.1 G 1.102(page v).15 F 1.102 -(alue, it will be stored on o)-.25 F -.15(ve)-.15 G(r\215o).15 E 3.602(wp)-.25 -G 1.102(ages instead of in the)451.164 120 R(page itself.)144 132 Q(If)5 E/F1 -10/Times-Italic@0 SF(mink)2.5 E -.3(ey)-.1 G(pa).3 E -.1(ge)-.1 G F0 -(is 0 \(no minimum number of k)2.6 E -.15(ey)-.1 G 2.5(si).15 G 2.5(ss)392.84 -132 S(peci\214ed\) a v)403.12 132 Q(alue of 2 is used.)-.25 E(compare)108 148.8 -Q .751(Compare is the k)144 160.8 R 1.051 -.15(ey c)-.1 H .751 -(omparison function.).15 F .751(It must return an inte)5.751 F .752 -(ger less than, equal to, or greater)-.15 F .913(than zero if the \214rst k)144 -172.8 R 1.213 -.15(ey a)-.1 H -.18(rg).15 G .913 -(ument is considered to be respecti).18 F -.15(ve)-.25 G .913 -(ly less than, equal to, or greater).15 F .352(than the second k)144 184.8 R -.652 -.15(ey a)-.1 H -.18(rg).15 G 2.852(ument. The).18 F .353 -(same comparison function must be used on a gi)2.852 F -.15(ve)-.25 G 2.853(nt) -.15 G .353(ree e)503.127 184.8 R -.15(ve)-.25 G(ry).15 E .817 -(time it is opened.)144 196.8 R(If)5.817 E F1(compar)3.317 E(e)-.37 E F0 .817 -(is NULL \(no comparison function is speci\214ed\), the k)3.317 F -.15(ey)-.1 G -3.316(sa).15 G .816(re com-)508.364 196.8 R(pared le)144 208.8 Q(xically)-.15 E -2.5(,w)-.65 G(ith shorter k)214.57 208.8 Q -.15(ey)-.1 G 2.5(sc).15 G -(onsidered less than longer k)282.92 208.8 Q -.15(ey)-.1 G(s.).15 E 10.17 -(pre\214x Pre\214x)108 225.6 R .291(is the pre\214x comparison function.)2.791 -F .292(If speci\214ed, this routine must return the number of bytes)5.291 F -.937(of the second k)144 237.6 R 1.237 -.15(ey a)-.1 H -.18(rg).15 G .937 -(ument which are necessary to determine that it is greater than the \214rst k) -.18 F -.15(ey)-.1 G(ar)144 249.6 Q 3.477(gument. If)-.18 F .977(the k)3.477 F --.15(ey)-.1 G 3.477(sa).15 G .977(re equal, the k)241.898 249.6 R 1.277 -.15 -(ey l)-.1 H .978(ength should be returned.).15 F .978 -(Note, the usefulness of this)5.978 F .558(routine is v)144 261.6 R .558 -(ery data dependent, b)-.15 F .558 -(ut, in some data sets can produce signi\214cantly reduced tree sizes)-.2 F -.354(and search times.)144 273.6 R(If)5.354 E F1(pr)2.854 E(e\214x)-.37 E F0 -.354(is NULL \(no pre\214x function is speci\214ed\),)2.854 F/F2 10 -/Times-Bold@0 SF(and)2.854 E F0 .354(no comparison function)2.854 F .193 -(is speci\214ed, a def)144 285.6 R .193(ault le)-.1 F .193 -(xical comparison routine is used.)-.15 F(If)5.192 E F1(pr)2.692 E(e\214x)-.37 -E F0 .192(is NULL and a comparison rou-)2.692 F -(tine is speci\214ed, no pre\214x comparison is done.)144 297.6 Q .79 -(If the \214le already e)108 314.4 R .79(xists \(and the O_TR)-.15 F .79 -(UNC \215ag is not speci\214ed\), the v)-.4 F .79 -(alues speci\214ed for the parameters)-.25 F -(\215ags, lorder and psize are ignored in f)108 326.4 Q -.2(avo)-.1 G 2.5(ro).2 -G 2.5(ft)284.4 326.4 S(he v)293.01 326.4 Q(alues used when the tree w)-.25 E -(as created.)-.1 E -.15(Fo)108 343.2 S(rw).15 E -(ard sequential scans of a tree are from the least k)-.1 E .3 -.15(ey t)-.1 H -2.5(ot).15 G(he greatest.)348.55 343.2 Q 1.043(Space freed up by deleting k)108 -360 R -.15(ey)-.1 G 1.043(/data pairs from the tree is ne).15 F -.15(ve)-.25 G -3.543(rr).15 G 1.043(eclaimed, although it is normally made)378.686 360 R -.2 -(av)108 372 S 1.394(ailable for reuse.)-.05 F 1.394 -(This means that the btree storage structure is gro)6.394 F(w-only)-.25 E 6.395 -(.T)-.65 G 1.395(he only solutions are to)441.09 372 R -.2(avo)108 384 S(id e) -.2 E(xcessi)-.15 E .3 -.15(ve d)-.25 H -(eletions, or to create a fresh tree periodically from a scan of an e).15 E -(xisting one.)-.15 E .344(Searches, insertions, and deletions in a btree will \ -all complete in O lg base N where base is the a)108 400.8 R -.15(ve)-.2 G .343 -(rage \214ll).15 F -.1(fa)108 412.8 S(ctor).1 E 5.798(.O)-.55 G .799 -(ften, inserting ordered data into btrees results in a lo)146.188 412.8 R 3.299 -<778c>-.25 G .799(ll f)377.505 412.8 R(actor)-.1 E 5.799(.T)-.55 G .799 -(his implementation has been)423.443 412.8 R(modi\214ed to mak)108 424.8 Q 2.5 -(eo)-.1 G(rdered insertion the best case, resulting in a much better than norm\ -al page \214ll f)185.4 424.8 Q(actor)-.1 E(.)-.55 E/F3 9/Times-Bold@0 SF -(SEE ALSO)72 441.6 Q F1(dbopen)108 453.6 Q F0(\(3\),).24 E F1(hash)2.5 E F0 -(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 -.37(re)2.5 G(cno).37 E F0 -(\(3\)).18 E F1(The Ubiquitous B-tr)108 477.6 Q(ee)-.37 E F0 2.5(,D).18 G -(ouglas Comer)209.47 477.6 Q 2.5(,A)-.4 G(CM Comput. Surv)276.72 477.6 Q 2.5 -(.1)-.65 G(1, 2 \(June 1979\), 121-138.)360.25 477.6 Q F1(Pr)108 501.6 Q 1.588 -(e\214x B-tr)-.37 F(ees)-.37 E F0 4.088(,B).27 G 1.587(ayer and Unterauer) -177.636 501.6 R 4.087(,A)-.4 G 1.587(CM T)270.447 501.6 R 1.587 -(ransactions on Database Systems, V)-.35 F 1.587(ol. 2, 1 \(March 1977\),)-1.29 -F(11-26.)108 513.6 Q F1(The Art of Computer Pr)108 537.6 Q -.1(og)-.45 G -.15 -(ra).1 G(mming V).15 E(ol. 3: Sorting and Sear)-1.11 E -.15(ch)-.37 G(ing).15 E -F0 2.5(,D).22 G(.E. Knuth, 1968, pp 471-480.)382 537.6 Q F3 -.09(BU)72 554.4 S -(GS).09 E F0(Only big and little endian byte order is supported.)108 566.4 Q(2) -535 768 Q EP -%%Trailer -end -%%EOF diff --git a/lib/libc/db/doc/dbopen.3.ps b/lib/libc/db/doc/dbopen.3.ps deleted file mode 100644 index 872c82e771c9..000000000000 --- a/lib/libc/db/doc/dbopen.3.ps +++ /dev/null @@ -1,496 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.08 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Bold -%%+ font Times-Italic -%%DocumentSuppliedResources: procset grops 1.08 0 -%%Pages: 4 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.08 0 -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}bind def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/FL{ -currentgray exch setgray fill setgray -}bind def -/BL/fill load def -/LW/setlinewidth load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -}bind def -/PEND{ -clear -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE -/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R/F1 9 -/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0 -(dbopen \255 database access methods)108 96 Q F1(SYNOPSIS)72 112.8 Q/F2 10 -/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <limits.h>)108 -136.8 Q(#include <db)108 148.8 Q(.h>)-.4 E(DB *)108 172.8 Q -(dbopen\(const char *\214le, int \215ags, int mode, DBTYPE type,)108 184.8 Q -(const v)158 196.8 Q(oid *openinf)-.1 E(o\);)-.25 E F1(DESCRIPTION)72 213.6 Q -/F3 10/Times-Italic@0 SF(Dbopen)108 225.6 Q F0 .032(is the library interf)2.532 -F .031(ace to database \214les.)-.1 F .031 -(The supported \214le formats are btree, hashed and UNIX \214le)5.031 F 2.82 -(oriented. The)108 237.6 R .32 -(btree format is a representation of a sorted, balanced tree structure.)2.82 F -.321(The hashed format is an)5.321 F -.15(ex)108 249.6 S .424 -(tensible, dynamic hashing scheme.).15 F .423 -(The \215at-\214le format is a byte stream \214le with \214x)5.423 F .423 -(ed or v)-.15 F .423(ariable length)-.25 F 2.906(records. The)108 261.6 R .407 -(formats and \214le format speci\214c information are described in detail in t\ -heir respecti)2.906 F .707 -.15(ve m)-.25 H(anual).15 E(pages)108 273.6 Q F3 -(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F3(hash)2.5 E F0(\(3\) and).28 E F3 -.37 -(re)2.5 G(cno).37 E F0(\(3\).).18 E .433(Dbopen opens)108 290.4 R F3(\214le) -2.933 E F0 .433(for reading and/or writing.)2.933 F .433(Files ne)5.433 F -.15 -(ve)-.25 G 2.933(ri).15 G .433(ntended to be preserv)346.737 290.4 R .433 -(ed on disk may be created)-.15 F(by setting the \214le parameter to NULL.)108 -302.4 Q(The)108 319.2 Q F3<8d61>4.661 E(gs)-.1 E F0(and)4.661 E F3 2.161 -(mode ar)4.661 F(guments)-.37 E F0 2.161(are as speci\214ed to the)4.661 F F3 -(open)4.661 E F0 2.162(\(2\) routine, ho).24 F(we)-.25 E -.15(ve)-.25 G 2.962 --.4(r, o).15 H 2.162(nly the O_CREA).4 F -.74(T,)-1.11 G 2.597 -(O_EXCL, O_EXLOCK, O_RDONL)108 331.2 R 5.177 -1.29(Y, O)-1 H(_RD)1.29 E 2.597 -(WR, O_SHLOCK and O_TR)-.3 F 2.596(UNC \215ags are meaningful.)-.4 F -(\(Note, opening a database \214le O_WR)108 343.2 Q(ONL)-.4 E 2.5(Yi)-1 G 2.5 -(sn)289.62 343.2 S(ot possible.\))301.01 343.2 Q(The)108 360 Q F3(type)5.337 E -F0(ar)5.337 E 2.837(gument is of type DBTYPE \(as de\214ned in the <db)-.18 F -2.838(.h> include \214le\) and may be set to)-.4 F -(DB_BTREE, DB_HASH or DB_RECNO.)108 372 Q(The)108 388.8 Q F3(openinfo)2.85 E F0 -(ar)2.85 E .349(gument is a pointer to an access method speci\214c structure d\ -escribed in the access method')-.18 F(s)-.55 E .03(manual page.)108 400.8 R(If) -5.03 E F3(openinfo)2.53 E F0 .031(is NULL, each access method will use def)2.53 -F .031(aults appropriate for the system and the)-.1 F(access method.)108 412.8 -Q F3(Dbopen)108 429.6 Q F0 .416 -(returns a pointer to a DB structure on success and NULL on error)2.917 F 5.416 -(.T)-.55 G .416(he DB structure is de\214ned in)423.21 429.6 R(the <db)108 -441.6 Q(.h> include \214le, and contains at least the follo)-.4 E -(wing \214elds:)-.25 E(typedef struct {)108 465.6 Q(DBTYPE type;)144 477.6 Q -(int \(*close\)\(const DB *db\);)144 489.6 Q -(int \(*del\)\(const DB *db, const DBT *k)144 501.6 Q -.15(ey)-.1 G 2.5(,u)-.5 -G(_int \215ags\);)318.92 501.6 Q(int \(*fd\)\(const DB *db\);)144 513.6 Q -(int \(*get\)\(const DB *db, DBT *k)144 525.6 Q -.15(ey)-.1 G 2.5(,D)-.5 G -(BT *data, u_int \215ags\);)297.53 525.6 Q(int \(*put\)\(const DB *db, DBT *k) -144 537.6 Q -.15(ey)-.1 G 2.5(,c)-.5 G(onst DBT *data,)295.31 537.6 Q -(u_int \215ags\);)194 549.6 Q(int \(*sync\)\(const DB *db, u_int \215ags\);)144 -561.6 Q(int \(*seq\)\(const DB *db, DBT *k)144 573.6 Q -.15(ey)-.1 G 2.5(,D)-.5 -G(BT *data, u_int \215ags\);)298.64 573.6 Q 2.5(}D)108 585.6 S(B;)122.52 585.6 -Q .101 -(These elements describe a database type and a set of functions performing v) -108 602.4 R .101(arious actions.)-.25 F .101(These functions)5.101 F(tak)108 -614.4 Q 3.039(eap)-.1 G .539(ointer to a structure as returned by)140.078 614.4 -R F3(dbopen)3.038 E F0 3.038(,a).24 G .538 -(nd sometimes one or more pointers to k)323.196 614.4 R -.15(ey)-.1 G .538 -(/data struc-).15 F(tures and a \215ag v)108 626.4 Q(alue.)-.25 E 16.28 -(type The)108 643.2 R -(type of the underlying access method \(and \214le format\).)2.5 E 12.95 -(close A)108 660 R .988(pointer to a routine to \215ush an)3.488 F 3.489(yc) --.15 G .989(ached information to disk, free an)293.968 660 R 3.489(ya)-.15 G -.989(llocated resources, and)446.662 660 R .112 -(close the underlying \214le\(s\).)144 672 R .111(Since k)5.112 F -.15(ey)-.1 G -.111(/data pairs may be cached in memory).15 F 2.611(,f)-.65 G .111 -(ailing to sync the \214le)455.666 672 R .494(with a)144 684 R F3(close)2.994 E -F0(or)2.994 E F3(sync)2.994 E F0 .495 -(function may result in inconsistent or lost information.)2.994 F F3(Close) -5.495 E F0 .495(routines return)2.995 F(-1 on error \(setting)144 696 Q F3 -(errno)2.5 E F0 2.5(\)a).18 G(nd 0 on success.)254.43 696 Q 21.28(del A)108 -712.8 R(pointer to a routine to remo)2.5 E .3 -.15(ve k)-.15 H -.15(ey).05 G -(/data pairs from the database.).15 E 209.835(24, May)72 768 R(1)535 768 Q EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R -(The parameter)144 84 Q/F1 10/Times-Italic@0 SF<8d61>2.5 E(g)-.1 E F0 -(may be set to the follo)2.5 E(wing v)-.25 E(alue:)-.25 E(R_CURSOR)144 100.8 Q -.289(Delete the record referenced by the cursor)180 112.8 R 5.288(.T)-.55 G -.288(he cursor must ha)363.342 112.8 R .588 -.15(ve p)-.2 H(re).15 E .288 -(viously been initial-)-.25 F(ized.)180 124.8 Q F1(Delete)144 141.6 Q F0 .03 -(routines return -1 on error \(setting)2.53 F F1(errno)2.53 E F0 .03 -(\), 0 on success, and 1 if the speci\214ed).18 F F1 -.1(ke)2.53 G(y)-.2 E F0 --.1(wa)2.53 G 2.53(sn).1 G .03(ot in)521.91 141.6 R(the \214le.)144 153.6 Q -25.17(fd A)108 170.4 R .451 -(pointer to a routine which returns a \214le descriptor representati)2.951 F -.75 -.15(ve o)-.25 H 2.95(ft).15 G .45(he underlying database.)431.73 170.4 R -(A)5.45 E .942(\214le descriptor referencing the same \214le will be returned \ -to all processes which call)144 182.4 R F1(dbopen)3.442 E F0(with)3.442 E 1.629 -(the same)144 194.4 R F1(\214le)4.129 E F0 4.129(name. This)4.129 F 1.628 -(\214le descriptor may be safely used as a ar)4.128 F 1.628(gument to the)-.18 -F F1(fcntl)4.128 E F0 1.628(\(2\) and).51 F F1(\215oc)144 206.4 Q(k)-.2 E F0 -.425(\(2\) locking functions.).67 F .425 -(The \214le descriptor is not necessarily associated with an)5.425 F 2.925(yo) --.15 G 2.925(ft)492.7 206.4 S .425(he under)501.735 206.4 R(-)-.2 E .198 -(lying \214les used by the access method.)144 218.4 R .198 -(No \214le descriptor is a)5.198 F -.25(va)-.2 G .198 -(ilable for in memory databases.).25 F F1(Fd)5.198 E F0 -(routines return -1 on error \(setting)144 230.4 Q F1(errno)2.5 E F0 -(\), and the \214le descriptor on success.).18 E 21.28(get A)108 247.2 R -(pointer to a routine which is the interf)2.5 E .001(ace for k)-.1 F -.15(ey) --.1 G .001(ed retrie).15 F -.25(va)-.25 G 2.501(lf).25 G .001 -(rom the database.)399.755 247.2 R .001(The address and)5.001 F .061 -(length of the data associated with the speci\214ed)144 259.2 R F1 -.1(ke)2.561 -G(y)-.2 E F0 .06(are returned in the structure referenced by)2.561 F F1(data) -2.56 E F0(.).26 E F1(Get)144 271.2 Q F0(routines return -1 on error \(setting) -2.5 E F1(errno)2.5 E F0(\), 0 on success, and 1 if the).18 E F1 -.1(ke)2.5 G(y) --.2 E F0 -.1(wa)2.5 G 2.5(sn).1 G(ot in the \214le.)471.66 271.2 Q 20.72(put A) -108 288 R(pointer to a routine to store k)2.5 E -.15(ey)-.1 G -(/data pairs in the database.).15 E(The parameter)144 304.8 Q F1<8d61>2.5 E(g) --.1 E F0(may be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E -(R_CURSOR)144 321.6 Q .051(Replace the k)180 333.6 R -.15(ey)-.1 G .051 -(/data pair referenced by the cursor).15 F 5.052(.T)-.55 G .052 -(he cursor must ha)393.98 333.6 R .352 -.15(ve p)-.2 H(re).15 E .052 -(viously been)-.25 F(initialized.)180 345.6 Q(R_IAFTER)144 362.4 Q 1.165 -(Append the data immediately after the data referenced by)180 374.4 R F1 -.1 -(ke)3.664 G(y)-.2 E F0 3.664(,c).32 G 1.164(reating a ne)446.758 374.4 R 3.664 -(wk)-.25 G -.15(ey)511.27 374.4 S(/data).15 E(pair)180 386.4 Q 6.065(.T)-.55 G -1.065(he record number of the appended k)209.675 386.4 R -.15(ey)-.1 G 1.065 -(/data pair is returned in the).15 F F1 -.1(ke)3.565 G(y)-.2 E F0(structure.) -3.565 E(\(Applicable only to the DB_RECNO access method.\))180 398.4 Q -(R_IBEFORE)144 415.2 Q 1.293 -(Insert the data immediately before the data referenced by)180 427.2 R F1 -.1 -(ke)3.793 G(y)-.2 E F0 3.793(,c).32 G 1.293(reating a ne)446.371 427.2 R 3.793 -(wk)-.25 G -.15(ey)511.27 427.2 S(/data).15 E(pair)180 439.2 Q 6.54(.T)-.55 G -1.54(he record number of the inserted k)210.15 439.2 R -.15(ey)-.1 G 1.541 -(/data pair is returned in the).15 F F1 -.1(ke)4.041 G(y)-.2 E F0(structure.) -4.041 E(\(Applicable only to the DB_RECNO access method.\))180 451.2 Q(R_NOO) -144 468 Q(VER)-.5 E(WRITE)-.55 E(Enter the ne)180 480 Q 2.5(wk)-.25 G -.15(ey) -242.69 480 S(/data pair only if the k).15 E .3 -.15(ey d)-.1 H(oes not pre).15 -E(viously e)-.25 E(xist.)-.15 E(R_SETCURSOR)144 496.8 Q 1.36(Store the k)180 -508.8 R -.15(ey)-.1 G 1.36(/data pair).15 F 3.86(,s)-.4 G 1.359 -(etting or initializing the position of the cursor to reference it.)283.94 -508.8 R(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))180 -520.8 Q .563(R_SETCURSOR is a)144 537.6 R -.25(va)-.2 G .564 -(ilable only for the DB_BTREE and DB_RECNO access methods because).25 F -(it implies that the k)144 549.6 Q -.15(ey)-.1 G 2.5(sh).15 G -2.25 -.2(av e) -241.81 549.6 T(an inherent order which does not change.)2.7 E .416 -(R_IAFTER and R_IBEFORE are a)144 566.4 R -.25(va)-.2 G .416 -(ilable only for the DB_RECNO access method because the).25 F(y)-.15 E 1.221 -(each imply that the access method is able to create ne)144 578.4 R 3.722(wk) --.25 G -.15(ey)385.644 578.4 S 3.722(s. This).15 F 1.222(is only true if the k) -3.722 F -.15(ey)-.1 G 3.722(sa).15 G(re)532.23 578.4 Q -(ordered and independent, record numbers for e)144 590.4 Q(xample.)-.15 E .289 -(The def)144 607.2 R .289(ault beha)-.1 F .289(vior of the)-.2 F F1(put)2.789 E -F0 .289(routines is to enter the ne)2.789 F 2.789(wk)-.25 G -.15(ey)388.998 -607.2 S .288(/data pair).15 F 2.788(,r)-.4 G .288(eplacing an)444.284 607.2 R -2.788(yp)-.15 G(re)503.03 607.2 Q(viously)-.25 E -.15(ex)144 619.2 S(isting k) -.15 E -.15(ey)-.1 G(.)-.5 E F1(Put)144 636 Q F0 .37 -(routines return -1 on error \(setting)2.87 F F1(errno)2.87 E F0 .37 -(\), 0 on success, and 1 if the R_NOO).18 F(VER)-.5 E(WRITE)-.55 E F1<8d61>2.87 -E(g)-.1 E F0 -.1(wa)144 648 S 2.5(ss).1 G(et and the k)165.84 648 Q .3 -.15 -(ey a)-.1 H(lready e).15 E(xists in the \214le.)-.15 E 20.17(seq A)108 664.8 R -.002(pointer to a routine which is the interf)2.502 F .002 -(ace for sequential retrie)-.1 F -.25(va)-.25 G 2.502(lf).25 G .002 -(rom the database.)416.694 664.8 R .001(The address)5.001 F .219 -(and length of the k)144 676.8 R .519 -.15(ey a)-.1 H .219 -(re returned in the structure referenced by).15 F F1 -.1(ke)2.72 G(y)-.2 E F0 -2.72(,a).32 G .22(nd the address and length of)426.42 676.8 R -(the data are returned in the structure referenced by)144 688.8 Q F1(data)2.5 E -F0(.).26 E .937(Sequential k)144 705.6 R -.15(ey)-.1 G .937(/data pair retrie) -.15 F -.25(va)-.25 G 3.437(lm).25 G .936(ay be)289.748 705.6 R .936(gin at an) --.15 F 3.436(yt)-.15 G .936(ime, and the position of the `)359.292 705.6 R -(`cursor')-.74 E 3.436('i)-.74 G 3.436(sn)519.894 705.6 S(ot)532.22 705.6 Q(af) -144 717.6 Q 1.585(fected by calls to the)-.25 F F1(del)4.085 E F0(,).51 E F1 --.1(ge)4.085 G(t).1 E F0(,).68 E F1(put)4.086 E F0 4.086(,o).68 G(r)308.452 -717.6 Q F1(sync)4.086 E F0 4.086(routines. Modi\214cations)4.086 F 1.586 -(to the database during a)4.086 F 1.404(sequential scan will be re\215ected in\ - the scan, i.e. records inserted behind the cursor will not be)144 729.6 R -209.835(24, May)72 768 R(2)535 768 Q EP -%%Page: 3 3 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R -(returned while records inserted in front of the cursor will be returned.)144 -84 Q(The \215ag v)144 100.8 Q(alue)-.25 E/F1 10/Times-Bold@0 SF(must)2.5 E F0 -(be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E(R_CURSOR)144 -117.6 Q .523(The data associated with the speci\214ed k)180 129.6 R .824 -.15 -(ey i)-.1 H 3.024(sr).15 G 3.024(eturned. This)367.236 129.6 R(dif)3.024 E .524 -(fers from the)-.25 F/F2 10/Times-Italic@0 SF -.1(ge)3.024 G(t).1 E F0 -(routines)3.024 E 1.143 -(in that it sets or initializes the cursor to the location of the k)180 141.6 R -1.443 -.15(ey a)-.1 H 3.642(sw).15 G 3.642(ell. \(Note,)464.924 141.6 R 1.142 -(for the)3.642 F 1.275(DB_BTREE access method, the returned k)180 153.6 R 1.575 --.15(ey i)-.1 H 3.775(sn).15 G 1.276(ot necessarily an e)386.425 153.6 R 1.276 -(xact match for the)-.15 F .598(speci\214ed k)180 165.6 R -.15(ey)-.1 G 5.598 -(.T)-.5 G .598(he returned k)246.396 165.6 R .898 -.15(ey i)-.1 H 3.098(st).15 -G .598(he smallest k)325.188 165.6 R .898 -.15(ey g)-.1 H .598 -(reater than or equal to the speci\214ed).15 F -.1(ke)180 177.6 S 1.3 -.65 -(y, p)-.05 H(ermitting partial k).65 E .3 -.15(ey m)-.1 H -(atches and range searches.\)).15 E(R_FIRST)144 194.4 Q 1.043(The \214rst k)180 -206.4 R -.15(ey)-.1 G 1.044(/data pair of the database is returned, and the cu\ -rsor is set or initialized to).15 F(reference it.)180 218.4 Q(R_LAST)144 235.2 -Q .085(The last k)180 247.2 R -.15(ey)-.1 G .085(/data pair of the database is\ - returned, and the cursor is set or initialized to ref-).15 F(erence it.)180 -259.2 Q(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))5 E -(R_NEXT)144 276 Q(Retrie)180 288 Q .604 -.15(ve t)-.25 H .304(he k).15 F -.15 -(ey)-.1 G .304(/data pair immediately after the cursor).15 F 5.304(.I)-.55 G -2.804(ft)410.622 288 S .305(he cursor is not yet set, this is)419.536 288 R -(the same as the R_FIRST \215ag.)180 300 Q(R_PREV)144 316.8 Q(Retrie)180 328.8 -Q .755 -.15(ve t)-.25 H .455(he k).15 F -.15(ey)-.1 G .455 -(/data pair immediately before the cursor).15 F 5.455(.I)-.55 G 2.955(ft)419.05 -328.8 S .454(he cursor is not yet set, this)428.115 328.8 R .62 -(is the same as the R_LAST \215ag.)180 340.8 R .621 -(\(Applicable only to the DB_BTREE and DB_RECNO)5.621 F(access methods.\))180 -352.8 Q .911(R_LAST and R_PREV are a)144 369.6 R -.25(va)-.2 G .911 -(ilable only for the DB_BTREE and DB_RECNO access methods).25 F(because the)144 -381.6 Q 2.5(ye)-.15 G(ach imply that the k)202.16 381.6 Q -.15(ey)-.1 G 2.5(sh) -.15 G -2.25 -.2(av e)302.18 381.6 T(an inherent order which does not change.) -2.7 E F2(Seq)144 398.4 Q F0 .061(routines return -1 on error \(setting)2.561 F -F2(errno)2.561 E F0 .061(\), 0 on success and 1 if there are no k).18 F -.15 -(ey)-.1 G .061(/data pairs less).15 F .35 -(than or greater than the speci\214ed or current k)144 410.4 R -.15(ey)-.1 G -5.349(.I)-.5 G 2.849(ft)346.467 410.4 S .349 -(he DB_RECNO access method is being used,)355.426 410.4 R .025 -(and if the database \214le is a character special \214le and no complete k)144 -422.4 R -.15(ey)-.1 G .025(/data pairs are currently a).15 F -.25(va)-.2 G(il-) -.25 E(able, the)144 434.4 Q F2(seq)2.5 E F0(routines return 2.)2.5 E 15.17 -(sync A)108 451.2 R .458(pointer to a routine to \215ush an)2.958 F 2.957(yc) --.15 G .457(ached information to disk.)289.72 451.2 R .457 -(If the database is in memory only)5.457 F(,)-.65 E(the)144 463.2 Q F2(sync)2.5 -E F0(routine has no ef)2.5 E(fect and will al)-.25 E -.1(wa)-.1 G(ys succeed.) -.1 E(The \215ag v)144 480 Q(alue may be set to the follo)-.25 E(wing v)-.25 E -(alue:)-.25 E(R_RECNOSYNC)144 496.8 Q .077(If the DB_RECNO access method is be\ -ing used, this \215ag causes the sync routine to apply)180 508.8 R .75(to the \ -btree \214le which underlies the recno \214le, not the recno \214le itself.)180 -520.8 R .75(\(See the)5.75 F F2(bfname)3.25 E F0(\214eld of the)180 532.8 Q F2 --.37(re)2.5 G(cno).37 E F0(\(3\) manual page for more information.\)).18 E F2 -(Sync)144 549.6 Q F0(routines return -1 on error \(setting)2.5 E F2(errno)2.5 E -F0 2.5(\)a).18 G(nd 0 on success.)336.91 549.6 Q/F3 9/Times-Bold@0 SF(KEY/D)72 -566.4 Q -1.35 -.855(AT A)-.315 H -.666(PA)3.105 G(IRS).666 E F0 .134 -(Access to all \214le types is based on k)108 578.4 R -.15(ey)-.1 G .134 -(/data pairs.).15 F .134(Both k)5.134 F -.15(ey)-.1 G 2.634(sa).15 G .134 -(nd data are represented by the follo)359.078 578.4 R .135(wing data)-.25 F -(structure:)108 590.4 Q(typedef struct {)108 607.2 Q -.2(vo)144 619.2 S -(id *data;).2 E(size_t size;)144 631.2 Q 2.5(}D)108 643.2 S(BT)122.52 643.2 Q -(;)-.55 E(The elements of the DBT structure are de\214ned as follo)108 660 Q -(ws:)-.25 E 16.84(data A)108 676.8 R(pointer to a byte string.)2.5 E 17.95 -(size The)108 693.6 R(length of the byte string.)2.5 E -2.15 -.25(Ke y)108 -710.4 T .829(and data byte strings may reference strings of essentially unlimi\ -ted length although an)3.579 F 3.328(yt)-.15 G 1.028 -.1(wo o)492.894 710.4 T -3.328(ft).1 G(hem)522.78 710.4 Q 1.133(must \214t into a)108 722.4 R -.25(va) --.2 G 1.134(ilable memory at the same time.).25 F 1.134 -(It should be noted that the access methods pro)6.134 F 1.134(vide no)-.15 F -209.835(24, May)72 768 R(3)535 768 Q EP -%%Page: 4 4 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R -(guarantees about byte string alignment.)108 84 Q/F1 9/Times-Bold@0 SF(ERR)72 -100.8 Q(ORS)-.27 E F0(The)108 112.8 Q/F2 10/Times-Italic@0 SF(dbopen)3.389 E F0 -.889(routine may f)3.389 F .889(ail and set)-.1 F F2(errno)3.388 E F0 .888 -(for an)3.388 F 3.388(yo)-.15 G 3.388(ft)324.376 112.8 S .888 -(he errors speci\214ed for the library routines)333.874 112.8 R F2(open)3.388 E -F0(\(2\)).24 E(and)108 124.8 Q F2(malloc)2.5 E F0(\(3\) or the follo).31 E -(wing:)-.25 E([EFTYPE])108 141.6 Q 2.5<418c>144 153.6 S -(le is incorrectly formatted.)159.28 153.6 Q([EINV)108 170.4 Q(AL])-1.35 E -2.812(Ap)144 182.4 S .313(arameter has been speci\214ed \(hash function, pad b\ -yte etc.\) that is incompatible with the current)159.032 182.4 R .406 -(\214le speci\214cation or which is not meaningful for the function \(for e)144 -194.4 R .405(xample, use of the cursor with-)-.15 F .099 -(out prior initialization\) or there is a mismatch between the v)144 206.4 R .1 -(ersion number of \214le and the softw)-.15 F(are.)-.1 E(The)108 223.2 Q F2 -(close)3.469 E F0 .969(routines may f)3.469 F .969(ail and set)-.1 F F2(errno) -3.469 E F0 .969(for an)3.469 F 3.469(yo)-.15 G 3.469(ft)320.18 223.2 S .969 -(he errors speci\214ed for the library routines)329.759 223.2 R F2(close)3.468 -E F0(\(2\),).18 E F2 -.37(re)108 235.2 S(ad).37 E F0(\(2\),).77 E F2(write)2.5 -E F0(\(2\),).18 E F2(fr)2.5 E(ee)-.37 E F0(\(3\), or).18 E F2(fsync)2.5 E F0 -(\(2\).).31 E(The)108 252 Q F2(del)2.969 E F0(,).51 E F2 -.1(ge)2.969 G(t).1 E -F0(,).68 E F2(put)2.969 E F0(and)2.969 E F2(seq)2.969 E F0 .469(routines may f) -2.969 F .469(ail and set)-.1 F F2(errno)2.97 E F0 .47(for an)2.97 F 2.97(yo) --.15 G 2.97(ft)377.59 252 S .47(he errors speci\214ed for the library rou-) -386.67 252 R(tines)108 264 Q F2 -.37(re)2.5 G(ad).37 E F0(\(2\),).77 E F2 -(write)2.5 E F0(\(2\),).18 E F2(fr)2.5 E(ee)-.37 E F0(\(3\) or).18 E F2(malloc) -2.5 E F0(\(3\).).31 E(The)108 280.8 Q F2(fd)2.5 E F0(routines will f)2.5 E -(ail and set)-.1 E F2(errno)2.5 E F0(to ENOENT for in memory databases.)2.5 E -(The)108 297.6 Q F2(sync)2.5 E F0(routines may f)2.5 E(ail and set)-.1 E F2 -(errno)2.5 E F0(for an)2.5 E 2.5(yo)-.15 G 2.5(ft)307.71 297.6 S -(he errors speci\214ed for the library routine)316.32 297.6 Q F2(fsync)2.5 E F0 -(\(2\).).31 E F1(SEE ALSO)72 314.4 Q F2(btr)108 326.4 Q(ee)-.37 E F0(\(3\),).18 -E F2(hash)2.5 E F0(\(3\),).28 E F2(mpool)2.5 E F0(\(3\),).51 E F2 -.37(re)2.5 G -(cno).37 E F0(\(3\)).18 E F1 -.09(BU)72 343.2 S(GS).09 E F0 .399 -(The typedef DBT is a mnemonic for `)108 355.2 R .399(`data base thang')-.74 F -.399(', and w)-.74 F .399(as used because noone could think of a rea-)-.1 F -(sonable name that w)108 367.2 Q(asn')-.1 E 2.5(ta)-.18 G(lready used.)216.03 -367.2 Q(The \214le descriptor interf)108 384 Q -(ace is a kluge and will be deleted in a future v)-.1 E(ersion of the interf) --.15 E(ace.)-.1 E(None of the access methods pro)108 400.8 Q(vide an)-.15 E 2.5 -(yf)-.15 G(orm of concurrent access, locking, or transactions.)275.16 400.8 Q -209.835(24, May)72 768 R(4)535 768 Q EP -%%Trailer -end -%%EOF diff --git a/lib/libc/db/doc/hash.3.ps b/lib/libc/db/doc/hash.3.ps deleted file mode 100644 index 8551b86d8ff2..000000000000 --- a/lib/libc/db/doc/hash.3.ps +++ /dev/null @@ -1,289 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.08 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Bold -%%+ font Times-Italic -%%DocumentSuppliedResources: procset grops 1.08 0 -%%Pages: 2 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.08 0 -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}bind def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/FL{ -currentgray exch setgray fill setgray -}bind def -/BL/fill load def -/LW/setlinewidth load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -}bind def -/PEND{ -clear -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE -/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 182.62(HASH\(3\) 1993 HASH\(3\))72 48 R/F1 9 -/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0 -(hash \255 hash database access method)108 96 Q F1(SYNOPSIS)72 112.8 Q/F2 10 -/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <db)108 136.8 Q -(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 .29(The routine)108 165.6 R/F3 10 -/Times-Italic@0 SF(dbopen)2.79 E F0 .29(is the library interf)2.79 F .29 -(ace to database \214les.)-.1 F .29 -(One of the supported \214le formats is hash \214les.)5.29 F .974 -(The general description of the database access methods is in)108 177.6 R F3 -(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F -(the hash speci\214c information.)108 189.6 Q(The hash data structure is an e) -108 206.4 Q(xtensible, dynamic hashing scheme.)-.15 E .83 -(The access method speci\214c data structure pro)108 223.2 R .83(vided to)-.15 -F F3(dbopen)3.33 E F0 .83(is de\214ned in the <db)3.33 F .83 -(.h> include \214le as fol-)-.4 F(lo)108 235.2 Q(ws:)-.25 E(typedef struct {) -108 259.2 Q(int bsize;)144 271.2 Q(int cachesize;)144 283.2 Q(int f)144 295.2 Q --.1(fa)-.25 G(ctor;).1 E(u_long \(*hash\)\(const v)144 307.2 Q -(oid *, size_t\);)-.2 E(int lorder;)144 319.2 Q(int nelem;)144 331.2 Q 2.5(}H) -108 343.2 S(ASHINFO;)122.52 343.2 Q -(The elements of this structure are as follo)108 360 Q(ws:)-.25 E(bsize)108 -376.8 Q F3(Bsize)144 376.8 Q F0 1.393(de\214nes the hash table b)3.893 F(uck) --.2 E 1.393(et size, and is, by def)-.1 F 1.394(ault, 256 bytes.)-.1 F 1.394 -(It may be preferable to)6.394 F -(increase the page size for disk-resident tables and tables with lar)144 388.8 -Q(ge data items.)-.18 E(cachesize)108 405.6 Q 3.16(As)144 417.6 S .66 -(uggested maximum size, in bytes, of the memory cache.)158.27 417.6 R .659 -(This v)5.659 F .659(alue is)-.25 F F2(only)3.159 E F0(advisory)3.159 E 3.159 -(,a)-.65 G .659(nd the)514.621 417.6 R -(access method will allocate more memory rather than f)144 429.6 Q(ail.)-.1 E --2.1 -.25(ff a)108 446.4 T(ctor).25 E F3(Ffactor)9.7 E F0 .482 -(indicates a desired density within the hash table.)2.981 F .482 -(It is an approximation of the number of)5.482 F -.1(ke)144 458.4 S .429 -(ys allo)-.05 F .429(wed to accumulate in an)-.25 F 2.929(yo)-.15 G .429(ne b) -291.454 458.4 R(uck)-.2 E .429(et, determining when the hash table gro)-.1 F -.428(ws or shrinks.)-.25 F(The def)144 470.4 Q(ault v)-.1 E(alue is 8.)-.25 E -(hash)108 487.2 Q F3(Hash)144 487.2 Q F0 .1(is a user de\214ned hash function.) -2.6 F .1(Since no hash function performs equally well on all possible)5.1 F -.924(data, the user may \214nd that the b)144 499.2 R .923 -(uilt-in hash function does poorly on a particular data set.)-.2 F(User)5.923 E -1.408(speci\214ed hash functions must tak)144 511.2 R 3.909(et)-.1 G 1.609 -.1 -(wo a)293.431 511.2 T -.18(rg).1 G 1.409 -(uments \(a pointer to a byte string and a length\) and).18 F -(return an u_long to be used as the hash v)144 523.2 Q(alue.)-.25 E 9.62 -(lorder The)108 540 R 1.597(byte order for inte)4.097 F 1.596 -(gers in the stored database metadata.)-.15 F 1.596 -(The number should represent the)6.596 F .688(order as an inte)144 552 R .689 -(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 -(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689 -(is 0 \(no)3.189 F .822(order is speci\214ed\) the current host order is used.) -144 564 R .822(If the)5.822 F .822(\214le already e)5.822 F .821 -(xists, the speci\214ed v)-.15 F .821(alue is)-.25 F(ignored and the v)144 576 -Q(alue speci\214ed when the tree w)-.25 E(as created is used.)-.1 E(nelem)108 -592.8 Q F3(Nelem)144 592.8 Q F0 .701 -(is an estimate of the \214nal size of the hash table.)3.2 F .701 -(If not set or set too lo)5.701 F 2.001 -.65(w, h)-.25 H .701(ash tables will) -.65 F -.15(ex)144 604.8 S .448(pand gracefully as k).15 F -.15(ey)-.1 G 2.948 -(sa).15 G .448(re entered, although a slight performance de)255.912 604.8 R -.447(gradation may be noticed.)-.15 F(The def)144 616.8 Q(ault v)-.1 E -(alue is 1.)-.25 E .79(If the \214le already e)108 633.6 R .79 -(xists \(and the O_TR)-.15 F .79(UNC \215ag is not speci\214ed\), the v)-.4 F -.79(alues speci\214ed for the parameters)-.25 F(bsize, f)108 645.6 Q -.1(fa) --.25 G(ctor).1 E 2.5(,l)-.4 G(order and nelem are ignored and the v)167.23 -645.6 Q(alues speci\214ed when the tree w)-.25 E(as created are used.)-.1 E -1.232(If a hash function is speci\214ed,)108 662.4 R F3(hash_open)3.731 E F0 -1.231(will attempt to determine if the hash function speci\214ed is the)3.731 F -(same as the one with which the database w)108 674.4 Q(as created, and will f) --.1 E(ail if it is not.)-.1 E(Backw)108 691.2 Q .861(ard compatible interf)-.1 -F .861(aces to the routines described in)-.1 F F3(dbm)3.362 E F0 .862 -(\(3\), and).32 F F3(ndbm)3.362 E F0 .862(\(3\) are pro).32 F .862(vided, ho) --.15 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G(these interf)108 703.2 Q -(aces are not compatible with pre)-.1 E(vious \214le formats.)-.25 E 214.835 -(6, June)72 768 R(1)535 768 Q EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 182.62(HASH\(3\) 1993 HASH\(3\))72 48 R/F1 9 -/Times-Bold@0 SF(SEE ALSO)72 84 Q/F2 10/Times-Italic@0 SF(btr)108 96 Q(ee)-.37 -E F0(\(3\),).18 E F2(dbopen)2.5 E F0(\(3\),).24 E F2(mpool)2.5 E F0(\(3\),).51 -E F2 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E F2(Dynamic Hash T)108 108 Q(ables) --.92 E F0 2.5(,P).27 G(er)206.79 108 Q(-Ak)-.2 E 2.5(eL)-.1 G -(arson, Communications of the A)242.86 108 Q(CM, April 1988.)-.4 E F2 2.5(AN) -108 120 S .3 -.15(ew H)123.28 120 T(ash P).15 E(ac)-.8 E(ka)-.2 E .2 -.1(ge f) --.1 H(or UNIX).1 E F0 2.5(,M).94 G(ar)248.41 120 Q(go Seltzer)-.18 E 2.5(,U)-.4 -G(SENIX Proceedings, W)308.09 120 Q(inter 1991.)-.4 E F1 -.09(BU)72 136.8 S(GS) -.09 E F0(Only big and little endian byte order is supported.)108 148.8 Q -214.835(6, June)72 768 R(2)535 768 Q EP -%%Trailer -end -%%EOF diff --git a/lib/libc/db/doc/hash.ps b/lib/libc/db/doc/hash.ps deleted file mode 100644 index 601e375d6c40..000000000000 --- a/lib/libc/db/doc/hash.ps +++ /dev/null @@ -1,12209 +0,0 @@ -%!PS-Adobe-1.0 -%%Creator: utopia:margo (& Seltzer,608-13E,8072,) -%%Title: stdin (ditroff) -%%CreationDate: Tue Dec 11 15:06:45 1990 -%%EndComments -% @(#)psdit.pro 1.3 4/15/88 -% lib/psdit.pro -- prolog for psdit (ditroff) files -% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved. -% last edit: shore Sat Nov 23 20:28:03 1985 -% RCSID: $Header: /a/cvs/386BSD/src/lib/libc/db/doc/hash.ps,v 1.1 1993/06/16 02:20:49 rgrimes Exp $ - -% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics, -% 17 Feb, 87. - -/$DITroff 140 dict def $DITroff begin -/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def -/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto - /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F - /pagesave save def}def -/PB{save /psv exch def currentpoint translate - resolution 72 div dup neg scale 0 0 moveto}def -/PE{psv restore}def -/arctoobig 90 def /arctoosmall .05 def -/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def -/tan{dup sin exch cos div}def -/point{resolution 72 div mul}def -/dround {transform round exch round exch itransform}def -/xT{/devname exch def}def -/xr{/mh exch def /my exch def /resolution exch def}def -/xp{}def -/xs{docsave restore end}def -/xt{}def -/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not - {fonts slotno fontname findfont put fontnames slotno fontname put}if}def -/xH{/fontheight exch def F}def -/xS{/fontslant exch def F}def -/s{/fontsize exch def /fontheight fontsize def F}def -/f{/fontnum exch def F}def -/F{fontheight 0 le{/fontheight fontsize def}if - fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore - fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if - makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def -/X{exch currentpoint exch pop moveto show}def -/N{3 1 roll moveto show}def -/Y{exch currentpoint pop exch moveto show}def -/S{show}def -/ditpush{}def/ditpop{}def -/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def -/AN{4 2 roll moveto 0 exch ashow}def -/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def -/AS{0 exch ashow}def -/MX{currentpoint exch pop moveto}def -/MY{currentpoint pop exch moveto}def -/MXY{moveto}def -/cb{pop}def % action on unknown char -- nothing for now -/n{}def/w{}def -/p{pop showpage pagesave restore /pagesave save def}def -/Dt{/Dlinewidth exch def}def 1 Dt -/Ds{/Ddash exch def}def -1 Ds -/Di{/Dstipple exch def}def 1 Di -/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def -/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]} - {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def -/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore - currentpoint newpath moveto}def -/Dl{rlineto Dstroke}def -/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop - currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def - currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def -/Dc{dup arcellipse Dstroke}def -/De{arcellipse Dstroke}def -/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def - /cradius centerv centerv mul centerh centerh mul add sqrt def - /eradius endv endv mul endh endh mul add sqrt def - /endang endv endh atan def - /startang centerv neg centerh neg atan def - /sweep startang endang sub dup 0 lt{360 add}if def - sweep arctoobig gt - {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def - /midh midang cos midrad mul def /midv midang sin midrad mul def - midh neg midv neg endh endv centerh centerv midh midv Da - Da} - {sweep arctoosmall ge - {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def - centerv neg controldelt mul centerh controldelt mul - endv neg controldelt mul centerh add endh add - endh controldelt mul centerv add endv add - centerh endh add centerv endv add rcurveto Dstroke} - {centerh endh add centerv endv add rlineto Dstroke} - ifelse} - ifelse}def -/Dpatterns[ -[%cf[widthbits] -[8<0000000000000010>] -[8<0411040040114000>] -[8<0204081020408001>] -[8<0000103810000000>] -[8<6699996666999966>] -[8<0000800100001008>] -[8<81c36666c3810000>] -[8<0f0e0c0800000000>] -[8<0000000000000010>] -[8<0411040040114000>] -[8<0204081020408001>] -[8<0000001038100000>] -[8<6699996666999966>] -[8<0000800100001008>] -[8<81c36666c3810000>] -[8<0f0e0c0800000000>] -[8<0042660000246600>] -[8<0000990000990000>] -[8<0804020180402010>] -[8<2418814242811824>] -[8<6699996666999966>] -[8<8000000008000000>] -[8<00001c3e363e1c00>] -[8<0000000000000000>] -[32<00000040000000c00000004000000040000000e0000000000000000000000000>] -[32<00000000000060000000900000002000000040000000f0000000000000000000>] -[32<000000000000000000e0000000100000006000000010000000e0000000000000>] -[32<00000000000000002000000060000000a0000000f00000002000000000000000>] -[32<0000000e0000000000000000000000000000000f000000080000000e00000001>] -[32<0000090000000600000000000000000000000000000007000000080000000e00>] -[32<00010000000200000004000000040000000000000000000000000000000f0000>] -[32<0900000006000000090000000600000000000000000000000000000006000000>]] -[%ug -[8<0000020000000000>] -[8<0000020000002000>] -[8<0004020000002000>] -[8<0004020000402000>] -[8<0004060000402000>] -[8<0004060000406000>] -[8<0006060000406000>] -[8<0006060000606000>] -[8<00060e0000606000>] -[8<00060e000060e000>] -[8<00070e000060e000>] -[8<00070e000070e000>] -[8<00070e020070e000>] -[8<00070e020070e020>] -[8<04070e020070e020>] -[8<04070e024070e020>] -[8<04070e064070e020>] -[8<04070e064070e060>] -[8<06070e064070e060>] -[8<06070e066070e060>] -[8<06070f066070e060>] -[8<06070f066070f060>] -[8<060f0f066070f060>] -[8<060f0f0660f0f060>] -[8<060f0f0760f0f060>] -[8<060f0f0760f0f070>] -[8<0e0f0f0760f0f070>] -[8<0e0f0f07e0f0f070>] -[8<0e0f0f0fe0f0f070>] -[8<0e0f0f0fe0f0f0f0>] -[8<0f0f0f0fe0f0f0f0>] -[8<0f0f0f0ff0f0f0f0>] -[8<1f0f0f0ff0f0f0f0>] -[8<1f0f0f0ff1f0f0f0>] -[8<1f0f0f8ff1f0f0f0>] -[8<1f0f0f8ff1f0f0f8>] -[8<9f0f0f8ff1f0f0f8>] -[8<9f0f0f8ff9f0f0f8>] -[8<9f0f0f9ff9f0f0f8>] -[8<9f0f0f9ff9f0f0f9>] -[8<9f8f0f9ff9f0f0f9>] -[8<9f8f0f9ff9f8f0f9>] -[8<9f8f1f9ff9f8f0f9>] -[8<9f8f1f9ff9f8f1f9>] -[8<bf8f1f9ff9f8f1f9>] -[8<bf8f1f9ffbf8f1f9>] -[8<bf8f1fdffbf8f1f9>] -[8<bf8f1fdffbf8f1fd>] -[8<ff8f1fdffbf8f1fd>] -[8<ff8f1fdffff8f1fd>] -[8<ff8f1ffffff8f1fd>] -[8<ff8f1ffffff8f1ff>] -[8<ff9f1ffffff8f1ff>] -[8<ff9f1ffffff9f1ff>] -[8<ff9f9ffffff9f1ff>] -[8<ff9f9ffffff9f9ff>] -[8<ffbf9ffffff9f9ff>] -[8<ffbf9ffffffbf9ff>] -[8<ffbfdffffffbf9ff>] -[8<ffbfdffffffbfdff>] -[8<ffffdffffffbfdff>] -[8<ffffdffffffffdff>] -[8<fffffffffffffdff>] -[8<ffffffffffffffff>]] -[%mg -[8<8000000000000000>] -[8<0822080080228000>] -[8<0204081020408001>] -[8<40e0400000000000>] -[8<66999966>] -[8<8001000010080000>] -[8<81c36666c3810000>] -[8<f0e0c08000000000>] -[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>] -[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>] -[8<c3c300000000c3c3>] -[16<0040008001000200040008001000200040008000000100020004000800100020>] -[16<0040002000100008000400020001800040002000100008000400020001000080>] -[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>] -[8<80>] -[8<8040201000000000>] -[8<84cc000048cc0000>] -[8<9900009900000000>] -[8<08040201804020100800020180002010>] -[8<2418814242811824>] -[8<66999966>] -[8<8000000008000000>] -[8<70f8d8f870000000>] -[8<0814224180402010>] -[8<aa00440a11a04400>] -[8<018245aa45820100>] -[8<221c224180808041>] -[8<88000000>] -[8<0855800080550800>] -[8<2844004482440044>] -[8<0810204080412214>] -[8<00>]]]def -/Dfill{ - transform /maxy exch def /maxx exch def - transform /miny exch def /minx exch def - minx maxx gt{/minx maxx /maxx minx def def}if - miny maxy gt{/miny maxy /maxy miny def def}if - Dpatterns Dstipple 1 sub get exch 1 sub get - aload pop /stip exch def /stipw exch def /stiph 128 def - /imatrix[stipw 0 0 stiph 0 0]def - /tmatrix[stipw 0 0 stiph 0 0]def - /minx minx cvi stiph idiv stiph mul def - /miny miny cvi stipw idiv stipw mul def - gsave eoclip 0 setgray - miny stiph maxy{ - tmatrix exch 5 exch put - minx stipw maxx{ - tmatrix exch 4 exch put tmatrix setmatrix - stipw stiph true imatrix {stip} imagemask - }for - }for - grestore -}def -/Dp{Dfill Dstroke}def -/DP{Dfill currentpoint newpath moveto}def -end - -/ditstart{$DITroff begin - /nfonts 60 def % NFONTS makedev/ditroff dependent! - /fonts[nfonts{0}repeat]def - /fontnames[nfonts{()}repeat]def -/docsave save def -}def - -% character outcalls -/oc{ - /pswid exch def /cc exch def /name exch def - /ditwid pswid fontsize mul resolution mul 72000 div def - /ditsiz fontsize resolution mul 72 div def - ocprocs name known{ocprocs name get exec}{name cb}ifelse -}def -/fractm [.65 0 0 .6 0 0] def -/fraction{ - /fden exch def /fnum exch def gsave /cf currentfont def - cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto - fnum show rmoveto currentfont cf setfont(\244)show setfont fden show - grestore ditwid 0 rmoveto -}def -/oce{grestore ditwid 0 rmoveto}def -/dm{ditsiz mul}def -/ocprocs 50 dict def ocprocs begin -(14){(1)(4)fraction}def -(12){(1)(2)fraction}def -(34){(3)(4)fraction}def -(13){(1)(3)fraction}def -(23){(2)(3)fraction}def -(18){(1)(8)fraction}def -(38){(3)(8)fraction}def -(58){(5)(8)fraction}def -(78){(7)(8)fraction}def -(sr){gsave 0 .06 dm rmoveto(\326)show oce}def -(is){gsave 0 .15 dm rmoveto(\362)show oce}def -(->){gsave 0 .02 dm rmoveto(\256)show oce}def -(<-){gsave 0 .02 dm rmoveto(\254)show oce}def -(==){gsave 0 .05 dm rmoveto(\272)show oce}def -(uc){gsave currentpoint 400 .009 dm mul add translate - 8 -8 scale ucseal oce}def -end - -% an attempt at a PostScript FONT to implement ditroff special chars -% this will enable us to -% cache the little buggers -% generate faster, more compact PS out of psdit -% confuse everyone (including myself)! -50 dict dup begin -/FontType 3 def -/FontName /DIThacks def -/FontMatrix [.001 0 0 .001 0 0] def -/FontBBox [-260 -260 900 900] def% a lie but ... -/Encoding 256 array def -0 1 255{Encoding exch /.notdef put}for -Encoding - dup 8#040/space put %space - dup 8#110/rc put %right ceil - dup 8#111/lt put %left top curl - dup 8#112/bv put %bold vert - dup 8#113/lk put %left mid curl - dup 8#114/lb put %left bot curl - dup 8#115/rt put %right top curl - dup 8#116/rk put %right mid curl - dup 8#117/rb put %right bot curl - dup 8#120/rf put %right floor - dup 8#121/lf put %left floor - dup 8#122/lc put %left ceil - dup 8#140/sq put %square - dup 8#141/bx put %box - dup 8#142/ci put %circle - dup 8#143/br put %box rule - dup 8#144/rn put %root extender - dup 8#145/vr put %vertical rule - dup 8#146/ob put %outline bullet - dup 8#147/bu put %bullet - dup 8#150/ru put %rule - dup 8#151/ul put %underline - pop -/DITfd 100 dict def -/BuildChar{0 begin - /cc exch def /fd exch def - /charname fd /Encoding get cc get def - /charwid fd /Metrics get charname get def - /charproc fd /CharProcs get charname get def - charwid 0 fd /FontBBox get aload pop setcachedevice - 2 setlinejoin 40 setlinewidth - newpath 0 0 moveto gsave charproc grestore - end}def -/BuildChar load 0 DITfd put -/CharProcs 50 dict def -CharProcs begin -/space{}def -/.notdef{}def -/ru{500 0 rls}def -/rn{0 840 moveto 500 0 rls}def -/vr{0 800 moveto 0 -770 rls}def -/bv{0 800 moveto 0 -1000 rls}def -/br{0 840 moveto 0 -1000 rls}def -/ul{0 -140 moveto 500 0 rls}def -/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def -/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def -/sq{80 0 rmoveto currentpoint dround newpath moveto - 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def -/bx{80 0 rmoveto currentpoint dround newpath moveto - 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def -/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc - 50 setlinewidth stroke}def - -/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def -/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def -/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def -/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def -/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub - 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def -/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub - 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def -/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def -/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def -/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def -/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def -end - -/Metrics 50 dict def Metrics begin -/.notdef 0 def -/space 500 def -/ru 500 def -/br 0 def -/lt 416 def -/lb 416 def -/rt 416 def -/rb 416 def -/lk 416 def -/rk 416 def -/rc 416 def -/lc 416 def -/rf 416 def -/lf 416 def -/bv 416 def -/ob 350 def -/bu 350 def -/ci 750 def -/bx 750 def -/sq 750 def -/rn 500 def -/ul 500 def -/vr 0 def -end - -DITfd begin -/s2 500 def /s4 250 def /s3 333 def -/a4p{arcto pop pop pop pop}def -/2cx{2 copy exch}def -/rls{rlineto stroke}def -/currx{currentpoint pop}def -/dround{transform round exch round exch itransform} def -end -end -/DIThacks exch definefont pop -ditstart -(psc)xT -576 1 1 xr -1(Times-Roman)xf 1 f -2(Times-Italic)xf 2 f -3(Times-Bold)xf 3 f -4(Times-BoldItalic)xf 4 f -5(Helvetica)xf 5 f -6(Helvetica-Bold)xf 6 f -7(Courier)xf 7 f -8(Courier-Bold)xf 8 f -9(Symbol)xf 9 f -10(DIThacks)xf 10 f -10 s -1 f -xi -%%EndProlog - -%%Page: 1 1 -10 s 10 xH 0 xS 1 f -3 f -22 s -1249 626(A)N -1420(N)X -1547(ew)X -1796(H)X -1933(ashing)X -2467(P)X -2574(ackage)X -3136(for)X -3405(U)X -3532(N)X -3659(IX)X -2 f -20 s -3855 562(1)N -1 f -12 s -1607 779(Margo)N -1887(Seltzer)X -9 f -2179(-)X -1 f -2256(University)X -2686(of)X -2790(California,)X -3229(Berkeley)X -2015 875(Ozan)N -2242(Yigit)X -9 f -2464(-)X -1 f -2541(York)X -2762(University)X -3 f -2331 1086(ABSTRACT)N -1 f -10 s -1152 1222(UNIX)N -1385(support)X -1657(of)X -1756(disk)X -1921(oriented)X -2216(hashing)X -2497(was)X -2654(originally)X -2997(provided)X -3314(by)X -2 f -3426(dbm)X -1 f -3595([ATT79])X -3916(and)X -1152 1310(subsequently)N -1595(improved)X -1927(upon)X -2112(in)X -2 f -2199(ndbm)X -1 f -2402([BSD86].)X -2735(In)X -2826(AT&T)X -3068(System)X -3327(V,)X -3429(in-memory)X -3809(hashed)X -1152 1398(storage)N -1420(and)X -1572(access)X -1814(support)X -2090(was)X -2251(added)X -2479(in)X -2577(the)X -2 f -2711(hsearch)X -1 f -3000(library)X -3249(routines)X -3542([ATT85].)X -3907(The)X -1152 1486(result)N -1367(is)X -1457(a)X -1530(system)X -1789(with)X -1968(two)X -2125(incompatible)X -2580(hashing)X -2865(schemes,)X -3193(each)X -3377(with)X -3555(its)X -3666(own)X -3840(set)X -3965(of)X -1152 1574(shortcomings.)N -1152 1688(This)N -1316(paper)X -1517(presents)X -1802(the)X -1922(design)X -2152(and)X -2289(performance)X -2717(characteristics)X -3198(of)X -3286(a)X -3343(new)X -3498(hashing)X -3768(package)X -1152 1776(providing)N -1483(a)X -1539(superset)X -1822(of)X -1909(the)X -2027(functionality)X -2456(provided)X -2761(by)X -2 f -2861(dbm)X -1 f -3019(and)X -2 f -3155(hsearch)X -1 f -3409(.)X -3469(The)X -3614(new)X -3768(package)X -1152 1864(uses)N -1322(linear)X -1537(hashing)X -1818(to)X -1912(provide)X -2189(ef\256cient)X -2484(support)X -2755(of)X -2853(both)X -3026(memory)X -3324(based)X -3538(and)X -3685(disk)X -3849(based)X -1152 1952(hash)N -1319(tables)X -1526(with)X -1688(performance)X -2115(superior)X -2398(to)X -2480(both)X -2 f -2642(dbm)X -1 f -2800(and)X -2 f -2936(hsearch)X -1 f -3210(under)X -3413(most)X -3588(conditions.)X -3 f -1380 2128(Introduction)N -1 f -892 2260(Current)N -1196(UNIX)X -1456(systems)X -1768(offer)X -1984(two)X -2163(forms)X -2409(of)X -720 2348(hashed)N -973(data)X -1137(access.)X -2 f -1413(Dbm)X -1 f -1599(and)X -1745(its)X -1850(derivatives)X -2231(provide)X -720 2436(keyed)N -939(access)X -1171(to)X -1259(disk)X -1418(resident)X -1698(data)X -1858(while)X -2 f -2062(hsearch)X -1 f -2342(pro-)X -720 2524(vides)N -929(access)X -1175(for)X -1309(memory)X -1616(resident)X -1910(data.)X -2124(These)X -2356(two)X -720 2612(access)N -979(methods)X -1302(are)X -1453(incompatible)X -1923(in)X -2037(that)X -2209(memory)X -720 2700(resident)N -1011(hash)X -1195(tables)X -1419(may)X -1593(not)X -1731(be)X -1843(stored)X -2075(on)X -2191(disk)X -2360(and)X -720 2788(disk)N -884(resident)X -1169(tables)X -1387(cannot)X -1632(be)X -1739(read)X -1909(into)X -2063(memory)X -2360(and)X -720 2876(accessed)N -1022(using)X -1215(the)X -1333(in-memory)X -1709(routines.)X -2 f -892 2990(Dbm)N -1 f -1091(has)X -1241(several)X -1512(shortcomings.)X -2026(Since)X -2247(data)X -2423(is)X -720 3078(assumed)N -1032(to)X -1130(be)X -1242(disk)X -1411(resident,)X -1721(each)X -1905(access)X -2146(requires)X -2440(a)X -720 3166(system)N -963(call,)X -1120(and)X -1257(almost)X -1491(certainly,)X -1813(a)X -1869(disk)X -2022(operation.)X -2365(For)X -720 3254(extremely)N -1072(large)X -1264(databases,)X -1623(where)X -1851(caching)X -2131(is)X -2214(unlikely)X -720 3342(to)N -810(be)X -914(effective,)X -1244(this)X -1386(is)X -1466(acceptable,)X -1853(however,)X -2177(when)X -2378(the)X -720 3430(database)N -1022(is)X -1100(small)X -1298(\(i.e.)X -1447(the)X -1569(password)X -1896(\256le\),)X -2069(performance)X -720 3518(improvements)N -1204(can)X -1342(be)X -1443(obtained)X -1744(through)X -2018(caching)X -2293(pages)X -720 3606(of)N -818(the)X -947(database)X -1255(in)X -1348(memory.)X -1685(In)X -1782(addition,)X -2 f -2094(dbm)X -1 f -2262(cannot)X -720 3694(store)N -902(data)X -1062(items)X -1261(whose)X -1492(total)X -1660(key)X -1802(and)X -1943(data)X -2102(size)X -2252(exceed)X -720 3782(the)N -850(page)X -1034(size)X -1191(of)X -1290(the)X -1420(hash)X -1599(table.)X -1827(Similarly,)X -2176(if)X -2257(two)X -2409(or)X -720 3870(more)N -907(keys)X -1076(produce)X -1357(the)X -1477(same)X -1664(hash)X -1833(value)X -2029(and)X -2166(their)X -2334(total)X -720 3958(size)N -876(exceeds)X -1162(the)X -1291(page)X -1474(size,)X -1650(the)X -1779(table)X -1966(cannot)X -2210(store)X -2396(all)X -720 4046(the)N -838(colliding)X -1142(keys.)X -892 4160(The)N -1050(in-memory)X -2 f -1439(hsearch)X -1 f -1725(routines)X -2015(have)X -2199(different)X -720 4248(shortcomings.)N -1219(First,)X -1413(the)X -1539(notion)X -1771(of)X -1865(a)X -1928(single)X -2146(hash)X -2320(table)X -720 4336(is)N -807(embedded)X -1171(in)X -1266(the)X -1397(interface,)X -1732(preventing)X -2108(an)X -2217(applica-)X -720 4424(tion)N -902(from)X -1116(accessing)X -1482(multiple)X -1806(tables)X -2050(concurrently.)X -720 4512(Secondly,)N -1063(the)X -1186(routine)X -1438(to)X -1525(create)X -1743(a)X -1804(hash)X -1976(table)X -2157(requires)X -2440(a)X -720 4600(parameter)N -1066(which)X -1286(declares)X -1573(the)X -1694(size)X -1842(of)X -1932(the)X -2053(hash)X -2223(table.)X -2422(If)X -720 4688(this)N -856(size)X -1001(is)X -1074(set)X -1183(too)X -1305(low,)X -1465(performance)X -1892(degradation)X -2291(or)X -2378(the)X -720 4776(inability)N -1008(to)X -1092(add)X -1230(items)X -1425(to)X -1509(the)X -1628(table)X -1805(may)X -1964(result.)X -2223(In)X -2311(addi-)X -720 4864(tion,)N -2 f -910(hsearch)X -1 f -1210(requires)X -1515(that)X -1681(the)X -1825(application)X -2226(allocate)X -720 4952(memory)N -1037(for)X -1181(the)X -1329(key)X -1495(and)X -1661(data)X -1845(items.)X -2108(Lastly,)X -2378(the)X -2 f -720 5040(hsearch)N -1 f -1013(routines)X -1310(provide)X -1594(no)X -1713(interface)X -2034(to)X -2135(store)X -2329(hash)X -720 5128(tables)N -927(on)X -1027(disk.)X -16 s -720 5593 MXY -864 0 Dl -2 f -8 s -760 5648(1)N -1 f -9 s -5673(UNIX)Y -990(is)X -1056(a)X -1106(registered)X -1408(trademark)X -1718(of)X -1796(AT&T.)X -10 s -2878 2128(The)N -3032(goal)X -3199(of)X -3295(our)X -3431(work)X -3625(was)X -3779(to)X -3870(design)X -4108(and)X -4253(imple-)X -2706 2216(ment)N -2900(a)X -2970(new)X -3138(package)X -3436(that)X -3590(provides)X -3899(a)X -3968(superset)X -4264(of)X -4364(the)X -2706 2304(functionality)N -3144(of)X -3240(both)X -2 f -3411(dbm)X -1 f -3578(and)X -2 f -3723(hsearch)X -1 f -3977(.)X -4045(The)X -4198(package)X -2706 2392(had)N -2871(to)X -2982(overcome)X -3348(the)X -3495(interface)X -3826(shortcomings)X -4306(cited)X -2706 2480(above)N -2930(and)X -3078(its)X -3185(implementation)X -3719(had)X -3867(to)X -3961(provide)X -4238(perfor-)X -2706 2568(mance)N -2942(equal)X -3142(or)X -3235(superior)X -3524(to)X -3612(that)X -3758(of)X -3851(the)X -3975(existing)X -4253(imple-)X -2706 2656(mentations.)N -3152(In)X -3274(order)X -3498(to)X -3614(provide)X -3913(a)X -4003(compact)X -4329(disk)X -2706 2744(representation,)N -3224(graceful)X -3531(table)X -3729(growth,)X -4018(and)X -4176(expected)X -2706 2832(constant)N -3033(time)X -3234(performance,)X -3720(we)X -3873(selected)X -4191(Litwin's)X -2706 2920(linear)N -2923(hashing)X -3206(algorithm)X -3551([LAR88,)X -3872(LIT80].)X -4178(We)X -4324(then)X -2706 3008(enhanced)N -3037(the)X -3161(algorithm)X -3498(to)X -3586(handle)X -3826(page)X -4004(over\257ows)X -4346(and)X -2706 3096(large)N -2900(key)X -3049(handling)X -3362(with)X -3537(a)X -3606(single)X -3830(mechanism,)X -4248(named)X -2706 3184(buddy-in-waiting.)N -3 f -2975 3338(Existing)N -3274(UNIX)X -3499(Hashing)X -3802(Techniques)X -1 f -2878 3470(Over)N -3076(the)X -3210(last)X -3357(decade,)X -3637(several)X -3901(dynamic)X -4213(hashing)X -2706 3558(schemes)N -3000(have)X -3174(been)X -3348(developed)X -3700(for)X -3816(the)X -3936(UNIX)X -4159(timeshar-)X -2706 3646(ing)N -2856(system,)X -3146(starting)X -3433(with)X -3622(the)X -3767(inclusion)X -4107(of)X -2 f -4221(dbm)X -1 f -4359(,)X -4426(a)X -2706 3734(minimal)N -3008(database)X -3321(library)X -3571(written)X -3834(by)X -3950(Ken)X -4120(Thompson)X -2706 3822([THOM90],)N -3141(in)X -3248(the)X -3391(Seventh)X -3694(Edition)X -3974(UNIX)X -4220(system.)X -2706 3910(Since)N -2916(then,)X -3106(an)X -3214(extended)X -3536(version)X -3804(of)X -3903(the)X -4032(same)X -4228(library,)X -2 f -2706 3998(ndbm)N -1 f -2884(,)X -2933(and)X -3078(a)X -3142(public-domain)X -3637(clone)X -3839(of)X -3934(the)X -4060(latter,)X -2 f -4273(sdbm)X -1 f -4442(,)X -2706 4086(have)N -2902(been)X -3098(developed.)X -3491(Another)X -3797 0.1645(interface-compatible)AX -2706 4174(library)N -2 f -2950(gdbm)X -1 f -3128(,)X -3178(was)X -3333(recently)X -3622(made)X -3826(available)X -4145(as)X -4241(part)X -4395(of)X -2706 4262(the)N -2829(Free)X -2997(Software)X -3312(Foundation's)X -3759(\(FSF\))X -3970(software)X -4271(distri-)X -2706 4350(bution.)N -2878 4464(All)N -3017(of)X -3121(these)X -3323(implementations)X -3893(are)X -4029(based)X -4248(on)X -4364(the)X -2706 4552(idea)N -2871(of)X -2969(revealing)X -3299(just)X -3445(enough)X -3711(bits)X -3856(of)X -3953(a)X -4019(hash)X -4196(value)X -4400(to)X -2706 4640(locate)N -2920(a)X -2978(page)X -3151(in)X -3234(a)X -3291(single)X -3503(access.)X -3770(While)X -2 f -3987(dbm/ndbm)X -1 f -4346(and)X -2 f -2706 4728(sdbm)N -1 f -2908(map)X -3079(the)X -3210(hash)X -3390(value)X -3597(directly)X -3874(to)X -3968(a)X -4036(disk)X -4201(address,)X -2 f -2706 4816(gdbm)N -1 f -2921(uses)X -3096(the)X -3231(hash)X -3414(value)X -3624(to)X -3722(index)X -3936(into)X -4096(a)X -2 f -4168(directory)X -1 f -2706 4904([ENB88])N -3020(containing)X -3378(disk)X -3531(addresses.)X -2878 5018(The)N -2 f -3033(hsearch)X -1 f -3317(routines)X -3605(in)X -3697(System)X -3962(V)X -4049(are)X -4177(designed)X -2706 5106(to)N -2804(provide)X -3085(memory-resident)X -3669(hash)X -3852(tables.)X -4115(Since)X -4328(data)X -2706 5194(access)N -2948(does)X -3131(not)X -3269(require)X -3533(disk)X -3702(access,)X -3964(simple)X -4213(hashing)X -2706 5282(schemes)N -3010(which)X -3238(may)X -3408(require)X -3667(multiple)X -3964(probes)X -4209(into)X -4364(the)X -2706 5370(table)N -2889(are)X -3015(used.)X -3209(A)X -3294(more)X -3486(interesting)X -3851(version)X -4114(of)X -2 f -4208(hsearch)X -1 f -2706 5458(is)N -2784(a)X -2845(public)X -3070(domain)X -3335(library,)X -2 f -3594(dynahash)X -1 f -3901(,)X -3945(that)X -4089(implements)X -2706 5546(Larson's)N -3036(in-memory)X -3440(adaptation)X -3822([LAR88])X -4164(of)X -4279(linear)X -2706 5634(hashing)N -2975([LIT80].)X -3 f -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -1 f -4424(1)X - -2 p -%%Page: 2 2 -10 s 10 xH 0 xS 1 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -2 f -1074 538(dbm)N -1 f -1232(and)X -2 f -1368(ndbm)X -1 f -604 670(The)N -2 f -760(dbm)X -1 f -928(and)X -2 f -1074(ndbm)X -1 f -1282(library)X -1526(implementations)X -2089(are)X -432 758(based)N -667(on)X -799(the)X -949(same)X -1166(algorithm)X -1529(by)X -1661(Ken)X -1846(Thompson)X -432 846([THOM90,)N -824(TOR88,)X -1113(WAL84],)X -1452(but)X -1582(differ)X -1789(in)X -1879(their)X -2054(pro-)X -432 934(grammatic)N -801(interfaces.)X -1160(The)X -1311(latter)X -1502(is)X -1581(a)X -1643(modi\256ed)X -1952(version)X -432 1022(of)N -533(the)X -665(former)X -918(which)X -1148(adds)X -1328(support)X -1601(for)X -1728(multiple)X -2027(data-)X -432 1110(bases)N -634(to)X -724(be)X -828(open)X -1011(concurrently.)X -1484(The)X -1636(discussion)X -1996(of)X -2090(the)X -432 1198(algorithm)N -774(that)X -925(follows)X -1196(is)X -1280(applicable)X -1640(to)X -1732(both)X -2 f -1904(dbm)X -1 f -2072(and)X -2 f -432 1286(ndbm)N -1 f -610(.)X -604 1400(The)N -760(basic)X -956(structure)X -1268(of)X -2 f -1366(dbm)X -1 f -1535(calls)X -1712(for)X -1836(\256xed-sized)X -432 1488(disk)N -612(blocks)X -868(\(buckets\))X -1214(and)X -1377(an)X -2 f -1499(access)X -1 f -1755(function)X -2068(that)X -432 1576(maps)N -623(a)X -681(key)X -819(to)X -902(a)X -959(bucket.)X -1234(The)X -1380(interface)X -1683(routines)X -1962(use)X -2090(the)X -2 f -432 1664(access)N -1 f -673(function)X -970(to)X -1062(obtain)X -1292(the)X -1420(appropriate)X -1816(bucket)X -2060(in)X -2152(a)X -432 1752(single)N -643(disk)X -796(access.)X -604 1866(Within)N -869(the)X -2 f -1010(access)X -1 f -1263(function,)X -1593(a)X -1672(bit-randomizing)X -432 1954(hash)N -610(function)X -2 f -8 s -877 1929(2)N -1 f -10 s -940 1954(is)N -1024(used)X -1202(to)X -1294(convert)X -1565(a)X -1631(key)X -1777(into)X -1931(a)X -1997(32-bit)X -432 2042(hash)N -605(value.)X -825(Out)X -971(of)X -1064(these)X -1254(32)X -1359(bits,)X -1519(only)X -1686(as)X -1778(many)X -1981(bits)X -2121(as)X -432 2130(necessary)N -773(are)X -900(used)X -1075(to)X -1165(determine)X -1514(the)X -1639(particular)X -1974(bucket)X -432 2218(on)N -533(which)X -750(a)X -807(key)X -944(resides.)X -1228(An)X -1347(in-memory)X -1724(bitmap)X -1967(is)X -2041(used)X -432 2306(to)N -533(determine)X -893(how)X -1070(many)X -1287(bits)X -1441(are)X -1579(required.)X -1905(Each)X -2104(bit)X -432 2394(indicates)N -746(whether)X -1033(its)X -1136(associated)X -1494(bucket)X -1736(has)X -1871(been)X -2051(split)X -432 2482(yet)N -562(\(a)X -657(0)X -728(indicating)X -1079(that)X -1230(the)X -1359(bucket)X -1604(has)X -1742(not)X -1875(yet)X -2004(split\).)X -432 2570(The)N -590(use)X -730(of)X -830(the)X -961(hash)X -1141(function)X -1441(and)X -1590(the)X -1720(bitmap)X -1974(is)X -2059(best)X -432 2658(described)N -769(by)X -878(stepping)X -1177(through)X -1454(database)X -1759(creation)X -2046(with)X -432 2746(multiple)N -718(invocations)X -1107(of)X -1194(a)X -2 f -1250(store)X -1 f -1430(operation.)X -604 2860(Initially,)N -906(the)X -1033(hash)X -1209(table)X -1394(contains)X -1690(a)X -1755(single)X -1974(bucket)X -432 2948(\(bucket)N -711(0\),)X -836(the)X -972(bit)X -1094(map)X -1270(contains)X -1575(a)X -1649(single)X -1878(bit)X -2000(\(bit)X -2148(0)X -432 3036(corresponding)N -913(to)X -997(bucket)X -1233(0\),)X -1342(and)X -1480(0)X -1542(bits)X -1699(of)X -1788(a)X -1846(hash)X -2014(value)X -432 3124(are)N -560(examined)X -901(to)X -992(determine)X -1342(where)X -1568(a)X -1633(key)X -1778(is)X -1860(placed)X -2099(\(in)X -432 3212(bucket)N -670(0\).)X -801(When)X -1017(bucket)X -1255(0)X -1319(is)X -1396(full,)X -1551(its)X -1650(bit)X -1758(in)X -1844(the)X -1966(bitmap)X -432 3300(\(bit)N -564(0\))X -652(is)X -726(set,)X -856(and)X -993(its)X -1089(contents)X -1377(are)X -1497(split)X -1655(between)X -1943(buckets)X -432 3388(0)N -499(and)X -641(1,)X -727(by)X -833(considering)X -1233(the)X -1357(0)X -2 f -7 s -3356(th)Y -10 s -1 f -1480 3388(bit)N -1590(\(the)X -1741(lowest)X -1976(bit)X -2086(not)X -432 3476(previously)N -800(examined\))X -1169(of)X -1266(the)X -1393(hash)X -1569(value)X -1772(for)X -1895(each)X -2072(key)X -432 3564(within)N -668(the)X -798(bucket.)X -1064(Given)X -1292(a)X -1359(well-designed)X -1840(hash)X -2018(func-)X -432 3652(tion,)N -613(approximately)X -1112(half)X -1273(of)X -1376(the)X -1510(keys)X -1693(will)X -1853(have)X -2041(hash)X -432 3740(values)N -666(with)X -837(the)X -964(0)X -2 f -7 s -3708(th)Y -10 s -1 f -1090 3740(bit)N -1203(set.)X -1341(All)X -1471(such)X -1646(keys)X -1821(and)X -1965(associ-)X -432 3828(ated)N -586(data)X -740(are)X -859(moved)X -1097(to)X -1179(bucket)X -1413(1,)X -1493(and)X -1629(the)X -1747(rest)X -1883(remain)X -2126(in)X -432 3916(bucket)N -666(0.)X -604 4030(After)N -804(this)X -949(split,)X -1135(the)X -1262(\256le)X -1393(now)X -1560(contains)X -1856(two)X -2005(buck-)X -432 4118(ets,)N -562(and)X -699(the)X -818(bitmap)X -1061(contains)X -1349(three)X -1530(bits:)X -1687(the)X -1805(0)X -2 f -7 s -4086(th)Y -10 s -1 f -1922 4118(bit)N -2026(is)X -2099(set)X -432 4206(to)N -525(indicate)X -810(a)X -876(bucket)X -1120(0)X -1190(split)X -1357(when)X -1561(no)X -1671(bits)X -1816(of)X -1913(the)X -2041(hash)X -432 4294(value)N -648(are)X -789(considered,)X -1199(and)X -1357(two)X -1519(more)X -1726(unset)X -1937(bits)X -2094(for)X -432 4382(buckets)N -706(0)X -775(and)X -920(1.)X -1029(The)X -1183(placement)X -1542(of)X -1638(an)X -1742(incoming)X -2072(key)X -432 4470(now)N -604(requires)X -897(examination)X -1327(of)X -1428(the)X -1560(0)X -2 f -7 s -4438(th)Y -10 s -1 f -1691 4470(bit)N -1809(of)X -1910(the)X -2041(hash)X -432 4558(value,)N -667(and)X -824(the)X -963(key)X -1119(is)X -1212(placed)X -1462(either)X -1685(in)X -1787(bucket)X -2041(0)X -2121(or)X -432 4646(bucket)N -674(1.)X -782(If)X -864(either)X -1075(bucket)X -1317(0)X -1385(or)X -1480(bucket)X -1722(1)X -1790(\256lls)X -1937(up,)X -2064(it)X -2135(is)X -432 4734(split)N -598(as)X -693(before,)X -947(its)X -1050(bit)X -1162(is)X -1243(set)X -1360(in)X -1450(the)X -1576(bitmap,)X -1846(and)X -1990(a)X -2054(new)X -432 4822(set)N -541(of)X -628(unset)X -817(bits)X -952(are)X -1071(added)X -1283(to)X -1365(the)X -1483(bitmap.)X -604 4936(Each)N -791(time)X -959(we)X -1079(consider)X -1376(a)X -1437(new)X -1596(bit)X -1705(\(bit)X -1841(n\),)X -1953(we)X -2072(add)X -432 5024(2)N -2 f -7 s -4992(n)Y -9 f -509(+)X -1 f -540(1)X -10 s -595 5024(bits)N -737(to)X -826(the)X -951(bitmap)X -1199(and)X -1341(obtain)X -1567(2)X -2 f -7 s -4992(n)Y -9 f -1644(+)X -1 f -1675(1)X -10 s -1729 5024(more)N -1920(address-)X -432 5112(able)N -595(buckets)X -869(in)X -960(the)X -1087(\256le.)X -1258(As)X -1376(a)X -1441(result,)X -1668(the)X -1795(bitmap)X -2045(con-)X -432 5200(tains)N -618(the)X -751(previous)X -1062(2)X -2 f -7 s -5168(n)Y -9 f -1139(+)X -1 f -1170(1)X -2 f -10 s -9 f -5200(-)Y -1 f -1242(1)X -1317(bits)X -1467(\(1)X -2 f -9 f -1534(+)X -1 f -1578(2)X -2 f -9 f -(+)S -1 f -1662(4)X -2 f -9 f -(+)S -1 f -1746(...)X -2 f -9 f -(+)S -1 f -1850(2)X -2 f -7 s -5168(n)Y -10 s -1 f -1931 5200(\))N -1992(which)X -432 5288(trace)N -649(the)X -807(entire)X -2 f -1050(split)X -1247(history)X -1 f -1529(of)X -1656(the)X -1813(addressable)X -16 s -432 5433 MXY -864 0 Dl -2 f -8 s -472 5488(2)N -1 f -9 s -523 5513(This)N -670(bit-randomizing)X -1153(property)X -1416(is)X -1482(important)X -1780(to)X -1854(obtain)X -2052(radi-)X -432 5593(cally)N -599(different)X -874(hash)X -1033(values)X -1244(for)X -1355(nearly)X -1562(identical)X -1836(keys,)X -2012(which)X -432 5673(in)N -506(turn)X -640(avoids)X -846(clustering)X -1148(of)X -1226(such)X -1376(keys)X -1526(in)X -1600(a)X -1650(single)X -1840(bucket.)X -10 s -2418 538(buckets.)N -2590 652(Given)N -2809(a)X -2868(key)X -3007(and)X -3146(the)X -3267(bitmap)X -3512(created)X -3768(by)X -3871(this)X -4009(algo-)X -2418 740(rithm,)N -2638(we)X -2759(\256rst)X -2910(examine)X -3209(bit)X -3320(0)X -3386(of)X -3479(the)X -3603(bitmap)X -3851(\(the)X -4002(bit)X -4112(to)X -2418 828(consult)N -2673(when)X -2871(0)X -2934(bits)X -3072(of)X -3162(the)X -3283(hash)X -3453(value)X -3650(are)X -3772(being)X -3973(exam-)X -2418 916(ined\).)N -2631(If)X -2713(it)X -2785(is)X -2866(set)X -2982(\(indicating)X -3356(that)X -3503(the)X -3628(bucket)X -3869(split\),)X -4080(we)X -2418 1004(begin)N -2617(considering)X -3012(the)X -3131(bits)X -3267(of)X -3355(the)X -3473(32-bit)X -3684(hash)X -3851(value.)X -4085(As)X -2418 1092(bit)N -2525(n)X -2587(is)X -2662(revealed,)X -2977(a)X -3035(mask)X -3226(equal)X -3422(to)X -3506(2)X -2 f -7 s -1060(n)Y -9 f -3583(+)X -1 f -3614(1)X -2 f -10 s -9 f -1092(-)Y -1 f -3686(1)X -3748(will)X -3894(yield)X -4076(the)X -2418 1180(current)N -2675(bucket)X -2918(address.)X -3228(Adding)X -3496(2)X -2 f -7 s -1148(n)Y -9 f -3573(+)X -1 f -3604(1)X -2 f -10 s -9 f -1180(-)Y -1 f -3676(1)X -3744(to)X -3834(the)X -3960(bucket)X -2418 1268(address)N -2701(identi\256es)X -3035(which)X -3272(bit)X -3397(in)X -3500(the)X -3639(bitmap)X -3902(must)X -4098(be)X -2418 1356(checked.)N -2743(We)X -2876(continue)X -3173(revealing)X -3493(bits)X -3628(of)X -3715(the)X -3833(hash)X -4000(value)X -2418 1444(until)N -2591(all)X -2698(set)X -2814(bits)X -2955(in)X -3043(the)X -3167(bitmap)X -3415(are)X -3540(exhausted.)X -3907(The)X -4058(fol-)X -2418 1532(lowing)N -2682(algorithm,)X -3055(a)X -3133(simpli\256cation)X -3614(of)X -3723(the)X -3863(algorithm)X -2418 1620(due)N -2565(to)X -2658(Ken)X -2823(Thompson)X -3196([THOM90,)X -3590(TOR88],)X -3908(uses)X -4076(the)X -2418 1708(hash)N -2625(value)X -2839(and)X -2995(the)X -3133(bitmap)X -3395(to)X -3497(calculate)X -3823(the)X -3960(bucket)X -2418 1796(address)N -2679(as)X -2766(discussed)X -3093(above.)X -0(Courier)xf 0 f -1 f -0 f -8 s -2418 2095(hash)N -2608(=)X -2684 -0.4038(calchash\(key\);)AX -2418 2183(mask)N -2608(=)X -2684(0;)X -2418 2271(while)N -2646 -0.4018(\(isbitset\(\(hash)AX -3254(&)X -3330(mask\))X -3558(+)X -3634(mask\)\))X -2706 2359(mask)N -2896(=)X -2972(\(mask)X -3200(<<)X -3314(1\))X -3428(+)X -3504(1;)X -2418 2447(bucket)N -2684(=)X -2760(hash)X -2950(&)X -3026(mask;)X -2 f -10 s -3211 2812(sdbm)N -1 f -2590 2944(The)N -2 f -2738(sdbm)X -1 f -2930(library)X -3167(is)X -3243(a)X -3302(public-domain)X -3791(clone)X -3987(of)X -4076(the)X -2 f -2418 3032(ndbm)N -1 f -2638(library,)X -2914(developed)X -3286(by)X -3408(Ozan)X -3620(Yigit)X -3826(to)X -3929(provide)X -2 f -2418 3120(ndbm)N -1 f -2596('s)X -2692(functionality)X -3139(under)X -3359(some)X -3565(versions)X -3869(of)X -3973(UNIX)X -2418 3208(that)N -2559(exclude)X -2830(it)X -2894(for)X -3008(licensing)X -3317(reasons)X -3578([YIG89].)X -3895(The)X -4040(pro-)X -2418 3296(grammer)N -2735(interface,)X -3064(and)X -3207(the)X -3332(basic)X -3524(structure)X -3832(of)X -2 f -3926(sdbm)X -1 f -4121(is)X -2418 3384(identical)N -2733(to)X -2 f -2834(ndbm)X -1 f -3051(but)X -3192(internal)X -3476(details)X -3723(of)X -3828(the)X -2 f -3964(access)X -1 f -2418 3472(function,)N -2726(such)X -2894(as)X -2982(the)X -3101(calculation)X -3474(of)X -3561(the)X -3679(bucket)X -3913(address,)X -2418 3560(and)N -2563(the)X -2690(use)X -2825(of)X -2920(different)X -3225(hash)X -3400(functions)X -3726(make)X -3928(the)X -4054(two)X -2418 3648(incompatible)N -2856(at)X -2934(the)X -3052(database)X -3349(level.)X -2590 3762(The)N -2 f -2740(sdbm)X -1 f -2934(library)X -3173(is)X -3251(based)X -3458(on)X -3562(a)X -3622(simpli\256ed)X -3965(imple-)X -2418 3850(mentation)N -2778(of)X -2885(Larson's)X -3206(1978)X -2 f -3406(dynamic)X -3717(hashing)X -1 f -4009(algo-)X -2418 3938(rithm)N -2616(including)X -2943(the)X -2 f -3066(re\256nements)X -3461(and)X -3605(variations)X -1 f -3953(of)X -4044(sec-)X -2418 4026(tion)N -2562(5)X -2622([LAR78].)X -2956(Larson's)X -3257(original)X -3526(algorithm)X -3857(calls)X -4024(for)X -4138(a)X -2418 4114(forest)N -2635(of)X -2736(binary)X -2975(hash)X -3156(trees)X -3341(that)X -3494(are)X -3626(accessed)X -3941(by)X -4054(two)X -2418 4202(hash)N -2586(functions.)X -2925(The)X -3071(\256rst)X -3216(hash)X -3384(function)X -3672(selects)X -3907(a)X -3964(partic-)X -2418 4290(ular)N -2571(tree)X -2720(within)X -2952(the)X -3078(forest.)X -3309(The)X -3462(second)X -3713(hash)X -3887(function,)X -2418 4378(which)N -2659(is)X -2757(required)X -3070(to)X -3177(be)X -3297(a)X -3377(boolean)X -3675(pseudo-random)X -2418 4466(number)N -2687(generator)X -3015(that)X -3159(is)X -3236(seeded)X -3479(by)X -3583(the)X -3705(key,)X -3865(is)X -3942(used)X -4112(to)X -2418 4554(traverse)N -2733(the)X -2890(tree)X -3070(until)X -3275(internal)X -3579(\(split\))X -3829(nodes)X -4075(are)X -2418 4642(exhausted)N -2763(and)X -2903(an)X -3003(external)X -3286(\(non-split\))X -3648(node)X -3827(is)X -3903(reached.)X -2418 4730(The)N -2571(bucket)X -2813(addresses)X -3149(are)X -3276(stored)X -3500(directly)X -3772(in)X -3861(the)X -3986(exter-)X -2418 4818(nal)N -2536(nodes.)X -2590 4932(Larson's)N -2903(re\256nements)X -3309(are)X -3440(based)X -3655(on)X -3767(the)X -3897(observa-)X -2418 5020(tion)N -2570(that)X -2718(the)X -2844(nodes)X -3059(can)X -3199(be)X -3303(represented)X -3702(by)X -3809(a)X -3872(single)X -4090(bit)X -2418 5108(that)N -2569(is)X -2653(set)X -2773(for)X -2898(internal)X -3174(nodes)X -3392(and)X -3539(not)X -3672(set)X -3791(for)X -3915(external)X -2418 5196(nodes,)N -2652(resulting)X -2959(in)X -3048(a)X -3111(radix)X -3303(search)X -3536(trie.)X -3709(Figure)X -3944(1)X -4010(illus-)X -2418 5284(trates)N -2621(this.)X -2804(Nodes)X -3037(A)X -3123(and)X -3267(B)X -3348(are)X -3475(internal)X -3748(\(split\))X -3967(nodes,)X -2418 5372(thus)N -2573(having)X -2813(no)X -2915(bucket)X -3151(addresses)X -3480(associated)X -3831(with)X -3994(them.)X -2418 5460(Instead,)N -2693(the)X -2814(external)X -3096(nodes)X -3306(\(C,)X -3429(D,)X -3530(and)X -3669(E\))X -3768(each)X -3938(need)X -4112(to)X -2418 5548(refer)N -2594(to)X -2679(a)X -2738(bucket)X -2975(address.)X -3279(These)X -3494(bucket)X -3731(addresses)X -4062(can)X -2418 5636(be)N -2529(stored)X -2760(in)X -2857(the)X -2990(trie)X -3132(itself)X -3327(where)X -3559(the)X -3691(subtries)X -3974(would)X -3 f -432 5960(2)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -3 p -%%Page: 3 3 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -1 f -720 538(live)N -862(if)X -933(they)X -1092(existed)X -1340([KNU68].)X -1709(For)X -1841(example,)X -2154(if)X -2224(nodes)X -2432(F)X -720 626(and)N -858(G)X -938(were)X -1117(the)X -1237(children)X -1522(of)X -1610(node)X -1787(C,)X -1881(the)X -2000(bucket)X -2235(address)X -720 714(L00)N -886(could)X -1101(reside)X -1330(in)X -1429(the)X -1563(bits)X -1714(that)X -1870(will)X -2030(eventually)X -2400(be)X -720 802(used)N -887(to)X -969(store)X -1145(nodes)X -1352(F)X -1416(and)X -1552(G)X -1630(and)X -1766(all)X -1866(their)X -2033(children.)X -10 f -720 890 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -1894 2247(L1)N -784 1925(A)N -1431(E)X -1106 2247(D)N -1428 1281(C)N -1109 1603(B)N -1884 1930(L01)N -1879 1286(L00)N -1221 1814(1)N -903 2131(1)N -1221 1402(0)N -903 1714(0)N -1 Dt -1397 1821 MXY --8 -32 Dl --5 19 Dl --20 6 Dl -33 7 Dl --187 -182 Dl -1397 1322 MXY --33 7 Dl -20 6 Dl -5 19 Dl -8 -32 Dl --187 182 Dl -1069 1639 MXY --32 7 Dl -20 6 Dl -5 19 Dl -7 -32 Dl --186 182 Dl -1374 1891 MXY -185 Dc -1779 2133 MXY -0 161 Dl -322 0 Dl -0 -161 Dl --322 0 Dl -1811 MY -0 161 Dl -322 0 Dl -0 -161 Dl --322 0 Dl -1166 MY -0 161 Dl -322 0 Dl -0 -161 Dl --322 0 Dl -1052 2213 MXY -185 Dc -1569 MY -185 Dc -720 1881 MXY -185 Dc -1779 2213 MXY --28 -17 Dl -10 17 Dl --10 18 Dl -28 -18 Dl --543 0 Dl -1769 1891 MXY --28 -18 Dl -10 18 Dl --10 18 Dl -28 -18 Dl --201 0 Dl -1364 1247 MXY -185 Dc -1769 MX --28 -18 Dl -10 18 Dl --10 18 Dl -28 -18 Dl --201 0 Dl -1064 2143 MXY --7 -32 Dl --5 19 Dl --20 6 Dl -32 7 Dl --181 -181 Dl -3 Dt --1 Ds -8 s -720 2482(Figure)N -925(1:)X -1 f -1002(Radix)X -1179(search)X -1365(trie)X -1474(with)X -1612(internal)X -1831(nodes)X -2004(A)X -2074(and)X -2189(B,)X -2271(external)X -720 2570(nodes)N -891(C,)X -972(D,)X -1056(and)X -1170(E,)X -1247(and)X -1361(bucket)X -1553(addresses)X -1819(stored)X -1997(in)X -2069(the)X -2168(unused)X -2370(por-)X -720 2658(tion)N -836(of)X -905(the)X -999(trie.)X -10 s -10 f -720 2922 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 f -892 3124(Further)N -1153(simpli\256cations)X -1647(of)X -1738(the)X -1860(above)X -2076([YIG89])X -2377(are)X -720 3212(possible.)N -1038(Using)X -1265(a)X -1337(single)X -1564(radix)X -1765(trie)X -1908(to)X -2006(avoid)X -2219(the)X -2352(\256rst)X -720 3300(hash)N -904(function,)X -1227(replacing)X -1562(the)X -1696(pseudo-random)X -2231(number)X -720 3388(generator)N -1052(with)X -1222(a)X -1286(well)X -1452(designed,)X -1785(bit-randomizing)X -2329(hash)X -720 3476(function,)N -1053(and)X -1215(using)X -1434(the)X -1578(portion)X -1855(of)X -1967(the)X -2110(hash)X -2302(value)X -720 3564(exposed)N -1021(during)X -1268(the)X -1404(trie)X -1549(traversal)X -1864(as)X -1969(a)X -2042(direct)X -2262(bucket)X -720 3652(address)N -990(results)X -1228(in)X -1319(an)X -2 f -1424(access)X -1 f -1663(function)X -1959(that)X -2108(works)X -2333(very)X -720 3740(similar)N -974(to)X -1068(Thompson's)X -1499(algorithm)X -1841(above.)X -2084(The)X -2240(follow-)X -720 3828(ing)N -847(algorithm)X -1183(uses)X -1346(the)X -1469(hash)X -1641(value)X -1840(to)X -1927(traverse)X -2206(a)X -2266(linear-)X -720 3916(ized)N -874(radix)X -1059(trie)X -2 f -8 s -1166 3891(3)N -1 f -10 s -1218 3916(starting)N -1478(at)X -1556(the)X -1674(0)X -2 f -7 s -3884(th)Y -10 s -1 f -1791 3916(bit.)N -0 f -8 s -720 4215(tbit)N -910(=)X -986(0;)X -1296(/*)X -1410(radix)X -1638(trie)X -1828(index)X -2056(*/)X -720 4303(hbit)N -910(=)X -986(0;)X -1296(/*)X -1410(hash)X -1600(bit)X -1752(index)X -2056(*/)X -720 4391(mask)N -910(=)X -986(0;)X -720 4479(hash)N -910(=)X -986 -0.4038(calchash\(key\);)AX -720 4655(for)N -872(\(mask)X -1100(=)X -1176(0;)X -910 4743 -0.4018(isbitset\(tbit\);)AN -910 4831(mask)N -1100(=)X -1176(\(mask)X -1404(<<)X -1518(1\))X -1632(+)X -1708(1\))X -1008 4919(if)N -1122(\(hash)X -1350(&)X -1426(\(1)X -1540(<<)X -1654 -0.4219(hbit++\)\)\))AX -1160 5007(/*)N -1274(right)X -1502(son)X -1692(*/)X -1160 5095(tbit)N -1350(=)X -1426(2)X -1502(*)X -1578(tbit)X -1768(+)X -1844(2;)X -1008 5183(else)N -1 f -16 s -720 5353 MXY -864 0 Dl -2 f -8 s -760 5408(3)N -1 f -9 s -818 5433(A)N -896(linearized)X -1206(radix)X -1380(trie)X -1502(is)X -1576(merely)X -1802(an)X -1895(array)X -2068(representation)X -720 5513(of)N -800(the)X -908(radix)X -1076(search)X -1280(trie)X -1396(described)X -1692(above.)X -1920(The)X -2052(children)X -2308(of)X -2388(the)X -720 5593(node)N -885(with)X -1038(index)X -1223(i)X -1267(can)X -1391(be)X -1483(found)X -1675(at)X -1751(the)X -1863(nodes)X -2055(indexed)X -2307(2*i+1)X -720 5673(and)N -842(2*i+2.)X -0 f -8 s -3146 538(/*)N -3260(left)X -3450(son)X -3678(*/)X -3146 626(tbit)N -3336(=)X -3412(2)X -3488(*)X -3564(tbit)X -3754(+)X -3830(1;)X -2706 802(bucket)N -2972(=)X -3048(hash)X -3238(&)X -3314(mask;)X -2 f -10 s -3495 1167(gdbm)N -1 f -2878 1299(The)N -3027(gdbm)X -3233(\(GNU)X -3458(data)X -3616(base)X -3783(manager\))X -4111(library)X -4349(is)X -4426(a)X -2706 1387(UNIX)N -2933(database)X -3236(manager)X -3539(written)X -3792(by)X -3897(Philip)X -4112(A.)X -4215(Nelson,)X -2706 1475(and)N -2848(made)X -3048(available)X -3364(as)X -3457(a)X -3518(part)X -3668(of)X -3760(the)X -3883(FSF)X -4040(software)X -4342(dis-)X -2706 1563(tribution.)N -3052(The)X -3207(gdbm)X -3419(library)X -3663(provides)X -3969(the)X -4097(same)X -4292(func-)X -2706 1651(tionality)N -3028(of)X -3151(the)X -2 f -3304(dbm)X -1 f -3442(/)X -2 f -3464(ndbm)X -1 f -3697(libraries)X -4015([NEL90])X -4360(but)X -2706 1739(attempts)N -3018(to)X -3121(avoid)X -3340(some)X -3550(of)X -3658(their)X -3846(shortcomings.)X -4337(The)X -2706 1827(gdbm)N -2918(library)X -3162(allows)X -3401(for)X -3525(arbitrary-length)X -4059(data,)X -4242(and)X -4387(its)X -2706 1915(database)N -3027(is)X -3124(a)X -3203(singular,)X -3524(non-sparse)X -2 f -8 s -3872 1890(4)N -1 f -10 s -3947 1915(\256le.)N -4112(The)X -4280(gdbm)X -2706 2003(library)N -2947(also)X -3103(includes)X -2 f -3396(dbm)X -1 f -3560(and)X -2 f -3702(ndbm)X -1 f -3906(compatible)X -4288(inter-)X -2706 2091(faces.)N -2878 2205(The)N -3025(gdbm)X -3229(library)X -3465(is)X -3540(based)X -3745(on)X -2 f -3847(extensible)X -4189(hashing)X -1 f -4442(,)X -2706 2293(a)N -2766(dynamic)X -3066(hashing)X -3339(algorithm)X -3674(by)X -3778(Fagin)X -3984(et)X -4066(al)X -4148([FAG79].)X -2706 2381(This)N -2881(algorithm)X -3225(differs)X -3467(from)X -3655(the)X -3785(previously)X -4155(discussed)X -2706 2469(algorithms)N -3069(in)X -3152(that)X -3293(it)X -3358(uses)X -3517(a)X -2 f -3574(directory)X -1 f -3889(that)X -4030(is)X -4103(a)X -4159(collapsed)X -2706 2557(representation)N -3192([ENB88])X -3517(of)X -3615(the)X -3744(radix)X -3940(search)X -4177(trie)X -4315(used)X -2706 2645(by)N -2 f -2806(sdbm)X -1 f -2975(.)X -10 f -2706 2733 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -7 s -3572 3761(L1)N -1 Dt -3485 3738 MXY --20 -13 Dl -7 13 Dl --7 13 Dl -20 -13 Dl --400 0 Dl -3180 3027 MXY -136 Dc -2706 3494 MXY -136 Dc -2950 3264 MXY -136 Dc -3738 MY -136 Dc -3485 2968 MXY -0 118 Dl -238 0 Dl -0 -118 Dl --238 0 Dl -3442 MY -0 119 Dl -238 0 Dl -0 -119 Dl --238 0 Dl -3679 MY -0 119 Dl -238 0 Dl -0 -119 Dl --238 0 Dl -3187 3501 MXY -136 Dc -2963 3316 MXY --24 5 Dl -15 4 Dl -4 15 Dl -5 -24 Dl --137 134 Dl -3204 3083 MXY --24 5 Dl -15 4 Dl -3 14 Dl -6 -23 Dl --137 133 Dl -3204 3450 MXY --6 -24 Dl --3 14 Dl --15 5 Dl -24 5 Dl --137 -134 Dl -2842 3369(0)N -3075 3139(0)N -2842 3676(1)N -3075 3443(1)N -3562 3054(L00)N -3565 3528(L01)N -4197 2968 MXY -0 118 Dl -237 0 Dl -0 -118 Dl --237 0 Dl -3205 MY -0 119 Dl -237 0 Dl -0 -119 Dl --237 0 Dl -3561 MY -0 118 Dl -237 0 Dl -0 -118 Dl --237 0 Dl -3960 2909 MXY -0 237 Dl -118 0 Dl -0 -237 Dl --118 0 Dl -3146 MY -0 237 Dl -118 0 Dl -0 -237 Dl --118 0 Dl -3383 MY -0 237 Dl -118 0 Dl -0 -237 Dl --118 0 Dl -3620 MY -0 237 Dl -118 0 Dl -0 -237 Dl --118 0 Dl -4197 3027 MXY --21 -13 Dl -8 13 Dl --8 13 Dl -21 -13 Dl --119 0 Dl -4197 3264 MXY --21 -13 Dl -8 13 Dl --8 13 Dl -21 -13 Dl --119 0 Dl -3501 MY -59 0 Dl -0 89 Dl -4078 3738 MXY -59 0 Dl -0 -88 Dl -4197 3590 MXY --21 -13 Dl -8 13 Dl --8 13 Dl -21 -13 Dl --60 0 Dl -4197 3650 MXY --21 -13 Dl -8 13 Dl --8 13 Dl -21 -13 Dl --60 0 Dl -3991 3050(00)N -3991 3287(01)N -3991 3524(10)N -3991 3761(11)N -4269 3050(L00)N -4269 3287(L01)N -4283 3643(L1)N -3485 3501 MXY --20 -13 Dl -7 13 Dl --7 13 Dl -20 -13 Dl --155 0 Dl -3485 3027 MXY --20 -13 Dl -7 13 Dl --7 13 Dl -20 -13 Dl --163 0 Dl -2967 3687 MXY --5 -24 Dl --4 14 Dl --15 4 Dl -24 6 Dl --141 -141 Dl -3 Dt --1 Ds -8 s -2706 4033(Figure)N -2903(2:)X -1 f -2972(A)X -3034(radix)X -3181(search)X -3359(trie)X -3460(and)X -3568(a)X -3612(directory)X -3858(representing)X -4189(the)X -4283(trie.)X -10 s -10 f -2706 4209 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 f -2878 4411(In)N -2968(this)X -3106(algorithm,)X -3460(a)X -3519(directory)X -3832(consists)X -4108(of)X -4198(a)X -4256(search)X -2706 4499(trie)N -2847(of)X -2947(depth)X -2 f -3158(n)X -1 f -3211(,)X -3264(containing)X -3635(2)X -2 f -7 s -4467(n)Y -10 s -1 f -3749 4499(bucket)N -3996(addresses)X -4337(\(i.e.)X -2706 4587(each)N -2897(element)X -3194(of)X -3304(the)X -3445(trie)X -3594(is)X -3689(a)X -3767(bucket)X -4023(address\).)X -4373(To)X -2706 4675(access)N -2935(the)X -3056(hash)X -3226(table,)X -3425(a)X -3483(32-bit)X -3696(hash)X -3865(value)X -4061(is)X -4136(calculated)X -2706 4763(and)N -2 f -2861(n)X -1 f -2953(bits)X -3107(of)X -3213(the)X -3350(value)X -3563(are)X -3701(used)X -3886(to)X -3986(index)X -4202(into)X -4364(the)X -2706 4851(directory)N -3018(to)X -3102(obtain)X -3324(a)X -3382(bucket)X -3618(address.)X -3921(It)X -3992(is)X -4067(important)X -4400(to)X -2706 4939(note)N -2866(that)X -3008(multiple)X -3296(entries)X -3532(of)X -3620(this)X -3756(directory)X -4067(may)X -4226(contain)X -2706 5027(the)N -2833(same)X -3026(bucket)X -3268(address)X -3537(as)X -3632(a)X -3696(result)X -3902(of)X -3997(directory)X -4315(dou-)X -2706 5115(bling)N -2903(during)X -3145(bucket)X -3392(splitting.)X -3706(Figure)X -3948(2)X -4021(illustrates)X -4364(the)X -2706 5203(relationship)N -3126(between)X -3436(a)X -3513(typical)X -3772(\(skewed\))X -4108(search)X -4355(trie)X -2706 5291(and)N -2850(its)X -2953(directory)X -3271(representation.)X -3774(The)X -3927(formation)X -4270(of)X -4364(the)X -2706 5379(directory)N -3016(shown)X -3245(in)X -3327(the)X -3445(\256gure)X -3652(is)X -3725(as)X -3812(follows.)X -16 s -2706 5593 MXY -864 0 Dl -2 f -8 s -2746 5648(4)N -1 f -9 s -2796 5673(It)N -2858(does)X -3008(not)X -3118(contain)X -3348(holes.)X -3 f -10 s -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4424(3)X - -4 p -%%Page: 4 4 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -1 f -604 538(Initially,)N -937(there)X -1158(is)X -1271(one)X -1446(slot)X -1620(in)X -1741(the)X -1898(directory)X -432 626(addressing)N -802(a)X -865(single)X -1083(bucket.)X -1364(The)X -1515(depth)X -1719(of)X -1812(the)X -1936(trie)X -2069(is)X -2148(0)X -432 714(and)N -577(0)X -646(bits)X -790(of)X -886(each)X -1063(hash)X -1239(value)X -1442(are)X -1570(examined)X -1910(to)X -2000(deter-)X -432 802(mine)N -624(in)X -718(which)X -946(bucket)X -1192(to)X -1286(place)X -1488(a)X -1556(key;)X -1726(all)X -1837(keys)X -2015(go)X -2126(in)X -432 890(bucket)N -682(0.)X -797(When)X -1024(this)X -1174(bucket)X -1423(is)X -1511(full,)X -1677(its)X -1787(contents)X -2089(are)X -432 978(divided)N -698(between)X -992(L0)X -1107(and)X -1249(L1)X -1363(as)X -1455(was)X -1605(done)X -1786(in)X -1873(the)X -1996(previ-)X -432 1066(ously)N -664(discussed)X -1030(algorithms.)X -1471(After)X -1700(this)X -1874(split,)X -2090(the)X -432 1154(address)N -710(of)X -814(the)X -948(second)X -1207(bucket)X -1457(must)X -1648(be)X -1760(stored)X -1992(in)X -2090(the)X -432 1242(directory.)N -796(To)X -939(accommodate)X -1438(the)X -1589(new)X -1776(address,)X -2090(the)X -432 1330(directory)N -752(is)X -835(split)X -2 f -8 s -972 1305(5)N -1 f -10 s -1330(,)Y -1054(by)X -1163(doubling)X -1476(it,)X -1569(thus)X -1731(increasing)X -2090(the)X -432 1418(depth)N -630(of)X -717(the)X -835(directory)X -1145(by)X -1245(one.)X -604 1532(After)N -813(this)X -967(split,)X -1163(a)X -1237(single)X -1466(bit)X -1588(of)X -1693(the)X -1829(hash)X -2014(value)X -432 1620(needs)N -663(to)X -773(be)X -896(examined)X -1255(to)X -1364(decide)X -1621(whether)X -1927(the)X -2072(key)X -432 1708(belongs)N -711(to)X -803(L0)X -922(or)X -1019(L1.)X -1158(Once)X -1358(one)X -1504(of)X -1601(these)X -1795(buckets)X -2069(\256lls)X -432 1796(\(L0)N -578(for)X -702(example\),)X -1051(it)X -1125(is)X -1208(split)X -1375(as)X -1472(before,)X -1728(and)X -1873(the)X -2000(direc-)X -432 1884(tory)N -585(is)X -662(split)X -823(again)X -1021(to)X -1107(make)X -1305(room)X -1498(for)X -1615(the)X -1736(address)X -2000(of)X -2090(the)X -432 1972(third)N -618(bucket.)X -927(This)X -1104(splitting)X -1400(causes)X -1645(the)X -1778(addresses)X -2121(of)X -432 2060(the)N -567(non-splitting)X -1012(bucket)X -1263(\(L1\))X -1443(to)X -1541(be)X -1653(duplicated.)X -2063(The)X -432 2148(directory)N -766(now)X -948(has)X -1099(four)X -1277(entries,)X -1555(a)X -1635(depth)X -1857(of)X -1968(2,)X -2072(and)X -432 2236(indexes)N -700(the)X -821(buckets)X -1089(L00,)X -1261(L01)X -1413(and)X -1552(L1,)X -1684(as)X -1774(shown)X -2006(in)X -2090(the)X -432 2324(Figure)N -661(2.)X -604 2438(The)N -756(crucial)X -1002(part)X -1154(of)X -1247(the)X -1371(algorithm)X -1708(is)X -1787(the)X -1911(observa-)X -432 2526(tion)N -580(that)X -724(L1)X -837(is)X -914(addressed)X -1255(twice)X -1453(in)X -1539(the)X -1661(directory.)X -1995(If)X -2073(this)X -432 2614(bucket)N -679(were)X -869(to)X -964(split)X -1134(now,)X -1324(the)X -1454(directory)X -1776(already)X -2045(con-)X -432 2702(tains)N -611(room)X -808(to)X -898(hold)X -1067(the)X -1192(address)X -1460(of)X -1554(the)X -1679(new)X -1840(bucket.)X -2121(In)X -432 2790(general,)N -711(the)X -831(relationship)X -1231(between)X -1521(the)X -1641(directory)X -1953(and)X -2090(the)X -432 2878(number)N -704(of)X -798(bucket)X -1039(addresses)X -1374(contained)X -1713(therein)X -1962(is)X -2041(used)X -432 2966(to)N -517(decide)X -750(when)X -947(to)X -1031(split)X -1190(the)X -1310(directory.)X -1662(Each)X -1845(bucket)X -2081(has)X -432 3054(a)N -505(depth,)X -740(\()X -2 f -767(n)X -7 s -3070(b)Y -10 s -1 f -848 3054(\),)N -932(associated)X -1299(with)X -1478(it)X -1558(and)X -1710(appears)X -1992(in)X -2090(the)X -432 3142(directory)N -744(exactly)X -998(2)X -2 f -7 s -3106(n)Y -9 f -1075(-)X -2 f -1106(n)X -4 s -3110(b)Y -7 s -1 f -10 s -1181 3142(times.)N -1396(When)X -1610(a)X -1668(bucket)X -1904(splits,)X -2113(its)X -432 3230(depth)N -638(increases)X -961(by)X -1069(one.)X -1253(The)X -1406(directory)X -1724(must)X -1907(split)X -2072(any)X -432 3318(time)N -602(a)X -665(bucket's)X -964(depth)X -1169(exceeds)X -1451(the)X -1576(depth)X -1781(of)X -1875(the)X -2000(direc-)X -432 3406(tory.)N -630(The)X -784(following)X -1123(code)X -1303(fragment)X -1621(helps)X -1818(to)X -1908(illustrate)X -432 3494(the)N -554(extendible)X -912(hashing)X -1185(algorithm)X -1520([FAG79])X -1838(for)X -1955(access-)X -432 3582(ing)N -554(individual)X -898(buckets)X -1163(and)X -1299(maintaining)X -1701(the)X -1819(directory.)X -0 f -8 s -432 3881(hash)N -622(=)X -698 -0.4038(calchash\(key\);)AX -432 3969(mask)N -622(=)X -698 -0.4018(maskvec[depth];)AX -432 4145(bucket)N -698(=)X -774 -0.4038(directory[hash)AX -1344(&)X -1420(mask];)X -432 4321(/*)N -546(Key)X -698 -0.4219(Insertion)AX -1078(*/)X -432 4409(if)N -546 -0.4038(\(store\(bucket,)AX -1116(key,)X -1306(data\))X -1534(==)X -1648(FAIL\))X -1876({)X -720 4497(newbl)N -948(=)X -1024 -0.4167(getpage\(\);)AX -720 4585 -0.4000(bucket->depth++;)AN -720 4673 -0.4091(newbl->depth)AN -1214(=)X -1290 -0.4038(bucket->depth;)AX -720 4761(if)N -834 -0.4038(\(bucket->depth)AX -1404(>)X -1480(depth\))X -1746({)X -1008 4849(/*)N -1122(double)X -1388 -0.4219(directory)AX -1768(*/)X -1008 4937(depth++;)N -1 f -16 s -432 5033 MXY -864 0 Dl -2 f -8 s -472 5088(5)N -1 f -9 s -534 5113(This)N -692(decision)X -962(to)X -1048(split)X -1202(the)X -1319(directory)X -1608(is)X -1685(based)X -1878(on)X -1979(a)X -2040(com-)X -432 5193(parison)N -666(of)X -748(the)X -858(depth)X -1040(of)X -1121(the)X -1230(page)X -1387(being)X -1568(split)X -1713(and)X -1838(the)X -1947(depth)X -2128(of)X -432 5273(the)N -543(trie.)X -698(In)X -781(Figure)X -992(2,)X -1069(the)X -1180(depths)X -1390(of)X -1472(both)X -1622(L00)X -1760(and)X -1886(L01)X -2024(are)X -2134(2,)X -432 5353(whereas)N -689(the)X -798(depth)X -979(of)X -1060(L1)X -1161(is)X -1230(1.)X -1323(Therefore,)X -1646(if)X -1710(L1)X -1810(were)X -1970(to)X -2046(split,)X -432 5433(the)N -543(directory)X -826(would)X -1029(not)X -1144(need)X -1303(to)X -1382(split.)X -1565(In)X -1648(reality,)X -1872(a)X -1926(bucket)X -2140(is)X -432 5513(allocated)N -727(for)X -846(the)X -969(directory)X -1264(at)X -1351(the)X -1474(time)X -1637(of)X -1732(\256le)X -1858(creation)X -2124(so)X -432 5593(although)N -707(the)X -818(directory)X -1100(splits)X -1274(logically,)X -1566(physical)X -1828(splits)X -2002(do)X -2096(not)X -432 5673(occur)N -610(until)X -760(the)X -866(\256le)X -976(becomes)X -1246(quite)X -1408(large.)X -0 f -8 s -2994 538 -0.4219(directory)AN -3374(=)X -3450 -0.3971(double\(directory\);)AX -2706 626(})N -2706 714 -0.3958(splitbucket\(bucket,)AN -3466(newbl\))X -2706 802(...)N -2418 890(})N -2 f -10 s -3169 1255(hsearch)N -1 f -2590 1387(Since)N -2 f -2807(hsearch)X -1 f -3100(does)X -3286(not)X -3427(have)X -3617(to)X -3717(translate)X -4027(hash)X -2418 1475(values)N -2659(into)X -2819(disk)X -2988(addresses,)X -3352(it)X -3432(can)X -3579(use)X -3721(much)X -3934(simpler)X -2418 1563(algorithms)N -2808(than)X -2994(those)X -3211(de\256ned)X -3495(above.)X -3775(System)X -4058(V's)X -2 f -2418 1651(hsearch)N -1 f -2708(constructs)X -3069(a)X -3141(\256xed-size)X -3489(hash)X -3671(table)X -3862(\(speci\256ed)X -2418 1739(by)N -2519(the)X -2637(user)X -2791(at)X -2869(table)X -3045(creation\).)X -3391(By)X -3504(default,)X -3767(a)X -3823(multiplica-)X -2418 1827(tive)N -2570(hash)X -2748(function)X -3046(based)X -3260(on)X -3371(that)X -3522(described)X -3861(in)X -3954(Knuth,)X -2418 1915(Volume)N -2710(3,)X -2804(section)X -3065(6.4)X -3199([KNU68])X -3541(is)X -3628(used)X -3809(to)X -3905(obtain)X -4138(a)X -2418 2003(primary)N -2694(bucket)X -2930(address.)X -3233(If)X -3309(this)X -3446(bucket)X -3681(is)X -3755(full,)X -3907(a)X -3964(secon-)X -2418 2091(dary)N -2593(multiplicative)X -3069(hash)X -3248(value)X -3454(is)X -3538(computed)X -3885(to)X -3978(de\256ne)X -2418 2179(the)N -2542(probe)X -2751(interval.)X -3062(The)X -3213(probe)X -3422(interval)X -3693(is)X -3772(added)X -3989(to)X -4076(the)X -2418 2267(original)N -2712(bucket)X -2971(address)X -3257(\(modulo)X -3573(the)X -3716(table)X -3916(size\))X -4112(to)X -2418 2355(obtain)N -2658(a)X -2734(new)X -2908(bucket)X -3162(address.)X -3483(This)X -3665(process)X -3946(repeats)X -2418 2443(until)N -2588(an)X -2688(empty)X -2911(bucket)X -3148(is)X -3224(found.)X -3474(If)X -3551(no)X -3654(bucket)X -3891(is)X -3967(found,)X -2418 2531(an)N -2514(insertion)X -2814(fails)X -2972(with)X -3134(a)X -3190(``table)X -3420(full'')X -3605(condition.)X -2590 2645(The)N -2768(basic)X -2986(algorithm)X -3350(may)X -3541(be)X -3670(modi\256ed)X -4006(by)X -4138(a)X -2418 2733(number)N -2705(of)X -2813(compile)X -3112(time)X -3295(options)X -3571(available)X -3902(to)X -4005(those)X -2418 2821(users)N -2604(with)X -2767(AT&T)X -3006(source)X -3237(code.)X -3450(First,)X -3637(the)X -3756(package)X -4040(pro-)X -2418 2909(vides)N -2638(two)X -2809(options)X -3094(for)X -3238(hash)X -3435(functions.)X -3803(Users)X -4036(may)X -2418 2997(specify)N -2690(their)X -2877(own)X -3055(hash)X -3242(function)X -3549(by)X -3669(compiling)X -4032(with)X -2418 3085(``USCR'')N -2757(de\256ned)X -3016(and)X -3155(declaring)X -3477(and)X -3616(de\256ning)X -3901(the)X -4022(vari-)X -2418 3173(able)N -2 f -2578(hcompar)X -1 f -2863(,)X -2909(a)X -2971(function)X -3263(taking)X -3488(two)X -3633(string)X -3840(arguments)X -2418 3261(and)N -2560(returning)X -2880(an)X -2982(integer.)X -3271(Users)X -3480(may)X -3643(also)X -3797(request)X -4054(that)X -2418 3349(hash)N -2587(values)X -2814(be)X -2912(computed)X -3250(simply)X -3489(by)X -3590(taking)X -3811(the)X -3930(modulo)X -2418 3437(of)N -2521(key)X -2673(\(using)X -2909(division)X -3201(rather)X -3424(than)X -3597(multiplication)X -4080(for)X -2418 3525(hash)N -2589(value)X -2787(calculation\).)X -3230(If)X -3308(this)X -3447(technique)X -3783(is)X -3859(used,)X -4049(col-)X -2418 3613(lisions)N -2651(are)X -2775(resolved)X -3072(by)X -3176(scanning)X -3485(sequentially)X -3896(from)X -4076(the)X -2418 3701(selected)N -2702(bucket)X -2941(\(linear)X -3176(probing\).)X -3517(This)X -3684(option)X -3913(is)X -3991(avail-)X -2418 3789(able)N -2572(by)X -2672(de\256ning)X -2954(the)X -3072(variable)X -3351(``DIV'')X -3622(at)X -3700(compile)X -3978(time.)X -2590 3903(A)N -2720(second)X -3015(option,)X -3311(based)X -3565(on)X -3716(an)X -3863(algorithm)X -2418 3991(discovered)N -2787(by)X -2888(Richard)X -3163(P.)X -3248(Brent,)X -3466(rearranges)X -3822(the)X -3940(table)X -4116(at)X -2418 4079(the)N -2549(time)X -2724(of)X -2824(insertion)X -3137(in)X -3232(order)X -3434(to)X -3528(speed)X -3743(up)X -3855(retrievals.)X -2418 4167(The)N -2571(basic)X -2764(idea)X -2926(is)X -3007(to)X -3097(shorten)X -3361(long)X -3531(probe)X -3741(sequences)X -4094(by)X -2418 4255(lengthening)N -2833(short)X -3030(probe)X -3249(sequences.)X -3651(Once)X -3857(the)X -3991(probe)X -2418 4343(chain)N -2613(has)X -2741(exceeded)X -3062(some)X -3252(threshold)X -3571(\(Brent)X -3796(suggests)X -4087(2\),)X -2418 4431(we)N -2541(attempt)X -2809(to)X -2899(shuf\257e)X -3145(any)X -3289(colliding)X -3601(keys)X -3776(\(keys)X -3978(which)X -2418 4519(appeared)N -2734(in)X -2821(the)X -2944(probe)X -3152(sequence)X -3471(of)X -3562(the)X -3684(new)X -3842(key\).)X -4049(The)X -2418 4607(details)N -2652(of)X -2744(this)X -2884(key)X -3025(shuf\257ing)X -3333(can)X -3469(be)X -3569(found)X -3780(in)X -3866([KNU68])X -2418 4695(and)N -2576([BRE73].)X -2946(This)X -3129(algorithm)X -3481(may)X -3660(be)X -3777(obtained)X -4094(by)X -2418 4783(de\256ning)N -2700(the)X -2818(variable)X -3097(``BRENT'')X -3487(at)X -3565(compile)X -3843(time.)X -2590 4897(A)N -2698(third)X -2899(set)X -3038(of)X -3154(options,)X -3458(obtained)X -3783(by)X -3912(de\256ning)X -2418 4985(``CHAINED'',)N -2943(use)X -3086(linked)X -3321(lists)X -3484(to)X -3581(resolve)X -3848(collisions.)X -2418 5073(Either)N -2647(of)X -2747(the)X -2878(primary)X -3164(hash)X -3343(function)X -3642(described)X -3982(above)X -2418 5161(may)N -2584(be)X -2688(used,)X -2882(but)X -3011(all)X -3118(collisions)X -3451(are)X -3577(resolved)X -3876(by)X -3983(build-)X -2418 5249(ing)N -2554(a)X -2623(linked)X -2856(list)X -2986(of)X -3086(entries)X -3333(from)X -3522(the)X -3653(primary)X -3940(bucket.)X -2418 5337(By)N -2542(default,)X -2816(new)X -2981(entries)X -3226(will)X -3381(be)X -3488(added)X -3711(to)X -3804(a)X -3871(bucket)X -4116(at)X -2418 5425(the)N -2541(beginning)X -2886(of)X -2978(the)X -3101(bucket)X -3339(chain.)X -3577(However,)X -3916(compile)X -2418 5513(options)N -2706(``SORTUP'')X -3173(or)X -3293(``SORTDOWN'')X -3908(may)X -4098(be)X -2418 5601(speci\256ed)N -2723(to)X -2805(order)X -2995(the)X -3113(hash)X -3280(chains)X -3505(within)X -3729(each)X -3897(bucket.)X -3 f -432 5960(4)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -5 p -%%Page: 5 5 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -2 f -1444 538(dynahash)N -1 f -892 670(The)N -2 f -1054(dynahash)X -1 f -1398(library,)X -1669(written)X -1932(by)X -2048(Esmond)X -2346(Pitt,)X -720 758(implements)N -1183(Larson's)X -1554(linear)X -1827(hashing)X -2165(algorithm)X -720 846([LAR88])N -1097(with)X -1302(an)X -2 f -1440(hsearch)X -1 f -1756(compatible)X -2174(interface.)X -720 934(Intuitively,)N -1099(a)X -1161(hash)X -1334(table)X -1516(begins)X -1751(as)X -1844(a)X -1905(single)X -2121(bucket)X -2360(and)X -720 1022(grows)N -941(in)X -1028(generations,)X -1443(where)X -1665(a)X -1725(generation)X -2088(corresponds)X -720 1110(to)N -815(a)X -884(doubling)X -1201(in)X -1296(the)X -1427(size)X -1585(of)X -1685(the)X -1815(hash)X -1994(table.)X -2222(The)X -2379(0)X -2 f -7 s -1078(th)Y -10 s -1 f -720 1198(generation)N -1085(occurs)X -1321(as)X -1414(the)X -1538(table)X -1719(grows)X -1940(from)X -2121(one)X -2262(bucket)X -720 1286(to)N -814(two.)X -1006(In)X -1105(the)X -1235(next)X -1405(generation)X -1776(the)X -1906(table)X -2093(grows)X -2320(from)X -720 1374(two)N -862(to)X -946(four.)X -1122(During)X -1371(each)X -1541(generation,)X -1921(every)X -2121(bucket)X -2356(that)X -720 1462(existed)N -967(at)X -1045(the)X -1163(beginning)X -1503(of)X -1590(the)X -1708(generation)X -2067(is)X -2140(split.)X -892 1576(The)N -1041(table)X -1221(starts)X -1414(as)X -1505(a)X -1565(single)X -1780(bucket)X -2018(\(numbered)X -2389(0\),)X -720 1664(the)N -839(current)X -1088(split)X -1245(bucket)X -1479(is)X -1552(set)X -1661(to)X -1743(bucket)X -1977(0,)X -2057(and)X -2193(the)X -2311(max-)X -720 1752(imum)N -933(split)X -1097(point)X -1288(is)X -1368(set)X -1483(to)X -1571(twice)X -1771(the)X -1895(current)X -2149(split)X -2312(point)X -720 1840(\(0\).)N -863(When)X -1084(it)X -1157(is)X -1239(time)X -1410(for)X -1532(a)X -1596(bucket)X -1838(to)X -1928(split,)X -2113(the)X -2239(keys)X -2414(in)X -720 1928(the)N -872(current)X -1154(split)X -1345(bucket)X -1612(are)X -1764(divided)X -2057(between)X -2378(the)X -720 2016(current)N -981(split)X -1151(bucket)X -1397(and)X -1545(a)X -1613(new)X -1779(bucket)X -2025(whose)X -2262(bucket)X -720 2104(number)N -1000(is)X -1088(equal)X -1297(to)X -1394(1)X -1469(+)X -1549(current)X -1812(split)X -1984(bucket)X -2232(+)X -2311(max-)X -720 2192(imum)N -927(split)X -1085(point.)X -1310(We)X -1442(can)X -1574(determine)X -1915(which)X -2131(keys)X -2298(move)X -720 2280(to)N -807(the)X -929(new)X -1087(bucket)X -1325(by)X -1429(examining)X -1791(the)X -2 f -1913(n)X -7 s -1962 2248(th)N -10 s -1 f -2043 2280(bit)N -2151(of)X -2242(a)X -2302(key's)X -720 2368(hash)N -899(value)X -1105(where)X -1334(n)X -1406(is)X -1491(the)X -1620(generation)X -1990(number.)X -2306(After)X -720 2456(the)N -846(bucket)X -1088(at)X -1174(the)X -1300(maximum)X -1651(split)X -1815(point)X -2006(has)X -2140(been)X -2319(split,)X -720 2544(the)N -839(generation)X -1198(number)X -1463(is)X -1536(incremented,)X -1973(the)X -2091(current)X -2339(split)X -720 2632(point)N -908(is)X -985(set)X -1098(back)X -1274(to)X -1360(zero,)X -1543(and)X -1683(the)X -1805(maximum)X -2152(split)X -2312(point)X -720 2720(is)N -815(set)X -946(to)X -1050(the)X -1190(number)X -1477(of)X -1586(the)X -1725(last)X -1877(bucket)X -2132(in)X -2235(the)X -2374(\256le)X -720 2808(\(which)N -971(is)X -1052(equal)X -1253(to)X -1342(twice)X -1543(the)X -1668(old)X -1797(maximum)X -2148(split)X -2312(point)X -720 2896(plus)N -873(1\).)X -892 3010(To)N -1031(facilitate)X -1361(locating)X -1668(keys,)X -1884(we)X -2027(maintain)X -2356(two)X -720 3098(masks.)N -989(The)X -1143(low)X -1291(mask)X -1488(is)X -1569(equal)X -1771(to)X -1861(the)X -1987(maximum)X -2339(split)X -720 3186(bucket)N -967(and)X -1116(the)X -1247(high)X -1422(mask)X -1624(is)X -1710(equal)X -1917(to)X -2011(the)X -2141(next)X -2311(max-)X -720 3274(imum)N -931(split)X -1093(bucket.)X -1372(To)X -1486(locate)X -1703(a)X -1764(speci\256c)X -2033(key,)X -2193(we)X -2311(com-)X -720 3362(pute)N -881(a)X -940(32-bit)X -1154(hash)X -1324(value)X -1520(using)X -1715(a)X -1773(bit-randomizing)X -2311(algo-)X -720 3450(rithm)N -932(such)X -1118(as)X -1224(the)X -1361(one)X -1516(described)X -1862(in)X -1962([LAR88].)X -2334(This)X -720 3538(hash)N -893(value)X -1093(is)X -1172(then)X -1336(masked)X -1607(with)X -1775(the)X -1898(high)X -2065(mask.)X -2299(If)X -2378(the)X -720 3626(resulting)N -1026(number)X -1297(is)X -1376(greater)X -1626(than)X -1790(the)X -1913(maximum)X -2262(bucket)X -720 3714(in)N -823(the)X -962(table)X -1159(\(current)X -1455(split)X -1633(bucket)X -1888(+)X -1974(maximum)X -2339(split)X -720 3802(point\),)N -962(the)X -1091(hash)X -1269(value)X -1474(is)X -1558(masked)X -1834(with)X -2007(the)X -2136(low)X -2287(mask.)X -720 3890(In)N -825(either)X -1046(case,)X -1242(the)X -1377(result)X -1592(of)X -1696(the)X -1831(mask)X -2037(is)X -2127(the)X -2262(bucket)X -720 3978(number)N -989(for)X -1107(the)X -1229(given)X -1431(key.)X -1611(The)X -1759(algorithm)X -2093(below)X -2312(illus-)X -720 4066(trates)N -914(this)X -1049(process.)X -0 f -8 s -720 4365(h)N -796(=)X -872 -0.4038(calchash\(key\);)AX -720 4453(bucket)N -986(=)X -1062(h)X -1138(&)X -1214 -0.4167(high_mask;)AX -720 4541(if)N -834(\()X -910(bucket)X -1176(>)X -1252 -0.4167(max_bucket)AX -1670(\))X -1008 4629(bucket)N -1274(=)X -1350(h)X -1426(&)X -1502 -0.4219(low_mask;)AX -720 4717 -0.4018(return\(bucket\);)AN -1 f -10 s -892 5042(In)N -1013(order)X -1237(to)X -1353(decide)X -1617(when)X -1845(to)X -1961(split)X -2152(a)X -2242(bucket,)X -2 f -720 5130(dynahash)N -1 f -1050(uses)X -2 f -1210(controlled)X -1561(splitting)X -1 f -1822(.)X -1884(A)X -1964(hash)X -2133(table)X -2311(has)X -2440(a)X -720 5218(\256ll)N -837(factor)X -1054(which)X -1279(is)X -1361(expressed)X -1707(in)X -1798(terms)X -2004(of)X -2099(the)X -2225(average)X -720 5306(number)N -990(of)X -1082(keys)X -1253(in)X -1339(each)X -1511(bucket.)X -1789(Each)X -1974(time)X -2140(the)X -2262(table's)X -720 5394(total)N -885(number)X -1153(of)X -1243(keys)X -1413(divided)X -1676(by)X -1778(its)X -1875(number)X -2142(of)X -2231(buckets)X -720 5482(exceeds)N -995(this)X -1130(\256ll)X -1238(factor,)X -1466(a)X -1522(bucket)X -1756(is)X -1829(split.)X -2878 538(Since)N -3079(the)X -2 f -3200(hsearch)X -1 f -3477(create)X -3693(interface)X -3998(\()X -2 f -4025(hcreate)X -1 f -4266(\))X -4315(calls)X -2706 626(for)N -2842(an)X -2960(estimate)X -3269(of)X -3378(the)X -3518(\256nal)X -3702(size)X -3869(of)X -3978(the)X -4118(hash)X -4306(table)X -2706 714(\()N -2 f -2733(nelem)X -1 f -2925(\),)X -2 f -3007(dynahash)X -1 f -3349(uses)X -3522(this)X -3672(information)X -4085(to)X -4182(initialize)X -2706 802(the)N -2848(table.)X -3088(The)X -3257(initial)X -3486(number)X -3774(of)X -3884(buckets)X -4172(is)X -4268(set)X -4400(to)X -2 f -2706 890(nelem)N -1 f -2926(rounded)X -3217(to)X -3306(the)X -3431(next)X -3596(higher)X -3828(power)X -4056(of)X -4150(two.)X -4337(The)X -2706 978(current)N -2958(split)X -3118(point)X -3305(is)X -3381(set)X -3493(to)X -3578(0)X -3641(and)X -3780(the)X -3901(maximum)X -4248(bucket)X -2706 1066(and)N -2842(maximum)X -3186(split)X -3343(point)X -3527(are)X -3646(set)X -3755(to)X -3837(this)X -3972(rounded)X -4255(value.)X -3 f -3148 1220(The)N -3301(New)X -3473(Implementation)X -1 f -2878 1352(Our)N -3042(implementation)X -3583(is)X -3675(also)X -3842(based)X -4063(on)X -4181(Larson's)X -2706 1440(linear)N -2939(hashing)X -3238([LAR88])X -3582(algorithm)X -3943(as)X -4060(well)X -4248(as)X -4364(the)X -2 f -2706 1528(dynahash)N -1 f -3047(implementation.)X -3623(The)X -2 f -3782(dbm)X -1 f -3954(family)X -4197(of)X -4297(algo-)X -2706 1616(rithms)N -2942(decide)X -3184(dynamically)X -3612(which)X -3840(bucket)X -4085(to)X -4178(split)X -4346(and)X -2706 1704(when)N -2914(to)X -3010(split)X -3180(it)X -3257(\(when)X -3491(it)X -3568(over\257ows\))X -3944(while)X -2 f -4155(dynahash)X -1 f -2706 1792(splits)N -2933(in)X -3054(a)X -3149(prede\256ned)X -3547(order)X -3776(\(linearly\))X -4134(and)X -4309(at)X -4426(a)X -2706 1880(prede\256ned)N -3116(time)X -3328(\(when)X -3599(the)X -3767(table)X -3993(\256ll)X -4151(factor)X -4409(is)X -2706 1968(exceeded\).)N -3121(We)X -3280(use)X -3434(a)X -3517(hybrid)X -3773(of)X -3887(these)X -4099(techniques.)X -2706 2056(Splits)N -2913(occur)X -3118(in)X -3206(the)X -3330(prede\256ned)X -3695(order)X -3891(of)X -3984(linear)X -4193(hashing,)X -2706 2144(but)N -2845(the)X -2980(time)X -3159(at)X -3253(which)X -3485(pages)X -3704(are)X -3839(split)X -4012(is)X -4101(determined)X -2706 2232(both)N -2869(by)X -2970(page)X -3143(over\257ows)X -3480(\()X -2 f -3507(uncontrolled)X -3937(splitting)X -1 f -4198(\))X -4246(and)X -4382(by)X -2706 2320(exceeding)N -3052(the)X -3170(\256ll)X -3278(factor)X -3486(\()X -2 f -3513(controlled)X -3862(splitting)X -1 f -4123(\))X -2878 2434(A)N -2962(hash)X -3135(table)X -3317(is)X -3395(parameterized)X -3876(by)X -3981(both)X -4148(its)X -4248(bucket)X -2706 2522(size)N -2904(\()X -2 f -2931(bsize)X -1 f -(\))S -3191(and)X -3380(\256ll)X -3541(factor)X -3801(\()X -2 f -3828(ffactor)X -1 f -4041(\).)X -4180(Whereas)X -2 f -2706 2610(dynahash's)N -1 f -3095(buckets)X -3364(can)X -3500(be)X -3599(represented)X -3993(as)X -4083(a)X -4142(linked)X -4365(list)X -2706 2698(of)N -2798(elements)X -3108(in)X -3195(memory,)X -3507(our)X -3639(package)X -3928(needs)X -4136(to)X -4222(support)X -2706 2786(disk)N -2874(access,)X -3135(and)X -3286(must)X -3476(represent)X -3806(buckets)X -4086(in)X -4183(terms)X -4395(of)X -2706 2874(pages.)N -2955(The)X -2 f -3106(bsize)X -1 f -3291(is)X -3369(the)X -3492(size)X -3642(\(in)X -3756(bytes\))X -3977(of)X -4069(these)X -4259(pages.)X -2706 2962(As)N -2833(in)X -2933(linear)X -3154(hashing,)X -3461(the)X -3597(number)X -3879(of)X -3983(buckets)X -4265(in)X -4364(the)X -2706 3050(table)N -2906(is)X -3003(equal)X -3221(to)X -3327(the)X -3469(number)X -3758(of)X -3869(keys)X -4060(in)X -4165(the)X -4306(table)X -2706 3138(divided)N -2988(by)X -2 f -3110(ffactor)X -1 f -3323(.)X -2 f -8 s -3113(6)Y -1 f -10 s -3417 3138(The)N -3584(controlled)X -3950(splitting)X -4252(occurs)X -2706 3226(each)N -2878(time)X -3044(the)X -3166(number)X -3435(of)X -3526(keys)X -3697(in)X -3783(the)X -3905(table)X -4085(exceeds)X -4364(the)X -2706 3314(\256ll)N -2814(factor)X -3022(multiplied)X -3370(by)X -3470(the)X -3588(number)X -3853(of)X -3940(buckets.)X -2878 3428(Inserting)N -3187(keys)X -3358(and)X -3498(splitting)X -3783(buckets)X -4051(is)X -4127(performed)X -2706 3516(precisely)N -3018(as)X -3107(described)X -3437(previously)X -3796(for)X -2 f -3911(dynahash)X -1 f -4218(.)X -4279(How-)X -2706 3604(ever,)N -2897(since)X -3094(buckets)X -3371(are)X -3502(now)X -3671(comprised)X -4036(of)X -4134(pages,)X -4368(we)X -2706 3692(must)N -2883(be)X -2981(prepared)X -3284(to)X -3367(handle)X -3602(cases)X -3793(where)X -4011(the)X -4130(size)X -4276(of)X -4364(the)X -2706 3780(keys)N -2873(and)X -3009(data)X -3163(in)X -3245(a)X -3301(bucket)X -3535(exceed)X -3779(the)X -3897(bucket)X -4131(size.)X -3 f -3318 3934(Over\257ow)N -3654(Pages)X -1 f -2878 4066(There)N -3095(are)X -3223(two)X -3372(cases)X -3571(where)X -3797(a)X -3862(key)X -4007(may)X -4174(not)X -4305(\256t)X -4400(in)X -2706 4154(its)N -2802(designated)X -3166(bucket.)X -3441(In)X -3529(the)X -3647(\256rst)X -3791(case,)X -3970(the)X -4088(total)X -4250(size)X -4395(of)X -2706 4242(the)N -2833(key)X -2978(and)X -3123(data)X -3286(may)X -3453(exceed)X -3706(the)X -3833(bucket)X -4076(size.)X -4269(In)X -4364(the)X -2706 4330(second,)N -3008(addition)X -3328(of)X -3453(a)X -3547(new)X -3739(key)X -3913(could)X -4149(cause)X -4386(an)X -2706 4418(over\257ow,)N -3068(but)X -3227(the)X -3382(bucket)X -3652(in)X -3770(question)X -4097(is)X -4206(not)X -4364(yet)X -2706 4506(scheduled)N -3049(to)X -3133(be)X -3230(split.)X -3428(In)X -3516(existing)X -3790(implementations,)X -4364(the)X -2706 4594(second)N -2953(case)X -3115(never)X -3317(arises)X -3523(\(since)X -3738(buckets)X -4006(are)X -4128(split)X -4288(when)X -2706 4682(they)N -2871(over\257ow\))X -3210(and)X -3352(the)X -3476(\256rst)X -3626(case)X -3791(is)X -3870(not)X -3998(handled)X -4278(at)X -4362(all.)X -2706 4770(Although)N -3036(large)X -3225(key/data)X -3525(pair)X -3678(handling)X -3986(is)X -4066(dif\256cult)X -4346(and)X -2706 4858(expensive,)N -3083(it)X -3163(is)X -3252(essential.)X -3604(In)X -3706(a)X -3777(linear)X -3995(hashed)X -4253(imple-)X -2706 4946(mentation,)N -3087(over\257ow)X -3413(pages)X -3636(are)X -3775(required)X -4083(for)X -4217(buckets)X -2706 5034(which)N -2935(over\257ow)X -3253(before)X -3492(they)X -3662(are)X -3793(split,)X -3982(so)X -4085(we)X -4211(can)X -4355(use)X -2706 5122(the)N -2833(same)X -3027(mechanism)X -3421(for)X -3544(large)X -3734(key/data)X -4035(pairs)X -4220(that)X -4368(we)X -2706 5210(use)N -2837(for)X -2955(over\257ow)X -3264(pages.)X -3511(Logically,)X -3862(we)X -3980(chain)X -4177(over\257ow)X -16 s -2706 5353 MXY -864 0 Dl -2 f -8 s -2746 5408(6)N -1 f -9 s -2801 5433(This)N -2952(is)X -3023(not)X -3138(strictly)X -3361(true.)X -3532(The)X -3667(\256le)X -3782(does)X -3937(not)X -4052(contract)X -4306(when)X -2706 5513(keys)N -2861(are)X -2972(deleted,)X -3221(so)X -3308(the)X -3419(number)X -3662(of)X -3744(buckets)X -3986(is)X -4056(actually)X -4306(equal)X -2706 5593(to)N -2782(the)X -2890(maximum)X -3202(number)X -3441(of)X -3520(keys)X -3671(ever)X -3814(present)X -4041(in)X -4116(the)X -4223(table)X -4382(di-)X -2706 5673(vided)N -2884(by)X -2974(the)X -3080(\256ll)X -3178(factor.)X -3 f -10 s -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4424(5)X - -6 p -%%Page: 6 6 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -1 f -432 538(pages)N -639(to)X -725(the)X -847(buckets)X -1116(\(also)X -1296(called)X -1512(primary)X -1789(pages\).)X -2062(In)X -2152(a)X -432 626(memory)N -730(based)X -943(representation,)X -1448(over\257ow)X -1763(pages)X -1976(do)X -2086(not)X -432 714(pose)N -628(any)X -792(special)X -1063(problems)X -1409(because)X -1712(we)X -1854(can)X -2014(chain)X -432 802(over\257ow)N -776(pages)X -1017(to)X -1137(primary)X -1449(pages)X -1690(using)X -1921(memory)X -432 890(pointers.)N -776(However,)X -1137(mapping)X -1463(these)X -1674(over\257ow)X -2005(pages)X -432 978(into)N -584(a)X -648(disk)X -809(\256le)X -939(is)X -1019(more)X -1211(of)X -1305(a)X -1368(challenge,)X -1723(since)X -1915(we)X -2036(need)X -432 1066(to)N -547(be)X -675(able)X -861(to)X -975(address)X -1268(both)X -1462(bucket)X -1728(pages,)X -1983(whose)X -432 1154(numbers)N -729(are)X -849(growing)X -1137(linearly,)X -1422(and)X -1558(some)X -1747(indeterminate)X -432 1242(number)N -715(of)X -820(over\257ow)X -1143(pages)X -1364(without)X -1646(reorganizing)X -2090(the)X -432 1330(\256le.)N -604 1444(One)N -789(simple)X -1053(solution)X -1361(would)X -1612(be)X -1739(to)X -1852(allocate)X -2152(a)X -432 1532(separate)N -737(\256le)X -880(for)X -1015(over\257ow)X -1341(pages.)X -1604(The)X -1769(disadvantage)X -432 1620(with)N -605(such)X -783(a)X -850(technique)X -1193(is)X -1276(that)X -1426(it)X -1500(requires)X -1789(an)X -1895(extra)X -2086(\256le)X -432 1708(descriptor,)N -794(an)X -891(extra)X -1073(system)X -1316(call)X -1453(on)X -1554(open)X -1731(and)X -1867(close,)X -2072(and)X -432 1796(logically)N -739(associating)X -1122(two)X -1269(independent)X -1687(\256les.)X -1886(For)X -2023(these)X -432 1884(reasons,)N -728(we)X -857(wanted)X -1123(to)X -1219(map)X -1391(both)X -1567(primary)X -1855(pages)X -2072(and)X -432 1972(over\257ow)N -737(pages)X -940(into)X -1084(the)X -1202(same)X -1387(\256le)X -1509(space.)X -604 2086(The)N -799(buddy-in-waiting)X -1425(algorithm)X -1806(provides)X -2152(a)X -432 2174(mechanism)N -851(to)X -966(support)X -1259(multiple)X -1578(pages)X -1814(per)X -1970(logical)X -432 2262(bucket)N -685(while)X -902(retaining)X -1226(the)X -1362(simple)X -1613(split)X -1788(sequence)X -2121(of)X -432 2350(linear)N -681(hashing.)X -1015(Over\257ow)X -1383(pages)X -1631(are)X -1795(preallocated)X -432 2438(between)N -781(generations)X -1232(of)X -1379(primary)X -1713(pages.)X -1996(These)X -432 2526(over\257ow)N -759(pages)X -984(are)X -1125(used)X -1314(by)X -1436(any)X -1594(bucket)X -1850(containing)X -432 2614(more)N -646(keys)X -842(than)X -1029(\256t)X -1144(on)X -1273(the)X -1420(primary)X -1723(page)X -1924(and)X -2089(are)X -432 2702(reclaimed,)N -808(if)X -896(possible,)X -1217(when)X -1430(the)X -1567(bucket)X -1819(later)X -2000(splits.)X -432 2790(Figure)N -687(3)X -773(depicts)X -1045(the)X -1188(layout)X -1433(of)X -1545(primary)X -1844(pages)X -2072(and)X -432 2878(over\257ow)N -752(pages)X -970(within)X -1209(the)X -1342(same)X -1542(\256le.)X -1699(Over\257ow)X -2036(page)X -432 2966(use)N -586(information)X -1011(is)X -1111(recorded)X -1440(in)X -1548(bitmaps)X -1847(which)X -2089(are)X -432 3054(themselves)N -819(stored)X -1046(on)X -1157(over\257ow)X -1472(pages.)X -1725(The)X -1880(addresses)X -432 3142(of)N -520(the)X -639(bitmap)X -882(pages)X -1086(and)X -1223(the)X -1342(number)X -1608(of)X -1695(pages)X -1898(allocated)X -432 3230(at)N -515(each)X -688(split)X -850(point)X -1039(are)X -1163(stored)X -1384(in)X -1470(the)X -1592(\256le)X -1718(header.)X -1997(Using)X -432 3318(this)N -577(information,)X -1005(both)X -1177(over\257ow)X -1492(addresses)X -1829(and)X -1974(bucket)X -432 3406(addresses)N -764(can)X -900(be)X -999(mapped)X -1276(to)X -1361(disk)X -1517(addresses)X -1848(by)X -1951(the)X -2072(fol-)X -432 3494(lowing)N -674(calculation:)X -0 f -8 s -432 3793(int)N -736(bucket;)X -1192(/*)X -1306(bucket)X -1572(address)X -1876(*/)X -432 3881(u_short)N -736(oaddr;)X -1192(/*)X -1306(OVERFLOW)X -1648(address)X -1952(*/)X -432 3969(int)N -736 -0.4125(nhdr_pages;)AX -1192(/*)X -1306(npages)X -1572(in)X -1686 -112.4062(\256le)AX -1838(header)X -2104(*/)X -432 4057(int)N -736 -0.4125(spares[32];)AX -1192(/*)X -1306(npages)X -1572(at)X -1686(each)X -1876(split)X -2104(*/)X -432 4145(int)N -736(log2\(\);)X -1198(/*)X -1312(ceil\(log)X -1654(base)X -1844(2\))X -1958(*/)X -432 4321(#DEFINE)N -736 -0.3929(BUCKET_TO_PAGE\(bucket\))AX -1610(\\)X -584 4409(bucket)N -850(+)X -926 -0.4167(nhdr_pages)AX -1344(+)X -1420(\\)X -584 4497 -0.3894(\(bucket?spares[logs2\(bucket)AN -1648(+)X -1724(1\)-1]:0\))X -432 4673(#DEFINE)N -736 -0.3947(OADDR_TO_PAGE\(oaddr\))AX -1534(\\)X -584 4761 -0.3984(BUCKET_TO_PAGE\(\(1)AN -1268(<<)X -1382 -0.4091(\(oaddr>>11\)\))AX -1876(-)X -1952(1\))X -2066(+)X -2142(\\)X -584 4849(oaddr)N -812(&)X -888(0x7ff;)X -1 f -10 s -604 5262(An)N -728(over\257ow)X -1039(page)X -1217(is)X -1295(addressed)X -1637(by)X -1742(its)X -1842(split)X -2004(point,)X -432 5350(identifying)N -858(the)X -1031(generations)X -1476(between)X -1819(which)X -2090(the)X -432 5438(over\257ow)N -740(page)X -915(is)X -991(allocated,)X -1324(and)X -1463(its)X -1561(page)X -1736(number,)X -2023(iden-)X -432 5526(tifying)N -665(the)X -783(particular)X -1111(page)X -1283(within)X -1507(the)X -1625(split)X -1782(point.)X -1986(In)X -2073(this)X -432 5614(implementation,)N -983(offsets)X -1225(within)X -1457(pages)X -1668(are)X -1795(16)X -1903(bits)X -2046(long)X -432 5702(\(limiting)N -732(the)X -851(maximum)X -1196(page)X -1368(size)X -1513(to)X -1595(32K\),)X -1800(so)X -1891(we)X -2005(select)X -2418 538(an)N -2535(over\257ow)X -2860(page)X -3052(addressing)X -3435(algorithm)X -3786(that)X -3946(can)X -4098(be)X -2418 626(expressed)N -2760(in)X -2847(16)X -2952(bits)X -3091(and)X -3231(which)X -3451(allows)X -3684(quick)X -3886(retrieval.)X -2418 714(The)N -2568(top)X -2695(\256ve)X -2840(bits)X -2980(indicate)X -3258(the)X -3380(split)X -3541(point)X -3729(and)X -3869(the)X -3991(lower)X -2418 802(eleven)N -2650(indicate)X -2926(the)X -3046(page)X -3220(number)X -3487(within)X -3713(the)X -3832(split)X -3990(point.)X -2418 890(Since)N -2633(\256ve)X -2789(bits)X -2940(are)X -3075(reserved)X -3384(for)X -3514(the)X -3648(split)X -3821(point,)X -4041(\256les)X -2418 978(may)N -2578(split)X -2737(32)X -2839(times)X -3034(yielding)X -3318(a)X -3376(maximum)X -3721(\256le)X -3844(size)X -3990(of)X -4078(2)X -7 s -946(32)Y -10 s -2418 1066(buckets)N -2698(and)X -2849(32)X -2 f -(*)S -1 f -2982(2)X -7 s -1034(11)Y -10 s -3113 1066(over\257ow)N -3433(pages.)X -3691(The)X -3850(maximum)X -2418 1154(page)N -2597(size)X -2749(is)X -2829(2)X -7 s -1122(15)Y -10 s -1154(,)Y -2971(yielding)X -3259(a)X -3321(maximum)X -3671(\256le)X -3799(size)X -3950(greater)X -2418 1242(than)N -2601(131,000)X -2906(GB)X -3061(\(on)X -3212(\256le)X -3358(systems)X -3655(supporting)X -4041(\256les)X -2418 1330(larger)N -2626(than)X -2784(4GB\).)X -10 f -2418 1418 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 Dt -4014 2275 MXY -0 133 Dl -3881 2275 MXY -0 133 Dl -3748 2275 MXY -0 133 Dl -3083 2275 MXY -0 133 Dl -5 s -1 f -3523 2475(2/3)N -3390(2/2)X -3257(2/1)X -2859(1/2)X -2726(1/1)X -5 Dt -3814 1743 MXY -0 133 Dl -3282 1743 MXY -0 133 Dl -3017 1743 MXY -0 133 Dl -2884 1743 MXY -0 133 Dl -1 Dt -3681 1743 MXY -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3548 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3415 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3282 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3150 MX -0 133 Dl -132 0 Dl -0 -133 Dl --132 0 Dl -3017 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -2884 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3 f -8 s -3017 2601(Over\257ow)N -3285(Addresses)X -3515 2833(Over\257ow)N -3783(Pages)X -2850(Buckets)X -1 Di -3349 2740 MXY - 3349 2740 lineto - 3482 2740 lineto - 3482 2873 lineto - 3349 2873 lineto - 3349 2740 lineto -closepath 3 3349 2740 3482 2873 Dp -2684 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -5 Dt -4146 2275 MXY -0 133 Dl -3216 2275 MXY -0 133 Dl -2684 2275 MXY -0 133 Dl -2551 2275 MXY -0 133 Dl -1 f -3798 1963(3)N -3266 1980(2)N -3001(1)X -2868(0)X -1 Dt -2751 1743 MXY -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3548 2275 MXY --15 -22 Dl -2 16 Dl --13 11 Dl -26 -5 Dl --282 -117 Dl -3432 2275 MXY --10 -25 Dl --2 16 Dl --15 8 Dl -27 1 Dl --166 -117 Dl -3282 2275 MXY -12 -25 Dl --14 10 Dl --15 -6 Dl -17 21 Dl --16 -117 Dl -2884 2275 MXY -26 7 Dl --12 -12 Dl -3 -16 Dl --17 21 Dl -382 -117 Dl -2751 2275 MXY -25 9 Dl --11 -12 Dl -5 -17 Dl --19 20 Dl -515 -117 Dl -3 f -3070 2152(Over\257ow)N -3338(Pages)X -3482 2275 MXY - 3482 2275 lineto - 3615 2275 lineto - 3615 2408 lineto - 3482 2408 lineto - 3482 2275 lineto -closepath 3 3482 2275 3615 2408 Dp -3349 MX - 3349 2275 lineto - 3482 2275 lineto - 3482 2408 lineto - 3349 2408 lineto - 3349 2275 lineto -closepath 3 3349 2275 3482 2408 Dp -3216 MX - 3216 2275 lineto - 3349 2275 lineto - 3349 2408 lineto - 3216 2408 lineto - 3216 2275 lineto -closepath 3 3216 2275 3349 2408 Dp -2817 MX - 2817 2275 lineto - 2950 2275 lineto - 2950 2408 lineto - 2817 2408 lineto - 2817 2275 lineto -closepath 3 2817 2275 2950 2408 Dp -2684 MX - 2684 2275 lineto - 2817 2275 lineto - 2817 2408 lineto - 2684 2408 lineto - 2684 2275 lineto -closepath 3 2684 2275 2817 2408 Dp -3615 MX -0 133 Dl -531 0 Dl -0 -133 Dl --531 0 Dl -2950 MX -0 133 Dl -266 0 Dl -0 -133 Dl --266 0 Dl -2551 MX -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3798 1726 MXY --21 -18 Dl -6 16 Dl --10 13 Dl -25 -11 Dl --599 -99 Dl -3266 1726 MXY --1 -27 Dl --7 15 Dl --17 1 Dl -25 11 Dl --67 -99 Dl -3033 1726 MXY -27 1 Dl --14 -8 Dl --1 -17 Dl --12 24 Dl -166 -99 Dl -2900 1726 MXY -27 7 Dl --13 -11 Dl -3 -17 Dl --17 21 Dl -299 -99 Dl -3058 1621(Split)N -3203(Points)X -2418 2275 MXY -0 133 Dl -133 0 Dl -0 -133 Dl --133 0 Dl -3 Dt --1 Ds -3137(Figure)Y -2619(3:)X -1 f -2691(Split)X -2832(points)X -3008(occur)X -3168(between)X -3399(generations)X -3712(and)X -3823(are)X -3919(numbered)X -2418 3225(from)N -2560(0.)X -2642(In)X -2713(this)X -2824(\256gure)X -2991(there)X -3136(are)X -3231(two)X -3345(over\257ow)X -3590(pages)X -3753(allocated)X -4000(at)X -4063(split)X -2418 3313(point)N -2566(1)X -2614(and)X -2722(three)X -2865(allocated)X -3111(at)X -3173(split)X -3300(point)X -3448(2.)X -10 s -10 f -2418 3489 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -2949 3731(Buffer)N -3192(Management)X -1 f -2590 3863(The)N -2744(hash)X -2920(table)X -3105(is)X -3187(stored)X -3412(in)X -3502(memory)X -3797(as)X -3892(a)X -3956(logical)X -2418 3951(array)N -2633(of)X -2749(bucket)X -3012(pointers.)X -3359(Physically,)X -3761(the)X -3907(array)X -4121(is)X -2418 4039(arranged)N -2728(in)X -2818(segments)X -3144(of)X -3239(256)X -3387(pointers.)X -3713(Initially,)X -4013(there)X -2418 4127(is)N -2530(space)X -2767(to)X -2887(allocate)X -3195(256)X -3373(segments.)X -3769(Reallocation)X -2418 4215(occurs)N -2651(when)X -2847(the)X -2967(number)X -3234(of)X -3323(buckets)X -3590(exceeds)X -3867(32K)X -4027(\(256)X -2418 4303(*)N -2508(256\).)X -2745(Primary)X -3053(pages)X -3286(may)X -3473(be)X -3598(accessed)X -3929(directly)X -2418 4391(through)N -2711(the)X -2853(array)X -3062(by)X -3185(bucket)X -3442(number)X -3730(and)X -3889(over\257ow)X -2418 4479(pages)N -2628(are)X -2754 0.4028(referenced)AX -3122(logically)X -3429(by)X -3536(their)X -3710(over\257ow)X -4022(page)X -2418 4567(address.)N -2726(For)X -2864(small)X -3063(hash)X -3236(tables,)X -3469(it)X -3539(is)X -3618(desirable)X -3934(to)X -4022(keep)X -2418 4655(all)N -2525(pages)X -2735(in)X -2823(main)X -3009(memory)X -3302(while)X -3506(on)X -3612(larger)X -3826(tables,)X -4059(this)X -2418 4743(is)N -2523(probably)X -2860(impossible.)X -3298(To)X -3438(satisfy)X -3698(both)X -3891(of)X -4009(these)X -2418 4831(requirements,)N -2900(the)X -3041(package)X -3348(includes)X -3658(buffer)X -3897(manage-)X -2418 4919(ment)N -2598(with)X -2760(LRU)X -2940(\(least)X -3134(recently)X -3413(used\))X -3607(replacement.)X -2590 5033(By)N -2730(default,)X -3020(the)X -3165(package)X -3475(allocates)X -3802(up)X -3928(to)X -4036(64K)X -2418 5121(bytes)N -2616(of)X -2712(buffered)X -3014(pages.)X -3246(All)X -3377(pages)X -3589(in)X -3680(the)X -3807(buffer)X -4032(pool)X -2418 5209(are)N -2542(linked)X -2766(in)X -2852(LRU)X -3036(order)X -3230(to)X -3316(facilitate)X -3621(fast)X -3761(replacement.)X -2418 5297(Whereas)N -2724(ef\256cient)X -3011(access)X -3241(to)X -3327(primary)X -3605(pages)X -3812(is)X -3889(provided)X -2418 5385(by)N -2521(the)X -2642(bucket)X -2879(array,)X -3087(ef\256cient)X -3372(access)X -3600(to)X -3684(over\257ow)X -3991(pages)X -2418 5473(is)N -2501(provided)X -2816(by)X -2926(linking)X -3182(over\257ow)X -3497(page)X -3679(buffers)X -3936(to)X -4027(their)X -2418 5561(predecessor)N -2827(page)X -3008(\(either)X -3247(the)X -3374(primary)X -3657(page)X -3838(or)X -3933(another)X -2418 5649(over\257ow)N -2742(page\).)X -3000(This)X -3181(means)X -3425(that)X -3584(an)X -3699(over\257ow)X -4022(page)X -3 f -432 5960(6)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -7 p -%%Page: 7 7 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -1 f -720 538(cannot)N -955(be)X -1052(present)X -1305(in)X -1388(the)X -1507(buffer)X -1724(pool)X -1886(if)X -1955(its)X -2050(primary)X -2324(page)X -720 626(is)N -804(not)X -937(present.)X -1240(This)X -1413(does)X -1591(not)X -1724(impact)X -1972(performance)X -2409(or)X -720 714(functionality,)N -1209(because)X -1524(an)X -1660(over\257ow)X -2005(page)X -2217(will)X -2400(be)X -720 802(accessed)N -1048(only)X -1236(after)X -1430(its)X -1550(predecessor)X -1975(page)X -2172(has)X -2324(been)X -720 890(accessed.)N -1068(Figure)X -1303(4)X -1369(depicts)X -1622(the)X -1746(data)X -1905(structures)X -2242(used)X -2414(to)X -720 978(manage)N -990(the)X -1108(buffer)X -1325(pool.)X -892 1092(The)N -1040(in-memory)X -1419(bucket)X -1656(array)X -1845(contains)X -2134(pointers)X -2414(to)X -720 1180(buffer)N -975(header)X -1248(structures)X -1617(which)X -1870(represent)X -2222(primary)X -720 1268(pages.)N -968(Buffer)X -1203(headers)X -1474(contain)X -1735(modi\256ed)X -2043(bits,)X -2202(the)X -2324(page)X -720 1356(address)N -995(of)X -1096(the)X -1228(buffer,)X -1479(a)X -1548(pointer)X -1808(to)X -1903(the)X -2034(actual)X -2259(buffer,)X -720 1444(and)N -875(a)X -950(pointer)X -1216(to)X -1317(the)X -1454(buffer)X -1690(header)X -1944(for)X -2077(an)X -2191(over\257ow)X -720 1532(page)N -901(if)X -979(it)X -1052(exists,)X -1283(in)X -1374(addition)X -1665(to)X -1756(the)X -1883(LRU)X -2072(links.)X -2296(If)X -2378(the)X -720 1620(buffer)N -950(corresponding)X -1442(to)X -1537(a)X -1606(particular)X -1947(bucket)X -2194(is)X -2280(not)X -2414(in)X -720 1708(memory,)N -1048(its)X -1164(pointer)X -1432(is)X -1526(NULL.)X -1801(In)X -1909(effect,)X -2154(pages)X -2377(are)X -720 1796(linked)N -950(in)X -1042(three)X -1233(ways.)X -1468(Using)X -1689(the)X -1817(buffer)X -2043(headers,)X -2338(they)X -720 1884(are)N -851(linked)X -1083(physically)X -1444(through)X -1725(the)X -1854(LRU)X -2045(links)X -2231(and)X -2378(the)X -720 1972(over\257ow)N -1036(links.)X -1241(Using)X -1462(the)X -1590(pages)X -1803(themselves,)X -2209(they)X -2377(are)X -720 2060(linked)N -943(logically)X -1246(through)X -1518(the)X -1639(over\257ow)X -1946(addresses)X -2276(on)X -2378(the)X -720 2148(page.)N -948(Since)X -1162(over\257ow)X -1482(pages)X -1700(are)X -1834(accessed)X -2151(only)X -2328(after)X -720 2236(their)N -904(predecessor)X -1321(pages,)X -1560(they)X -1734(are)X -1869(removed)X -2186(from)X -2378(the)X -720 2324(buffer)N -937(pool)X -1099(when)X -1293(their)X -1460(primary)X -1734(is)X -1807(removed.)X -10 f -720 2412 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 Dt -2309 3177 MXY -24 15 Dl --8 -15 Dl -8 -15 Dl --24 15 Dl -52 0 Dl -789 3160 MXY --35 0 Dl -0 -156 Dl -1607 0 Dl -0 173 Dl -789 3091 MXY --24 -15 Dl -9 15 Dl --9 15 Dl -24 -15 Dl --69 0 Dl -2309 3125 MXY -104 0 Dl -0 -155 Dl --1693 0 Dl -0 121 Dl -927 3160 MXY -24 15 Dl --9 -15 Dl -9 -15 Dl --24 15 Dl -553 0 Dl -1618 3177 MXY -8 27 Dl -4 -17 Dl -16 -6 Dl --28 -4 Dl -138 121 Dl -1895 3315 MXY -28 3 Dl --15 -9 Dl -1 -18 Dl --14 24 Dl -276 -138 Dl -3108 MY --28 -3 Dl -15 10 Dl --1 17 Dl -14 -24 Dl --276 138 Dl -1756 3229 MXY --8 -27 Dl --3 17 Dl --16 6 Dl -27 4 Dl --138 -121 Dl -1480 MX --24 -15 Dl -9 15 Dl --9 15 Dl -24 -15 Dl --553 0 Dl -3 f -5 s -1083 3073(LRU)N -1178(chain)X -4 Ds -1402 3851 MXY - 1402 3851 lineto - 1471 3851 lineto - 1471 3920 lineto - 1402 3920 lineto - 1402 3851 lineto -closepath 19 1402 3851 1471 3920 Dp -1445 3747(Over\257ow)N -1613(Address)X -1549 3609 MXY -0 69 Dl -1756 MX --23 -15 Dl -8 15 Dl --8 15 Dl -23 -15 Dl --207 0 Dl --1 Ds -3 Dt -1756 3419 MXY --6 -28 Dl --4 17 Dl --17 5 Dl -27 6 Dl --138 -138 Dl -2240 3471 MXY -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -1826 3609 MXY -15 -24 Dl --15 9 Dl --16 -9 Dl -16 24 Dl -0 -138 Dl -1549 MX -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -858 3471 MXY -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -2240 3056 MXY -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -1549 3056 MXY -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -858 3056 MXY -15 -24 Dl --15 9 Dl --15 -9 Dl -15 24 Dl -0 -138 Dl -1 Dt -2171 3471 MXY - 2171 3471 lineto - 2448 3471 lineto - 2448 3609 lineto - 2171 3609 lineto - 2171 3471 lineto -closepath 19 2171 3471 2448 3609 Dp -1756 3609 MXY - 1756 3609 lineto - 2033 3609 lineto - 2033 3747 lineto - 1756 3747 lineto - 1756 3609 lineto -closepath 3 1756 3609 2033 3747 Dp -1480 3471 MXY - 1480 3471 lineto - 1756 3471 lineto - 1756 3609 lineto - 1480 3609 lineto - 1480 3471 lineto -closepath 19 1480 3471 1756 3609 Dp -789 MX - 789 3471 lineto - 1065 3471 lineto - 1065 3609 lineto - 789 3609 lineto - 789 3471 lineto -closepath 19 789 3471 1065 3609 Dp -962 3903(Buffer)N -1083(Header)X -849 3851 MXY - 849 3851 lineto - 918 3851 lineto - 918 3920 lineto - 849 3920 lineto - 849 3851 lineto -closepath 14 849 3851 918 3920 Dp -1756 3194 MXY - 1756 3194 lineto - 1895 3194 lineto - 1895 3471 lineto - 1756 3471 lineto - 1756 3194 lineto -closepath 14 1756 3194 1895 3471 Dp -2171 3056 MXY - 2171 3056 lineto - 2309 3056 lineto - 2309 3333 lineto - 2171 3333 lineto - 2171 3056 lineto -closepath 14 2171 3056 2309 3333 Dp -1480 MX - 1480 3056 lineto - 1618 3056 lineto - 1618 3333 lineto - 1480 3333 lineto - 1480 3056 lineto -closepath 14 1480 3056 1618 3333 Dp -789 MX - 789 3056 lineto - 927 3056 lineto - 927 3333 lineto - 789 3333 lineto - 789 3056 lineto -closepath 14 789 3056 927 3333 Dp -2780 MY -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -927 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -1065 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -1203 MX -0 138 Dl -139 0 Dl -0 -138 Dl --139 0 Dl -1342 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -1480 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -1618 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -1756 MX -0 138 Dl -139 0 Dl -0 -138 Dl --139 0 Dl -1895 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -2033 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -2171 MX -0 138 Dl -138 0 Dl -0 -138 Dl --138 0 Dl -2309 MX -0 138 Dl -139 0 Dl -0 -138 Dl --139 0 Dl -13 s -1048 2720(In)N -1173(Memory)X -1580(Bucket)X -1918(Array)X -867 3584(B0)N -1558(B5)X -2223(B10)X -1788 3722(O1/1)N -5 s -1515 3903(Primay)N -1651(Buffer)X -4 Ds -1990 3851 MXY - 1990 3851 lineto - 2059 3851 lineto - 2059 3920 lineto - 1990 3920 lineto - 1990 3851 lineto -closepath 3 1990 3851 2059 3920 Dp -2102 3903(Over\257ow)N -2270(Buffer)X -3 Dt --1 Ds -8 s -720 4184(Figure)N -922(4:)X -1 f -996(Three)X -1164(primary)X -1386(pages)X -1551(\(B0,)X -1683(B5,)X -1794(B10\))X -1942(are)X -2039(accessed)X -2281(directly)X -720 4272(from)N -862(the)X -958(bucket)X -1146(array.)X -1326(The)X -1443(one)X -1553(over\257ow)X -1798(page)X -1935(\(O1/1\))X -2122(is)X -2182(linked)X -2359(phy-)X -720 4360(sically)N -915(from)X -1067(its)X -1155(primary)X -1384(page's)X -1577(buffer)X -1759(header)X -1955(as)X -2035(well)X -2172(as)X -2252(logically)X -720 4448(from)N -860(its)X -937(predecessor)X -1253(page)X -1389(buffer)X -1560(\(B5\).)X -10 s -10 f -720 4624 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -1191 4954(Table)N -1406(Parameterization)X -1 f -892 5086(When)N -1107(a)X -1166(hash)X -1336(table)X -1515(is)X -1590(created,)X -1865(the)X -1985(bucket)X -2221(size,)X -2388(\256ll)X -720 5174(factor,)N -953(initial)X -1164(number)X -1434(of)X -1526(elements,)X -1856(number)X -2125(of)X -2216(bytes)X -2409(of)X -720 5262(main)N -919(memory)X -1225(used)X -1411(for)X -1543(caching,)X -1851(and)X -2005(a)X -2079(user-de\256ned)X -720 5350(hash)N -892(function)X -1184(may)X -1347(be)X -1448(speci\256ed.)X -1797(The)X -1946(bucket)X -2184(size)X -2333(\(and)X -720 5438(page)N -906(size)X -1064(for)X -1191(over\257ow)X -1509(pages\))X -1752(defaults)X -2039(to)X -2134(256)X -2287(bytes.)X -720 5526(For)N -858(tables)X -1072(with)X -1241(large)X -1429(data)X -1590(items,)X -1810(it)X -1881(may)X -2046(be)X -2149(preferable)X -720 5614(to)N -803(increase)X -1088(the)X -1207(page)X -1380(size,)X -1545(and,)X -1701(conversely,)X -2089(applications)X -720 5702(storing)N -1002(small)X -1235(items)X -1467(exclusively)X -1891(in)X -2012(memory)X -2338(may)X -2706 538(bene\256t)N -2966(from)X -3164(a)X -3242(smaller)X -3520(bucket)X -3776(size.)X -3983(A)X -4082(bucket)X -4337(size)X -2706 626(smaller)N -2962(than)X -3120(64)X -3220(bytes)X -3409(is)X -3482(not)X -3604(recommended.)X -2878 740(The)N -3031(\256ll)X -3147(factor)X -3363(indicates)X -3676(a)X -3740(desired)X -4000(density)X -4258(within)X -2706 828(the)N -2833(hash)X -3009(table.)X -3234(It)X -3312(is)X -3394(an)X -3499(approximation)X -3995(of)X -4091(the)X -4217(number)X -2706 916(of)N -2815(keys)X -3004(allowed)X -3300(to)X -3404(accumulate)X -3811(in)X -3914(any)X -4071(one)X -4228(bucket,)X -2706 1004(determining)N -3119(when)X -3319(the)X -3442(hash)X -3614(table)X -3795(grows.)X -4056(Its)X -4161(default)X -4409(is)X -2706 1092(eight.)N -2953(If)X -3054(the)X -3199(user)X -3380(knows)X -3636(the)X -3781(average)X -4079(size)X -4251(of)X -4364(the)X -2706 1180(key/data)N -3008(pairs)X -3194(being)X -3402(stored)X -3627(in)X -3718(the)X -3845(table,)X -4050(near)X -4218(optimal)X -2706 1268(bucket)N -2943(sizes)X -3122(and)X -3261(\256ll)X -3372(factors)X -3614(may)X -3775(be)X -3874(selected)X -4155(by)X -4257(apply-)X -2706 1356(ing)N -2828(the)X -2946(equation:)X -0 f -8 s -2706 1655(\(1\))N -2994 -0.3938(\(\(average_pair_length)AX -3830(+)X -3906(4\))X -4020(*)X -3032 1743(ffactor\))N -3374(>=)X -3488(bsize)X -1 f -10 s -2706 2042(For)N -2859(highly)X -3104(time)X -3287(critical)X -3551(applications,)X -3999(experimenting)X -2706 2130(with)N -2919(different)X -3266(bucket)X -3550(sizes)X -3776(and)X -3962(\256ll)X -4120(factors)X -4409(is)X -2706 2218(encouraged.)N -2878 2332(Figures)N -3144(5a,b,)X -3326(and)X -3468(c)X -3530(illustrate)X -3836(the)X -3960(effects)X -4200(of)X -4292(vary-)X -2706 2420(ing)N -2841(page)X -3026(sizes)X -3215(and)X -3363(\256ll)X -3483(factors)X -3734(for)X -3860(the)X -3990(same)X -4187(data)X -4353(set.)X -2706 2508(The)N -2864(data)X -3031(set)X -3152(consisted)X -3482(of)X -3581(24474)X -3813(keys)X -3992(taken)X -4198(from)X -4386(an)X -2706 2596(online)N -2931(dictionary.)X -3301(The)X -3451(data)X -3609(value)X -3807(for)X -3925(each)X -4097(key)X -4237(was)X -4386(an)X -2706 2684(ASCII)N -2938(string)X -3143(for)X -3260(an)X -3359(integer)X -3605(from)X -3784(1)X -3847(to)X -3931(24474)X -4153(inclusive.)X -2706 2772(The)N -2867(test)X -3013(run)X -3155(consisted)X -3488(of)X -3590(creating)X -3884(a)X -3955(new)X -4124(hash)X -4306(table)X -2706 2860(\(where)N -2966(the)X -3100(ultimate)X -3398(size)X -3559(of)X -3662(the)X -3796(table)X -3987(was)X -4147(known)X -4400(in)X -2706 2948(advance\),)N -3054(entering)X -3354(each)X -3539(key/data)X -3848(pair)X -4010(into)X -4171(the)X -4306(table)X -2706 3036(and)N -2849(then)X -3014(retrieving)X -3353(each)X -3528(key/data)X -3827(pair)X -3979(from)X -4162(the)X -4286(table.)X -2706 3124(Each)N -2898(of)X -2996(the)X -3125(graphs)X -3369(shows)X -3599(the)X -3727(timings)X -3996(resulting)X -4306(from)X -2706 3212(varying)N -2973(the)X -3093(pagesize)X -3392(from)X -3570(128)X -3712(bytes)X -3903(to)X -3986(1M)X -4118(and)X -4255(the)X -4374(\256ll)X -2706 3300(factor)N -2929(from)X -3120(1)X -3195(to)X -3292(128.)X -3486(For)X -3631(each)X -3813(run,)X -3974(the)X -4106(buffer)X -4337(size)X -2706 3388(was)N -2874(set)X -3006(at)X -3106(1M.)X -3299(The)X -3466(tests)X -3650(were)X -3849(all)X -3971(run)X -4120(on)X -4242(an)X -4360(HP)X -2706 3476(9000/370)N -3077(\(33.3)X -3312(Mhz)X -3527(MC68030\),)X -3966(with)X -4176(16M)X -4395(of)X -2706 3564(memory,)N -3042(64K)X -3228(physically)X -3605(addressed)X -3970(cache,)X -4222(and)X -4386(an)X -2706 3652(HP7959S)N -3055(disk)X -3231(drive,)X -3459(running)X -3751(4.3BSD-Reno)X -4244(single-)X -2706 3740(user.)N -2878 3854(Both)N -3066(system)X -3321(time)X -3496(\(Figure)X -3764(5a\))X -3899(and)X -4047(elapsed)X -4320(time)X -2706 3942(\(Figure)N -2966(5b\))X -3097(show)X -3290(that)X -3434(for)X -3552(all)X -3655(bucket)X -3892(sizes,)X -4091(the)X -4212(greatest)X -2706 4030(performance)N -3137(gains)X -3329(are)X -3451(made)X -3648(by)X -3751(increasing)X -4104(the)X -4225(\256ll)X -4336(fac-)X -2706 4118(tor)N -2822(until)X -2995(equation)X -3298(1)X -3365(is)X -3445(satis\256ed.)X -3774(The)X -3925(user)X -4085(time)X -4253(shown)X -2706 4206(in)N -2791(Figure)X -3023(5c)X -3122(gives)X -3314(a)X -3373(more)X -3561(detailed)X -3838(picture)X -4083(of)X -4172(how)X -4332(per-)X -2706 4294(formance)N -3054(varies.)X -3330(The)X -3499(smaller)X -3778(bucket)X -4035(sizes)X -4234(require)X -2706 4382(fewer)N -2921(keys)X -3099(per)X -3233(page)X -3416(to)X -3509(satisfy)X -3749(equation)X -4056(1)X -4127(and)X -4274(there-)X -2706 4470(fore)N -2860(incur)X -3049(fewer)X -3257(collisions.)X -3607(However,)X -3946(when)X -4144(the)X -4265(buffer)X -2706 4558(pool)N -2884(size)X -3045(is)X -3134(\256xed,)X -3349(smaller)X -3620(pages)X -3838(imply)X -4059(more)X -4259(pages.)X -2706 4646(An)N -2830(increased)X -3160(number)X -3430(of)X -3522(pages)X -3730(means)X -3960(more)X -2 f -4150(malloc\(3\))X -1 f -2706 4734(calls)N -2879(and)X -3021(more)X -3212(overhead)X -3533(in)X -3621(the)X -3745(hash)X -3918(package's)X -4265(buffer)X -2706 4822(manager)N -3003(to)X -3085(manage)X -3355(the)X -3473(additional)X -3813(pages.)X -2878 4936(The)N -3028(tradeoff)X -3308(works)X -3529(out)X -3655(most)X -3834(favorably)X -4166(when)X -4364(the)X -2706 5024(page)N -2886(size)X -3039(is)X -3120(256)X -3268(and)X -3412(the)X -3538(\256ll)X -3654(factor)X -3870(is)X -3950(8.)X -4057(Similar)X -4319(con-)X -2706 5112(clusions)N -3009(were)X -3207(obtained)X -3524(if)X -3614(the)X -3753(test)X -3905(was)X -4071(run)X -4218(without)X -2706 5200(knowing)N -3007(the)X -3126(\256nal)X -3289(table)X -3466(size)X -3612(in)X -3695(advance.)X -4020(If)X -4095(the)X -4214(\256le)X -4337(was)X -2706 5288(closed)N -2942(and)X -3088(written)X -3345(to)X -3437(disk,)X -3620(the)X -3748(conclusions)X -4156(were)X -4343(still)X -2706 5376(the)N -2832(same.)X -3065(However,)X -3408(rereading)X -3740(the)X -3865(\256le)X -3994(from)X -4177(disk)X -4337(was)X -2706 5464(slightly)N -2983(faster)X -3199(if)X -3285(a)X -3358(larger)X -3583(bucket)X -3834(size)X -3996(and)X -4149(\256ll)X -4274(factor)X -2706 5552(were)N -2898(used)X -3079(\(1K)X -3238(bucket)X -3486(size)X -3645(and)X -3795(32)X -3909(\256ll)X -4031(factor\).)X -4320(This)X -2706 5640(follows)N -2987(intuitively)X -3356(from)X -3553(the)X -3691(improved)X -4038(ef\256ciency)X -4395(of)X -3 f -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4424(7)X - -8 p -%%Page: 8 8 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -1 f -432 538(performing)N -830(1K)X -965(reads)X -1172(from)X -1365(the)X -1500(disk)X -1670(rather)X -1894(than)X -2068(256)X -432 626(byte)N -609(reads.)X -857(In)X -962(general,)X -1257(performance)X -1702(for)X -1834(disk)X -2005(based)X -432 714(tables)N -639(is)X -712(best)X -861(when)X -1055(the)X -1173(page)X -1345(size)X -1490(is)X -1563(approximately)X -2046(1K.)X -10 f -432 802 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -619 2380 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -629 2437 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -648 2504 MXY --12 25 Dl -24 0 Dl --12 -25 Dl -686 2515 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -762 2516 MXY --12 24 Dl -25 0 Dl --13 -24 Dl -916 2515 MXY --13 24 Dl -25 0 Dl --12 -24 Dl -1222 2516 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -1834 2515 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -1 Dt -619 2392 MXY -10 57 Dl -19 67 Dl -38 11 Dl -76 1 Dl -154 -1 Dl -306 1 Dl -612 -1 Dl -8 s -1 f -1628 2522(128)N -3 Dt -607 2245 MXY -24 Dc -617 2375 MXY -23 Dc -635 2442 MXY -24 Dc -674 2525 MXY -23 Dc -750 2529 MXY -24 Dc -904 2527 MXY -23 Dc -1210 MX -23 Dc -1822 2528 MXY -23 Dc -20 Ds -1 Dt -619 2245 MXY -10 130 Dl -19 67 Dl -38 83 Dl -76 4 Dl -154 -2 Dl -306 0 Dl -612 1 Dl -678 2482(256)N --1 Ds -3 Dt -619 2127 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -629 2191 MXY -0 25 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -648 2334 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -686 2409 MXY -0 25 Dl -0 -13 Dl -12 0 Dl --24 0 Dl -762 2516 MXY -0 25 Dl -0 -12 Dl -13 0 Dl --25 0 Dl -916 2516 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --25 0 Dl -1222 2515 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -1834 2515 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -5 Dt -619 2139 MXY -10 65 Dl -19 142 Dl -38 75 Dl -76 108 Dl -154 -1 Dl -306 -1 Dl -612 0 Dl -694 2401(512)N -3 Dt -631 2064 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -641 2077 MXY --24 25 Dl -12 -12 Dl --12 -13 Dl -24 25 Dl -660 2132 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -698 2292 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -775 2382 MXY --25 24 Dl -12 -12 Dl --12 -12 Dl -25 24 Dl -928 2516 MXY --25 24 Dl -13 -12 Dl --13 -12 Dl -25 24 Dl -1234 2516 MXY --24 25 Dl -12 -12 Dl --12 -13 Dl -24 25 Dl -1846 2516 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -16 Ds -1 Dt -619 2076 MXY -10 14 Dl -19 54 Dl -38 160 Dl -76 90 Dl -154 134 Dl -306 1 Dl -612 -1 Dl -694 2257(1024)N --1 Ds -3 Dt -619 1877 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -629 1855 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -648 1838 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -686 1860 MXY -12 -25 Dl --24 0 Dl -12 25 Dl -762 1923 MXY -13 -24 Dl --25 0 Dl -12 24 Dl -916 2087 MXY -12 -24 Dl --25 0 Dl -13 24 Dl -1222 2256 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -1834 2541 MXY -12 -25 Dl --24 0 Dl -12 25 Dl -619 1865 MXY -10 -22 Dl -19 -17 Dl -38 21 Dl -76 64 Dl -154 164 Dl -306 169 Dl -612 285 Dl -1645 2427(4096)N -619 1243 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -629 1196 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -648 1146 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -686 1174 MXY -0 25 Dl -0 -13 Dl -12 0 Dl --24 0 Dl -762 1249 MXY -0 24 Dl -0 -12 Dl -13 0 Dl --25 0 Dl -916 1371 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --25 0 Dl -1222 1680 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -1834 1999 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -619 1255 MXY -10 -47 Dl -19 -50 Dl -38 28 Dl -76 75 Dl -154 122 Dl -306 309 Dl -612 319 Dl -1741 1934(8192)N -5 Dt -609 2531 MXY -1225 0 Dl -609 MX -0 -1553 Dl -2531 MY -0 16 Dl -4 Ds -1 Dt -2531 MY -0 -1553 Dl -593 2625(0)N --1 Ds -5 Dt -916 2531 MXY -0 16 Dl -4 Ds -1 Dt -2531 MY -0 -1553 Dl -884 2625(32)N --1 Ds -5 Dt -1222 2531 MXY -0 16 Dl -4 Ds -1 Dt -2531 MY -0 -1553 Dl -1190 2625(64)N --1 Ds -5 Dt -1528 2531 MXY -0 16 Dl -4 Ds -1 Dt -2531 MY -0 -1553 Dl -1496 2625(96)N --1 Ds -5 Dt -1834 2531 MXY -0 16 Dl -4 Ds -1 Dt -2531 MY -0 -1553 Dl -1786 2625(128)N --1 Ds -5 Dt -609 2531 MXY --16 0 Dl -4 Ds -1 Dt -609 MX -1225 0 Dl -545 2558(0)N --1 Ds -5 Dt -609 2013 MXY --16 0 Dl -4 Ds -1 Dt -609 MX -1225 0 Dl -481 2040(100)N --1 Ds -5 Dt -609 1496 MXY --16 0 Dl -4 Ds -1 Dt -609 MX -1225 0 Dl -481 1523(200)N --1 Ds -5 Dt -609 978 MXY --16 0 Dl -4 Ds -1 Dt -609 MX -1225 0 Dl -481 1005(300)N -1088 2724(Fill)N -1194(Factor)X -422 1611(S)N -426 1667(e)N -426 1724(c)N -424 1780(o)N -424 1837(n)N -424 1893(d)N -428 1949(s)N -3 Dt --1 Ds -3 f -432 2882(Figure)N -636(5a:)X -1 f -744(System)X -956(Time)X -1113(for)X -1209(dictionary)X -1490(data)X -1618(set)X -1711(with)X -1847(1M)X -1958(of)X -2033(buffer)X -432 2970(space)N -594(and)X -707(varying)X -923(bucket)X -1114(sizes)X -1259(and)X -1372(\256ll)X -1465(factors.)X -1675(Each)X -1823(line)X -1940(is)X -2004(labeled)X -432 3058(with)N -562(its)X -639(bucket)X -825(size.)X -10 s -10 f -432 3234 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -8 s -1 f -428 4381(s)N -424 4325(d)N -424 4269(n)N -424 4212(o)N -426 4156(c)N -426 4099(e)N -422 4043(S)N -1116 5156(Fill)N -1222(Factor)X -506 3437(3200)N -4 Ds -1 Dt -666 3410 MXY -1168 0 Dl --1 Ds -5 Dt -666 MX --16 0 Dl -506 3825(2400)N -4 Ds -1 Dt -666 3799 MXY -1168 0 Dl --1 Ds -5 Dt -666 MX --16 0 Dl -506 4214(1600)N -4 Ds -1 Dt -666 4186 MXY -1168 0 Dl --1 Ds -5 Dt -666 MX --16 0 Dl -538 4602(800)N -4 Ds -1 Dt -666 4575 MXY -1168 0 Dl --1 Ds -5 Dt -666 MX --16 0 Dl -602 4990(0)N -4 Ds -1 Dt -666 4963 MXY -1168 0 Dl --1 Ds -5 Dt -666 MX --16 0 Dl -1786 5057(128)N -4 Ds -1 Dt -1834 4963 MXY -0 -1553 Dl --1 Ds -5 Dt -4963 MY -0 16 Dl -1510 5057(96)N -4 Ds -1 Dt -1542 4963 MXY -0 -1553 Dl --1 Ds -5 Dt -4963 MY -0 16 Dl -1218 5057(64)N -4 Ds -1 Dt -1250 4963 MXY -0 -1553 Dl --1 Ds -5 Dt -4963 MY -0 16 Dl -926 5057(32)N -4 Ds -1 Dt -958 4963 MXY -0 -1553 Dl --1 Ds -5 Dt -4963 MY -0 16 Dl -650 5057(0)N -4 Ds -1 Dt -666 4963 MXY -0 -1553 Dl --1 Ds -5 Dt -4963 MY -0 16 Dl -4963 MY -0 -1553 Dl -4963 MY -1168 0 Dl -1741 4752(8192)N -3 Dt -675 3732 MXY -9 -172 Dl -18 -118 Dl -37 128 Dl -73 -121 Dl -146 623 Dl -292 497 Dl -584 245 Dl -4802 MY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -1250 4557 MXY -0 25 Dl -0 -13 Dl -12 0 Dl --24 0 Dl -958 4060 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -812 3437 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -739 3558 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -702 3430 MXY -0 25 Dl -0 -13 Dl -13 0 Dl --25 0 Dl -684 3548 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -675 3720 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -1637 4912(4096)N -675 4307 MXY -9 -58 Dl -18 30 Dl -37 89 Dl -73 144 Dl -146 235 Dl -292 122 Dl -584 89 Dl -4970 MY -12 -24 Dl --24 0 Dl -12 24 Dl -1250 4881 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -958 4759 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -812 4524 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -739 4380 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -702 4291 MXY -13 -24 Dl --25 0 Dl -12 24 Dl -684 4261 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -675 4319 MXY -12 -24 Dl --24 0 Dl -12 24 Dl -734 4662(1024)N -16 Ds -1 Dt -675 4352 MXY -9 60 Dl -18 134 Dl -37 266 Dl -73 117 Dl -146 30 Dl -292 0 Dl -584 -1 Dl --1 Ds -3 Dt -1846 4946 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -1262 4946 MXY --24 25 Dl -12 -12 Dl --12 -13 Dl -24 25 Dl -970 4947 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -824 4917 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -751 4800 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -715 4534 MXY --25 25 Dl -12 -13 Dl --12 -12 Dl -25 25 Dl -696 4400 MXY --24 24 Dl -12 -12 Dl --12 -12 Dl -24 24 Dl -687 4339 MXY --24 25 Dl -12 -12 Dl --12 -13 Dl -24 25 Dl -718 4792(512)N -5 Dt -675 4422 MXY -9 137 Dl -18 278 Dl -37 105 Dl -73 18 Dl -146 -1 Dl -292 0 Dl -584 -1 Dl -3 Dt -4946 MY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -1250 4946 MXY -0 25 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -958 4947 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -812 4948 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -739 4930 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -702 4824 MXY -0 25 Dl -0 -12 Dl -13 0 Dl --25 0 Dl -684 4547 MXY -0 24 Dl -0 -12 Dl -12 0 Dl --24 0 Dl -675 4410 MXY -0 25 Dl -0 -13 Dl -12 0 Dl --24 0 Dl -750 4921(256)N -20 Ds -1 Dt -675 4597 MXY -9 246 Dl -18 106 Dl -37 10 Dl -73 0 Dl -146 0 Dl -292 0 Dl -584 -1 Dl --1 Ds -3 Dt -1822 MX -23 Dc -1238 4959 MXY -23 Dc -946 MX -23 Dc -800 MX -23 Dc -727 MX -23 Dc -691 4949 MXY -23 Dc -672 4843 MXY -24 Dc -663 4597 MXY -24 Dc -1395 4961(128)N -1 Dt -675 4855 MXY -9 93 Dl -18 10 Dl -37 1 Dl -73 0 Dl -146 -1 Dl -292 0 Dl -584 0 Dl -3 Dt -4946 MY --12 24 Dl -24 0 Dl --12 -24 Dl -1250 MX --12 24 Dl -24 0 Dl --12 -24 Dl -958 MX --12 24 Dl -24 0 Dl --12 -24 Dl -812 MX --12 25 Dl -24 0 Dl --12 -25 Dl -739 4947 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -702 4946 MXY --12 24 Dl -25 0 Dl --13 -24 Dl -684 4936 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -675 4843 MXY --12 24 Dl -24 0 Dl --12 -24 Dl -3 Dt --1 Ds -3 f -432 5314(Figure)N -634(5b:)X -1 f -744(Elapsed)X -967(Time)X -1123(for)X -1218(dictionary)X -1498(data)X -1625(set)X -1717(with)X -1851(1M)X -1960(of)X -2033(buffer)X -432 5402(space)N -593(and)X -705(varying)X -920(bucket)X -1110(sizes)X -1254(and)X -1366(\256ll)X -1457(factors.)X -1681(Each)X -1827(line)X -1942(is)X -2004(labeled)X -432 5490(with)N -562(its)X -639(bucket)X -825(size.)X -10 s -2590 538(If)N -2677(an)X -2785(approximation)X -3284(of)X -3383(the)X -3513(number)X -3790(of)X -3889(elements)X -2418 626(ultimately)N -2773(to)X -2866(be)X -2973(stored)X -3200(in)X -3293(the)X -3422(hash)X -3599(table)X -3785(is)X -3868(known)X -4116(at)X -2418 714(the)N -2564(time)X -2754(of)X -2869(creation,)X -3196(the)X -3342(hash)X -3536(package)X -3847(takes)X -4059(this)X -2418 802(number)N -2688(as)X -2779(a)X -2839(parameter)X -3185(and)X -3325(uses)X -3487(it)X -3555(to)X -3641(hash)X -3812(entries)X -4050(into)X -2418 890(the)N -2541(full)X -2677(sized)X -2867(table)X -3048(rather)X -3261(than)X -3424(growing)X -3716(the)X -3838(table)X -4018(from)X -2418 978(a)N -2477(single)X -2691(bucket.)X -2968(If)X -3044(this)X -3181(number)X -3448(is)X -3523(not)X -3647(known,)X -3907(the)X -4027(hash)X -2418 1066(table)N -2632(starts)X -2859(with)X -3059(a)X -3153(single)X -3402(bucket)X -3674(and)X -3848(gracefully)X -2418 1154(expands)N -2707(as)X -2800(elements)X -3111(are)X -3236(added,)X -3474(although)X -3780(a)X -3842(slight)X -4044(per-)X -2418 1242(formance)N -2747(degradation)X -3151(may)X -3313(be)X -3413(noticed.)X -3713(Figure)X -3946(6)X -4010(illus-)X -2418 1330(trates)N -2625(the)X -2756(difference)X -3116(in)X -3211(performance)X -3651(between)X -3952(storing)X -2418 1418(keys)N -2588(in)X -2673(a)X -2732(\256le)X -2857(when)X -3054(the)X -3174(ultimate)X -3458(size)X -3605(is)X -3680(known)X -3920(\(the)X -4067(left)X -2418 1506(bars)N -2581(in)X -2672(each)X -2849(set\),)X -3014(compared)X -3360(to)X -3450(building)X -3744(the)X -3870(\256le)X -4000(when)X -2418 1594(the)N -2550(ultimate)X -2846(size)X -3005(is)X -3091(unknown)X -3422(\(the)X -3580(right)X -3764(bars)X -3931(in)X -4026(each)X -2418 1682(set\).)N -2609(Once)X -2814(the)X -2947(\256ll)X -3069(factor)X -3291(is)X -3378(suf\256ciently)X -3772(high)X -3948(for)X -4076(the)X -2418 1770(page)N -2596(size)X -2747(\(8\),)X -2887(growing)X -3180(the)X -3304(table)X -3486(dynamically)X -3908(does)X -4081(lit-)X -2418 1858(tle)N -2518(to)X -2600(degrade)X -2875(performance.)X -10 f -2418 1946 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -9 s -1 f -2413 3238(s)N -2409 3173(d)N -2409 3108(n)N -2409 3043(o)N -2411 2979(c)N -2411 2914(e)N -2407 2849(S)N -3143 4129(Fill)N -3261(Factor)X -2448 2152(15)N -4 Ds -1 Dt -2557 2122 MXY -1473 0 Dl --1 Ds -5 Dt -2557 MX --19 0 Dl -2448 2747(10)N -4 Ds -1 Dt -2557 2717 MXY -1473 0 Dl --1 Ds -5 Dt -2557 MX --19 0 Dl -2484 3343(5)N -4 Ds -1 Dt -2557 3313 MXY -1473 0 Dl --1 Ds -5 Dt -2557 MX --19 0 Dl -2484 3938(0)N -4 Ds -1 Dt -2557 3908 MXY -1473 0 Dl --1 Ds -5 Dt -2557 MX --19 0 Dl -3976 4015(128)N -4 Ds -1 Dt -4030 3908 MXY -0 -1786 Dl --1 Ds -5 Dt -3908 MY -0 19 Dl -3626 4015(96)N -4 Ds -1 Dt -3662 3908 MXY -0 -1786 Dl --1 Ds -5 Dt -3908 MY -0 19 Dl -3258 4015(64)N -4 Ds -1 Dt -3294 3908 MXY -0 -1786 Dl --1 Ds -5 Dt -3908 MY -0 19 Dl -2889 4015(32)N -4 Ds -1 Dt -2925 3908 MXY -0 -1786 Dl --1 Ds -5 Dt -3908 MY -0 19 Dl -2539 4015(0)N -4 Ds -1 Dt -2557 3908 MXY -0 -1786 Dl --1 Ds -5 Dt -3908 MY -0 19 Dl -3908 MY -0 -1786 Dl -3908 MY -1473 0 Dl -4053 2378(8192)N -3 Dt -2569 2277 MXY -11 0 Dl -23 48 Dl -46 -167 Dl -92 35 Dl -184 12 Dl -369 143 Dl -736 0 Dl -2334 MY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -3294 2334 MXY -0 28 Dl -0 -14 Dl -13 0 Dl --27 0 Dl -2925 2192 MXY -0 27 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2741 2180 MXY -0 27 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2649 2144 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2603 2311 MXY -0 27 Dl -0 -13 Dl -14 0 Dl --28 0 Dl -2580 2263 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2569 2263 MXY -0 28 Dl -0 -14 Dl -13 0 Dl --27 0 Dl -4053 2591(4096)N -2569 2348 MXY -11 -11 Dl -23 -96 Dl -46 71 Dl -92 72 Dl -184 226 Dl -369 48 Dl -736 -60 Dl -2612 MY -14 -28 Dl --28 0 Dl -14 28 Dl -3294 2672 MXY -13 -28 Dl --27 0 Dl -14 28 Dl -2925 2624 MXY -14 -28 Dl --28 0 Dl -14 28 Dl -2741 2398 MXY -14 -28 Dl --28 0 Dl -14 28 Dl -2649 2326 MXY -14 -27 Dl --28 0 Dl -14 27 Dl -2603 2255 MXY -14 -28 Dl --28 0 Dl -14 28 Dl -2580 2350 MXY -14 -27 Dl --28 0 Dl -14 27 Dl -2569 2362 MXY -13 -28 Dl --27 0 Dl -14 28 Dl -4053 2681(1024)N -16 Ds -1 Dt -2569 2300 MXY -11 48 Dl -23 96 Dl -46 95 Dl -92 274 Dl -184 202 Dl -369 -155 Dl -736 -190 Dl --1 Ds -3 Dt -4044 2656 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -3307 2846 MXY --27 28 Dl -14 -14 Dl --14 -14 Dl -27 28 Dl -2939 3001 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -2755 2799 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -2663 2525 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -2617 2430 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -2594 2334 MXY --28 28 Dl -14 -14 Dl --14 -14 Dl -28 28 Dl -2582 2287 MXY --27 27 Dl -14 -14 Dl --14 -13 Dl -27 27 Dl -4053 2851(512)N -5 Dt -2569 2372 MXY -11 -24 Dl -23 405 Dl -46 83 Dl -92 227 Dl -184 -72 Dl -369 -119 Dl -736 -107 Dl -3 Dt -2751 MY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -3294 2858 MXY -0 28 Dl -0 -14 Dl -13 0 Dl --27 0 Dl -2925 2977 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2741 3049 MXY -0 27 Dl -0 -13 Dl -14 0 Dl --28 0 Dl -2649 2823 MXY -0 27 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2603 2739 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2580 2334 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2569 2358 MXY -0 28 Dl -0 -14 Dl -13 0 Dl --27 0 Dl -4053 2795(256)N -20 Ds -1 Dt -2569 2456 MXY -11 285 Dl -23 95 Dl -46 251 Dl -92 -60 Dl -184 -84 Dl -369 -107 Dl -736 -71 Dl --1 Ds -3 Dt -4016 MX -27 Dc -3280 2836 MXY -27 Dc -2912 2943 MXY -27 Dc -2728 3027 MXY -27 Dc -2635 3087 MXY -28 Dc -2589 2836 MXY -28 Dc -2566 2741 MXY -27 Dc -2554 2456 MXY -28 Dc -4053 2741(128)N -1 Dt -2569 2729 MXY -11 203 Dl -23 131 Dl -46 -60 Dl -92 -119 Dl -184 -60 Dl -369 -83 Dl -736 -12 Dl -3 Dt -2716 MY --14 27 Dl -28 0 Dl --14 -27 Dl -3294 2727 MXY --14 28 Dl -27 0 Dl --13 -28 Dl -2925 2811 MXY --14 27 Dl -28 0 Dl --14 -27 Dl -2741 2870 MXY --14 28 Dl -28 0 Dl --14 -28 Dl -2649 2989 MXY --14 28 Dl -28 0 Dl --14 -28 Dl -2603 3049 MXY --14 27 Dl -28 0 Dl --14 -27 Dl -2580 2918 MXY --14 28 Dl -28 0 Dl --14 -28 Dl -2569 2716 MXY --14 27 Dl -27 0 Dl --13 -27 Dl -3 Dt --1 Ds -3 f -8 s -2418 4286(Figure)N -2628(5c:)X -1 f -2738(User)X -2887(Time)X -3051(for)X -3154(dictionary)X -3442(data)X -3577(set)X -3677(with)X -3820(1M)X -3938(of)X -4019(buffer)X -2418 4374(space)N -2579(and)X -2691(varying)X -2906(bucket)X -3096(sizes)X -3240(and)X -3352(\256ll)X -3443(factors.)X -3667(Each)X -3813(line)X -3928(is)X -3990(labeled)X -2418 4462(with)N -2548(its)X -2625(bucket)X -2811(size.)X -10 s -10 f -2418 4638 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 f -2590 4840(Since)N -2796(no)X -2904(known)X -3150(hash)X -3325(function)X -3620(performs)X -3938(equally)X -2418 4928(well)N -2589(on)X -2702(all)X -2815(possible)X -3110(data,)X -3297(the)X -3428(user)X -3595(may)X -3766(\256nd)X -3923(that)X -4076(the)X -2418 5016(built-in)N -2678(hash)X -2849(function)X -3140(does)X -3311(poorly)X -3544(on)X -3648(a)X -3708(particular)X -4040(data)X -2418 5104(set.)N -2548(In)X -2636(this)X -2771(case,)X -2950(a)X -3006(hash)X -3173(function,)X -3480(taking)X -3700(two)X -3840(arguments)X -2418 5192(\(a)N -2507(pointer)X -2760(to)X -2848(a)X -2910(byte)X -3074(string)X -3282(and)X -3424(a)X -3486(length\))X -3739(and)X -3880(returning)X -2418 5280(an)N -2517(unsigned)X -2829(long)X -2993(to)X -3077(be)X -3175(used)X -3344(as)X -3433(the)X -3553(hash)X -3722(value,)X -3938(may)X -4098(be)X -2418 5368(speci\256ed)N -2731(at)X -2817(hash)X -2992(table)X -3176(creation)X -3463(time.)X -3673(When)X -3893(an)X -3996(exist-)X -2418 5456(ing)N -2570(hash)X -2767(table)X -2973(is)X -3076(opened)X -3358(and)X -3524(a)X -3609(hash)X -3805(function)X -4121(is)X -2418 5544(speci\256ed,)N -2752(the)X -2879(hash)X -3054(package)X -3346(will)X -3498(try)X -3615(to)X -3705(determine)X -4054(that)X -2418 5632(the)N -2546(hash)X -2723(function)X -3020(supplied)X -3321(is)X -3404(the)X -3532(one)X -3678(with)X -3850(which)X -4076(the)X -2418 5720(table)N -2630(was)X -2811(created.)X -3139(There)X -3382(are)X -3536(a)X -3627(variety)X -3905(of)X -4027(hash)X -3 f -432 5960(8)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -9 p -%%Page: 9 9 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -1 f -720 538(functions)N -1065(provided)X -1397(with)X -1586(the)X -1731(package.)X -2082(The)X -2253(default)X -720 626(function)N -1014(for)X -1135(the)X -1260(package)X -1551(is)X -1631(the)X -1755(one)X -1897(which)X -2119(offered)X -2378(the)X -720 714(best)N -875(performance)X -1308(in)X -1396(terms)X -1600(of)X -1693(cycles)X -1920(executed)X -2232(per)X -2360(call)X -720 802(\(it)N -827(did)X -965(not)X -1103(produce)X -1398(the)X -1531(fewest)X -1776(collisions)X -2117(although)X -2432(it)X -720 890(was)N -866(within)X -1091(a)X -1148(small)X -1341(percentage)X -1710(of)X -1797(the)X -1915(function)X -2202(that)X -2342(pro-)X -720 978(duced)N -947(the)X -1080(fewest)X -1324(collisions\).)X -1731(Again,)X -1981(in)X -2077(time)X -2253(critical)X -720 1066(applications,)N -1152(users)X -1342(are)X -1466(encouraged)X -1862(to)X -1949(experiment)X -2334(with)X -720 1154(a)N -783(variety)X -1032(of)X -1125(hash)X -1298(functions)X -1622(to)X -1710(achieve)X -1982(optimal)X -2252(perfor-)X -720 1242(mance.)N -10 f -720 1330 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -7 s -1038 2925(Full)N -1149(size)X -1251(table)X -1384(\(left\))X -1547 2718(Fill)N -1643(Factor)X -2268 2662(64)N -1964(32)X -1674(16)X -1384(8)X -1093(4)X -4 Ds -1 Dt -900 2280 MXY -1548 0 Dl -900 1879 MXY -1548 0 Dl -900 1506 MXY -1548 0 Dl -1563 2902 MXY -111 0 Dl --1 Ds -900 MX -110 0 Dl -1425 2828(System)N -983(User)X -1895 2778 MXY - 1895 2778 lineto - 1950 2778 lineto - 1950 2833 lineto - 1895 2833 lineto - 1895 2778 lineto -closepath 21 1895 2778 1950 2833 Dp -1342 MX - 1342 2778 lineto - 1397 2778 lineto - 1397 2833 lineto - 1342 2833 lineto - 1342 2778 lineto -closepath 14 1342 2778 1397 2833 Dp -900 MX - 900 2778 lineto - 955 2778 lineto - 955 2833 lineto - 900 2833 lineto - 900 2778 lineto -closepath 3 900 2778 955 2833 Dp -5 Dt -2283 2211 MXY -96 0 Dl -1992 MX -97 0 Dl -1702 MX -97 0 Dl -1411 2252 MXY -97 0 Dl -4 Ds -1 Dt -2283 2211 MXY - 2283 2211 lineto - 2379 2211 lineto - 2379 2252 lineto - 2283 2252 lineto - 2283 2211 lineto -closepath 14 2283 2211 2379 2252 Dp -1992 MX - 1992 2211 lineto - 2089 2211 lineto - 2089 2252 lineto - 1992 2252 lineto - 1992 2211 lineto -closepath 14 1992 2211 2089 2252 Dp -1702 MX - 1702 2211 lineto - 1799 2211 lineto - 1799 2252 lineto - 1702 2252 lineto - 1702 2211 lineto -closepath 14 1702 2211 1799 2252 Dp -1411 2252 MXY - 1411 2252 lineto - 1508 2252 lineto - 1508 2294 lineto - 1411 2294 lineto - 1411 2252 lineto -closepath 14 1411 2252 1508 2294 Dp -2283 MX - 2283 2252 lineto - 2379 2252 lineto - 2379 2612 lineto - 2283 2612 lineto - 2283 2252 lineto -closepath 3 2283 2252 2379 2612 Dp -1992 MX - 1992 2252 lineto - 2089 2252 lineto - 2089 2612 lineto - 1992 2612 lineto - 1992 2252 lineto -closepath 3 1992 2252 2089 2612 Dp -1702 MX - 1702 2252 lineto - 1799 2252 lineto - 1799 2612 lineto - 1702 2612 lineto - 1702 2252 lineto -closepath 3 1702 2252 1799 2612 Dp -1411 2294 MXY - 1411 2294 lineto - 1508 2294 lineto - 1508 2612 lineto - 1411 2612 lineto - 1411 2294 lineto -closepath 3 1411 2294 1508 2612 Dp --1 Ds -2158 2238 MXY - 2158 2238 lineto - 2255 2238 lineto - 2255 2252 lineto - 2158 2252 lineto - 2158 2238 lineto -closepath 21 2158 2238 2255 2252 Dp -1868 MX - 1868 2238 lineto - 1965 2238 lineto - 1965 2280 lineto - 1868 2280 lineto - 1868 2238 lineto -closepath 21 1868 2238 1965 2280 Dp -1577 MX - 1577 2238 lineto - 1674 2238 lineto - 1674 2308 lineto - 1577 2308 lineto - 1577 2238 lineto -closepath 21 1577 2238 1674 2308 Dp -1287 2308 MXY - 1287 2308 lineto - 1287 2280 lineto - 1384 2280 lineto - 1384 2308 lineto - 1287 2308 lineto -closepath 21 1287 2280 1384 2308 Dp -2158 2280 MXY - 2158 2280 lineto - 2158 2252 lineto - 2255 2252 lineto - 2255 2280 lineto - 2158 2280 lineto -closepath 14 2158 2252 2255 2280 Dp -1868 2308 MXY - 1868 2308 lineto - 1868 2280 lineto - 1965 2280 lineto - 1965 2308 lineto - 1868 2308 lineto -closepath 14 1868 2280 1965 2308 Dp -1577 2335 MXY - 1577 2335 lineto - 1577 2308 lineto - 1674 2308 lineto - 1674 2335 lineto - 1577 2335 lineto -closepath 14 1577 2308 1674 2335 Dp -1287 2363 MXY - 1287 2363 lineto - 1287 2308 lineto - 1384 2308 lineto - 1384 2363 lineto - 1287 2363 lineto -closepath 14 1287 2308 1384 2363 Dp -2158 2280 MXY - 2158 2280 lineto - 2255 2280 lineto - 2255 2612 lineto - 2158 2612 lineto - 2158 2280 lineto -closepath 3 2158 2280 2255 2612 Dp -1868 2308 MXY - 1868 2308 lineto - 1965 2308 lineto - 1965 2612 lineto - 1868 2612 lineto - 1868 2308 lineto -closepath 3 1868 2308 1965 2612 Dp -1577 2335 MXY - 1577 2335 lineto - 1674 2335 lineto - 1674 2612 lineto - 1577 2612 lineto - 1577 2335 lineto -closepath 3 1577 2335 1674 2612 Dp -1287 2363 MXY - 1287 2363 lineto - 1384 2363 lineto - 1384 2612 lineto - 1287 2612 lineto - 1287 2363 lineto -closepath 3 1287 2363 1384 2612 Dp -4 Ds -1121 2066 MXY - 1121 2066 lineto - 1218 2066 lineto - 1224 2080 lineto - 1127 2080 lineto - 1121 2066 lineto -closepath 21 1121 2066 1224 2080 Dp -2080 MY - 1121 2080 lineto - 1218 2080 lineto - 1218 2273 lineto - 1121 2273 lineto - 1121 2080 lineto -closepath 14 1121 2080 1218 2273 Dp -2273 MY - 1121 2273 lineto - 1218 2273 lineto - 1218 2612 lineto - 1121 2612 lineto - 1121 2273 lineto -closepath 3 1121 2273 1218 2612 Dp --1 Ds -997 1589 MXY - 997 1589 lineto - 1093 1589 lineto - 1093 1644 lineto - 997 1644 lineto - 997 1589 lineto -closepath 21 997 1589 1093 1644 Dp -1644 MY - 997 1644 lineto - 1093 1644 lineto - 1093 2280 lineto - 997 2280 lineto - 997 1644 lineto -closepath 14 997 1644 1093 2280 Dp -2280 MY - 997 2280 lineto - 1093 2280 lineto - 1093 2612 lineto - 997 2612 lineto - 997 2280 lineto -closepath 3 997 2280 1093 2612 Dp -10 s -719 2093(s)N -712 2037(d)N -712 1982(n)N -714 1927(o)N -716 1872(c)N -716 1816(e)N -712 1761(S)N -804 2286(10)N -804 1899(20)N -804 1540(30)N -3 Dt -900 1506 MXY -0 1106 Dl -1548 0 Dl -7 s -1978 2828(Elapsed)N -1701 2925(Dynamically)N -2018(grown)X -2184(table)X -2317(\(right\))X -3 Dt --1 Ds -8 s -720 3180(Figure)N -934(6:)X -1 f -1020(The)X -1152(total)X -1299(regions)X -1520(indicate)X -1755(the)X -1865(difference)X -2154(between)X -2398(the)X -720 3268(elapsed)N -931(time)X -1065(and)X -1177(the)X -1275(sum)X -1402(of)X -1475(the)X -1573(system)X -1771(and)X -1883(user)X -2008(time.)X -2173(The)X -2291(left)X -2395(bar)X -720 3356(of)N -798(each)X -939(set)X -1035(depicts)X -1241(the)X -1344(timing)X -1537(of)X -1615(the)X -1718(test)X -1831(run)X -1940(when)X -2102(the)X -2204(number)X -2423(of)X -720 3444(entries)N -910(is)X -973(known)X -1167(in)X -1237(advance.)X -1496(The)X -1614(right)X -1754(bars)X -1879(depict)X -2054(the)X -2151(timing)X -2338(when)X -720 3532(the)N -814(\256le)X -912(is)X -971(grown)X -1150(from)X -1290(a)X -1334(single)X -1503(bucket.)X -10 s -10 f -720 3708 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -1 f -892 3910(Since)N -1131(this)X -1307(hashing)X -1617(package)X -1942(provides)X -2279(buffer)X -720 3998(management,)N -1188(the)X -1323(amount)X -1600(of)X -1704(space)X -1920(allocated)X -2247(for)X -2378(the)X -720 4086(buffer)N -948(pool)X -1121(may)X -1290(be)X -1397(speci\256ed)X -1713(by)X -1824(the)X -1953(user.)X -2157(Using)X -2378(the)X -720 4174(same)N -910(data)X -1069(set)X -1183(and)X -1324(test)X -1459(procedure)X -1805(as)X -1896(used)X -2067(to)X -2153(derive)X -2378(the)X -720 4262(graphs)N -962(in)X -1052(Figures)X -1320(5a-c,)X -1507(Figure)X -1744(7)X -1812(shows)X -2039(the)X -2164(impact)X -2409(of)X -720 4350(varying)N -997(the)X -1126(size)X -1282(of)X -1380(the)X -1509(buffer)X -1737(pool.)X -1950(The)X -2106(bucket)X -2351(size)X -720 4438(was)N -873(set)X -989(to)X -1078(256)X -1225(bytes)X -1421(and)X -1564(the)X -1689(\256ll)X -1804(factor)X -2019(was)X -2171(set)X -2287(to)X -2376(16.)X -720 4526(The)N -869(buffer)X -1090(pool)X -1256(size)X -1404(was)X -1552(varied)X -1776(from)X -1955(0)X -2018(\(the)X -2166(minimum)X -720 4614(number)N -986(of)X -1074(pages)X -1277(required)X -1565(to)X -1647(be)X -1743(buffered\))X -2063(to)X -2145(1M.)X -2316(With)X -720 4702(1M)N -854(of)X -944(buffer)X -1164(space,)X -1386(the)X -1507(package)X -1794(performed)X -2151(no)X -2253(I/O)X -2382(for)X -720 4790(this)N -871(data)X -1040(set.)X -1204(As)X -1328(Figure)X -1572(7)X -1647(illustrates,)X -2013(increasing)X -2378(the)X -720 4878(buffer)N -944(pool)X -1113(size)X -1265(can)X -1404(have)X -1583(a)X -1646(dramatic)X -1954(affect)X -2165(on)X -2271(result-)X -720 4966(ing)N -842(performance.)X -2 f -8 s -1269 4941(7)N -1 f -16 s -720 5353 MXY -864 0 Dl -2 f -8 s -760 5408(7)N -1 f -9 s -826 5433(Some)N -1024(allocators)X -1338(are)X -1460(extremely)X -1782(inef\256cient)X -2107(at)X -2192(allocating)X -720 5513(memory.)N -1029(If)X -1110(you)X -1251(\256nd)X -1396(that)X -1536(applications)X -1916(are)X -2036(running)X -2292(out)X -2416(of)X -720 5593(memory)N -1005(before)X -1234(you)X -1386(think)X -1578(they)X -1746(should,)X -2000(try)X -2124(varying)X -2388(the)X -720 5673(pagesize)N -986(to)X -1060(get)X -1166(better)X -1348(utilization)X -1658(from)X -1816(the)X -1922(memory)X -2180(allocator.)X -10 s -2830 1975 MXY -0 -28 Dl -28 0 Dl -0 28 Dl --28 0 Dl -2853 2004 MXY -0 -27 Dl -28 0 Dl -0 27 Dl --28 0 Dl -2876 2016 MXY -0 -27 Dl -27 0 Dl -0 27 Dl --27 0 Dl -2922 1998 MXY -0 -27 Dl -27 0 Dl -0 27 Dl --27 0 Dl -2967 2025 MXY -0 -28 Dl -28 0 Dl -0 28 Dl --28 0 Dl -3013 2031 MXY -0 -28 Dl -28 0 Dl -0 28 Dl --28 0 Dl -3059 MX -0 -28 Dl -27 0 Dl -0 28 Dl --27 0 Dl -3196 2052 MXY -0 -28 Dl -27 0 Dl -0 28 Dl --27 0 Dl -3561 2102 MXY -0 -28 Dl -28 0 Dl -0 28 Dl --28 0 Dl -4292 2105 MXY -0 -28 Dl -27 0 Dl -0 28 Dl --27 0 Dl -4 Ds -1 Dt -2844 1961 MXY -23 30 Dl -23 12 Dl -45 -18 Dl -46 26 Dl -46 6 Dl -45 0 Dl -137 21 Dl -366 50 Dl -730 3 Dl -9 s -4227 2158(User)N --1 Ds -3 Dt -2830 1211 MXY -27 Dc -2853 1261 MXY -27 Dc -2876 1267 MXY -27 Dc -2921 1341 MXY -27 Dc -2967 1385 MXY -27 Dc -3013 1450 MXY -27 Dc -3059 1497 MXY -27 Dc -3196 1686 MXY -27 Dc -3561 2109 MXY -27 Dc -4292 2295 MXY -27 Dc -20 Ds -1 Dt -2844 1211 MXY -23 50 Dl -23 6 Dl -45 74 Dl -46 44 Dl -46 65 Dl -45 47 Dl -137 189 Dl -366 423 Dl -730 186 Dl -4181 2270(System)N --1 Ds -3 Dt -2844 583 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2867 672 MXY -0 27 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -2890 701 MXY -0 28 Dl -0 -14 Dl -13 0 Dl --27 0 Dl -2935 819 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --27 0 Dl -2981 849 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -3027 908 MXY -0 27 Dl -0 -13 Dl -14 0 Dl --28 0 Dl -3072 1026 MXY -0 27 Dl -0 -13 Dl -14 0 Dl --27 0 Dl -3209 1292 MXY -0 27 Dl -0 -14 Dl -14 0 Dl --27 0 Dl -3575 1823 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --28 0 Dl -4305 2059 MXY -0 28 Dl -0 -14 Dl -14 0 Dl --27 0 Dl -5 Dt -2844 597 MXY -23 88 Dl -23 30 Dl -45 118 Dl -46 30 Dl -46 59 Dl -45 118 Dl -137 265 Dl -366 532 Dl -730 236 Dl -4328 2103(Total)N -2844 2310 MXY -1461 0 Dl -2844 MX -0 -1772 Dl -2310 MY -0 18 Dl -4 Ds -1 Dt -2310 MY -0 -1772 Dl -2826 2416(0)N --1 Ds -5 Dt -3209 2310 MXY -0 18 Dl -4 Ds -1 Dt -2310 MY -0 -1772 Dl -3155 2416(256)N --1 Ds -5 Dt -3575 2310 MXY -0 18 Dl -4 Ds -1 Dt -2310 MY -0 -1772 Dl -3521 2416(512)N --1 Ds -5 Dt -3940 2310 MXY -0 18 Dl -4 Ds -1 Dt -2310 MY -0 -1772 Dl -3886 2416(768)N --1 Ds -5 Dt -4305 2310 MXY -0 18 Dl -4 Ds -1 Dt -2310 MY -0 -1772 Dl -4233 2416(1024)N --1 Ds -5 Dt -2844 2310 MXY --18 0 Dl -4 Ds -1 Dt -2844 MX -1461 0 Dl -2771 2340(0)N --1 Ds -5 Dt -2844 2014 MXY --18 0 Dl -2844 1719 MXY --18 0 Dl -4 Ds -1 Dt -2844 MX -1461 0 Dl -2735 1749(20)N --1 Ds -5 Dt -2844 1423 MXY --18 0 Dl -2844 1128 MXY --18 0 Dl -4 Ds -1 Dt -2844 MX -1461 0 Dl -2735 1158(40)N --1 Ds -5 Dt -2844 833 MXY --18 0 Dl -2844 538 MXY --18 0 Dl -4 Ds -1 Dt -2844 MX -1461 0 Dl -2735 568(60)N -3239 2529(Buffer)N -3445(Pool)X -3595(Size)X -3737(\(in)X -3835(K\))X -2695 1259(S)N -2699 1324(e)N -2699 1388(c)N -2697 1452(o)N -2697 1517(n)N -2697 1581(d)N -2701 1645(s)N -3 Dt --1 Ds -3 f -8 s -2706 2773(Figure)N -2908(7:)X -1 f -2982(User)X -3123(time)X -3258(is)X -3322(virtually)X -3560(insensitive)X -3854(to)X -3924(the)X -4022(amount)X -4234(of)X -4307(buffer)X -2706 2861(pool)N -2852(available,)X -3130(however,)X -3396(both)X -3541(system)X -3750(time)X -3895(and)X -4018(elapsed)X -4240(time)X -4385(are)X -2706 2949(inversely)N -2960(proportional)X -3296(to)X -3366(the)X -3464(size)X -3583(of)X -3656(the)X -3753(buffer)X -3927(pool.)X -4092(Even)X -4242(for)X -4335(large)X -2706 3037(data)N -2831(sets)X -2946(where)X -3120(one)X -3230(expects)X -3439(few)X -3552(collisions,)X -3832(specifying)X -4116(a)X -4162(large)X -4307(buffer)X -2706 3125(pool)N -2836(dramatically)X -3171(improves)X -3425(performance.)X -10 s -10 f -2706 3301 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -3175 3543(Enhanced)N -3536(Functionality)X -1 f -2878 3675(This)N -3046(hashing)X -3320(package)X -3609(provides)X -3910(a)X -3971(set)X -4085(of)X -4177(compati-)X -2706 3763(bility)N -2895(routines)X -3174(to)X -3257(implement)X -3620(the)X -2 f -3739(ndbm)X -1 f -3937(interface.)X -4279(How-)X -2706 3851(ever,)N -2893(when)X -3095(the)X -3220(native)X -3443(interface)X -3752(is)X -3832(used,)X -4026(the)X -4151(following)X -2706 3939(additional)N -3046(functionality)X -3475(is)X -3548(provided:)X -10 f -2798 4071(g)N -1 f -2946(Inserts)X -3197(never)X -3413(fail)X -3556(because)X -3847(too)X -3985(many)X -4199(keys)X -2946 4159(hash)N -3113(to)X -3195(the)X -3313(same)X -3498(value.)X -10 f -2798 4247(g)N -1 f -2946(Inserts)X -3187(never)X -3393(fail)X -3527(because)X -3808(key)X -3950(and/or)X -4181(asso-)X -2946 4335(ciated)N -3158(data)X -3312(is)X -3385(too)X -3507(large)X -10 f -2798 4423(g)N -1 f -2946(Hash)X -3131(functions)X -3449(may)X -3607(be)X -3703(user-speci\256ed.)X -10 f -2798 4511(g)N -1 f -2946(Multiple)X -3268(pages)X -3498(may)X -3683(be)X -3806(cached)X -4077(in)X -4186(main)X -2946 4599(memory.)N -2706 4731(It)N -2801(also)X -2976(provides)X -3298(a)X -3380(set)X -3514(of)X -3626(compatibility)X -4097(routines)X -4400(to)X -2706 4819(implement)N -3087(the)X -2 f -3224(hsearch)X -1 f -3516(interface.)X -3876(Again,)X -4130(the)X -4266(native)X -2706 4907(interface)N -3008(offers)X -3216(enhanced)X -3540(functionality:)X -10 f -2798 5039(g)N -1 f -2946(Files)X -3121(may)X -3279(grow)X -3464(beyond)X -2 f -3720(nelem)X -1 f -3932(elements.)X -10 f -2798 5127(g)N -1 f -2946(Multiple)X -3247(hash)X -3420(tables)X -3632(may)X -3795(be)X -3896(accessed)X -4203(con-)X -2946 5215(currently.)N -10 f -2798 5303(g)N -1 f -2946(Hash)X -3134(tables)X -3344(may)X -3505(be)X -3604(stored)X -3823(and)X -3962(accessed)X -4266(on)X -2946 5391(disk.)N -10 f -2798 5479(g)N -1 f -2946(Hash)X -3155(functions)X -3497(may)X -3679(be)X -3799(user-speci\256ed)X -4288(at)X -2946 5567(runtime.)N -3 f -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4424(9)X - -10 p -%%Page: 10 10 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -459 538(Relative)N -760(Performance)X -1227(of)X -1314(the)X -1441(New)X -1613(Implementation)X -1 f -604 670(The)N -761(performance)X -1200(testing)X -1445(of)X -1544(the)X -1674(new)X -1840(package)X -2135(is)X -432 758(divided)N -711(into)X -874(two)X -1033(test)X -1183(suites.)X -1424(The)X -1588(\256rst)X -1751(suite)X -1941(of)X -2046(tests)X -432 846(requires)N -727(that)X -882(the)X -1015(tables)X -1237(be)X -1348(read)X -1522(from)X -1713(and)X -1864(written)X -2126(to)X -432 934(disk.)N -640(In)X -742(these)X -942(tests,)X -1139(the)X -1272(basis)X -1467(for)X -1595(comparison)X -2003(is)X -2090(the)X -432 1022(4.3BSD-Reno)N -908(version)X -1169(of)X -2 f -1260(ndbm)X -1 f -1438(.)X -1502(Based)X -1722(on)X -1826(the)X -1948(designs)X -432 1110(of)N -2 f -521(sdbm)X -1 f -712(and)X -2 f -850(gdbm)X -1 f -1028(,)X -1070(they)X -1230(are)X -1351(expected)X -1659(to)X -1743(perform)X -2024(simi-)X -432 1198(larly)N -605(to)X -2 f -693(ndbm)X -1 f -871(,)X -917(and)X -1059(we)X -1179(do)X -1285(not)X -1413(show)X -1608(their)X -1781(performance)X -432 1286(numbers.)N -800(The)X -977(second)X -1252(suite)X -1454(contains)X -1772(the)X -1921(memory)X -432 1374(resident)N -712(test)X -849(which)X -1071(does)X -1243(not)X -1370(require)X -1623(that)X -1768(the)X -1891(\256les)X -2049(ever)X -432 1462(be)N -533(written)X -784(to)X -870(disk,)X -1047(only)X -1213(that)X -1357(hash)X -1528(tables)X -1739(may)X -1901(be)X -2001(mani-)X -432 1550(pulated)N -692(in)X -778(main)X -961(memory.)X -1291(In)X -1381(this)X -1519(test,)X -1673(we)X -1790(compare)X -2090(the)X -432 1638(performance)N -859(to)X -941(that)X -1081(of)X -1168(the)X -2 f -1286(hsearch)X -1 f -1560(routines.)X -604 1752(For)N -760(both)X -947(suites,)X -1194(two)X -1358(different)X -1679(databases)X -2031(were)X -432 1840(used.)N -656(The)X -818(\256rst)X -979(is)X -1069(the)X -1204(dictionary)X -1566(database)X -1880(described)X -432 1928(previously.)N -836(The)X -987(second)X -1236(was)X -1386(constructed)X -1781(from)X -1962(a)X -2023(pass-)X -432 2016(word)N -647(\256le)X -799(with)X -990(approximately)X -1502(300)X -1671(accounts.)X -2041(Two)X -432 2104(records)N -700(were)X -887(constructed)X -1287(for)X -1411(each)X -1589(account.)X -1909(The)X -2064(\256rst)X -432 2192(used)N -604(the)X -727(logname)X -1028(as)X -1120(the)X -1243(key)X -1384(and)X -1525(the)X -1648(remainder)X -1999(of)X -2090(the)X -432 2280(password)N -768(entry)X -965(for)X -1091(the)X -1221(data.)X -1427(The)X -1584(second)X -1839(was)X -1996(keyed)X -432 2368(by)N -541(uid)X -672(and)X -817(contained)X -1157(the)X -1283(entire)X -1494(password)X -1825(entry)X -2018(as)X -2113(its)X -432 2456(data)N -589(\256eld.)X -794(The)X -942(tests)X -1107(were)X -1287(all)X -1389(run)X -1518(on)X -1620(the)X -1740(HP)X -1864(9000)X -2046(with)X -432 2544(the)N -574(same)X -783(con\256guration)X -1254(previously)X -1636(described.)X -2027(Each)X -432 2632(test)N -576(was)X -734(run)X -874(\256ve)X -1027(times)X -1232(and)X -1380(the)X -1510(timing)X -1750(results)X -1991(of)X -2090(the)X -432 2720(runs)N -602(were)X -791(averaged.)X -1154(The)X -1311(variance)X -1616(across)X -1849(the)X -1979(5)X -2050(runs)X -432 2808(was)N -591(approximately)X -1088(1%)X -1229(of)X -1330(the)X -1462(average)X -1746(yielding)X -2041(95%)X -432 2896(con\256dence)N -800(intervals)X -1096(of)X -1183(approximately)X -1666(2%.)X -3 f -1021 3050(Disk)N -1196(Based)X -1420(Tests)X -1 f -604 3182(In)N -693(these)X -880(tests,)X -1064(we)X -1180(use)X -1308(a)X -1365(bucket)X -1600(size)X -1746(of)X -1834(1024)X -2015(and)X -2152(a)X -432 3270(\256ll)N -540(factor)X -748(of)X -835(32.)X -3 f -432 3384(create)N -663(test)X -1 f -547 3498(The)N -703(keys)X -881(are)X -1011(entered)X -1279(into)X -1433(the)X -1561(hash)X -1738(table,)X -1944(and)X -2090(the)X -547 3586(\256le)N -669(is)X -742(\257ushed)X -993(to)X -1075(disk.)X -3 f -432 3700(read)N -608(test)X -1 f -547 3814(A)N -640(lookup)X -897(is)X -984(performed)X -1353(for)X -1481(each)X -1663(key)X -1813(in)X -1909(the)X -2041(hash)X -547 3902(table.)N -3 f -432 4016(verify)N -653(test)X -1 f -547 4130(A)N -640(lookup)X -897(is)X -984(performed)X -1353(for)X -1481(each)X -1663(key)X -1813(in)X -1909(the)X -2041(hash)X -547 4218(table,)N -759(and)X -911(the)X -1045(data)X -1215(returned)X -1519(is)X -1608(compared)X -1961(against)X -547 4306(that)N -687(originally)X -1018(stored)X -1234(in)X -1316(the)X -1434(hash)X -1601(table.)X -3 f -432 4420(sequential)N -798(retrieve)X -1 f -547 4534(All)N -674(keys)X -846(are)X -970(retrieved)X -1281(in)X -1367(sequential)X -1716(order)X -1910(from)X -2090(the)X -547 4622(hash)N -724(table.)X -950(The)X -2 f -1105(ndbm)X -1 f -1313(interface)X -1625(allows)X -1863(sequential)X -547 4710(retrieval)N -848(of)X -948(the)X -1079(keys)X -1259(from)X -1448(the)X -1578(database,)X -1907(but)X -2041(does)X -547 4798(not)N -701(return)X -945(the)X -1094(data)X -1279(associated)X -1660(with)X -1853(each)X -2052(key.)X -547 4886(Therefore,)N -929(we)X -1067(compare)X -1388(the)X -1530(performance)X -1980(of)X -2090(the)X -547 4974(new)N -703(package)X -989(to)X -1073(two)X -1215(different)X -1514(runs)X -1674(of)X -2 f -1763(ndbm)X -1 f -1941(.)X -2002(In)X -2090(the)X -547 5062(\256rst)N -697(case,)X -2 f -882(ndbm)X -1 f -1086(returns)X -1335(only)X -1503(the)X -1627(keys)X -1800(while)X -2003(in)X -2090(the)X -547 5150(second,)N -2 f -823(ndbm)X -1 f -1034(returns)X -1290(both)X -1465(the)X -1596(keys)X -1776(and)X -1924(the)X -2054(data)X -547 5238(\(requiring)N -894(a)X -956(second)X -1204(call)X -1345(to)X -1432(the)X -1555(library\).)X -1861(There)X -2074(is)X -2152(a)X -547 5326(single)N -764(run)X -897(for)X -1017(the)X -1141(new)X -1300(library)X -1539(since)X -1729(it)X -1798(returns)X -2046(both)X -547 5414(the)N -665(key)X -801(and)X -937(the)X -1055(data.)X -3 f -3014 538(In-Memory)N -3431(Test)X -1 f -2590 670(This)N -2757(test)X -2892(uses)X -3054(a)X -3114(bucket)X -3352(size)X -3501(of)X -3592(256)X -3736(and)X -3876(a)X -3936(\256ll)X -4048(fac-)X -2418 758(tor)N -2527(of)X -2614(8.)X -3 f -2418 872(create/read)N -2827(test)X -1 f -2533 986(In)N -2627(this)X -2769(test,)X -2927(a)X -2989(hash)X -3162(table)X -3344(is)X -3423(created)X -3682(by)X -3788(inserting)X -4094(all)X -2533 1074(the)N -2660(key/data)X -2961(pairs.)X -3186(Then)X -3380(a)X -3445(keyed)X -3666(retrieval)X -3963(is)X -4044(per-)X -2533 1162(formed)N -2801(for)X -2931(each)X -3115(pair,)X -3295(and)X -3446(the)X -3579(hash)X -3761(table)X -3952(is)X -4040(des-)X -2533 1250(troyed.)N -3 f -2938 1404(Performance)N -3405(Results)X -1 f -2590 1536(Figures)N -2866(8a)X -2978(and)X -3130(8b)X -3246(show)X -3451(the)X -3585(user)X -3755(time,)X -3952(system)X -2418 1624(time,)N -2608(and)X -2752(elapsed)X -3021(time)X -3191(for)X -3312(each)X -3487(test)X -3625(for)X -3746(both)X -3915(the)X -4040(new)X -2418 1712(implementation)N -2951(and)X -3098(the)X -3227(old)X -3360(implementation)X -3893(\()X -2 f -3920(hsearch)X -1 f -2418 1800(or)N -2 f -2528(ndbm)X -1 f -2706(,)X -2769(whichever)X -3147(is)X -3243(appropriate\))X -3678(as)X -3787(well)X -3967(as)X -4076(the)X -2418 1888(improvement.)N -2929(The)X -3098(improvement)X -3569(is)X -3666(expressed)X -4027(as)X -4138(a)X -2418 1976(percentage)N -2787(of)X -2874(the)X -2992(old)X -3114(running)X -3383(time:)X -0 f -8 s -2418 2275(%)N -2494(=)X -2570(100)X -2722(*)X -2798 -0.4219(\(old_time)AX -3178(-)X -3254 -0.4219(new_time\))AX -3634(/)X -3710(old_time)X -1 f -10 s -2590 2600(In)N -2700(nearly)X -2944(all)X -3067(cases,)X -3299(the)X -3439(new)X -3615(routines)X -3915(perform)X -2418 2688(better)N -2628(than)X -2793(the)X -2918(old)X -3047(routines)X -3332(\(both)X -2 f -3527(hsearch)X -1 f -3807(and)X -2 f -3949(ndbm)X -1 f -4127(\).)X -2418 2776(Although)N -2755(the)X -3 f -2888(create)X -1 f -3134(tests)X -3311(exhibit)X -3567(superior)X -3864(user)X -4032(time)X -2418 2864(performance,)N -2869(the)X -2991(test)X -3126(time)X -3292(is)X -3369(dominated)X -3731(by)X -3834(the)X -3955(cost)X -4107(of)X -2418 2952(writing)N -2677(the)X -2803(actual)X -3023(\256le)X -3153(to)X -3243(disk.)X -3444(For)X -3583(the)X -3709(large)X -3897(database)X -2418 3040(\(the)N -2564(dictionary\),)X -2957(this)X -3093(completely)X -3470(overwhelmed)X -3927(the)X -4045(sys-)X -2418 3128(tem)N -2570(time.)X -2783(However,)X -3129(for)X -3254(the)X -3383(small)X -3587(data)X -3752(base,)X -3946(we)X -4071(see)X -2418 3216(that)N -2569(differences)X -2958(in)X -3051(both)X -3224(user)X -3389(and)X -3536(system)X -3788(time)X -3960(contri-)X -2418 3304(bute)N -2576(to)X -2658(the)X -2776(superior)X -3059(performance)X -3486(of)X -3573(the)X -3691(new)X -3845(package.)X -2590 3418(The)N -3 f -2764(read)X -1 f -2920(,)X -3 f -2989(verify)X -1 f -3190(,)X -3259(and)X -3 f -3424(sequential)X -1 f -3818(results)X -4075(are)X -2418 3506(deceptive)N -2758(for)X -2883(the)X -3012(small)X -3216(database)X -3524(since)X -3720(the)X -3849(entire)X -4063(test)X -2418 3594(ran)N -2551(in)X -2643(under)X -2856(a)X -2922(second.)X -3215(However,)X -3560(on)X -3669(the)X -3796(larger)X -4013(data-)X -2418 3682(base)N -2590(the)X -3 f -2716(read)X -1 f -2900(and)X -3 f -3044(verify)X -1 f -3273(tests)X -3443(bene\256t)X -3689(from)X -3873(the)X -3999(cach-)X -2418 3770(ing)N -2546(of)X -2639(buckets)X -2910(in)X -2998(the)X -3122(new)X -3282(package)X -3571(to)X -3658(improve)X -3950(perfor-)X -2418 3858(mance)N -2666(by)X -2784(over)X -2965(80%.)X -3169(Since)X -3384(the)X -3519(\256rst)X -3 f -3680(sequential)X -1 f -4063(test)X -2418 3946(does)N -2598(not)X -2733(require)X -2 f -2994(ndbm)X -1 f -3205(to)X -3299(return)X -3523(the)X -3653(data)X -3819(values,)X -4076(the)X -2418 4034(user)N -2573(time)X -2735(is)X -2808(lower)X -3011(than)X -3169(for)X -3283(the)X -3401(new)X -3555(package.)X -3879(However)X -2418 4122(when)N -2613(we)X -2728(require)X -2977(both)X -3139(packages)X -3454(to)X -3536(return)X -3748(data,)X -3922(the)X -4040(new)X -2418 4210(package)N -2702(excels)X -2923(in)X -3005(all)X -3105(three)X -3286(timings.)X -2590 4324(The)N -2773(small)X -3003(database)X -3337(runs)X -3532(so)X -3660(quickly)X -3957(in)X -4076(the)X -2418 4412(memory-resident)N -3000(case)X -3173(that)X -3326(the)X -3457(results)X -3699(are)X -3831(uninterest-)X -2418 4500(ing.)N -2589(However,)X -2933(for)X -3056(the)X -3183(larger)X -3400(database)X -3706(the)X -3833(new)X -3995(pack-)X -2418 4588(age)N -2567(pays)X -2751(a)X -2824(small)X -3033(penalty)X -3305(in)X -3403(system)X -3661(time)X -3839(because)X -4130(it)X -2418 4676(limits)N -2636(its)X -2748(main)X -2944(memory)X -3247(utilization)X -3607(and)X -3759(swaps)X -3991(pages)X -2418 4764(out)N -2550(to)X -2642(temporary)X -3002(storage)X -3264(in)X -3356(the)X -3484(\256le)X -3616(system)X -3868(while)X -4076(the)X -2 f -2418 4852(hsearch)N -1 f -2698(package)X -2988(requires)X -3273(that)X -3419(the)X -3543(application)X -3924(allocate)X -2418 4940(enough)N -2692(space)X -2909(for)X -3041(all)X -3159(key/data)X -3468(pair.)X -3670(However,)X -4022(even)X -2418 5028(with)N -2600(the)X -2738(system)X -3000(time)X -3182(penalty,)X -3477(the)X -3614(resulting)X -3933(elapsed)X -2418 5116(time)N -2580(improves)X -2898(by)X -2998(over)X -3161(50%.)X -3 f -432 5960(10)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -11 p -%%Page: 11 11 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -1 f -10 f -908 454(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2 f -1379 546(hash)N -1652(ndbm)X -1950(%change)X -1 f -10 f -908 550(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -948 642(CREATE)N -10 f -908 646(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1125 738(user)N -1424(6.4)X -1671(12.2)X -2073(48)X -1157 826(sys)N -1384(32.5)X -1671(34.7)X -2113(6)X -3 f -1006 914(elapsed)N -10 f -1310 922(c)N -890(c)Y -810(c)Y -730(c)Y -3 f -1384 914(90.4)N -10 f -1581 922(c)N -890(c)Y -810(c)Y -730(c)Y -3 f -1671 914(99.6)N -10 f -1883 922(c)N -890(c)Y -810(c)Y -730(c)Y -3 f -2113 914(9)N -1 f -10 f -908 910(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -908 926(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -948 1010(READ)N -10 f -908 1014(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1125 1106(user)N -1424(3.4)X -1711(6.1)X -2073(44)X -1157 1194(sys)N -1424(1.2)X -1671(15.3)X -2073(92)X -3 f -1006 1282(elapsed)N -10 f -1310 1290(c)N -1258(c)Y -1178(c)Y -1098(c)Y -3 f -1424 1282(4.0)N -10 f -1581 1290(c)N -1258(c)Y -1178(c)Y -1098(c)Y -3 f -1671 1282(21.2)N -10 f -1883 1290(c)N -1258(c)Y -1178(c)Y -1098(c)Y -3 f -2073 1282(81)N -1 f -10 f -908 1278(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -908 1294(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -948 1378(VERIFY)N -10 f -908 1382(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1125 1474(user)N -1424(3.5)X -1711(6.3)X -2073(44)X -1157 1562(sys)N -1424(1.2)X -1671(15.3)X -2073(92)X -3 f -1006 1650(elapsed)N -10 f -1310 1658(c)N -1626(c)Y -1546(c)Y -1466(c)Y -3 f -1424 1650(4.0)N -10 f -1581 1658(c)N -1626(c)Y -1546(c)Y -1466(c)Y -3 f -1671 1650(21.2)N -10 f -1883 1658(c)N -1626(c)Y -1546(c)Y -1466(c)Y -3 f -2073 1650(81)N -1 f -10 f -908 1646(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -908 1662(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -948 1746(SEQUENTIAL)N -10 f -908 1750(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1125 1842(user)N -1424(2.7)X -1711(1.9)X -2046(-42)X -1157 1930(sys)N -1424(0.7)X -1711(3.9)X -2073(82)X -3 f -1006 2018(elapsed)N -10 f -1310 2026(c)N -1994(c)Y -1914(c)Y -1834(c)Y -3 f -1424 2018(3.0)N -10 f -1581 2026(c)N -1994(c)Y -1914(c)Y -1834(c)Y -3 f -1711 2018(5.0)N -10 f -1883 2026(c)N -1994(c)Y -1914(c)Y -1834(c)Y -3 f -2073 2018(40)N -1 f -10 f -908 2014(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -908 2030(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -948 2114(SEQUENTIAL)N -1467(\(with)X -1656(data)X -1810(retrieval\))X -10 f -908 2118(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1125 2210(user)N -1424(2.7)X -1711(8.2)X -2073(67)X -1157 2298(sys)N -1424(0.7)X -1711(4.3)X -2073(84)X -3 f -1006 2386(elapsed)N -1424(3.0)X -1671(12.0)X -2073(75)X -1 f -10 f -908 2390(i)N -927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -899 2394(c)N -2378(c)Y -2298(c)Y -2218(c)Y -2138(c)Y -2058(c)Y -1978(c)Y -1898(c)Y -1818(c)Y -1738(c)Y -1658(c)Y -1578(c)Y -1498(c)Y -1418(c)Y -1338(c)Y -1258(c)Y -1178(c)Y -1098(c)Y -1018(c)Y -938(c)Y -858(c)Y -778(c)Y -698(c)Y -618(c)Y -538(c)Y -1310 2394(c)N -2362(c)Y -2282(c)Y -2202(c)Y -1581 2394(c)N -2362(c)Y -2282(c)Y -2202(c)Y -1883 2394(c)N -2362(c)Y -2282(c)Y -2202(c)Y -2278 2394(c)N -2378(c)Y -2298(c)Y -2218(c)Y -2138(c)Y -2058(c)Y -1978(c)Y -1898(c)Y -1818(c)Y -1738(c)Y -1658(c)Y -1578(c)Y -1498(c)Y -1418(c)Y -1338(c)Y -1258(c)Y -1178(c)Y -1098(c)Y -1018(c)Y -938(c)Y -858(c)Y -778(c)Y -698(c)Y -618(c)Y -538(c)Y -905 2574(i)N -930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2 f -1318 2666(hash)N -1585(hsearch)X -1953(%change)X -1 f -10 f -905 2670(i)N -930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -945 2762(CREATE/READ)N -10 f -905 2766(i)N -930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -1064 2858(user)N -1343(6.6)X -1642(17.2)X -2096(62)X -1096 2946(sys)N -1343(1.1)X -1682(0.3)X -2029(-266)X -3 f -945 3034(elapsed)N -1343(7.8)X -1642(17.0)X -2096(54)X -1 f -10 f -905 3038(i)N -930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -896 3050(c)N -2978(c)Y -2898(c)Y -2818(c)Y -2738(c)Y -2658(c)Y -1249 3034(c)N -3010(c)Y -2930(c)Y -2850(c)Y -1520 3034(c)N -3010(c)Y -2930(c)Y -2850(c)Y -1886 3034(c)N -3010(c)Y -2930(c)Y -2850(c)Y -2281 3050(c)N -2978(c)Y -2898(c)Y -2818(c)Y -2738(c)Y -2658(c)Y -3 f -720 3174(Figure)N -967(8a:)X -1 f -1094(Timing)X -1349(results)X -1578(for)X -1692(the)X -1810(dictionary)X -2155(database.)X -10 f -720 3262 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -1407 3504(Conclusion)N -1 f -892 3636(This)N -1063(paper)X -1271(has)X -1407(presented)X -1744(the)X -1871(design,)X -2129(implemen-)X -720 3724(tation)N -928(and)X -1070(performance)X -1503(of)X -1596(a)X -1658(new)X -1818(hashing)X -2093(package)X -2382(for)X -720 3812(UNIX.)N -993(The)X -1150(new)X -1316(package)X -1612(provides)X -1919(a)X -1986(superset)X -2280(of)X -2378(the)X -720 3900(functionality)N -1159(of)X -1255(existing)X -1537(hashing)X -1815(packages)X -2139(and)X -2284(incor-)X -720 3988(porates)N -975(additional)X -1318(features)X -1596(such)X -1766(as)X -1855(large)X -2038(key)X -2176(handling,)X -720 4076(user)N -876(de\256ned)X -1134(hash)X -1302(functions,)X -1641(multiple)X -1928(hash)X -2096(tables,)X -2324(vari-)X -720 4164(able)N -894(sized)X -1099(pages,)X -1342(and)X -1498(linear)X -1721(hashing.)X -2050(In)X -2156(nearly)X -2396(all)X -720 4252(cases,)N -954(the)X -1096(new)X -1274(package)X -1582(provides)X -1902(improved)X -2252(perfor-)X -720 4340(mance)N -974(on)X -1098(the)X -1240(order)X -1454(of)X -1565(50-80%)X -1863(for)X -2001(the)X -2142(workloads)X -720 4428(shown.)N -990(Applications)X -1420(such)X -1588(as)X -1676(the)X -1794(loader,)X -2035(compiler,)X -2360(and)X -720 4516(mail,)N -921(which)X -1156(currently)X -1485(implement)X -1866(their)X -2051(own)X -2227(hashing)X -720 4604(routines,)N -1032(should)X -1279(be)X -1389(modi\256ed)X -1706(to)X -1801(use)X -1941(the)X -2072(generic)X -2342(rou-)X -720 4692(tines.)N -892 4806(This)N -1087(hashing)X -1389(package)X -1705(is)X -1810(one)X -1978(access)X -2236(method)X -720 4894(which)N -953(is)X -1043(part)X -1205(of)X -1309(a)X -1382(generic)X -1656(database)X -1970(access)X -2212(package)X -720 4982(being)N -955(developed)X -1342(at)X -1457(the)X -1612(University)X -2007(of)X -2131(California,)X -720 5070(Berkeley.)N -1089(It)X -1177(will)X -1340(include)X -1614(a)X -1688(btree)X -1887(access)X -2131(method)X -2409(as)X -720 5158(well)N -916(as)X -1041(\256xed)X -1259(and)X -1433(variable)X -1750(length)X -2007(record)X -2270(access)X -720 5246(methods)N -1024(in)X -1119(addition)X -1414(to)X -1509(the)X -1640(hashed)X -1896(support)X -2168(presented)X -720 5334(here.)N -948(All)X -1099(of)X -1215(the)X -1361(access)X -1615(methods)X -1934(are)X -2081(based)X -2312(on)X -2440(a)X -720 5422(key/data)N -1037(pair)X -1207(interface)X -1533(and)X -1693(appear)X -1952(identical)X -2272(to)X -2378(the)X -720 5510(application)N -1121(layer,)X -1347(allowing)X -1671(application)X -2071(implementa-)X -720 5598(tions)N -906(to)X -999(be)X -1106(largely)X -1360(independent)X -1783(of)X -1881(the)X -2010(database)X -2318(type.)X -720 5686(The)N -873(package)X -1165(is)X -1246(expected)X -1560(to)X -1650(be)X -1754(an)X -1858(integral)X -2131(part)X -2284(of)X -2378(the)X -2706 538(4.4BSD)N -3006(system,)X -3293(with)X -3479(various)X -3759(standard)X -4075(applications)X -2706 626(such)N -2879(as)X -2972(more\(1\),)X -3277(sort\(1\))X -3517(and)X -3659(vi\(1\))X -3841(based)X -4050(on)X -4156(it.)X -4266(While)X -2706 714(the)N -2833(current)X -3089(design)X -3326(does)X -3501(not)X -3631(support)X -3899(multi-user)X -4256(access)X -2706 802(or)N -2804(transactions,)X -3238(they)X -3407(could)X -3616(be)X -3723(incorporated)X -4159(relatively)X -2706 890(easily.)N -10 f -2894 938(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2 f -3365 1030(hash)N -3638(ndbm)X -3936(%change)X -1 f -10 f -2894 1034(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2934 1126(CREATE)N -10 f -2894 1130(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3111 1222(user)N -3390(0.2)X -3677(0.4)X -4079(50)X -3143 1310(sys)N -3390(0.1)X -3677(1.0)X -4079(90)X -3 f -2992 1398(elapsed)N -10 f -3296 1406(c)N -1374(c)Y -1294(c)Y -1214(c)Y -3 f -3390 1398(0)N -10 f -3567 1406(c)N -1374(c)Y -1294(c)Y -1214(c)Y -3 f -3677 1398(3.2)N -10 f -3869 1406(c)N -1374(c)Y -1294(c)Y -1214(c)Y -3 f -4039 1398(100)N -1 f -10 f -2894 1394(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2894 1410(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2934 1494(READ)N -10 f -2894 1498(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3111 1590(user)N -3390(0.1)X -3677(0.1)X -4119(0)X -3143 1678(sys)N -3390(0.1)X -3677(0.4)X -4079(75)X -3 f -2992 1766(elapsed)N -10 f -3296 1774(c)N -1742(c)Y -1662(c)Y -1582(c)Y -3 f -3390 1766(0.0)N -10 f -3567 1774(c)N -1742(c)Y -1662(c)Y -1582(c)Y -3 f -3677 1766(0.0)N -10 f -3869 1774(c)N -1742(c)Y -1662(c)Y -1582(c)Y -3 f -4119 1766(0)N -1 f -10 f -2894 1762(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2894 1778(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2934 1862(VERIFY)N -10 f -2894 1866(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3111 1958(user)N -3390(0.1)X -3677(0.2)X -4079(50)X -3143 2046(sys)N -3390(0.1)X -3677(0.3)X -4079(67)X -3 f -2992 2134(elapsed)N -10 f -3296 2142(c)N -2110(c)Y -2030(c)Y -1950(c)Y -3 f -3390 2134(0.0)N -10 f -3567 2142(c)N -2110(c)Y -2030(c)Y -1950(c)Y -3 f -3677 2134(0.0)N -10 f -3869 2142(c)N -2110(c)Y -2030(c)Y -1950(c)Y -3 f -4119 2134(0)N -1 f -10 f -2894 2130(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2894 2146(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2934 2230(SEQUENTIAL)N -10 f -2894 2234(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3111 2326(user)N -3390(0.1)X -3677(0.0)X -4012(-100)X -3143 2414(sys)N -3390(0.1)X -3677(0.1)X -4119(0)X -3 f -2992 2502(elapsed)N -10 f -3296 2510(c)N -2478(c)Y -2398(c)Y -2318(c)Y -3 f -3390 2502(0.0)N -10 f -3567 2510(c)N -2478(c)Y -2398(c)Y -2318(c)Y -3 f -3677 2502(0.0)N -10 f -3869 2510(c)N -2478(c)Y -2398(c)Y -2318(c)Y -3 f -4119 2502(0)N -1 f -10 f -2894 2498(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2894 2514(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2934 2598(SEQUENTIAL)N -3453(\(with)X -3642(data)X -3796(retrieval\))X -10 f -2894 2602(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3111 2694(user)N -3390(0.1)X -3677(0.1)X -4119(0)X -3143 2782(sys)N -3390(0.1)X -3677(0.1)X -4119(0)X -3 f -2992 2870(elapsed)N -3390(0.0)X -3677(0.0)X -4119(0)X -1 f -10 f -2894 2874(i)N -2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2885 2878(c)N -2862(c)Y -2782(c)Y -2702(c)Y -2622(c)Y -2542(c)Y -2462(c)Y -2382(c)Y -2302(c)Y -2222(c)Y -2142(c)Y -2062(c)Y -1982(c)Y -1902(c)Y -1822(c)Y -1742(c)Y -1662(c)Y -1582(c)Y -1502(c)Y -1422(c)Y -1342(c)Y -1262(c)Y -1182(c)Y -1102(c)Y -1022(c)Y -3296 2878(c)N -2846(c)Y -2766(c)Y -2686(c)Y -3567 2878(c)N -2846(c)Y -2766(c)Y -2686(c)Y -3869 2878(c)N -2846(c)Y -2766(c)Y -2686(c)Y -4264 2878(c)N -2862(c)Y -2782(c)Y -2702(c)Y -2622(c)Y -2542(c)Y -2462(c)Y -2382(c)Y -2302(c)Y -2222(c)Y -2142(c)Y -2062(c)Y -1982(c)Y -1902(c)Y -1822(c)Y -1742(c)Y -1662(c)Y -1582(c)Y -1502(c)Y -1422(c)Y -1342(c)Y -1262(c)Y -1182(c)Y -1102(c)Y -1022(c)Y -2891 3058(i)N -2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2 f -3304 3150(hash)N -3571(hsearch)X -3939(%change)X -1 f -10 f -2891 3154(i)N -2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -2931 3246(CREATE/READ)N -10 f -2891 3250(i)N -2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -1 f -3050 3342(user)N -3329(0.3)X -3648(0.4)X -4048(25)X -3082 3430(sys)N -3329(0.0)X -3648(0.0)X -4088(0)X -3 f -2931 3518(elapsed)N -3329(0.0)X -3648(0.0)X -4088(0)X -1 f -10 f -2891 3522(i)N -2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X -2882 3534(c)N -3462(c)Y -3382(c)Y -3302(c)Y -3222(c)Y -3142(c)Y -3235 3518(c)N -3494(c)Y -3414(c)Y -3334(c)Y -3506 3518(c)N -3494(c)Y -3414(c)Y -3334(c)Y -3872 3518(c)N -3494(c)Y -3414(c)Y -3334(c)Y -4267 3534(c)N -3462(c)Y -3382(c)Y -3302(c)Y -3222(c)Y -3142(c)Y -3 f -2706 3658(Figure)N -2953(8b:)X -1 f -3084(Timing)X -3339(results)X -3568(for)X -3682(the)X -3800(password)X -4123(database.)X -10 f -2706 3746 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN -3 f -3396 3988(References)N -1 f -2706 4120([ATT79])N -3058(AT&T,)X -3358(DBM\(3X\),)X -2 f -3773(Unix)X -3990(Programmer's)X -2878 4208(Manual,)N -3194(Seventh)X -3491(Edition,)X -3793(Volume)X -4085(1)X -1 f -(,)S -4192(January,)X -2878 4296(1979.)N -2706 4472([ATT85])N -3027(AT&T,)X -3296(HSEARCH\(BA_LIB\),)X -2 f -4053(Unix)X -4239(System)X -2878 4560(User's)N -3112(Manual,)X -3401(System)X -3644(V.3)X -1 f -3753(,)X -3793(pp.)X -3913(506-508,)X -4220(1985.)X -2706 4736([BRE73])N -3025(Brent,)X -3253(Richard)X -3537(P.,)X -3651(``Reducing)X -4041(the)X -4168(Retrieval)X -2878 4824(Time)N -3071(of)X -3162(Scatter)X -3409(Storage)X -3678(Techniques'',)X -2 f -4146(Commun-)X -2878 4912(ications)N -3175(of)X -3281(the)X -3422(ACM)X -1 f -3591(,)X -3654(Volume)X -3955(16,)X -4098(No.)X -4259(2,)X -4362(pp.)X -2878 5000(105-109,)N -3185(February,)X -3515(1973.)X -2706 5176([BSD86])N -3055(NDBM\(3\),)X -2 f -3469(4.3BSD)X -3775(Unix)X -3990(Programmer's)X -2878 5264(Manual)N -3155(Reference)X -3505(Guide)X -1 f -3701(,)X -3749(University)X -4114(of)X -4208(Califor-)X -2878 5352(nia,)N -3016(Berkeley,)X -3346(1986.)X -2706 5528([ENB88])N -3025(Enbody,)X -3319(R.)X -3417(J.,)X -3533(Du,)X -3676(H.)X -3779(C.,)X -3897(``Dynamic)X -4270(Hash-)X -2878 5616(ing)N -3034(Schemes'',)X -2 f -3427(ACM)X -3630(Computing)X -4019(Surveys)X -1 f -4269(,)X -4322(Vol.)X -2878 5704(20,)N -2998(No.)X -3136(2,)X -3216(pp.)X -3336(85-113,)X -3603(June)X -3770(1988.)X -3 f -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4384(11)X - -12 p -%%Page: 12 12 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 258(A)N -510(New)X -682(Hashing)X -985(Package)X -1290(for)X -1413(UNIX)X -3663(Seltzer)X -3920(&)X -4007(Yigit)X -1 f -432 538([FAG79])N -776(Ronald)X -1057(Fagin,)X -1308(Jurg)X -1495(Nievergelt,)X -1903(Nicholas)X -604 626(Pippenger,)N -1003(H.)X -1135(Raymond)X -1500(Strong,)X -1787(``Extendible)X -604 714(Hashing)N -901(--)X -985(A)X -1073(Fast)X -1236(Access)X -1493(Method)X -1771(for)X -1894(Dynamic)X -604 802(Files'',)N -2 f -855(ACM)X -1046(Transactions)X -1485(on)X -1586(Database)X -1914(Systems)X -1 f -2168(,)X -604 890(Volume)N -882(4,)X -962(No.)X -1100(3.,)X -1200(September)X -1563(1979,)X -1763(pp)X -1863(315-34)X -432 1066([KNU68],)N -802(Knuth,)X -1064(D.E.,)X -2 f -1273(The)X -1434(Art)X -1577(of)X -1680(Computer)X -2041(Pro-)X -604 1154(gramming)N -971(Vol.)X -1140(3:)X -1245(Sorting)X -1518(and)X -1676(Searching)X -1 f -2001(,)X -2058(sec-)X -604 1242(tions)N -779(6.3-6.4,)X -1046(pp)X -1146(481-550.)X -432 1418([LAR78])N -747(Larson,)X -1011(Per-Ake,)X -1319(``Dynamic)X -1687(Hashing'',)X -2 f -2048(BIT)X -1 f -(,)S -604 1506(Vol.)N -764(18,)X -884(1978,)X -1084(pp.)X -1204(184-201.)X -432 1682([LAR88])N -752(Larson,)X -1021(Per-Ake,)X -1335(``Dynamic)X -1709(Hash)X -1900(Tables'',)X -2 f -604 1770(Communications)N -1183(of)X -1281(the)X -1415(ACM)X -1 f -1584(,)X -1640(Volume)X -1934(31,)X -2070(No.)X -604 1858(4.,)N -704(April)X -893(1988,)X -1093(pp)X -1193(446-457.)X -432 2034([LIT80])N -731(Witold,)X -1013(Litwin,)X -1286(``Linear)X -1590(Hashing:)X -1939(A)X -2036(New)X -604 2122(Tool)N -786(for)X -911(File)X -1065(and)X -1211(Table)X -1424(Addressing'',)X -2 f -1893(Proceed-)X -604 2210(ings)N -761(of)X -847(the)X -969(6th)X -1095(International)X -1540(Conference)X -1933(on)X -2036(Very)X -604 2298(Large)N -815(Databases)X -1 f -1153(,)X -1193(1980.)X -432 2474([NEL90])N -743(Nelson,)X -1011(Philip)X -1222(A.,)X -2 f -1341(Gdbm)X -1558(1.4)X -1679(source)X -1913(distribu-)X -604 2562(tion)N -748(and)X -888(README)X -1 f -1209(,)X -1249(August)X -1500(1990.)X -432 2738([THOM90])N -840(Ken)X -1011(Thompson,)X -1410(private)X -1670(communication,)X -604 2826(Nov.)N -782(1990.)X -432 3002([TOR87])N -790(Torek,)X -1066(C.,)X -1222(``Re:)X -1470(dbm.a)X -1751(and)X -1950(ndbm.a)X -604 3090(archives'',)N -2 f -966(USENET)X -1279(newsgroup)X -1650(comp.unix)X -1 f -2002(1987.)X -432 3266([TOR88])N -760(Torek,)X -1006(C.,)X -1133(``Re:)X -1351(questions)X -1686(regarding)X -2027(data-)X -604 3354(bases)N -826(created)X -1106(with)X -1295(dbm)X -1484(and)X -1647(ndbm)X -1876(routines'')X -2 f -604 3442(USENET)N -937(newsgroup)X -1328(comp.unix.questions)X -1 f -1982(,)X -2041(June)X -604 3530(1988.)N -432 3706([WAL84])N -773(Wales,)X -1018(R.,)X -1135(``Discussion)X -1564(of)X -1655("dbm")X -1887(data)X -2045(base)X -604 3794(system'',)N -2 f -973(USENET)X -1339(newsgroup)X -1762(unix.wizards)X -1 f -2168(,)X -604 3882(January,)N -894(1984.)X -432 4058([YIG89])N -751(Ozan)X -963(S.)X -1069(Yigit,)X -1294(``How)X -1545(to)X -1648(Roll)X -1826(Your)X -2032(Own)X -604 4146(Dbm/Ndbm'',)N -2 f -1087(unpublished)X -1504(manuscript)X -1 f -(,)S -1910(Toronto,)X -604 4234(July,)N -777(1989)X -3 f -432 5960(12)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -13 p -%%Page: 13 13 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -720 258(Seltzer)N -977(&)X -1064(Yigit)X -3278(A)X -3356(New)X -3528(Hashing)X -3831(Package)X -4136(for)X -4259(UNIX)X -1 f -720 538(Margo)N -960(I.)X -1033(Seltzer)X -1282(is)X -1361(a)X -1423(Ph.D.)X -1631(student)X -1887(in)X -1974(the)X -2097(Department)X -720 626(of)N -823(Electrical)X -1167(Engineering)X -1595(and)X -1747(Computer)X -2102(Sciences)X -2418(at)X -720 714(the)N -850(University)X -1220(of)X -1318(California,)X -1694(Berkeley.)X -2055(Her)X -2207(research)X -720 802(interests)N -1017(include)X -1283(\256le)X -1415(systems,)X -1718(databases,)X -2076(and)X -2221(transac-)X -720 890(tion)N -896(processing)X -1291(systems.)X -1636(She)X -1807(spent)X -2027(several)X -2306(years)X -720 978(working)N -1026(at)X -1123(startup)X -1380(companies)X -1762(designing)X -2112(and)X -2267(imple-)X -720 1066(menting)N -1048(\256le)X -1216(systems)X -1535(and)X -1716(transaction)X -2133(processing)X -720 1154(software)N -1026(and)X -1170(designing)X -1509(microprocessors.)X -2103(Ms.)X -2253(Seltzer)X -720 1242(received)N -1057(her)X -1223(AB)X -1397(in)X -1522(Applied)X -1843(Mathematics)X -2320(from)X -720 1330 0.1953(Harvard/Radcliffe)AN -1325(College)X -1594(in)X -1676(1983.)X -720 1444(In)N -810(her)X -936(spare)X -1129(time,)X -1313(Margo)X -1549(can)X -1683(usually)X -1936(be)X -2034(found)X -2243(prepar-)X -720 1532(ing)N -868(massive)X -1171(quantities)X -1527(of)X -1639(food)X -1831(for)X -1970(hungry)X -2242(hoards,)X -720 1620(studying)N -1022(Japanese,)X -1355(or)X -1449(playing)X -1716(soccer)X -1948(with)X -2116(an)X -2218(exciting)X -720 1708(Bay)N -912(Area)X -1132(Women's)X -1507(Soccer)X -1788(team,)X -2026(the)X -2186(Berkeley)X -720 1796(Bruisers.)N -720 1910(Ozan)N -915(\()X -3 f -942(Oz)X -1 f -1040(\))X -1092(Yigit)X -1281(is)X -1358(currently)X -1672(a)X -1732(software)X -2033(engineer)X -2334(with)X -720 1998(the)N -886(Communications)X -1499(Research)X -1861(and)X -2044(Development)X -720 2086(group,)N -948(Computing)X -1328(Services,)X -1641(York)X -1826(University.)X -2224(His)X -2355(for-)X -720 2174(mative)N -967(years)X -1166(were)X -1352(also)X -1510(spent)X -1708(at)X -1795(York,)X -2009(where)X -2234(he)X -2338(held)X -720 2262(system)N -985(programmer)X -1425(and)X -1583(administrator)X -2052(positions)X -2382(for)X -720 2350(various)N -995(mixtures)X -1314(of)X -1420(of)X -1526(UNIX)X -1765(systems)X -2056(starting)X -2334(with)X -720 2438(Berkeley)N -1031(4.1)X -1151(in)X -1233(1982,)X -1433(while)X -1631(at)X -1709(the)X -1827(same)X -2012(time)X -2174(obtaining)X -720 2526(a)N -776(degree)X -1011(in)X -1093(Computer)X -1433(Science.)X -720 2640(In)N -813(his)X -931(copious)X -1205(free)X -1356(time,)X -1543(Oz)X -1662(enjoys)X -1896(working)X -2188(on)X -2293(what-)X -720 2728(ever)N -890(software)X -1197(looks)X -1400(interesting,)X -1788(which)X -2014(often)X -2209(includes)X -720 2816(language)N -1044(interpreters,)X -1464(preprocessors,)X -1960(and)X -2110(lately,)X -2342(pro-)X -720 2904(gram)N -905(generators)X -1260(and)X -1396(expert)X -1617(systems.)X -720 3018(Oz)N -836(has)X -964(authored)X -1266(several)X -1515(public-domain)X -2003(software)X -2301(tools,)X -720 3106(including)N -1069(an)X -1191(nroff-like)X -1545(text)X -1711(formatter)X -2 f -2056(proff)X -1 f -2257(that)X -2423(is)X -720 3194(apparently)N -1083(still)X -1226(used)X -1397(in)X -1483(some)X -1676(basement)X -2002(PCs.)X -2173(His)X -2307(latest)X -720 3282(obsessions)N -1143(include)X -1460(the)X -1639(incredible)X -2040(programming)X -720 3370(language)N -1030(Scheme,)X -1324(and)X -1460(Chinese)X -1738(Brush)X -1949(painting.)X -3 f -720 5960(USENIX)N -9 f -1042(-)X -3 f -1106(Winter)X -1371('91)X -9 f -1498(-)X -3 f -1562(Dallas,)X -1815(TX)X -4384(13)X - -14 p -%%Page: 14 14 -0(Courier)xf 0 f -10 s 10 xH 0 xS 0 f -3 f -432 5960(14)N -2970(USENIX)X -9 f -3292(-)X -3 f -3356(Winter)X -3621('91)X -9 f -3748(-)X -3 f -3812(Dallas,)X -4065(TX)X - -14 p -%%Trailer -xt - -xs diff --git a/lib/libc/db/doc/mpool.3.ps b/lib/libc/db/doc/mpool.3.ps deleted file mode 100644 index f595480d6be6..000000000000 --- a/lib/libc/db/doc/mpool.3.ps +++ /dev/null @@ -1,318 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.08 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Bold -%%+ font Times-Italic -%%DocumentSuppliedResources: procset grops 1.08 0 -%%Pages: 2 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.08 0 -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}bind def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/FL{ -currentgray exch setgray fill setgray -}bind def -/BL/fill load def -/LW/setlinewidth load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -}bind def -/PEND{ -clear -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE -/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 174.84(MPOOL\(3\) 1991 MPOOL\(3\))72 48 R/F1 9 -/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0(mpool \255 shared memory b)108 96 -Q(uf)-.2 E(fer pool)-.25 E F1(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF -(#include <db)108 124.8 Q(.h>)-.4 E(#include <mpool.h>)108 136.8 Q(MPOOL *)108 -160.8 Q(mpool_open \(DBT *k)108 172.8 Q(ey)-.1 E 2.5(,i)-.55 G -(nt fd, pgno_t pagesize, pgno_t maxcache\);)216.25 172.8 Q -.1(vo)108 196.8 S -(id).1 E(mpool_\214lter \(MPOOL *mp, v)108 208.8 Q(oid \(*pgin\)\(v)-.1 E -(oid *, pgno_t, v)-.1 E(oid *\),)-.1 E -.1(vo)158 220.8 S(id \(*pgout\)\(v).1 E -(oid *, pgno_t, v)-.1 E(oid *\), v)-.1 E(oid *pgcookie\);)-.1 E -.1(vo)108 -244.8 S(id *).1 E(mpool_new \(MPOOL *mp, pgno_t *pgnoaddr\);)108 256.8 Q -.1 -(vo)108 280.8 S(id *).1 E(mpool_get \(MPOOL *mp, pgno_t pgno, u_int \215ags\);) -108 292.8 Q(int)108 316.8 Q(mpool_put \(MPOOL *mp, v)108 328.8 Q(oid *pgaddr) --.1 E 2.5(,u)-.92 G(_int \215ags\);)290.62 328.8 Q(int)108 352.8 Q -(mpool_sync \(MPOOL *mp\);)108 364.8 Q(int)108 388.8 Q -(mpool_close \(MPOOL *mp\);)108 400.8 Q F1(DESCRIPTION)72 417.6 Q/F3 10 -/Times-Italic@0 SF(Mpool)108 429.6 Q F0 1.013(is the library interf)3.513 F -1.013(ace intended to pro)-.1 F 1.013(vide page oriented b)-.15 F(uf)-.2 E -1.012(fer management of \214les.)-.25 F 1.012(The b)6.012 F(uf)-.2 E(fers)-.25 -E(may be shared between processes.)108 441.6 Q .416(The function)108 458.4 R F3 -(mpool_open)2.916 E F0 .417(initializes a memory pool.)2.917 F(The)5.417 E F3 --.1(ke)2.917 G(y)-.2 E F0(ar)2.917 E .417(gument is the byte string used to ne) --.18 F(gotiate)-.15 E .697(between multiple processes wishing to share b)108 -470.4 R(uf)-.2 E 3.196(fers. If)-.25 F .696(the \214le b)3.196 F(uf)-.2 E .696 -(fers are mapped in shared memory)-.25 F 3.196(,a)-.65 G(ll)534.44 470.4 Q .894 -(processes using the same k)108 482.4 R 1.194 -.15(ey w)-.1 H .894 -(ill share the b).15 F(uf)-.2 E 3.394(fers. If)-.25 F F3 -.1(ke)3.394 G(y)-.2 E -F0 .895(is NULL, the b)3.395 F(uf)-.2 E .895(fers are mapped into pri)-.25 F --.25(va)-.25 G(te).25 E(memory)108 494.4 Q 5.116(.T)-.65 G(he)154.406 494.4 Q -F3(fd)2.616 E F0(ar)2.616 E .115(gument is a \214le descriptor for the underly\ -ing \214le, which must be seekable.)-.18 F(If)5.115 E F3 -.1(ke)2.615 G(y)-.2 E -F0 .115(is non-)2.615 F(NULL and matches a \214le already being mapped, the)108 -506.4 Q F3(fd)2.5 E F0(ar)2.5 E(gument is ignored.)-.18 E(The)108 523.2 Q F3 -(pa)3.328 E -.1(ge)-.1 G(size).1 E F0(ar)3.329 E .829 -(gument is the size, in bytes, of the pages into which the \214le is brok)-.18 -F .829(en up.)-.1 F(The)5.829 E F3(maxcac)3.329 E(he)-.15 E F0(ar)108 535.2 Q -.153(gument is the maximum number of pages from the underlying \214le to cache\ - at an)-.18 F 2.653(yo)-.15 G .153(ne time.)451.308 535.2 R .153(This v)5.153 F -.153(alue is)-.25 F .099(not relati)108 547.2 R .399 -.15(ve t)-.25 H 2.599(ot) -.15 G .099(he number of processes which share a \214le')168.727 547.2 R 2.6(sb) --.55 G(uf)350.39 547.2 Q .1(fers, b)-.25 F .1(ut will be the lar)-.2 F .1 -(gest v)-.18 F .1(alue speci\214ed by)-.25 F(an)108 559.2 Q 2.5(yo)-.15 G 2.5 -(ft)129.79 559.2 S(he processes sharing the \214le.)138.4 559.2 Q(The)108 576 Q -F3(mpool_\214lter)3.254 E F0 .754(function is intended to mak)3.254 F 3.254(et) --.1 G .754(ransparent input and output processing of the pages possi-)301.778 -576 R 3.095(ble. If)108 588 R(the)3.095 E F3(pgin)3.095 E F0 .596 -(function is speci\214ed, it is called each time a b)3.095 F(uf)-.2 E .596 -(fer is read into the memory pool from the)-.25 F .125(backing \214le.)108 600 -R .125(If the)5.125 F F3(pgout)2.625 E F0 .125 -(function is speci\214ed, it is called each time a b)2.625 F(uf)-.2 E .125 -(fer is written into the backing \214le.)-.25 F .276 -(Both functions are are called with the)108 612 R F3(pgcookie)2.777 E F0 -(pointer)2.777 E 2.777(,t)-.4 G .277 -(he page number and a pointer to the page to being)337.27 612 R -(read or written.)108 624 Q .124(The function)108 640.8 R F3(mpool_ne)2.624 E -(w)-.15 E F0(tak)2.624 E .123(es an MPOOL pointer and an address as ar)-.1 F -2.623(guments. If)-.18 F 2.623(an)2.623 G .623 -.25(ew p)457.568 640.8 T .123 -(age can be allo-).25 F .944(cated, a pointer to the page is returned and the \ -page number is stored into the)108 652.8 R F3(pgnoaddr)3.445 E F0 3.445 -(address. Other)3.445 F(-)-.2 E(wise, NULL is returned and errno is set.)108 -664.8 Q 1.167(The function)108 681.6 R F3(mpool_g)3.667 E(et)-.1 E F0(tak)3.667 -E 1.167(es a MPOOL pointer and a page number as ar)-.1 F 3.666(guments. If)-.18 -F 1.166(the page e)3.666 F 1.166(xists, a)-.15 F .686 -(pointer to the page is returned.)108 693.6 R .687 -(Otherwise, NULL is returned and errno is set.)5.686 F .687 -(The \215ags parameter is not)5.687 F(currently used.)108 705.6 Q 1.463 -(The function)108 722.4 R F3(mpool_put)3.963 E F0 1.462 -(unpins the page referenced by)3.962 F F3(pgaddr)3.962 E F0(.).73 E F3(Pgaddr) -6.462 E F0 1.462(must be an address pre)3.962 F(viously)-.25 E 197.615 -(12, September)72 768 R(1)535 768 Q EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 174.84(MPOOL\(3\) 1991 MPOOL\(3\))72 48 R(returned by) -108 84 Q/F1 10/Times-Italic@0 SF(mpool_g)2.5 E(et)-.1 E F0(or)2.5 E F1 -(mpool_ne)2.5 E(w)-.15 E F0 5(.T).31 G(he \215ag v)271.65 84 Q -(alue is speci\214ed by)-.25 E F1(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5 -(ft)434.74 84 S(he follo)443.35 84 Q(wing v)-.25 E(alues:)-.25 E(MPOOL_DIR)108 -100.8 Q(TY)-.6 E -(The page has been modi\214ed and needs to be written to the backing \214le.) -144 112.8 Q F1(Mpool_put)108 129.6 Q F0 -(returns 0 on success and -1 if an error occurs.)2.5 E .247(The function)108 -146.4 R F1(mpool_sync)2.747 E F0 .247(writes all modi\214ed pages associated w\ -ith the MPOOL pointer to the backing \214le.)2.747 F F1(Mpool_sync)108 158.4 Q -F0(returns 0 on success and -1 if an error occurs.)2.5 E(The)108 175.2 Q F1 -(mpool_close)2.698 E F0 .198(function free')2.698 F 2.698(su)-.55 G 2.698(pa) -245.432 175.2 S .498 -.15(ny a)257.57 175.2 T .198 -(llocated memory associated with the memory pool cookie.).15 F(Modi-)5.197 E -(\214ed pages are)108 187.2 Q/F2 10/Times-Bold@0 SF(not)2.5 E F0 -(written to the backing \214le.)2.5 E F1(Mpool_close)5 E F0 -(returns 0 on success and -1 if an error occurs.)2.5 E/F3 9/Times-Bold@0 SF -(ERR)72 204 Q(ORS)-.27 E F0(The)108 216 Q F1(mpool_open)2.938 E F0 .438 -(function may f)2.938 F .438(ail and set)-.1 F F1(errno)2.938 E F0 .438(for an) -2.938 F 2.938(yo)-.15 G 2.938(ft)344.87 216 S .439 -(he errors speci\214ed for the library routine)353.918 216 R F1(mal-)2.939 E -(loc)108 228 Q F0(\(3\).).31 E(The)108 244.8 Q F1(mpool_g)2.5 E(et)-.1 E F0 -(function may f)2.5 E(ail and set)-.1 E F1(errno)2.5 E F0(for the follo)2.5 E -(wing:)-.25 E([EINV)108 261.6 Q 29.98(AL] The)-1.35 F(requested record doesn') -2.5 E 2.5(te)-.18 G(xist.)305.96 261.6 Q(The)108 278.4 Q F1(mpool_ne)4.073 E(w) --.15 E F0(and)4.073 E F1(mpool_g)4.073 E(et)-.1 E F0 1.573(functions may f) -4.073 F 1.573(ail and set)-.1 F F1(errno)4.073 E F0 1.573(for an)4.073 F 4.073 -(yo)-.15 G 4.073(ft)421.336 278.4 S 1.573(he errors speci\214ed for the)431.519 -278.4 R(library routines)108 290.4 Q F1 -.37(re)2.5 G(ad).37 E F0(\(2\)).77 E -F1 2.5(,w).54 G(rite)214.48 290.4 Q F0(\(2\)).18 E F1(,).54 E F0(and)2.5 E F1 -(malloc)2.5 E F0(\(3\).).31 E(The)108 307.2 Q F1(mpool_sync)4.287 E F0 1.787 -(function may f)4.287 F 1.787(ail and set)-.1 F F1(errno)4.288 E F0 1.788 -(for an)4.288 F 4.288(yo)-.15 G 4.288(ft)356.694 307.2 S 1.788 -(he errors speci\214ed for the library routine)367.092 307.2 R F1(write)108 -319.2 Q F0(\(2\).).18 E(The)108 336 Q F1(mpool_close)4.125 E F0 1.624 -(function may f)4.125 F 1.624(ail and set)-.1 F F1(errno)4.124 E F0 1.624 -(for an)4.124 F 4.124(yo)-.15 G 4.124(ft)357.842 336 S 1.624 -(he errors speci\214ed for the library routine)368.076 336 R F1(fr)108 348 Q -(ee)-.37 E F0(\(3\).).18 E F3(SEE ALSO)72 364.8 Q F1(dbopen)108 376.8 Q F0 -(\(3\),).24 E F1(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F1(hash)2.5 E F0(\(3\),) -.28 E F1 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E 197.615(12, September)72 768 R -(2)535 768 Q EP -%%Trailer -end -%%EOF diff --git a/lib/libc/db/doc/recno.3.ps b/lib/libc/db/doc/recno.3.ps deleted file mode 100644 index 6ea5344151d7..000000000000 --- a/lib/libc/db/doc/recno.3.ps +++ /dev/null @@ -1,317 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.08 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Bold -%%+ font Times-Italic -%%DocumentSuppliedResources: procset grops 1.08 0 -%%Pages: 2 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.08 0 -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}bind def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/FL{ -currentgray exch setgray fill setgray -}bind def -/BL/fill load def -/LW/setlinewidth load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -}bind def -/PEND{ -clear -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE -/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 175.95(RECNO\(3\) 1993 RECNO\(3\))72 48 R/F1 9 -/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0 -(recno \255 record number database access method)108 96 Q F1(SYNOPSIS)72 112.8 -Q/F2 10/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <db)108 -136.8 Q(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 1.158(The routine)108 165.6 R/F3 -10/Times-Italic@0 SF(dbopen)3.658 E F0 1.158(is the library interf)3.658 F -1.158(ace to database \214les.)-.1 F 1.157 -(One of the supported \214le formats is record)6.158 F 1.159(number \214les.) -108 177.6 R 1.159(The general description of the database access methods is in) -6.159 F F3(dbopen)3.66 E F0 1.16(\(3\), this manual page).24 F -(describes only the recno speci\214c information.)108 189.6 Q 1.944 -(The record number data structure is either v)108 206.4 R 1.944 -(ariable or \214x)-.25 F 1.944 -(ed-length records stored in a \215at-\214le format,)-.15 F 2.04 -(accessed by the logical record number)108 218.4 R 7.04(.T)-.55 G 2.04(he e) -286.31 218.4 R 2.04(xistence of record number \214v)-.15 F 4.54(ei)-.15 G 2.04 -(mplies the e)442.1 218.4 R 2.04(xistence of)-.15 F .876 -(records one through four)108 230.4 R 3.376(,a)-.4 G .875 -(nd the deletion of record number one causes record number \214v)219.684 230.4 -R 3.375(et)-.15 G 3.375(ob)489.93 230.4 S 3.375(er)503.305 230.4 S(enum-)514.45 -230.4 Q .282(bered to record number four)108 242.4 R 2.782(,a)-.4 G 2.782(sw) -231.19 242.4 S .283(ell as the cursor)245.082 242.4 R 2.783(,i)-.4 G 2.783(fp) -316.633 242.4 S .283(ositioned after record number one, to shift do)327.746 -242.4 R .283(wn one)-.25 F(record.)108 254.4 Q .373 -(The recno access method speci\214c data structure pro)108 271.2 R .373 -(vided to)-.15 F F3(dbopen)2.873 E F0 .373(is de\214ned in the <db)2.873 F .373 -(.h> include \214le as)-.4 F(follo)108 283.2 Q(ws:)-.25 E(typedef struct {)108 -300 Q(u_char b)144 312 Q -.25(va)-.15 G(l;).25 E(u_int cachesize;)144 324 Q -(inde)144 336 Q(x_t psize;)-.15 E(u_long \215ags;)144 348 Q(int lorder;)144 360 -Q(size_t reclen;)144 372 Q(char *bfname;)144 384 Q 2.5(}R)108 396 S(ECNOINFO;) -121.97 396 Q(The elements of this structure are de\214ned as follo)108 412.8 Q -(ws:)-.25 E -.15(bv)108 429.6 S 16.68(al The)-.1 F .182 -(delimiting byte to be used to mark the end of a record for v)2.682 F .183 -(ariable-length records, and the pad)-.25 F .809(character for \214x)144 441.6 -R .809(ed-length records.)-.15 F .809(If no v)5.809 F .809 -(alue is speci\214ed, ne)-.25 F .809(wlines \(`)-.25 F(`\\n')-.74 E .808 -('\) are used to mark the)-.74 F(end of v)144 453.6 Q -(ariable-length records and \214x)-.25 E -(ed-length records are padded with spaces.)-.15 E(cachesize)108 470.4 Q 3.159 -(As)144 482.4 S .659(uggested maximum size, in bytes, of the memory cache.) -158.269 482.4 R .66(This v)5.659 F .66(alue is)-.25 F F2(only)3.16 E F0 -(advisory)3.16 E 3.16(,a)-.65 G .66(nd the)514.62 482.4 R -(access method will allocate more memory rather than f)144 494.4 Q(ail.)-.1 E -12.95(psize The)108 511.2 R .715 -(recno access method stores the in-memory copies of its records in a btree.) -3.216 F .715(This v)5.715 F .715(alue is the)-.25 F -(size \(in bytes\) of the pages used for nodes in that tree.)144 523.2 Q(See)5 -E F3(btr)2.5 E(ee)-.37 E F0(\(3\) for more information.).18 E 3.51(bfname The) -108 540 R .505 -(recno access method stores the in-memory copies of its records in a btree.) -3.005 F .506(If bfname is non-)5.506 F .065(NULL, it speci\214es the name of t\ -he btree \214le, as if speci\214ed as the \214le name for a dbopen of a btree) -144 552 R(\214le.)144 564 Q 14.61(\215ags The)108 580.8 R(\215ag v)2.5 E -(alue is speci\214ed by)-.25 E F3(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5 -(ft)313.2 580.8 S(he follo)321.81 580.8 Q(wing v)-.25 E(alues:)-.25 E -(R_FIXEDLEN)144 597.6 Q .962(The records are \214x)180 609.6 R .963 -(ed-length, not byte delimited.)-.15 F .963(The structure element)5.963 F F3 --.37(re)3.463 G(clen).37 E F0(speci\214es)3.463 E -(the length of the record, and the structure element)180 621.6 Q F3(bval)2.5 E -F0(is used as the pad character)2.5 E(.)-.55 E(R_NOKEY)144 638.4 Q 2.34 -(In the interf)180 650.4 R 2.34(ace speci\214ed by)-.1 F F3(dbopen)4.84 E F0 -4.84(,t).24 G 2.34(he sequential record retrie)344.98 650.4 R -.25(va)-.25 G -4.84<6c8c>.25 G 2.34(lls in both the)478.25 650.4 R(caller')180 662.4 Q 3.556 -(sk)-.55 G 1.357 -.15(ey a)217.336 662.4 T 1.057(nd data structures.).15 F -1.057(If the R_NOKEY \215ag is speci\214ed, the)6.057 F F3(cur)3.557 E(sor)-.1 -E F0(routines)3.557 E .029(are not required to \214ll in the k)180 674.4 R .329 --.15(ey s)-.1 H 2.529(tructure. This).15 F .028(permits applications to retrie) -2.529 F .328 -.15(ve r)-.25 H .028(ecords at).15 F -(the end of \214les without reading all of the interv)180 686.4 Q -(ening records.)-.15 E(R_SN)144 703.2 Q(APSHO)-.35 E(T)-.4 E .964 -(This \215ag requires that a snapshot of the \214le be tak)180 715.2 R .965 -(en when)-.1 F F3(dbopen)3.465 E F0 .965(is called, instead of)3.465 F -(permitting an)180 727.2 Q 2.5(yu)-.15 G -(nmodi\214ed records to be read from the original \214le.)245.96 727.2 Q -209.835(16, May)72 768 R(1)535 768 Q EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF 175.95(RECNO\(3\) 1993 RECNO\(3\))72 48 R 9.62 -(lorder The)108 84 R 1.597(byte order for inte)4.097 F 1.596 -(gers in the stored database metadata.)-.15 F 1.596 -(The number should represent the)6.596 F .688(order as an inte)144 96 R .689 -(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689 -(ould be the number 4,321.)-.1 F(If)5.689 E/F1 10/Times-Italic@0 SF(lor)3.189 E -(der)-.37 E F0 .689(is 0 \(no)3.189 F -(order is speci\214ed\) the current host order is used.)144 108 Q 9.07 -(reclen The)108 124.8 R(length of a \214x)2.5 E(ed-length record.)-.15 E .972 -(The data part of the k)108 141.6 R -.15(ey)-.1 G .971(/data pair used by the \ -recno access method is the same as other access methods.).15 F .198(The k)108 -153.6 R .498 -.15(ey i)-.1 H 2.698(sd).15 G(if)157.504 153.6 Q 2.698 -(ferent. The)-.25 F F1(data)2.698 E F0 .198(\214eld of the k)2.698 F .499 -.15 -(ey s)-.1 H .199(hould be a pointer to a memory location of type).15 F F1 -.37 -(re)2.699 G(cno_t).37 E F0 2.699(,a).68 G(s)536.11 153.6 Q .506 -(de\214ned in the <db)108 165.6 R .506(.h> include \214le.)-.4 F .506 -(This type is normally the lar)5.506 F .506(gest unsigned inte)-.18 F .506 -(gral type a)-.15 F -.25(va)-.2 G .505(ilable to the).25 F 2.5 -(implementation. The)108 177.6 R F1(size)2.5 E F0(\214eld of the k)2.5 E .3 --.15(ey s)-.1 H(hould be the size of that type.).15 E .064(In the interf)108 -194.4 R .064(ace speci\214ed by)-.1 F F1(dbopen)2.564 E F0 2.564(,u).24 G .064 -(sing the)261.544 194.4 R F1(put)2.564 E F0(interf)2.564 E .064 -(ace to create a ne)-.1 F 2.564(wr)-.25 G .065 -(ecord will cause the creation of)414.436 194.4 R .755(multiple, empty records\ - if the record number is more than one greater than the lar)108 206.4 R .754 -(gest record currently in)-.18 F(the database.)108 218.4 Q/F2 9/Times-Bold@0 SF -(SEE ALSO)72 235.2 Q F1(dbopen)108 247.2 Q F0(\(3\),).24 E F1(hash)2.5 E F0 -(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 -.37(re)2.5 G(cno).37 E F0 -(\(3\)).18 E F1 2.754(Document Pr)108 271.2 R 2.754 -(ocessing in a Relational Database System)-.45 F F0 5.255(,M).32 G 2.755 -(ichael Stonebrak)362.13 271.2 R(er)-.1 E 5.255(,H)-.4 G 2.755(eidi Stettner) -454.06 271.2 R 5.255(,J)-.4 G(oseph)516.67 271.2 Q -(Kalash, Antonin Guttman, Nadene L)108 283.2 Q -(ynn, Memorandum No. UCB/ERL M82/32, May 1982.)-.55 E F2 -.09(BU)72 300 S(GS) -.09 E F0(Only big and little endian byte order is supported.)108 312 Q 209.835 -(16, May)72 768 R(2)535 768 Q EP -%%Trailer -end -%%EOF diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c index aa2e42856ebe..e9b25831d20e 100644 --- a/lib/libc/db/hash/hash.c +++ b/lib/libc/db/hash/hash.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)hash.c 8.4 (Berkeley) 10/12/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -93,9 +93,9 @@ long hash_accesses, hash_collisions, hash_expansions, hash_overflows; /* OPEN/CLOSE */ extern DB * -__hash_open(file, flags, mode, info) +__hash_open(file, flags, mode, info, dflags) const char *file; - int flags, mode; + int flags, mode, dflags; const HASHINFO *info; /* Special directives for create */ { HTAB *hashp; @@ -111,13 +111,14 @@ __hash_open(file, flags, mode, info) if (!(hashp = calloc(1, sizeof(HTAB)))) return (NULL); hashp->fp = -1; + /* - * Select flags relevant to us. Even if user wants write only, we need - * to be able to read the actual file, so we need to open it read/write. - * But, the field in the hashp structure needs to be accurate so that + * Even if user wants write only, we need to be able to read + * the actual file, so we need to open it read/write. But, the + * field in the hashp structure needs to be accurate so that * we can check accesses. */ - hashp->flags = flags = flags & __USE_OPEN_FLAGS; + hashp->flags = flags; new_table = 0; if (!file || (flags & O_TRUNC) || @@ -152,7 +153,9 @@ __hash_open(file, flags, mode, info) /* Verify file type, versions and hash function */ if (hashp->MAGIC != HASHMAGIC) RETURN_ERROR(EFTYPE, error1); - if (hashp->VERSION != HASHVERSION) +#define OLDHASHVERSION 1 + if (hashp->VERSION != HASHVERSION && + hashp->VERSION != OLDHASHVERSION) RETURN_ERROR(EFTYPE, error1); if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY) RETURN_ERROR(EFTYPE, error1); @@ -865,7 +868,7 @@ hash_realloc(p_ptr, oldsize, newsize) if (p = malloc(newsize)) { memmove(p, *p_ptr, oldsize); - memset(p + oldsize, 0, newsize - oldsize); + memset((char *)p + oldsize, 0, newsize - oldsize); free(*p_ptr); *p_ptr = p; } diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c index c2260f7b21a3..463189b15d2b 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)hash_page.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)hash_page.c 8.2 (Berkeley) 9/6/93"; #endif /* LIBC_SCCS and not lint */ /* @@ -302,12 +302,8 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved) n = ino[0] - 1; while (n < ino[0]) { if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) { - /* - * Ov_addr gets set before reaching this point; there's - * always an overflow page before a big key/data page. - */ if (__big_split(hashp, old_bufp, - new_bufp, bufp, ov_addr, obucket, &ret)) + new_bufp, bufp, bufp->addr, obucket, &ret)) return (-1); old_bufp = ret.oldp; if (!old_bufp) @@ -409,11 +405,14 @@ __addel(hashp, bufp, key, val) bp = (u_short *)bufp->page; do_expand = 0; - while (bp[0] && (bp[bp[0]] < REAL_KEY)) + while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) /* Exception case */ - if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { - /* This is a big-keydata pair */ - bufp = __add_ovflpage(hashp, bufp); + if (bp[2] == FULL_KEY_DATA && bp[0] == 2) + /* This is the last page of a big key/data pair + and we need to add another page */ + break; + else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { + bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); bp = (u_short *)bufp->page; diff --git a/lib/libc/db/hash/hsearch.c b/lib/libc/db/hash/hsearch.c index 30657b2c8ab6..8074d67945cf 100644 --- a/lib/libc/db/hash/hsearch.c +++ b/lib/libc/db/hash/hsearch.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)hsearch.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)hsearch.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -62,7 +62,7 @@ hcreate(nel) info.cachesize = NULL; info.hash = NULL; info.lorder = 0; - dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info); + dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0); return ((int)dbp); } diff --git a/lib/libc/db/hash/ndbm.c b/lib/libc/db/hash/ndbm.c index 2756074744c2..89b9916566b2 100644 --- a/lib/libc/db/hash/ndbm.c +++ b/lib/libc/db/hash/ndbm.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ndbm.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)ndbm.c 8.2 (Berkeley) 9/11/93"; #endif /* LIBC_SCCS and not lint */ /* @@ -72,7 +72,7 @@ dbm_open(file, flags, mode) info.lorder = 0; (void)strcpy(path, file); (void)strcat(path, DBM_SUFFIX); - return ((DBM *)__hash_open(path, flags, mode, &info)); + return ((DBM *)__hash_open(path, flags, mode, &info, 0)); } extern void diff --git a/lib/libc/db/man/btree.3 b/lib/libc/db/man/btree.3 index 923bc263cae2..afd3a672c884 100644 --- a/lib/libc/db/man/btree.3 +++ b/lib/libc/db/man/btree.3 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)btree.3 8.1 (Berkeley) 6/4/93 +.\" @(#)btree.3 8.2 (Berkeley) 1/2/94 .\" -.TH BTREE 3 +.TH BTREE 3 "January 2, 1994" .\".UC 7 .SH NAME btree \- btree database access method @@ -64,17 +64,17 @@ u_long flags; .br u_int cachesize; .br -index_t psize; -.br -int lorder; -.\" .br -.\" int maxkeypage; +int maxkeypage; .br int minkeypage; .br +index_t psize; +.br int (*compare)(const DBT *key1, const DBT *key2); .br int (*prefix)(const DBT *key1, const DBT *key2); +.br +int lorder; .RE } BTREEINFO; .PP @@ -121,23 +121,9 @@ If .I cachesize is 0 (no size is specified) a default cache is used. .TP -psize -Page size is the size (in bytes) of the pages used for nodes in the tree. -The minimum page size is 512 bytes and the maximum page size is 64K. -If -.I psize -is 0 (no page size is specified) a page size is chosen based on the -underlying file system I/O block size. -.TP -lorder -The byte order for integers in the stored database metadata. -The number should represent the order as an integer; for example, -big endian order would be the number 4,321. -If -.I lorder -is 0 (no order is specified) the current host order is used. -.\" .TP -.\" maxkeypage +maxkeypage +The maximum number of keys which will be stored on any single page. +Not currently implemented. .\" The maximum number of keys which will be stored on any single page. .\" Because of the way the btree data structure works, .\" .I maxkeypage @@ -157,6 +143,14 @@ If .I minkeypage is 0 (no minimum number of keys is specified) a value of 2 is used. .TP +psize +Page size is the size (in bytes) of the pages used for nodes in the tree. +The minimum page size is 512 bytes and the maximum page size is 64K. +If +.I psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +.TP compare Compare is the key comparison function. It must return an integer less than, equal to, or greater than zero if the @@ -187,6 +181,14 @@ If .I prefix is NULL and a comparison routine is specified, no prefix comparison is done. +.TP +lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.I lorder +is 0 (no order is specified) the current host order is used. .PP If the file already exists (and the O_TRUNC flag is not specified), the values specified for the parameters flags, lorder and psize are ignored diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3 index a2e2bfd14b43..fbfabadc6445 100644 --- a/lib/libc/db/man/dbopen.3 +++ b/lib/libc/db/man/dbopen.3 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)dbopen.3 8.1 (Berkeley) 6/4/93 +.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94 .\" -.TH DBOPEN 3 "June 4, 1993" +.TH DBOPEN 3 "January 2, 1994" .UC 7 .SH NAME dbopen \- database access methods @@ -51,7 +51,7 @@ const void *openinfo); .SH DESCRIPTION .IR Dbopen is the library interface to database files. -The supported file formats are btree, hashed and UNIX file oriented. +The supported file formats are btree, hashed and flat-file oriented. The btree format is a representation of a sorted, balanced tree structure. The hashed format is an extensible, dynamic hashing scheme. The flat-file format is a byte stream file with fixed or variable length @@ -75,9 +75,29 @@ and .I mode arguments are as specified to the .IR open (2) -routine, however, only the O_CREAT, O_EXCL, O_EXLOCK, O_RDONLY, O_RDWR, -O_SHLOCK and O_TRUNC flags are meaningful. +routine, however, only the O_CREAT, O_EXCL, O_EXLOCK, O_NONBLOCK, +O_RDONLY, O_RDWR, O_SHLOCK and O_TRUNC flags are meaningful. (Note, opening a database file O_WRONLY is not possible.) +.\"Three additional options may be specified by +.\".IR or 'ing +.\"them into the +.\".I flags +.\"argument. +.\".TP +.\"DB_LOCK +.\"Do the necessary locking in the database to support concurrent access. +.\"If concurrent access isn't needed or the database is read-only this +.\"flag should not be set, as it tends to have an associated performance +.\"penalty. +.\".TP +.\"DB_SHMEM +.\"Place the underlying memory pool used by the database in shared +.\"memory. +.\"Necessary for concurrent access. +.\".TP +.\"DB_TXN +.\"Support transactions in the database. +.\"The DB_LOCK and DB_SHMEM flags must be set as well. .PP The .I type @@ -167,7 +187,7 @@ processes which call with the same .I file name. -This file descriptor may be safely used as a argument to the +This file descriptor may be safely used as an argument to the .IR fcntl (2) and .IR flock (2) @@ -442,6 +462,9 @@ for any of the errors specified for the library routine .IR hash (3), .IR mpool (3), .IR recno (3) +.sp +.IR "LIBTP: Portable, Modular Transactions for UNIX" , +Margo Seltzer, Michael Olson, USENIX proceedings, Winter 1992. .SH BUGS The typedef DBT is a mnemonic for ``data base thang'', and was used because noone could think of a reasonable name that wasn't already used. diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3 index 698f10ca185c..57a77c1f870d 100644 --- a/lib/libc/db/man/hash.3 +++ b/lib/libc/db/man/hash.3 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)hash.3 8.1 (Berkeley) 6/6/93 +.\" @(#)hash.3 8.4 (Berkeley) 1/2/94 .\" -.TH HASH 3 "June 6, 1993" +.TH HASH 3 "January 2, 1994" .UC 7 .SH NAME hash \- hash database access method @@ -61,15 +61,15 @@ typedef struct { .RS int bsize; .br -int cachesize; -.br int ffactor; .br +int nelem; +.br +int cachesize; +.br u_long (*hash)(const void *, size_t); .br int lorder; -.br -int nelem; .RE } HASHINFO; .PP @@ -81,13 +81,6 @@ defines the hash table bucket size, and is, by default, 256 bytes. It may be preferable to increase the page size for disk-resident tables and tables with large data items. .TP -cachesize -A suggested maximum size, in bytes, of the memory cache. -This value is -.B only -advisory, and the access method will allocate more memory rather -than fail. -.TP ffactor .I Ffactor indicates a desired density within the hash table. @@ -95,6 +88,20 @@ It is an approximation of the number of keys allowed to accumulate in any one bucket, determining when the hash table grows or shrinks. The default value is 8. .TP +nelem +.I Nelem +is an estimate of the final size of the hash table. +If not set or set too low, hash tables will expand gracefully as keys +are entered, although a slight performance degradation may be noticed. +The default value is 1. +.TP +cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.B only +advisory, and the access method will allocate more memory rather +than fail. +.TP hash .I Hash is a user defined hash function. @@ -113,13 +120,6 @@ If is 0 (no order is specified) the current host order is used. If the file already exists, the specified value is ignored and the value specified when the tree was created is used. -.TP -nelem -.I Nelem -is an estimate of the final size of the hash table. -If not set or set too low, hash tables will expand gracefully as keys -are entered, although a slight performance degradation may be noticed. -The default value is 1. .PP If the file already exists (and the O_TRUNC flag is not specified), the values specified for the parameters bsize, ffactor, lorder and nelem are @@ -134,17 +134,17 @@ Backward compatible interfaces to the routines described in .IR dbm (3), and .IR ndbm (3) -are provided, however, these interfaces are not compatible with +are provided, however these interfaces are not compatible with previous file formats. .SH "SEE ALSO" .IR btree (3), .IR dbopen (3), .IR mpool (3), .IR recno (3) -.br +.sp .IR "Dynamic Hash Tables" , Per-Ake Larson, Communications of the ACM, April 1988. -.br +.sp .IR "A New Hash Package for UNIX" , Margo Seltzer, USENIX Proceedings, Winter 1991. .SH BUGS diff --git a/lib/libc/db/man/recno.3 b/lib/libc/db/man/recno.3 index 476155642a2e..a6f218b2efe4 100644 --- a/lib/libc/db/man/recno.3 +++ b/lib/libc/db/man/recno.3 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)recno.3 8.1 (Berkeley) 6/4/93 +.\" @(#)recno.3 8.2 (Berkeley) 1/2/94 .\" -.TH RECNO 3 "June 4, 1993" +.TH RECNO 3 "January 2, 1994" .UC 7 .SH NAME recno \- record number database access method @@ -66,59 +66,24 @@ is defined in the <db.h> include file as follows: .PP typedef struct { .RS -u_char bval; +u_long flags; .br u_int cachesize; .br index_t psize; .br -u_long flags; -.br int lorder; .br size_t reclen; .br +u_char bval; +.br char *bfname; .RE } RECNOINFO; .PP The elements of this structure are defined as follows: .TP -bval -The delimiting byte to be used to mark the end of a record for -variable-length records, and the pad character for fixed-length -records. -If no value is specified, newlines (``\en'') are used to mark the end -of variable-length records and fixed-length records are padded with -spaces. -.TP -cachesize -A suggested maximum size, in bytes, of the memory cache. -This value is -.B only -advisory, and the access method will allocate more memory rather than fail. -If -.I cachesize -is 0 (no size is specified) a default cache is used. -.TP -psize -The recno access method stores the in-memory copies of its records -in a btree. -This value is the size (in bytes) of the pages used for nodes in that tree. -If -.I psize -is 0 (no page size is specified) a page size is chosen based on the -underlying file system I/O block size. -See -.IR btree (3) -for more information. -.TP -bfname -The recno access method stores the in-memory copies of its records -in a btree. -If bfname is non-NULL, it specifies the name of the btree file, -as if specified as the file name for a dbopen of a btree file. -.TP flags The flag value is specified by .IR or 'ing @@ -151,6 +116,27 @@ is called, instead of permitting any unmodified records to be read from the original file. .RE .TP +cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.B only +advisory, and the access method will allocate more memory rather than fail. +If +.I cachesize +is 0 (no size is specified) a default cache is used. +.TP +psize +The recno access method stores the in-memory copies of its records +in a btree. +This value is the size (in bytes) of the pages used for nodes in that tree. +If +.I psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +See +.IR btree (3) +for more information. +.TP lorder The byte order for integers in the stored database metadata. The number should represent the order as an integer; for example, @@ -161,6 +147,20 @@ is 0 (no order is specified) the current host order is used. .TP reclen The length of a fixed-length record. +.TP +bval +The delimiting byte to be used to mark the end of a record for +variable-length records, and the pad character for fixed-length +records. +If no value is specified, newlines (``\en'') are used to mark the end +of variable-length records and fixed-length records are padded with +spaces. +.TP +bfname +The recno access method stores the in-memory copies of its records +in a btree. +If bfname is non-NULL, it specifies the name of the btree file, +as if specified as the file name for a dbopen of a btree file. .PP The data part of the key/data pair used by the recno access method is the same as other access methods. diff --git a/lib/libc/db/recno/rec_close.c b/lib/libc/db/recno/rec_close.c index 49c5f2ca5e56..73e3690394ba 100644 --- a/lib/libc/db/recno/rec_close.c +++ b/lib/libc/db/recno/rec_close.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_close.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_close.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -63,12 +63,18 @@ __rec_close(dbp) BTREE *t; int rval; + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + if (__rec_sync(dbp, 0) == RET_ERROR) return (RET_ERROR); /* Committed to closing. */ - t = dbp->internal; - rval = RET_SUCCESS; if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) rval = RET_ERROR; @@ -110,6 +116,12 @@ __rec_sync(dbp, flags) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + if (flags == R_RECNOSYNC) return (__bt_sync(dbp, 0)); diff --git a/lib/libc/db/recno/rec_delete.c b/lib/libc/db/recno/rec_delete.c index 98d135331d55..fc4bea8a128d 100644 --- a/lib/libc/db/recno/rec_delete.c +++ b/lib/libc/db/recno/rec_delete.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_delete.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_delete.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -71,6 +71,13 @@ __rec_delete(dbp, key, flags) int status; t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + switch(flags) { case 0: if ((nrec = *(recno_t *)key->data) == 0) diff --git a/lib/libc/db/recno/rec_get.c b/lib/libc/db/recno/rec_get.c index d02451272284..55d080bdfb5e 100644 --- a/lib/libc/db/recno/rec_get.c +++ b/lib/libc/db/recno/rec_get.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_get.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_get.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -71,6 +71,15 @@ __rec_get(dbp, key, data, flags) recno_t nrec; int status; + t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* Get currently doesn't take any flags, and keys of 0 are illegal. */ if (flags || (nrec = *(recno_t *)key->data) == 0) { errno = EINVAL; return (RET_ERROR); @@ -80,7 +89,6 @@ __rec_get(dbp, key, data, flags) * If we haven't seen this record yet, try to find it in the * original file. */ - t = dbp->internal; if (nrec > t->bt_nrecs) { if (ISSET(t, R_EOF | R_INMEM)) return (RET_SPECIAL); @@ -93,7 +101,10 @@ __rec_get(dbp, key, data, flags) return (RET_ERROR); status = __rec_ret(t, e, 0, NULL, data); - mpool_put(t->bt_mp, e->page, 0); + if (ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; return (status); } diff --git a/lib/libc/db/recno/rec_open.c b/lib/libc/db/recno/rec_open.c index a0e152e476da..f05a44bb0026 100644 --- a/lib/libc/db/recno/rec_open.c +++ b/lib/libc/db/recno/rec_open.c @@ -35,7 +35,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_open.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_open.c 8.4 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -49,13 +49,14 @@ static char sccsid[] = "@(#)rec_open.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <unistd.h> +#define __DBINTERFACE_PRIVATE #include <db.h> #include "recno.h" DB * -__rec_open(fname, flags, mode, openinfo) +__rec_open(fname, flags, mode, openinfo, dflags) const char *fname; - int flags, mode; + int flags, mode, dflags; const RECNOINFO *openinfo; { BTREE *t; @@ -83,9 +84,9 @@ __rec_open(fname, flags, mode, openinfo) btopeninfo.prefix = NULL; btopeninfo.lorder = openinfo->lorder; dbp = __bt_open(openinfo->bfname, - O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo); + O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags); } else - dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL); + dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags); if (dbp == NULL) goto err; @@ -158,8 +159,8 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL) SET(t, R_EOF); else { t->bt_msize = sb.st_size; - if ((t->bt_smap = - mmap(NULL, t->bt_msize, PROT_READ, 0, rfd, + if ((t->bt_smap = mmap(NULL, t->bt_msize, + PROT_READ, MAP_PRIVATE, rfd, (off_t)0)) == (caddr_t)-1) goto slow; t->bt_cmap = t->bt_smap; @@ -213,6 +214,13 @@ __rec_fd(dbp) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + + /* In-memory database can't have a file descriptor. */ if (ISSET(t, R_INMEM)) { errno = ENOENT; return (-1); diff --git a/lib/libc/db/recno/rec_put.c b/lib/libc/db/recno/rec_put.c index 9dcdc9c30bf4..515c90a46518 100644 --- a/lib/libc/db/recno/rec_put.c +++ b/lib/libc/db/recno/rec_put.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_put.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_put.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -72,6 +72,12 @@ __rec_put(dbp, key, data, flags) t = dbp->internal; + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + switch (flags) { case R_CURSOR: if (!ISSET(t, B_SEQINIT)) diff --git a/lib/libc/db/recno/rec_search.c b/lib/libc/db/recno/rec_search.c index 9d50b2f50ca4..ea3e06a6aee4 100644 --- a/lib/libc/db/recno/rec_search.c +++ b/lib/libc/db/recno/rec_search.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_search.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_search.c 8.2 (Berkeley) 9/14/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -55,9 +55,10 @@ static char sccsid[] = "@(#)rec_search.c 8.1 (Berkeley) 6/4/93"; * EPG for matching record, if any, or the EPG for the location of the * key, if it were inserted into the tree. * - * Warnings: - * The EPG returned is in static memory, and will be overwritten by the - * next search of any kind in any tree. + * Returns: + * The EPG for matching record, if any, or the EPG for the location + * of the key, if it were inserted into the tree, is entered into + * the bt_cur field of the tree. A pointer to the field is returned. */ EPG * __rec_search(t, recno, op) @@ -65,7 +66,6 @@ __rec_search(t, recno, op) recno_t recno; enum SRCHOP op; { - static EPG e; register indx_t index; register PAGE *h; EPGNO *parent; @@ -80,9 +80,9 @@ __rec_search(t, recno, op) if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) goto err; if (h->flags & P_RLEAF) { - e.page = h; - e.index = recno - total; - return (&e); + t->bt_cur.page = h; + t->bt_cur.index = recno - total; + return (&t->bt_cur); } for (index = 0, top = NEXTINDEX(h);;) { r = GETRINTERNAL(h, index); diff --git a/lib/libc/db/recno/rec_seq.c b/lib/libc/db/recno/rec_seq.c index 29210a753697..bc66d1c4987e 100644 --- a/lib/libc/db/recno/rec_seq.c +++ b/lib/libc/db/recno/rec_seq.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)rec_seq.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_seq.c 8.2 (Berkeley) 9/7/93"; #endif /* not lint */ #include <sys/types.h> @@ -69,6 +69,13 @@ __rec_seq(dbp, key, data, flags) int status; t = dbp->internal; + + /* Toss any page pinned across calls. */ + if (t->bt_pinned != NULL) { + mpool_put(t->bt_mp, t->bt_pinned, 0); + t->bt_pinned = NULL; + } + switch(flags) { case R_CURSOR: if ((nrec = *(recno_t *)key->data) == 0) @@ -116,7 +123,9 @@ einval: errno = EINVAL; t->bt_rcursor = nrec; status = __rec_ret(t, e, nrec, key, data); - - mpool_put(t->bt_mp, e->page, 0); + if (ISSET(t, B_DB_LOCK)) + mpool_put(t->bt_mp, e->page, 0); + else + t->bt_pinned = e->page; return (status); } diff --git a/lib/libc/db/recno/rec_utils.c b/lib/libc/db/recno/rec_utils.c index c55f4df0f81c..ad87a4aa444e 100644 --- a/lib/libc/db/recno/rec_utils.c +++ b/lib/libc/db/recno/rec_utils.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rec_utils.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)rec_utils.c 8.2 (Berkeley) 9/7/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -70,11 +70,17 @@ __rec_ret(t, e, nrec, key, data) rl = GETRLEAF(e->page, e->index); + /* + * We always copy big data to make it contigous. Otherwise, we + * leave the page pinned and don't copy unless the user specified + * concurrent access. + */ if (rl->flags & P_BIGDATA) { if (__ovfl_get(t, rl->bytes, &data->size, &t->bt_dbuf, &t->bt_dbufsz)) return (RET_ERROR); - } else { + data->data = t->bt_dbuf; + } else if (ISSET(t, B_DB_LOCK)) { /* Use +1 in case the first record retrieved is 0 length. */ if (rl->dsize + 1 > t->bt_dbufsz) { if ((p = realloc(t->bt_dbuf, rl->dsize + 1)) == NULL) @@ -84,12 +90,16 @@ __rec_ret(t, e, nrec, key, data) } memmove(t->bt_dbuf, rl->bytes, rl->dsize); data->size = rl->dsize; + data->data = t->bt_dbuf; + } else { + data->size = rl->dsize; + data->data = rl->bytes; } - data->data = t->bt_dbuf; retkey: if (key == NULL) return (RET_SUCCESS); + /* We have to copy the key, it's not on the page. */ if (sizeof(recno_t) > t->bt_kbufsz) { if ((p = realloc(t->bt_kbuf, sizeof(recno_t))) == NULL) return (RET_ERROR); diff --git a/lib/libc/db/test/Makefile b/lib/libc/db/test/Makefile index f04a780c74dc..a070941f8f2d 100644 --- a/lib/libc/db/test/Makefile +++ b/lib/libc/db/test/Makefile @@ -1,10 +1,14 @@ -# @(#)Makefile 8.1 (Berkeley) 6/4/93 +# @(#)Makefile 8.7 (Berkeley) 1/2/94 PROG= dbtest -SRCS= dbtest.c +OBJS= dbtest.o -CFLAGS+= -g -DDEBUG -DSTATISTICS -NOMAN= noman +# Add -DSTATISTICS to CFLAGS to get btree statistical use info. +# Note, the db library has to be compiled for statistics as well. +CFLAGS= -O -DDEBUG -NOINCLUDE=1 -.include <bsd.prog.mk> +dbtest: ${OBJS} ${LIB} + ${CC} -o $@ ${OBJS} ${LIB} + +clean: + rm -f gmon.out ${OBJS} ${PROG} t1 t2 t3 diff --git a/lib/libc/db/test/dbtest.c b/lib/libc/db/test/dbtest.c index 823223088dd1..41a115e9b602 100644 --- a/lib/libc/db/test/dbtest.c +++ b/lib/libc/db/test/dbtest.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)dbtest.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)dbtest.c 8.7 (Berkeley) 1/2/94"; #endif /* not lint */ #include <sys/param.h> @@ -91,12 +91,13 @@ main(argc, argv) DB *dbp; DBT data, key, keydata; size_t len; - int ch; + int ch, oflags; char *fname, *infoarg, *p, buf[8 * 1024]; infoarg = NULL; fname = NULL; - while ((ch = getopt(argc, argv, "f:i:o:")) != EOF) + oflags = O_CREAT | O_RDWR; + while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF) switch(ch) { case 'f': fname = optarg; @@ -104,6 +105,9 @@ main(argc, argv) case 'i': infoarg = optarg; break; + case 'l': + oflags |= DB_LOCK; + break; case 'o': if ((ofd = open(optarg, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) @@ -145,7 +149,7 @@ main(argc, argv) (void)unlink(buf); } if ((dbp = dbopen(fname, - O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, type, infop)) == NULL) + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) err("dbopen: %s", strerror(errno)); XXdbp = dbp; @@ -238,7 +242,7 @@ ldata: switch(command) { err("line %lu: not expecting a key", lineno); if (type == DB_RECNO) { static recno_t recno; - recno = strtol(p + 1, NULL, 0); + recno = atoi(p + 1); key.data = &recno; key.size = sizeof(recno); } else { @@ -284,6 +288,10 @@ lkey: switch(command) { p, lineno); } } +#ifdef STATISTICS + if (type == DB_BTREE) + __bt_stat(dbp); +#endif if (dbp->close(dbp)) err("db->close: %s", strerror(errno)); (void)close(ofd); @@ -502,75 +510,75 @@ setinfo(type, s) switch(type) { case DB_BTREE: if (!strcmp("flags", s)) { - ib.flags = strtoul(eq, NULL, 0); + ib.flags = atoi(eq); return (&ib); } if (!strcmp("cachesize", s)) { - ib.cachesize = strtoul(eq, NULL, 0); + ib.cachesize = atoi(eq); return (&ib); } if (!strcmp("maxkeypage", s)) { - ib.maxkeypage = strtoul(eq, NULL, 0); + ib.maxkeypage = atoi(eq); return (&ib); } if (!strcmp("minkeypage", s)) { - ib.minkeypage = strtoul(eq, NULL, 0); + ib.minkeypage = atoi(eq); return (&ib); } if (!strcmp("lorder", s)) { - ib.lorder = strtoul(eq, NULL, 0); + ib.lorder = atoi(eq); return (&ib); } if (!strcmp("psize", s)) { - ib.psize = strtoul(eq, NULL, 0); + ib.psize = atoi(eq); return (&ib); } break; case DB_HASH: if (!strcmp("bsize", s)) { - ih.bsize = strtoul(eq, NULL, 0); + ih.bsize = atoi(eq); return (&ih); } if (!strcmp("ffactor", s)) { - ih.ffactor = strtoul(eq, NULL, 0); + ih.ffactor = atoi(eq); return (&ih); } if (!strcmp("nelem", s)) { - ih.nelem = strtoul(eq, NULL, 0); + ih.nelem = atoi(eq); return (&ih); } if (!strcmp("cachesize", s)) { - ih.cachesize = strtoul(eq, NULL, 0); + ih.cachesize = atoi(eq); return (&ih); } if (!strcmp("lorder", s)) { - ih.lorder = strtoul(eq, NULL, 0); + ih.lorder = atoi(eq); return (&ih); } break; case DB_RECNO: if (!strcmp("flags", s)) { - rh.flags = strtoul(eq, NULL, 0); + rh.flags = atoi(eq); return (&rh); } if (!strcmp("cachesize", s)) { - rh.cachesize = strtoul(eq, NULL, 0); + rh.cachesize = atoi(eq); return (&rh); } if (!strcmp("lorder", s)) { - rh.lorder = strtoul(eq, NULL, 0); + rh.lorder = atoi(eq); return (&rh); } if (!strcmp("reclen", s)) { - rh.reclen = strtoul(eq, NULL, 0); + rh.reclen = atoi(eq); return (&rh); } if (!strcmp("bval", s)) { - rh.bval = strtoul(eq, NULL, 0); + rh.bval = atoi(eq); return (&rh); } if (!strcmp("psize", s)) { - rh.psize = strtoul(eq, NULL, 0); + rh.psize = atoi(eq); return (&rh); } break; @@ -595,8 +603,10 @@ rfile(name, lenp) if ((fd = open(name, O_RDONLY, 0)) < 0 || fstat(fd, &sb)) err("%s: %s\n", name, strerror(errno)); +#ifdef NOT_PORTABLE if (sb.st_size > (off_t)SIZE_T_MAX) err("%s: %s\n", name, strerror(E2BIG)); +#endif if ((p = malloc((u_int)sb.st_size)) == NULL) err("%s", strerror(errno)); (void)read(fd, p, (int)sb.st_size); @@ -622,7 +632,7 @@ void usage() { (void)fprintf(stderr, - "usage: dbtest [-f file] [-i info] [-o file] type script\n"); + "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); exit(1); } diff --git a/lib/libc/db/test/run.test b/lib/libc/db/test/run.test index 2e0bd8d196ff..5eeaf743dd68 100644 --- a/lib/libc/db/test/run.test +++ b/lib/libc/db/test/run.test @@ -1,32 +1,50 @@ #!/bin/sh - # -# @(#)run.test 8.1 (Berkeley) 6/4/93 +# @(#)run.test 8.7 (Berkeley) 9/16/93 # # db regression tests - main() { - DICT=/usr/share/dict/words - PROG=obj/dbtest - TMP1=t1 - TMP2=t2 - TMP3=t3 - test1 - test2 - test3 - test4 - test5 - test6 - test7 - test8 - test9 - test10 - test11 - test12 - test13 - test20 +DICT=/usr/share/dict/words +#DICT=/usr/dict/words +PROG=./dbtest +TMP1=t1 +TMP2=t2 +TMP3=t3 + + if [ $# -eq 0 ]; then + for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do + test$t + done + else + while [ $# -gt 0 ] + do case "$1" in + test*) + $1;; + [0-9]*) + test$1;; + btree) + for t in 1 2 3 7 8 9 10 12 13; do + test$t + done;; + hash) + for t in 1 2 3 8 13 20; do + test$t + done;; + recno) + for t in 1 2 3 4 5 6 7 10 11; do + test$t + done;; + *) + echo "run.test: unknown test $1" + echo "usage: run.test test# | type" + exit 1 + esac + shift + done + fi rm -f $TMP1 $TMP2 $TMP3 exit 0 } @@ -35,21 +53,25 @@ main() # be key/data pairs. test1() { - printf "Test 1: btree, hash: small key, small data pairs\n" + echo "Test 1: btree, hash: small key, small data pairs" sed 200q $DICT > $TMP1 for type in btree hash; do rm -f $TMP2 $TMP3 for i in `sed 200q $DICT`; do - printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i + echo p + echo k$i + echo d$i + echo g + echo k$i done > $TMP2 $PROG -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test1: type %s: failed\n" $type + echo "test1: type $type: failed" exit 1 fi done - printf "Test 1: recno: small key, small data pairs\n" + echo "Test 1: recno: small key, small data pairs" rm -f $TMP2 $TMP3 sed 200q $DICT | awk '{ @@ -59,7 +81,7 @@ test1() $PROG -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test1: type recno: failed\n" + echo "test1: type recno: failed" exit 1 fi } @@ -68,23 +90,27 @@ test1() # each a medium size data entry. test2() { - printf "Test 2: btree, hash: small key, medium data pairs\n" + echo "Test 2: btree, hash: small key, medium data pairs" mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz echo $mdata | awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1 for type in hash btree; do rm -f $TMP2 $TMP3 for i in `sed 200q $DICT`; do - printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i + echo p + echo k$i + echo d$mdata + echo g + echo k$i done > $TMP2 $PROG -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test2: type %s: failed\n" $type + echo "test2: type $type: failed" exit 1 fi done - printf "Test 2: recno: small key, medium data pairs\n" + echo "Test 2: recno: small key, medium data pairs" rm -f $TMP2 $TMP3 echo $mdata | awk '{ for (i = 1; i < 201; ++i) @@ -93,7 +119,7 @@ test2() $PROG -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test2: type recno: failed\n" + echo "test2: type recno: failed" exit 1 fi } @@ -101,40 +127,46 @@ test2() # Insert the programs in /bin with their paths as their keys. test3() { - printf "Test 3: hash: small key, big data pairs\n" + echo "Test 3: hash: small key, big data pairs" rm -f $TMP1 (find /bin -type f -print | xargs cat) > $TMP1 for type in hash; do rm -f $TMP2 $TMP3 for i in `find /bin -type f -print`; do - printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i + echo p + echo k$i + echo D$i + echo g + echo k$i done > $TMP2 $PROG -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test3: %s: page size %d: failed\n" \ - $type $psize + echo "test3: $type: failed" exit 1 fi done - printf "Test 3: btree: small key, big data pairs\n" + echo "Test 3: btree: small key, big data pairs" for psize in 512 16384 65536; do - printf "\tpage size %d\n" $psize + echo " page size $psize" for type in btree; do rm -f $TMP2 $TMP3 for i in `find /bin -type f -print`; do - printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i + echo p + echo k$i + echo D$i + echo g + echo k$i done > $TMP2 $PROG -i psize=$psize -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test3: %s: page size %d: failed\n" \ - $type $psize + echo "test3: $type: page size $psize: failed" exit 1 fi done done - printf "Test 3: recno: big data pairs\n" + echo "Test 3: recno: big data pairs" rm -f $TMP2 $TMP3 find /bin -type f -print | awk '{ @@ -142,11 +174,11 @@ test3() printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); }' > $TMP2 for psize in 512 16384 65536; do - printf "\tpage size %d\n" $psize + echo " page size $psize" $PROG -i psize=$psize -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test3: recno: page size %d: failed\n" $psize + echo "test3: recno: page size $psize: failed" exit 1 fi done @@ -155,18 +187,33 @@ test3() # Do random recno entries. test4() { - printf "Test 4: recno: random entries\n" + echo "Test 4: recno: random entries" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk '{ - for (i = 37; i <= 37 + 88 * 17; i += 17) - printf("input key %d: %.*s\n", i, i % 41, $0); - for (i = 1; i <= 15; ++i) - printf("input key %d: %.*s\n", i, i % 41, $0); - for (i = 19234; i <= 19234 + 61 * 27; i += 27) - printf("input key %d: %.*s\n", i, i % 41, $0); + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } exit }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 cat $TMP1 | awk 'BEGIN { i = 37; @@ -196,7 +243,7 @@ test4() $PROG -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test4: type recno: failed\n" + echo "test4: type recno: failed" exit 1 fi } @@ -204,14 +251,19 @@ test4() # Do reverse order recno entries. test5() { - printf "Test 5: recno: reverse order entries\n" + echo "Test 5: recno: reverse order entries" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk ' { - for (i = 1500; i; --i) - printf("input key %d: %.*s\n", i, i % 34, $0); + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 cat $TMP1 | awk 'BEGIN { i = 1500; @@ -227,7 +279,7 @@ test5() $PROG -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test5: type recno: failed\n" + echo "test5: type recno: failed" exit 1 fi } @@ -235,16 +287,26 @@ test5() # Do alternating order recno entries. test6() { - printf "Test 6: recno: alternating order entries\n" + echo "Test 6: recno: alternating order entries" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk ' { - for (i = 1; i < 1200; i += 2) - printf("input key %d: %.*s\n", i, i % 34, $0); - for (i = 2; i < 1200; i += 2) - printf("input key %d: %.*s\n", i, i % 34, $0); + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 cat $TMP1 | awk 'BEGIN { i = 1; @@ -269,7 +331,7 @@ test6() sort -o $TMP3 $TMP3 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test6: type recno: failed\n" + echo "test6: type recno: failed" exit 1 fi } @@ -277,7 +339,7 @@ test6() # Delete cursor record test7() { - printf "Test 7: btree, recno: delete cursor record\n" + echo "Test 7: btree, recno: delete cursor record" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk '{ for (i = 1; i <= 120; ++i) @@ -288,7 +350,7 @@ test7() printf("%05d: input key %d: %s\n", 2, 2, $0); exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 for type in btree recno; do cat $TMP1 | @@ -311,7 +373,7 @@ test7() $PROG -o $TMP3 recno $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test7: type $type: failed\n" + echo "test7: type $type: failed" exit 1 fi done @@ -320,8 +382,9 @@ test7() # Make sure that overflow pages are reused. test8() { - printf "Test 8: btree, hash: repeated small key, big data pairs\n" + echo "Test 8: btree, hash: repeated small key, big data pairs" rm -f $TMP1 + echo "" | awk 'BEGIN { for (i = 1; i <= 10; ++i) { printf("p\nkkey1\nD/bin/sh\n"); @@ -338,21 +401,21 @@ test8() printf("eend of test8 run\n"); }' > $TMP1 $PROG btree $TMP1 - $PROG hash $TMP1 +# $PROG hash $TMP1 # No explicit test for success. } # Test btree duplicate keys test9() { - printf "Test 9: btree: duplicate keys\n" + echo "Test 9: btree: duplicate keys" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk '{ for (i = 1; i <= 543; ++i) printf("%05d: input key %d: %s\n", i, i, $0); exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 for type in btree; do cat $TMP1 | @@ -369,7 +432,7 @@ test9() sort -o $TMP3 $TMP3 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test9: type $type: failed\n" + echo "test9: type $type: failed" exit 1 fi done @@ -378,14 +441,14 @@ test9() # Test use of cursor flags without initialization test10() { - printf "Test 10: btree, recno: test cursor flag use\n" + echo "Test 10: btree, recno: test cursor flag use" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk '{ for (i = 1; i <= 20; ++i) printf("%05d: input key %d: %s\n", i, i, $0); exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 # Test that R_CURSOR doesn't succeed before cursor initialized for type in btree recno; do @@ -401,7 +464,7 @@ test10() }' > $TMP2 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 if [ -s $TMP3 ] ; then - printf "Test 10: delete: R_CURSOR SHOULD HAVE FAILED\n" + echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED" exit 1 fi done @@ -418,7 +481,7 @@ test10() }' > $TMP2 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 if [ -s $TMP3 ] ; then - printf "Test 10: put: R_CURSOR SHOULD HAVE FAILED\n" + echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED" exit 1 fi done @@ -427,14 +490,14 @@ test10() # Test insert in reverse order. test11() { - printf "Test 11: recno: reverse order insert\n" + echo "Test 11: recno: reverse order insert" echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | awk '{ for (i = 1; i <= 779; ++i) printf("%05d: input key %d: %s\n", i, i, $0); exit; }' > $TMP1 - rm -f TMP2 $TMP3 + rm -f $TMP2 $TMP3 for type in recno; do cat $TMP1 | @@ -452,7 +515,7 @@ test11() $PROG -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test11: type $type: failed\n" + echo "test11: type $type: failed" exit 1 fi done @@ -463,19 +526,23 @@ test11() # the btree split code gets hammered. test12() { - printf "Test 12: btree: lots of keys, small page size\n" + echo "Test 12: btree: lots of keys, small page size" mdata=abcdefghijklmnopqrstuvwxy echo $mdata | awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1 for type in btree; do rm -f $TMP2 $TMP3 for i in `sed 20000q $DICT | rev`; do - printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i + echo p + echo k$i + echo d$mdata + echo g + echo k$i done > $TMP2 $PROG -i psize=512 -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test12: type %s: failed\n" $type + echo "test12: type $type: failed" exit 1 fi done @@ -484,27 +551,32 @@ test12() # Test different byte orders. test13() { - printf "Test 13: btree, hash: differing byte orders\n" + echo "Test 13: btree, hash: differing byte orders" sed 50q $DICT > $TMP1 for order in 1234 4321; do for type in btree hash; do rm -f byte.file $TMP2 $TMP3 for i in `sed 50q $DICT`; do - printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i + echo p + echo k$i + echo d$i + echo g + echo k$i done > $TMP2 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test13: %s/%s put failed\n" $type $order + echo "test13: $type/$order put failed" exit 1 fi for i in `sed 50q $DICT`; do - printf "g\nk%s\n" $i + echo g + echo k$i done > $TMP2 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test13: %s/%s get failed\n" $type $order + echo "test13: $type/$order get failed" exit 1 fi done @@ -515,18 +587,29 @@ test13() # Try a variety of bucketsizes and fill factors for hashing test20() { - printf\ - "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536\n" - awk 'BEGIN { - for (i = 1; i <= 10000; ++i) - printf("%.*s\n", i % 34, - "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"); + echo\ + "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; }' > $TMP1 sed 10000q $DICT | - awk '{ - ++i; - printf("p\nk%s\nd%.*s\n", $0, i % 34, - "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"); + awk 'BEGIN { + ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); }' > $TMP2 sed 10000q $DICT | awk '{ @@ -535,82 +618,82 @@ test20() }' >> $TMP2 bsize=256 for ffactor in 11 14 21; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done bsize=512 for ffactor in 21 28 43; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done bsize=1024 for ffactor in 43 57 85; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done bsize=2048 for ffactor in 85 114 171; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done bsize=4096 for ffactor in 171 228 341; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done bsize=8192 for ffactor in 341 455 683; do - printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor + echo " bucketsize $bsize, fill factor $ffactor" $PROG -o$TMP3 \ -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ hash $TMP2 if (cmp -s $TMP1 $TMP3) ; then : else - printf "test20: type hash:\ -bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n" + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" exit 1 fi done } -main +main $* diff --git a/lib/libc/db/test/strerror.c b/lib/libc/db/test/strerror.c new file mode 100644 index 000000000000..53f374bdf796 --- /dev/null +++ b/lib/libc/db/test/strerror.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <string.h> + +char * +strerror(num) + int num; +{ + extern int sys_nerr; + extern char *sys_errlist[]; +#define UPREFIX "Unknown error: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + register unsigned int errnum; + register char *p, *t; + char tmp[40]; + + errnum = num; /* convert to unsigned */ + if (errnum < sys_nerr) + return(sys_errlist[errnum]); + + /* Do this by hand, so we don't include stdio(3). */ + t = tmp; + do { + *t++ = "0123456789"[errnum % 10]; + } while (errnum /= 10); + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + return(ebuf); +} diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index f7d472e667e4..0f0a66405d13 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -1,23 +1,22 @@ # @(#)Makefile.inc 5.21 (Berkeley) 5/24/91 # gen sources -.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen ${.CURDIR}/gen/regexp +.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctime.c ctype_.c \ directory.c difftime.c disklabel.c err.c errlst.c exec.c \ fnmatch.c frexp.c fstab.c fts.c getcap.c getcwd.c getgrent.c \ getlogin.c getmntinfo.c getpass.c getpwent.c getsubopt.c getttyent.c \ getusershell.c glob.c infinity.c initgroups.c insque.c isatty.c \ - isctype.c isinf.c mktemp.c nice.c nlist.c pause.c popen.c psignal.c \ - raise.c setjmperr.c setmode.c setrgid.c setruid.c \ + isctype.c isinf.c mktemp.c msgctl.c msgget.c msgsnd.c msgrcv.c \ + nice.c nlist.c pause.c popen.c psignal.c raise.c scandir.c \ + semconfig.c semctl.c semget.c semop.c \ + setjmperr.c setmode.c setrgid.c setruid.c \ shmat.c shmctl.c shmdt.c shmget.c \ - siginterrupt.c \ - scandir.c siglist.c signal.c sigsetops.c sleep.c syslog.c termios.c \ - time.c times.c timezone.c ttyname.c ttyslot.c ualarm.c unvis.c \ - usleep.c utime.c valloc.c vis.c wait.c wait3.c waitpid.c - -# gen/regexp sources -SRCS+= regerror.c regexp.c regsub.c + siginterrupt.c siglist.c signal.c sigsetops.c sleep.c syslog.c \ + termios.c time.c times.c timezone.c ttyname.c ttyslot.c \ + ualarm.c unvis.c usleep.c utime.c valloc.c vis.c \ + wait.c wait3.c waitpid.c .if (${MACHINE} == "hp300") SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s @@ -27,8 +26,8 @@ SRCS+= adddf3.s addsf3.s ashlsi3.s ashrsi3.s cmpdf2.s cmpsf2.s divdf3.s \ negdf2.s negsf2.s saveregs.c subdf3.s subsf3.s truncdfsf2.s udivsi3.s \ umodsi3.s umulsi3.s .elif (${MACHINE} == "i386") -SRCS+= _setjmp.s alloca.s fabs.s ldexp.c modf.s setjmp.s sigsetjmp.s -SRCS+= divsi3.s fixdfsi.s fixunsdfsi.s udivsi3.s +SRCS+= _setjmp.S alloca.S fabs.S ldexp.c modf.S setjmp.S sigsetjmp.S +SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S .elif (${MACHINE} == "tahoe") CFLAGS+=-I/sys SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s @@ -48,14 +47,14 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/crypt.3 gen/ctermid.3 gen/ctime.3 \ gen/islower.3 gen/isprint.3 gen/ispunct.3 gen/isspace.3 \ gen/isupper.3 gen/isxdigit.3 gen/ldexp.3 gen/modf.3 gen/nice.3 \ gen/nlist.3 gen/pause.3 gen/popen.3 gen/psignal.3 gen/raise.3 \ - gen/regexp.3 gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \ + gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \ gen/siginterrupt.3 gen/signal.3 gen/sigsetops.3 gen/sleep.3 \ - gen/syslog.3 gen/tcsendbreak.3 gen/time.3 gen/times.3 \ - gen/timezone.3 gen/tolower.3 gen/toupper.3 gen/ttyname.3 \ - gen/tzset.3 gen/ualarm.3 gen/unvis.3 gen/usleep.3 gen/utime.3 \ - gen/valloc.3 gen/vis.3 + gen/syslog.3 gen/tcgetpgrp.3 gen/tcsendbreak.3 gen/tcsetattr.3 \ + gen/tcsetpgrp.3 gen/time.3 gen/times.3 gen/timezone.3 gen/tolower.3 \ + gen/toupper.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 gen/unvis.3 \ + gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3 -MLINKS= crypt.3 encrypt.3 crypt.3 setkey.3 +MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \ ctime.3 localtime.3 ctime.3 mktime.3 MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ @@ -83,8 +82,6 @@ MLINKS+=insque.3 remque.3 MLINKS+=isinf.3 isnan.3 MLINKS+=popen.3 pclose.3 MLINKS+=psignal.3 sys_siglist.3 -MLINKS+=regexp.3 regcomp.3 regexp.3 regexec.3 regexp.3 regsub.3 \ - regexp.3 regerror.3 MLINKS+=scandir.3 alphasort.3 MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \ setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3 setjmp.3 longjmperror.3 @@ -97,8 +94,10 @@ MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \ MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \ syslog.3 vsyslog.3 MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflush.3 tcsendbreak.3 tcflow.3 - - +MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfsetispeed.3 \ + tcsetattr.3 cfgetospeed.3 tcsetattr.3 cfsetospeed.3 \ + tcsetattr.3 cfsetspeed.3 tcsetattr.3 cfmakeraw.3 \ + tcsetattr.3 tcgetattr.3 MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3 MLINKS+=tzset.3 tzsetwall.3 diff --git a/lib/libc/gen/alarm.3 b/lib/libc/gen/alarm.3 index c34abc21e6af..63c338ebac1c 100644 --- a/lib/libc/gen/alarm.3 +++ b/lib/libc/gen/alarm.3 @@ -56,7 +56,7 @@ before asserting the terminating signal When the signal has successfully been caught, .Fn alarm returns the amount of time left on the clock. -The maximum mumber of +The maximum number of .Ar seconds allowed is 2147483647. @@ -65,7 +65,7 @@ If an alarm has been set with .Fn alarm , another call to .Fn alarm -will superceed the prior call. +will supercede the prior call. The request .Fn alarm "0" voids the current diff --git a/lib/libc/gen/crypt.c b/lib/libc/gen/crypt.c index be5d6873fe48..e0a96988ac01 100644 --- a/lib/libc/gen/crypt.c +++ b/lib/libc/gen/crypt.c @@ -36,7 +36,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /* from static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 6/25/91"; */ -static char rcsid[] = "$Header: /a/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $"; +static char rcsid[] = "$Header: /home/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $"; #endif /* LIBC_SCCS and not lint */ #include <unistd.h> diff --git a/lib/libc/gen/ctype_.c b/lib/libc/gen/ctype_.c index b6f83051411e..d361c1617cea 100644 --- a/lib/libc/gen/ctype_.c +++ b/lib/libc/gen/ctype_.c @@ -1,4 +1,13 @@ /* + * Copyright (c) UNIX System Laboratories, Inc. All or some portions + * of this file are derived from material licensed to the + * University of California by American Telephone and Telegraph Co. + * or UNIX System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * $Id: ctype_.c,v 1.1.1.1.2.1 1994/05/04 07:39:42 rgrimes Exp $ + */ +/* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3 index cae5ea3dda56..6b5ea9d88301 100644 --- a/lib/libc/gen/directory.3 +++ b/lib/libc/gen/directory.3 @@ -48,7 +48,7 @@ .Fd #include <dirent.h> .Ft DIR * .Fn opendir "const char *filename" -.Ft struct direct +.Ft struct dirent * .Fn readdir "DIR *dirp" .Ft long .Fn telldir "const DIR *dirp" diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3 index 44ca0942c1b3..2a3f4c391fd3 100644 --- a/lib/libc/gen/err.3 +++ b/lib/libc/gen/err.3 @@ -1,5 +1,5 @@ -.\" Copyright (c) 1993 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)err.3 5.2 (Berkeley) 3/19/93 +.\" @(#)err.3 8.1 (Berkeley) 6/9/93 .\" -.Dd "March 19, 1993" +.Dd "June 9, 1993" .Dt ERR 3 .Os BSD 4 .Sh NAME @@ -125,5 +125,4 @@ The .Fn err and .Fn warn -functions are -.Ud . +functions first appeared in 4.4BSD. diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3 index 2d967d2d1bd0..d3d3ccaa3b6e 100644 --- a/lib/libc/gen/fnmatch.3 +++ b/lib/libc/gen/fnmatch.3 @@ -1,5 +1,5 @@ -.\" Copyright (c) 1989, 1991 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Guido van Rossum. @@ -31,9 +31,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)fnmatch.3 5.4 (Berkeley) 6/28/92 +.\" from: @(#)fnmatch.3 8.1 (Berkeley) 6/9/93 +.\" $Id: fnmatch.3,v 1.3 1993/11/23 00:10:08 jtc Exp $ .\" -.Dd June 28, 1992 +.Dd June 9, 1993 .Dt FNMATCH 3 .Os .Sh NAME @@ -94,7 +95,6 @@ Additionally, if .Dv FNM_PATHNAME is set, a period is ``leading'' if it immediately follows a slash. -.Em "This flag is not currently implemented." .El .Sh RETURN VALUES The @@ -110,19 +110,16 @@ otherwise, it returns the value .Xr glob 3 , .Xr wordexp 3 , .Xr regexp 3 +.Sh STANDARDS +The +.Fn fnmatch +function is expected to conform to +.St -p1003.2-92 . .Sh HISTORY The .Fn fnmatch -function is -.Ud . +function first appeared in 4.4BSD. .Sh BUGS -Quotes and slashes in range patterns are not handled correctly by -this implementation. -.Pp -The -.Dv FNM_PERIOD -flag is not implemented. -.Pp The pattern .Ql * matches the empty string, even if diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 7b54c3b7254a..9d64cf5573ad 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. @@ -35,11 +35,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92"; +/* from: static char sccsid[] = "@(#)fnmatch.c 8.1 (Berkeley) 6/4/93"; */ +static char *rcsid = "$Id: fnmatch.c,v 1.3 1993/11/23 00:10:09 jtc Exp $"; #endif /* LIBC_SCCS and not lint */ /* - * Function fnmatch() as proposed in POSIX 1003.2 B.6 (D11.2). + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ @@ -48,12 +49,14 @@ static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92"; #define EOS '\0' -static const char *rangematch __P((const char *, int)); +static const char *rangematch __P((const char *, int, int)); +int fnmatch(pattern, string, flags) register const char *pattern, *string; int flags; { + const char *stringstart = string; register char c; char test; @@ -62,9 +65,14 @@ fnmatch(pattern, string, flags) case EOS: return (*string == EOS ? 0 : FNM_NOMATCH); case '?': - if ((test = *string++) == EOS || - test == '/' && flags & FNM_PATHNAME) + if (*string == EOS) return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; break; case '*': c = *pattern; @@ -72,6 +80,10 @@ fnmatch(pattern, string, flags) while (c == '*') c = *++pattern; + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + /* Optimize for pattern with * at end or before /. */ if (c == EOS) if (flags & FNM_PATHNAME) @@ -87,7 +99,7 @@ fnmatch(pattern, string, flags) /* General case, use recursion. */ while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags)) + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) return (0); if (test == '/' && flags & FNM_PATHNAME) break; @@ -95,11 +107,13 @@ fnmatch(pattern, string, flags) } return (FNM_NOMATCH); case '[': - if ((test = *string++) == EOS || - test == '/' && flags & FNM_PATHNAME) + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && flags & FNM_PATHNAME) return (FNM_NOMATCH); - if ((pattern = rangematch(pattern, test)) == NULL) + if ((pattern = rangematch(pattern, *string, flags)) == NULL) return (FNM_NOMATCH); + ++string; break; case '\\': if (!(flags & FNM_NOESCAPE)) { @@ -107,9 +121,6 @@ fnmatch(pattern, string, flags) c = '\\'; --pattern; } - if (c != *string++) - return (FNM_NOMATCH); - break; } /* FALLTHROUGH */ default: @@ -121,30 +132,48 @@ fnmatch(pattern, string, flags) } static const char * -rangematch(pattern, test) +rangematch(pattern, test, flags) register const char *pattern; register int test; + int flags; { register char c, c2; int negate, ok; - if (negate = (*pattern == '!')) - ++pattern; - - /* - * XXX - * TO DO: quoting + /* A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). I have chosen to treat it like '!', for + * consistancy with regular expression syntax. */ + if (negate = (*pattern == '!' || *pattern == '^')) { + pattern++; + } + for (ok = 0; (c = *pattern++) != ']';) { - if (c == EOS) - return (NULL); /* Illegal pattern. */ - if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') { - if (c <= test && test <= c2) - ok = 1; - pattern += 2; + if (c == '\\' && !(flags & FNM_NOESCAPE)) { + c = *pattern++; + } + if (c == EOS) { + return (NULL); } - else if (c == test) + + if (*pattern == '-' + && (c2 = *(pattern+1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) { + c2 = *pattern++; + } + if (c2 == EOS) { + return (NULL); + } + + if (c <= test && test <= c2) { + ok = 1; + } + } else if (c == test) { ok = 1; + } } + return (ok == negate ? NULL : pattern); } diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3 index 4af162f1af62..d18b3797bc7e 100644 --- a/lib/libc/gen/getcap.3 +++ b/lib/libc/gen/getcap.3 @@ -32,7 +32,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getcap.3 5.4 (Berkeley) 8/11/92 +.\" from: @(#)getcap.3 5.4 (Berkeley) 8/11/92 +.\" $Id: getcap.3,v 1.1.2.1 1994/05/01 16:05:00 jkh Exp $ .\" .Dd "August 11, 1992" .Dt GETCAP 3 @@ -236,7 +237,7 @@ Upon completion of the database 0 is returned, 1 is returned upon successful return of record with possibly more remaining (we haven't reached the end of the database yet), 2 is returned if the record contains an unresolved .Nm tc -expansion, \-1 is returned if an system error occured, and \-2 +expansion, \-1 is returned if an system error occurred, and \-2 is returned if a potential reference loop is detected (see .Ic tc= comments below). diff --git a/lib/libc/gen/getgrent.3 b/lib/libc/gen/getgrent.3 index 45d3bced27ab..fd2e2e194e76 100644 --- a/lib/libc/gen/getgrent.3 +++ b/lib/libc/gen/getgrent.3 @@ -96,7 +96,7 @@ function sequentially reads the group database and is intended for programs that wish to step through the complete list of groups. .Pp -All three routines will open the group file for reading, if necesssary. +All three routines will open the group file for reading, if necessary. .Pp The .Fn setgroupent diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index 60593c2831fd..18f7079eff30 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -32,13 +32,20 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getgrent.c 5.9 (Berkeley) 4/1/91"; +/* static char *sccsid = "from: @(#)getgrent.c 5.9 (Berkeley) 4/1/91"; */ +static char *rcsid = "$Id: getgrent.c,v 1.3 1994/01/11 19:00:57 nate Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <grp.h> +#ifdef YP +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#endif static FILE *_gr_fp; static struct group _gr_group; @@ -50,6 +57,11 @@ static char *members[MAXGRP]; #define MAXLINELENGTH 1024 static char line[MAXLINELENGTH]; +#ifdef YP +static char *__ypcurrent, *__ypdomain; +static int __ypcurrentlen, __ypmode=0; +#endif + struct group * getgrent() { @@ -90,7 +102,7 @@ getgrgid(gid) return(rval ? &_gr_group : NULL); } -static +static int start_gr() { if (_gr_fp) { @@ -100,10 +112,10 @@ start_gr() return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0); } -int +void setgrent() { - return(setgroupent(0)); + (void) setgroupent(0); } int @@ -125,27 +137,88 @@ endgrent() } } -static +static int grscan(search, gid, name) register int search, gid; register char *name; { register char *cp, **m; char *bp; - char *fgets(), *strsep(), *index(); for (;;) { +#ifdef YP + if(__ypmode) { + char *key, *data; + int keylen, datalen; + int r; + + if(!__ypdomain) { + if(yp_get_default_domain(&__ypdomain)) { + __ypmode = 0; + continue; + } + } + if(__ypcurrent) { + r = yp_next(__ypdomain, "group.byname", + __ypcurrent, __ypcurrentlen, + &key, &keylen, &data, &datalen); + free(__ypcurrent); + /*printf("yp_next %d\n", r);*/ + switch(r) { + case 0: + break; + default: + __ypcurrent = NULL; + __ypmode = 0; + free(data); + continue; + } + __ypcurrent = key; + __ypcurrentlen = keylen; + bcopy(data, line, datalen); + free(data); + } else { + r = yp_first(__ypdomain, "group.byname", + &__ypcurrent, &__ypcurrentlen, + &data, &datalen); + /*printf("yp_first %d\n", r);*/ + switch(r) { + case 0: + break; + default: + __ypmode = 0; + free(data); + continue; + } + bcopy(data, line, datalen); + free(data); + } + line[datalen] = '\0'; + /*printf("line = %s\n", line);*/ + bp = line; + goto parse; + } +#endif if (!fgets(line, sizeof(line), _gr_fp)) return(0); bp = line; /* skip lines that are too big */ - if (!index(line, '\n')) { + if (!strchr(line, '\n')) { int ch; while ((ch = getc(_gr_fp)) != '\n' && ch != EOF) ; continue; } +#ifdef YP + if ((strcmp("+\n", line) == 0) || (strncmp("+:*:0:", line, 5) == 0)) { + if(_yp_check(NULL)) { + __ypmode = 1; + continue; + } + } +parse: +#endif _gr_group.gr_name = strsep(&bp, ":\n"); if (search && name && strcmp(_gr_group.gr_name, name)) continue; diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index fe1b19cc2563..93a09ee52ff6 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91"; +/*static char *sccsid = "from: @(#)getpwent.c 5.21 (Berkeley) 3/14/91";*/ +static char *rcsid = "$Id: getpwent.c,v 1.4 1994/01/11 19:00:58 nate Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -46,6 +47,12 @@ static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91"; #include <stdlib.h> #include <string.h> #include <limits.h> +#ifdef YP +#include <stdio.h> +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#endif static struct passwd _pw_passwd; /* password structure */ static DB *_pw_db; /* password database */ @@ -53,21 +60,142 @@ static int _pw_keynum; /* key counter */ static int _pw_stayopen; /* keep fd's open */ static int __hashpw(), __initdb(); +#ifdef YP +static char *__ypcurrent, *__ypdomain; +static int __ypcurrentlen, __ypmode=0; +static char line[1024]; + +static int +__ypparse(pw, s) +struct passwd *pw; +char *s; +{ + char *bp, *cp; + + bp = s; + pw->pw_name = strsep(&bp, ":\n"); + pw->pw_passwd = strsep(&bp, ":\n"); + if (!(cp = strsep(&bp, ":\n"))) + return 1; + pw->pw_uid = atoi(cp); + if (!(cp = strsep(&bp, ":\n"))) + return 0; + pw->pw_gid = atoi(cp); + pw->pw_change = 0; + pw->pw_class = ""; + pw->pw_gecos = strsep(&bp, ":\n"); + pw->pw_dir = strsep(&bp, ":\n"); + pw->pw_shell = strsep(&bp, ":\n"); + pw->pw_expire = 0; + return 0; +} +#endif + struct passwd * getpwent() { DBT key; char bf[sizeof(_pw_keynum) + 1]; +#ifdef YP + char *bp, *cp; +#endif if (!_pw_db && !__initdb()) return((struct passwd *)NULL); +#ifdef YP +again: + if(__ypmode) { + char *key, *data; + int keylen, datalen; + int r; + + if(!__ypdomain) { + if( _yp_check(&__ypdomain) == 0) { + __ypmode = 0; + goto again; + } + } + if(__ypcurrent) { + r = yp_next(__ypdomain, "passwd.byname", + __ypcurrent, __ypcurrentlen, + &key, &keylen, &data, &datalen); + free(__ypcurrent); + __ypcurrent = NULL; + /*printf("yp_next %d\n", r);*/ + switch(r) { + case 0: + break; + default: + __ypcurrent = NULL; + __ypmode = 0; + free(data); + data = NULL; + goto again; + } + __ypcurrent = key; + __ypcurrentlen = keylen; + bcopy(data, line, datalen); + free(data); + data = NULL; + } else { + r = yp_first(__ypdomain, "passwd.byname", + &__ypcurrent, &__ypcurrentlen, + &data, &datalen); + /*printf("yp_first %d\n", r);*/ + switch(r) { + case 0: + break; + default: + __ypmode = 0; + free(data); + goto again; + } + bcopy(data, line, datalen); + free(data); + data = NULL; + } + line[datalen] = '\0'; + /*printf("line = %s\n", line);*/ + bp = line; + goto parse; + } +#endif + ++_pw_keynum; bf[0] = _PW_KEYBYNUM; bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); key.data = (u_char *)bf; key.size = sizeof(_pw_keynum) + 1; - return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL); + if(__hashpw(&key)) { +#ifdef YP + if(strcmp(_pw_passwd.pw_name, "+") == 0) { + __ypmode = 1; + goto again; + } +#endif + return &_pw_passwd; + } + return (struct passwd *)NULL; + +#ifdef YP +parse: + _pw_passwd.pw_name = strsep(&bp, ":\n"); + _pw_passwd.pw_passwd = strsep(&bp, ":\n"); + if (!(cp = strsep(&bp, ":\n"))) + goto again; + _pw_passwd.pw_uid = atoi(cp); + if (!(cp = strsep(&bp, ":\n"))) + goto again; + _pw_passwd.pw_gid = atoi(cp); + _pw_passwd.pw_change = 0; + _pw_passwd.pw_class = ""; + _pw_passwd.pw_gecos = strsep(&bp, ":\n"); + _pw_passwd.pw_dir = strsep(&bp, ":\n"); + _pw_passwd.pw_shell = strsep(&bp, ":\n"); + _pw_passwd.pw_expire = 0; + return &_pw_passwd; +#endif } struct passwd * @@ -81,6 +209,70 @@ getpwnam(name) if (!_pw_db && !__initdb()) return((struct passwd *)NULL); +#ifdef YP + bf[0] = _PW_KEYBYNAME; + len = strlen("+"); + bcopy("+", bf + 1, MIN(len, UT_NAMESIZE)); + key.data = (u_char *)bf; + key.size = len + 1; + + /* + * If there is a user called "+", then YP is active. In that + * case we must sequence through the passwd file in sequence. + */ + if ( __hashpw(&key)) { + int r; + + for(_pw_keynum=1; _pw_keynum; _pw_keynum++) { + bf[0] = _PW_KEYBYNUM; + bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); + key.data = (u_char *)bf; + key.size = sizeof(_pw_keynum) + 1; + if(__hashpw(&key) == 0) + break; + if(strcmp(_pw_passwd.pw_name, "+") == 0) { + if(!__ypdomain) { + if(_yp_check(&__ypdomain) == 0) { + continue; + } + } + if(__ypcurrent) { + free(__ypcurrent); + __ypcurrent = NULL; + } + r = yp_match(__ypdomain, "passwd.byname", + name, strlen(name), + &__ypcurrent, &__ypcurrentlen); + switch(r) { + case 0: + break; + default: + free(__ypcurrent); + __ypcurrent = NULL; + continue; + } + bcopy(__ypcurrent, line, __ypcurrentlen); + line[__ypcurrentlen] = '\0'; + if(__ypparse(&_pw_passwd, line)) + continue; + } + if( strcmp(_pw_passwd.pw_name, name) == 0) { + if (!_pw_stayopen) { + (void)(_pw_db->close)(_pw_db); + _pw_db = (DB *)NULL; + } + return &_pw_passwd; + } + continue; + } + if (!_pw_stayopen) { + (void)(_pw_db->close)(_pw_db); + _pw_db = (DB *)NULL; + } + return (struct passwd *)NULL; + } +#endif /* YP */ + bf[0] = _PW_KEYBYNAME; len = strlen(name); bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); @@ -104,12 +296,78 @@ getpwuid(uid) #endif { DBT key; - int keyuid, rval; - char bf[sizeof(keyuid) + 1]; + char bf[sizeof(_pw_keynum) + 1]; + int keyuid, rval, len; if (!_pw_db && !__initdb()) return((struct passwd *)NULL); +#ifdef YP + bf[0] = _PW_KEYBYNAME; + len = strlen("+"); + bcopy("+", bf + 1, MIN(len, UT_NAMESIZE)); + key.data = (u_char *)bf; + key.size = len + 1; + + /* + * If there is a user called "+", then YP is active. In that + * case we must sequence through the passwd file in sequence. + */ + if ( __hashpw(&key)) { + char uidbuf[20]; + int r; + + for(_pw_keynum=1; _pw_keynum; _pw_keynum++) { + bf[0] = _PW_KEYBYNUM; + bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); + key.data = (u_char *)bf; + key.size = sizeof(_pw_keynum) + 1; + if(__hashpw(&key) == 0) + break; + if(strcmp(_pw_passwd.pw_name, "+") == 0) { + if(!__ypdomain) { + if(_yp_check(&__ypdomain) == 0) { + continue; + } + } + if(__ypcurrent) { + free(__ypcurrent); + __ypcurrent = NULL; + } + sprintf(uidbuf, "%d", uid); + r = yp_match(__ypdomain, "passwd.byuid", + uidbuf, strlen(uidbuf), + &__ypcurrent, &__ypcurrentlen); + switch(r) { + case 0: + break; + default: + free(__ypcurrent); + __ypcurrent = NULL; + continue; + } + bcopy(__ypcurrent, line, __ypcurrentlen); + line[__ypcurrentlen] = '\0'; + if(__ypparse(&_pw_passwd, line)) + continue; + } + if( _pw_passwd.pw_uid == uid) { + if (!_pw_stayopen) { + (void)(_pw_db->close)(_pw_db); + _pw_db = (DB *)NULL; + } + return &_pw_passwd; + } + continue; + } + if (!_pw_stayopen) { + (void)(_pw_db->close)(_pw_db); + _pw_db = (DB *)NULL; + } + return (struct passwd *)NULL; + } +#endif /* YP */ + bf[0] = _PW_KEYBYUID; keyuid = uid; bcopy(&keyuid, bf + 1, sizeof(keyuid)); @@ -130,15 +388,19 @@ setpassent(stayopen) { _pw_keynum = 0; _pw_stayopen = stayopen; +#ifdef YP + __ypmode = 0; + if(__ypcurrent) + free(__ypcurrent); + __ypcurrent = NULL; +#endif return(1); } -int +void setpwent() { - _pw_keynum = 0; - _pw_stayopen = 0; - return(1); + (void) setpassent(0); } void @@ -149,9 +411,15 @@ endpwent() (void)(_pw_db->close)(_pw_db); _pw_db = (DB *)NULL; } +#ifdef YP + __ypmode = 0; + if(__ypcurrent) + free(__ypcurrent); + __ypcurrent = NULL; +#endif } -static +static int __initdb() { static int warned; @@ -166,7 +434,7 @@ __initdb() return(0); } -static +static int __hashpw(key) DBT *key; { diff --git a/lib/libc/gen/isctype.c b/lib/libc/gen/isctype.c index e598f1069d12..d8dd5bc33e9f 100644 --- a/lib/libc/gen/isctype.c +++ b/lib/libc/gen/isctype.c @@ -1,4 +1,13 @@ /* + * Copyright (c) UNIX System Laboratories, Inc. All or some portions + * of this file are derived from material licensed to the + * University of California by American Telephone and Telegraph Co. + * or UNIX System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * $Id: isctype.c,v 1.1.1.1.2.1 1994/05/04 07:39:44 rgrimes Exp $ + */ +/* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * @@ -30,12 +39,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE - * -------------------- ----- ---------------------- - * CURRENT PATCH LEVEL: 1 00027 - * -------------------- ----- ---------------------- - * - * 02 Aug 92 Wiljo Heinen Fixed toupper()/tolower() range check */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libc/gen/isupper.3 b/lib/libc/gen/isupper.3 index a9ac34b089a5..22d39e2114fe 100644 --- a/lib/libc/gen/isupper.3 +++ b/lib/libc/gen/isupper.3 @@ -44,7 +44,7 @@ .Sh SYNOPSIS .Fd #include <ctype.h> .Ft int -.Fn supper "int c" +.Fn isupper "int c" .Sh DESCRIPTION The .Fn isupper diff --git a/lib/libc/gen/ldexp.3 b/lib/libc/gen/ldexp.3 index 7b96ef4871fa..9920fc45a2f2 100644 --- a/lib/libc/gen/ldexp.3 +++ b/lib/libc/gen/ldexp.3 @@ -40,7 +40,7 @@ .Os .Sh NAME .Nm ldexp -.Nd mutliply floating-point number by integral power of 2 +.Nd multiply floating-point number by integral power of 2 .Sh SYNOPSIS .Fd #include <math.h> .Ft double diff --git a/lib/libc/gen/msgctl.c b/lib/libc/gen/msgctl.c new file mode 100644 index 000000000000..7b74c51e2466 --- /dev/null +++ b/lib/libc/gen/msgctl.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> + +#if __STDC__ +int msgctl(int msqid, int cmd, struct msqid_ds *buf) +#else +int msgctl(msqid,cmd,buf) + int msqid; + int cmd; + caddr_t buf; +#endif +{ + return (msgsys(0, msqid, cmd, buf)); +} diff --git a/lib/libc/gen/msgget.c b/lib/libc/gen/msgget.c new file mode 100644 index 000000000000..3e146b05cbe6 --- /dev/null +++ b/lib/libc/gen/msgget.c @@ -0,0 +1,14 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> + +#if __STDC__ +int msgget(key_t key, int msgflg) +#else +int msgget(key,msgflg) + key_t key; + int msgflg; +#endif +{ + return (msgsys(1, key, msgflg)); +} diff --git a/lib/libc/gen/msgrcv.c b/lib/libc/gen/msgrcv.c new file mode 100644 index 000000000000..5c1e387d1439 --- /dev/null +++ b/lib/libc/gen/msgrcv.c @@ -0,0 +1,17 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> + +#if __STDC__ +int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) +#else +int msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) + int msqid; + void *msgp; + size_t msgsz; + long msgtyp; + int msgflg; +#endif +{ + return (msgsys(3, msqid, msgp, msgsz, msgtyp, msgflg)); +} diff --git a/lib/libc/gen/msgsnd.c b/lib/libc/gen/msgsnd.c new file mode 100644 index 000000000000..a6209159ff50 --- /dev/null +++ b/lib/libc/gen/msgsnd.c @@ -0,0 +1,16 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> + +#if __STDC__ +int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg) +#else +int msgsnd(msqid, msgp, msgsz, msgflg) + int msqid; + void *msgp; + size_t msgsz; + int msgflg; +#endif +{ + return (msgsys(2, msqid, msgp, msgsz, msgflg)); +} diff --git a/lib/libc/gen/nlist.3 b/lib/libc/gen/nlist.3 index 4e4fe24c1c90..4d0bdf302139 100644 --- a/lib/libc/gen/nlist.3 +++ b/lib/libc/gen/nlist.3 @@ -46,7 +46,7 @@ The .Fn nlist function retrieves name list entries from the symbol table of an -exectutable file. (See +executable file. (See .Xr a.out 5 . ) The argument .Fa \&nl diff --git a/lib/libc/gen/regexp.3 b/lib/libc/gen/regexp.3 deleted file mode 100644 index c78082bb8b0d..000000000000 --- a/lib/libc/gen/regexp.3 +++ /dev/null @@ -1,315 +0,0 @@ -.\" Copyright 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. -.\" -.\" @(#)regexp.3 5.2 (Berkeley) 4/19/91 -.\" -.Dd April 19, 1991 -.Dt REGEXP 3 -.Os -.Sh NAME -.Nm regcomp , -.Nm regexec , -.Nm regsub , -.Nm regerror -.Nd regular expression handlers -.Sh SYNOPSIS -.Fd #include <regexp.h> -.Ft regexp * -.Fn regcomp "const char *exp" -.Ft int -.Fn regexec "const regexp *prog" "const char *string" -.Ft void -.Fn regsub "const regexp *prog" "const char *source" "char *dest" -.Sh DESCRIPTION -The -.Fn regcomp , -.Fn regexec , -.Fn regsub , -and -.Fn regerror -functions -implement -.Xr egrep 1 Ns -style -regular expressions and supporting facilities. -.Pp -The -.Fn regcomp -function -compiles a regular expression into a structure of type -.Xr regexp , -and returns a pointer to it. -The space has been allocated using -.Xr malloc 3 -and may be released by -.Xr free . -.Pp -The -.Fn regexec -function -matches a -.Dv NUL Ns -terminated -.Fa string -against the compiled regular expression -in -.Fa prog . -It returns 1 for success and 0 for failure, and adjusts the contents of -.Fa prog Ns 's -.Em startp -and -.Em endp -(see below) accordingly. -.Pp -The members of a -.Xr regexp -structure include at least the following (not necessarily in order): -.Bd -literal -offset indent -char *startp[NSUBEXP]; -char *endp[NSUBEXP]; -.Ed -.Pp -where -.Dv NSUBEXP -is defined (as 10) in the header file. -Once a successful -.Fn regexec -has been done using the -.Fn regexp , -each -.Em startp Ns - Em endp -pair describes one substring -within the -.Fa string , -with the -.Em startp -pointing to the first character of the substring and -the -.Em endp -pointing to the first character following the substring. -The 0th substring is the substring of -.Fa string -that matched the whole -regular expression. -The others are those substrings that matched parenthesized expressions -within the regular expression, with parenthesized expressions numbered -in left-to-right order of their opening parentheses. -.Pp -The -.Fn regsub -function -copies -.Fa source -to -.Fa dest , -making substitutions according to the -most recent -.Fn regexec -performed using -.Fa prog . -Each instance of `&' in -.Fa source -is replaced by the substring -indicated by -.Em startp Ns Bq -and -.Em endp Ns Bq . -Each instance of -.Sq \e Ns Em n , -where -.Em n -is a digit, is replaced by -the substring indicated by -.Em startp Ns Bq Em n -and -.Em endp Ns Bq Em n . -To get a literal `&' or -.Sq \e Ns Em n -into -.Fa dest , -prefix it with `\e'; -to get a literal `\e' preceding `&' or -.Sq \e Ns Em n , -prefix it with -another `\e'. -.Pp -The -.Fn regerror -function -is called whenever an error is detected in -.Fn regcomp , -.Fn regexec , -or -.Fn regsub . -The default -.Fn regerror -writes the string -.Fa msg , -with a suitable indicator of origin, -on the standard -error output -and invokes -.Xr exit 2 . -The -.Fn regerror -function -can be replaced by the user if other actions are desirable. -.Sh REGULAR EXPRESSION SYNTAX -A regular expression is zero or more -.Em branches , -separated by `|'. -It matches anything that matches one of the branches. -.Pp -A branch is zero or more -.Em pieces , -concatenated. -It matches a match for the first, followed by a match for the second, etc. -.Pp -A piece is an -.Em atom -possibly followed by `*', `+', or `?'. -An atom followed by `*' matches a sequence of 0 or more matches of the atom. -An atom followed by `+' matches a sequence of 1 or more matches of the atom. -An atom followed by `?' matches a match of the atom, or the null string. -.Pp -An atom is a regular expression in parentheses (matching a match for the -regular expression), a -.Em range -(see below), `.' -(matching any single character), `^' (matching the null string at the -beginning of the input string), `$' (matching the null string at the -end of the input string), a `\e' followed by a single character (matching -that character), or a single character with no other significance -(matching that character). -.Pp -A -.Em range -is a sequence of characters enclosed in `[]'. -It normally matches any single character from the sequence. -If the sequence begins with `^', -it matches any single character -.Em not -from the rest of the sequence. -If two characters in the sequence are separated by `\-', this is shorthand -for the full list of -.Tn ASCII -characters between them -(e.g. `[0-9]' matches any decimal digit). -To include a literal `]' in the sequence, make it the first character -(following a possible `^'). -To include a literal `\-', make it the first or last character. -.Sh AMBIGUITY -If a regular expression could match two different parts of the input string, -it will match the one which begins earliest. -If both begin in the same place but match different lengths, or match -the same length in different ways, life gets messier, as follows. -.Pp -In general, the possibilities in a list of branches are considered in -left-to-right order, the possibilities for `*', `+', and `?' are -considered longest-first, nested constructs are considered from the -outermost in, and concatenated constructs are considered leftmost-first. -The match that will be chosen is the one that uses the earliest -possibility in the first choice that has to be made. -If there is more than one choice, the next will be made in the same manner -(earliest possibility) subject to the decision on the first choice. -And so forth. -.Pp -For example, -.Sq Li (ab|a)b*c -could match -`abc' in one of two ways. -The first choice is between `ab' and `a'; since `ab' is earlier, and does -lead to a successful overall match, it is chosen. -Since the `b' is already spoken for, -the `b*' must match its last possibility\(emthe empty string\(emsince -it must respect the earlier choice. -.Pp -In the particular case where no `|'s are present and there is only one -`*', `+', or `?', the net effect is that the longest possible -match will be chosen. -So -.Sq Li ab* , -presented with `xabbbby', will match `abbbb'. -Note that if -.Sq Li ab* , -is tried against `xabyabbbz', it -will match `ab' just after `x', due to the begins-earliest rule. -(In effect, the decision on where to start the match is the first choice -to be made, hence subsequent choices must respect it even if this leads them -to less-preferred alternatives.) -.Sh RETURN VALUES -The -.Fn regcomp -function -returns -.Dv NULL -for a failure -.Pf ( Fn regerror -permitting), -where failures are syntax errors, exceeding implementation limits, -or applying `+' or `*' to a possibly-null operand. -.Sh SEE ALSO -.Xr ed 1 , -.Xr ex 1 , -.Xr expr 1 , -.Xr egrep 1 , -.Xr fgrep 1 , -.Xr grep 1 , -.Xr regex 3 -.Sh HISTORY -Both code and manual page for -.Fn regcomp , -.Fn regexec , -.Fn regsub , -and -.Fn regerror -were written at the University of Toronto -and appeared in -.Bx 4.3 tahoe . -They are intended to be compatible with the Bell V8 -.Xr regexp 3 , -but are not derived from Bell code. -.Sh BUGS -Empty branches and empty regular expressions are not portable to V8. -.Pp -The restriction against -applying `*' or `+' to a possibly-null operand is an artifact of the -simplistic implementation. -.Pp -Does not support -.Xr egrep Ns 's -newline-separated branches; -neither does the V8 -.Xr regexp 3 , -though. -.Pp -Due to emphasis on -compactness and simplicity, -it's not strikingly fast. -It does give special attention to handling simple cases quickly. diff --git a/lib/libc/gen/regexp/COPYRIGHT b/lib/libc/gen/regexp/COPYRIGHT deleted file mode 100644 index 48b3f4339171..000000000000 --- a/lib/libc/gen/regexp/COPYRIGHT +++ /dev/null @@ -1,22 +0,0 @@ -This entire subtree is copyright the University of Toronto. -The following copyright notice applies to all files found here. None of -these files contain AT&T proprietary source code. -_____________________________________________________________________________ - - Copyright (c) 1986 by University of Toronto. - Written by Henry Spencer. Not derived from licensed software. - - Permission is granted to anyone to use this software for any - purpose on any computer system, and to redistribute it freely, - subject to the following restrictions: - - 1. The author is not responsible for the consequences of use of - this software, no matter how awful, even if they arise - from defects in it. - - 2. The origin of this software must not be misrepresented, either - by explicit claim or by omission. - - 3. Altered versions must be plainly marked as such, and must not - be misrepresented as being the original software. - diff --git a/lib/libc/gen/regexp/README b/lib/libc/gen/regexp/README deleted file mode 100644 index 37d6f51c7119..000000000000 --- a/lib/libc/gen/regexp/README +++ /dev/null @@ -1,84 +0,0 @@ -This is a nearly-public-domain reimplementation of the V8 regexp(3) package. -It gives C programs the ability to use egrep-style regular expressions, and -does it in a much cleaner fashion than the analogous routines in SysV. - - Copyright (c) 1986 by University of Toronto. - Written by Henry Spencer. Not derived from licensed software. - - Permission is granted to anyone to use this software for any - purpose on any computer system, and to redistribute it freely, - subject to the following restrictions: - - 1. The author is not responsible for the consequences of use of - this software, no matter how awful, even if they arise - from defects in it. - - 2. The origin of this software must not be misrepresented, either - by explicit claim or by omission. - - 3. Altered versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -Barring a couple of small items in the BUGS list, this implementation is -believed 100% compatible with V8. It should even be binary-compatible, -sort of, since the only fields in a "struct regexp" that other people have -any business touching are declared in exactly the same way at the same -location in the struct (the beginning). - -This implementation is *NOT* AT&T/Bell code, and is not derived from licensed -software. Even though U of T is a V8 licensee. This software is based on -a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed -here is a complete rewrite and hence is not covered by AT&T copyright). -The software was nearly complete at the time of arrival of our V8 tape. -I haven't even looked at V8 yet, although a friend elsewhere at U of T has -been kind enough to run a few test programs using the V8 regexp(3) to resolve -a few fine points. I admit to some familiarity with regular-expression -implementations of the past, but the only one that this code traces any -ancestry to is the one published in Kernighan & Plauger (from which this -one draws ideas but not code). - -Simplistically: put this stuff into a source directory, copy regexp.h into -/usr/include, inspect Makefile for compilation options that need changing -to suit your local environment, and then do "make r". This compiles the -regexp(3) functions, compiles a test program, and runs a large set of -regression tests. If there are no complaints, then put regexp.o, regsub.o, -and regerror.o into your C library, and regexp.3 into your manual-pages -directory. - -Note that if you don't put regexp.h into /usr/include *before* compiling, -you'll have to add "-I." to CFLAGS before compiling. - -The files are: - -Makefile instructions to make everything -regexp.3 manual page -regexp.h header file, for /usr/include -regexp.c source for regcomp() and regexec() -regsub.c source for regsub() -regerror.c source for default regerror() -regmagic.h internal header file -try.c source for test program -timer.c source for timing program -tests test list for try and timer - -This implementation uses nondeterministic automata rather than the -deterministic ones found in some other implementations, which makes it -simpler, smaller, and faster at compiling regular expressions, but slower -at executing them. In theory, anyway. This implementation does employ -some special-case optimizations to make the simpler cases (which do make -up the bulk of regular expressions actually used) run quickly. In general, -if you want blazing speed you're in the wrong place. Replacing the insides -of egrep with this stuff is probably a mistake; if you want your own egrep -you're going to have to do a lot more work. But if you want to use regular -expressions a little bit in something else, you're in luck. Note that many -existing text editors use nondeterministic regular-expression implementations, -so you're in good company. - -This stuff should be pretty portable, given appropriate option settings. -If your chars have less than 8 bits, you're going to have to change the -internal representation of the automaton, although knowledge of the details -of this is fairly localized. There are no "reserved" char values except for -NUL, and no special significance is attached to the top bit of chars. -The string(3) functions are used a fair bit, on the grounds that they are -probably faster than coding the operations in line. Some attempts at code -tuning have been made, but this is invariably a bit machine-specific. diff --git a/lib/libc/gen/regexp/regerror.c b/lib/libc/gen/regexp/regerror.c deleted file mode 100644 index 6d0077d63429..000000000000 --- a/lib/libc/gen/regexp/regerror.c +++ /dev/null @@ -1,18 +0,0 @@ -#include <regexp.h> -#include <stdio.h> - -void -regerror(s) -const char *s; -{ -#ifdef ERRAVAIL - error("regexp: %s", s); -#else -/* - fprintf(stderr, "regexp(3): %s\n", s); - exit(1); -*/ - return; /* let std. egrep handle errors */ -#endif - /* NOTREACHED */ -} diff --git a/lib/libc/gen/regexp/regexp.3 b/lib/libc/gen/regexp/regexp.3 deleted file mode 100644 index b25fb4b498c6..000000000000 --- a/lib/libc/gen/regexp/regexp.3 +++ /dev/null @@ -1,315 +0,0 @@ -.\" Copyright 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. -.\" -.\" @(#)regexp.3 5.2 (Berkeley) 4/20/91 -.\" -.Dd April 20, 1991 -.Dt REGEXP 3 -.Os -.Sh NAME -.Nm regcomp , -.Nm regexec , -.Nm regsub , -.Nm regerror -.Nd regular expression handlers -.Sh SYNOPSIS -.Fd #include <regexp.h> -.Ft regexp * -.Fn regcomp "const char *exp" -.Ft int -.Fn regexec "const regexp *prog" "const char *string" -.Ft void -.Fn regsub "const regexp *prog" "const char *source" "char *dest" -.Sh DESCRIPTION -The -.Fn regcomp , -.Fn regexec , -.Fn regsub , -and -.Fn regerror -functions -implement -.Xr egrep 1 Ns -style -regular expressions and supporting facilities. -.Pp -The -.Fn regcomp -function -compiles a regular expression into a structure of type -.Xr regexp , -and returns a pointer to it. -The space has been allocated using -.Xr malloc 3 -and may be released by -.Xr free . -.Pp -The -.Fn regexec -function -matches a -.Dv NUL Ns -terminated -.Fa string -against the compiled regular expression -in -.Fa prog . -It returns 1 for success and 0 for failure, and adjusts the contents of -.Fa prog Ns 's -.Em startp -and -.Em endp -(see below) accordingly. -.Pp -The members of a -.Xr regexp -structure include at least the following (not necessarily in order): -.Bd -literal -offset indent -char *startp[NSUBEXP]; -char *endp[NSUBEXP]; -.Ed -.Pp -where -.Dv NSUBEXP -is defined (as 10) in the header file. -Once a successful -.Fn regexec -has been done using the -.Fn regexp , -each -.Em startp Ns - Em endp -pair describes one substring -within the -.Fa string , -with the -.Em startp -pointing to the first character of the substring and -the -.Em endp -pointing to the first character following the substring. -The 0th substring is the substring of -.Fa string -that matched the whole -regular expression. -The others are those substrings that matched parenthesized expressions -within the regular expression, with parenthesized expressions numbered -in left-to-right order of their opening parentheses. -.Pp -The -.Fn regsub -function -copies -.Fa source -to -.Fa dest , -making substitutions according to the -most recent -.Fn regexec -performed using -.Fa prog . -Each instance of `&' in -.Fa source -is replaced by the substring -indicated by -.Em startp Ns Bq -and -.Em endp Ns Bq . -Each instance of -.Sq \e Ns Em n , -where -.Em n -is a digit, is replaced by -the substring indicated by -.Em startp Ns Bq Em n -and -.Em endp Ns Bq Em n . -To get a literal `&' or -.Sq \e Ns Em n -into -.Fa dest , -prefix it with `\e'; -to get a literal `\e' preceding `&' or -.Sq \e Ns Em n , -prefix it with -another `\e'. -.Pp -The -.Fn regerror -function -is called whenever an error is detected in -.Fn regcomp , -.Fn regexec , -or -.Fn regsub . -The default -.Fn regerror -writes the string -.Fa msg , -with a suitable indicator of origin, -on the standard -error output -and invokes -.Xr exit 2 . -The -.Fn regerror -function -can be replaced by the user if other actions are desirable. -.Sh REGULAR EXPRESSION SYNTAX -A regular expression is zero or more -.Em branches , -separated by `|'. -It matches anything that matches one of the branches. -.Pp -A branch is zero or more -.Em pieces , -concatenated. -It matches a match for the first, followed by a match for the second, etc. -.Pp -A piece is an -.Em atom -possibly followed by `*', `+', or `?'. -An atom followed by `*' matches a sequence of 0 or more matches of the atom. -An atom followed by `+' matches a sequence of 1 or more matches of the atom. -An atom followed by `?' matches a match of the atom, or the null string. -.Pp -An atom is a regular expression in parentheses (matching a match for the -regular expression), a -.Em range -(see below), `.' -(matching any single character), `^' (matching the null string at the -beginning of the input string), `$' (matching the null string at the -end of the input string), a `\e' followed by a single character (matching -that character), or a single character with no other significance -(matching that character). -.Pp -A -.Em range -is a sequence of characters enclosed in `[]'. -It normally matches any single character from the sequence. -If the sequence begins with `^', -it matches any single character -.Em not -from the rest of the sequence. -If two characters in the sequence are separated by `\-', this is shorthand -for the full list of -.Tn ASCII -characters between them -(e.g. `[0-9]' matches any decimal digit). -To include a literal `]' in the sequence, make it the first character -(following a possible `^'). -To include a literal `\-', make it the first or last character. -.Sh AMBIGUITY -If a regular expression could match two different parts of the input string, -it will match the one which begins earliest. -If both begin in the same place but match different lengths, or match -the same length in different ways, life gets messier, as follows. -.Pp -In general, the possibilities in a list of branches are considered in -left-to-right order, the possibilities for `*', `+', and `?' are -considered longest-first, nested constructs are considered from the -outermost in, and concatenated constructs are considered leftmost-first. -The match that will be chosen is the one that uses the earliest -possibility in the first choice that has to be made. -If there is more than one choice, the next will be made in the same manner -(earliest possibility) subject to the decision on the first choice. -And so forth. -.Pp -For example, -.Sq Li (ab|a)b*c -could match -`abc' in one of two ways. -The first choice is between `ab' and `a'; since `ab' is earlier, and does -lead to a successful overall match, it is chosen. -Since the `b' is already spoken for, -the `b*' must match its last possibility\(emthe empty string\(emsince -it must respect the earlier choice. -.Pp -In the particular case where no `|'s are present and there is only one -`*', `+', or `?', the net effect is that the longest possible -match will be chosen. -So -.Sq Li ab* , -presented with `xabbbby', will match `abbbb'. -Note that if -.Sq Li ab* , -is tried against `xabyabbbz', it -will match `ab' just after `x', due to the begins-earliest rule. -(In effect, the decision on where to start the match is the first choice -to be made, hence subsequent choices must respect it even if this leads them -to less-preferred alternatives.) -.Sh RETURN VALUES -The -.Fn regcomp -function -returns -.Dv NULL -for a failure -.Pf ( Fn regerror -permitting), -where failures are syntax errors, exceeding implementation limits, -or applying `+' or `*' to a possibly-null operand. -.Sh SEE ALSO -.Xr ed 1 , -.Xr ex 1 , -.Xr expr 1 , -.Xr egrep 1 , -.Xr fgrep 1 , -.Xr grep 1 , -.Xr regex 3 -.Sh HISTORY -Both code and manual page for -.Fn regcomp , -.Fn regexec , -.Fn regsub , -and -.Fn regerror -were written at the University of Toronto -and appeared in -.Bx 4.3 tahoe . -They are intended to be compatible with the Bell V8 -.Xr regexp 3 , -but are not derived from Bell code. -.Sh BUGS -Empty branches and empty regular expressions are not portable to V8. -.Pp -The restriction against -applying `*' or `+' to a possibly-null operand is an artifact of the -simplistic implementation. -.Pp -Does not support -.Xr egrep Ns 's -newline-separated branches; -neither does the V8 -.Xr regexp 3 , -though. -.Pp -Due to emphasis on -compactness and simplicity, -it's not strikingly fast. -It does give special attention to handling simple cases quickly. diff --git a/lib/libc/gen/regexp/regexp.c b/lib/libc/gen/regexp/regexp.c deleted file mode 100644 index 0084295bfb37..000000000000 --- a/lib/libc/gen/regexp/regexp.c +++ /dev/null @@ -1,1320 +0,0 @@ -/* - * regcomp and regexec -- regsub and regerror are elsewhere - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to | - *** to assist in implementing egrep. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching - *** as in BSD grep and ex. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \. - *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods, - *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy. - * - * Beware that some of this code is subtly aware of the way operator - * precedence is structured in regular expressions. Serious changes in - * regular-expression syntax might require a total rethink. - */ -#include <regexp.h> -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include "regmagic.h" - -/* - * The "internal use only" fields in regexp.h are present to pass info from - * compile to execute that permits the execute phase to run lots faster on - * simple cases. They are: - * - * regstart char that must begin a match; '\0' if none obvious - * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string - * - * Regstart and reganch permit very fast decisions on suitable starting points - * for a match, cutting down the work a lot. Regmust permits fast rejection - * of lines that cannot possibly match. The regmust tests are costly enough - * that regcomp() supplies a regmust only if the r.e. contains something - * potentially expensive (at present, the only such thing detected is * or + - * at the start of the r.e., which can involve a lot of backup). Regmlen is - * supplied because the test in regexec() needs it and regcomp() is computing - * it anyway. - */ - -/* - * Structure for regexp "program". This is essentially a linear encoding - * of a nondeterministic finite-state machine (aka syntax charts or - * "railroad normal form" in parsing technology). Each node is an opcode - * plus a "next" pointer, possibly plus an operand. "Next" pointers of - * all nodes except BRANCH implement concatenation; a "next" pointer with - * a BRANCH on both ends of it is connecting two alternatives. (Here we - * have one of the subtle syntax dependencies: an individual BRANCH (as - * opposed to a collection of them) is never concatenated with anything - * because of operator precedence.) The operand of some types of node is - * a literal string; for others, it is a node leading into a sub-FSM. In - * particular, the operand of a BRANCH node is the first node of the branch. - * (NB this is *not* a tree structure: the tail of the branch connects - * to the thing following the set of BRANCHes.) The opcodes are: - */ - -/* definition number opnd? meaning */ -#define END 0 /* no End of program. */ -#define BOL 1 /* no Match "" at beginning of line. */ -#define EOL 2 /* no Match "" at end of line. */ -#define ANY 3 /* no Match any one character. */ -#define ANYOF 4 /* str Match any character in this string. */ -#define ANYBUT 5 /* str Match any character not in this string. */ -#define BRANCH 6 /* node Match this alternative, or the next... */ -#define BACK 7 /* no Match "", "next" ptr points backward. */ -#define EXACTLY 8 /* str Match this string. */ -#define NOTHING 9 /* no Match empty string. */ -#define STAR 10 /* node Match this (simple) thing 0 or more times. */ -#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ -#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */ -#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */ -#define OPEN 20 /* no Mark this point in input as start of #n. */ - /* OPEN+1 is number 1, etc. */ -#define CLOSE 30 /* no Analogous to OPEN. */ - -/* - * Opcode notes: - * - * BRANCH The set of branches constituting a single choice are hooked - * together with their "next" pointers, since precedence prevents - * anything being concatenated to any individual branch. The - * "next" pointer of the last BRANCH in a choice points to the - * thing following the whole choice. This is also where the - * final "next" pointer of each individual branch points; each - * branch starts with the operand node of a BRANCH node. - * - * BACK Normal "next" pointers all implicitly point forward; BACK - * exists to make loop structures possible. - * - * STAR,PLUS '?', and complex '*' and '+', are implemented as circular - * BRANCH structures using BACK. Simple cases (one character - * per match) are implemented with STAR and PLUS for speed - * and to minimize recursive plunges. - * - * OPEN,CLOSE ...are numbered at compile time. - */ - -/* - * A node is one char of opcode followed by two chars of "next" pointer. - * "Next" pointers are stored as two 8-bit pieces, high order first. The - * value is a positive offset from the opcode of the node containing it. - * An operand, if any, simply follows the node. (Note that much of the - * code generation knows about this implicit relationship.) - * - * Using two bytes for the "next" pointer is vast overkill for most things, - * but allows patterns to get big without disasters. - */ -#define OP(p) (*(p)) -#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) -#define OPERAND(p) ((p) + 3) - -/* - * See regmagic.h for one further detail of program structure. - */ - - -/* - * Utility definitions. - */ -#ifndef CHARBITS -#define UCHARAT(p) ((int)*(unsigned char *)(p)) -#else -#define UCHARAT(p) ((int)*(p)&CHARBITS) -#endif - -#define FAIL(m) { regerror(m); return(NULL); } -#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') - -/* - * Flags to be passed up and down. - */ -#define HASWIDTH 01 /* Known never to match null string. */ -#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ -#define SPSTART 04 /* Starts with * or +. */ -#define WORST 0 /* Worst case. */ - -/* - * Global work variables for regcomp(). - */ -static char *regparse; /* Input-scan pointer. */ -static int regnpar; /* () count. */ -static char regdummy; -static char *regcode; /* Code-emit pointer; ®dummy = don't. */ -static long regsize; /* Code size. */ - -/* - * Forward declarations for regcomp()'s friends. - */ -#ifndef STATIC -#define STATIC static -#endif -STATIC char *reg(); -STATIC char *regbranch(); -STATIC char *regpiece(); -STATIC char *regatom(); -STATIC char *regnode(); -STATIC char *regnext(); -STATIC void regc(); -STATIC void reginsert(); -STATIC void regtail(); -STATIC void regoptail(); -#ifdef STRCSPN -STATIC int strcspn(); -#endif - -/* - - regcomp - compile a regular expression into internal code - * - * We can't allocate space until we know how big the compiled form will be, - * but we can't compile it (and thus know how big it is) until we've got a - * place to put the code. So we cheat: we compile it twice, once with code - * generation turned off and size counting turned on, and once "for real". - * This also means that we don't allocate space until we are sure that the - * thing really will compile successfully, and we never have to move the - * code and thus invalidate pointers into it. (Note that it has to be in - * one piece because free() must be able to free it all.) - * - * Beware that the optimization-preparation code in here knows about some - * of the structure of the compiled regexp. - */ -regexp * -regcomp(exp) -const char *exp; -{ - register regexp *r; - register char *scan; - register char *longest; - register int len; - int flags; - - if (exp == NULL) - FAIL("NULL argument"); - - /* First pass: determine size, legality. */ -#ifdef notdef - if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */ -#endif - regparse = (char *)exp; - regnpar = 1; - regsize = 0L; - regcode = ®dummy; - regc(MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Small enough for pointer-storage convention? */ - if (regsize >= 32767L) /* Probably could be 65535L. */ - FAIL("regexp too big"); - - /* Allocate space. */ - r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); - if (r == NULL) - FAIL("out of space"); - - /* Second pass: emit code. */ - regparse = (char *)exp; - regnpar = 1; - regcode = r->program; - regc(MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Dig out information for optimizations. */ - r->regstart = '\0'; /* Worst-case defaults. */ - r->reganch = 0; - r->regmust = NULL; - r->regmlen = 0; - scan = r->program+1; /* First BRANCH. */ - if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ - scan = OPERAND(scan); - - /* Starting-point info. */ - if (OP(scan) == EXACTLY) - r->regstart = *OPERAND(scan); - else if (OP(scan) == BOL) - r->reganch++; - - /* - * If there's something expensive in the r.e., find the - * longest literal string that must appear and make it the - * regmust. Resolve ties in favor of later strings, since - * the regstart check works with the beginning of the r.e. - * and avoiding duplication strengthens checking. Not a - * strong reason, but sufficient in the absence of others. - */ - if (flags&SPSTART) { - longest = NULL; - len = 0; - for (; scan != NULL; scan = regnext(scan)) - if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { - longest = OPERAND(scan); - len = strlen(OPERAND(scan)); - } - r->regmust = longest; - r->regmlen = len; - } - } - - return(r); -} - -/* - - reg - regular expression, i.e. main body or parenthesized thing - * - * Caller must absorb opening parenthesis. - * - * Combining parenthesis handling with the base level of regular expression - * is a trifle forced, but the need to tie the tails of the branches to what - * follows makes it hard to avoid. - */ -static char * -reg(paren, flagp) -int paren; /* Parenthesized? */ -int *flagp; -{ - register char *ret; - register char *br; - register char *ender; - register int parno; - int flags; - - *flagp = HASWIDTH; /* Tentatively. */ - - /* Make an OPEN node, if parenthesized. */ - if (paren) { - if (regnpar >= NSUBEXP) - FAIL("too many ()"); - parno = regnpar; - regnpar++; - ret = regnode(OPEN+parno); - } else - ret = NULL; - - /* Pick up the branches, linking them together. */ - br = regbranch(&flags); - if (br == NULL) - return(NULL); - if (ret != NULL) - regtail(ret, br); /* OPEN -> first. */ - else - ret = br; - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - while (*regparse == '|' || *regparse == '\n') { - regparse++; - br = regbranch(&flags); - if (br == NULL) - return(NULL); - regtail(ret, br); /* BRANCH -> BRANCH. */ - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - } - - /* Make a closing node, and hook it on the end. */ - ender = regnode((paren) ? CLOSE+parno : END); - regtail(ret, ender); - - /* Hook the tails of the branches to the closing node. */ - for (br = ret; br != NULL; br = regnext(br)) - regoptail(br, ender); - - /* Check for proper termination. */ - if (paren && *regparse++ != ')') { - FAIL("unmatched ()"); - } else if (!paren && *regparse != '\0') { - if (*regparse == ')') { - FAIL("unmatched ()"); - } else - FAIL("junk on end"); /* "Can't happen". */ - /* NOTREACHED */ - } - - return(ret); -} - -/* - - regbranch - one alternative of an | operator - * - * Implements the concatenation operator. - */ -static char * -regbranch(flagp) -int *flagp; -{ - register char *ret; - register char *chain; - register char *latest; - int flags; - - *flagp = WORST; /* Tentatively. */ - - ret = regnode(BRANCH); - chain = NULL; - while (*regparse != '\0' && *regparse != ')' && - *regparse != '\n' && *regparse != '|') { - latest = regpiece(&flags); - if (latest == NULL) - return(NULL); - *flagp |= flags&HASWIDTH; - if (chain == NULL) /* First piece. */ - *flagp |= flags&SPSTART; - else - regtail(chain, latest); - chain = latest; - } - if (chain == NULL) /* Loop ran zero times. */ - (void) regnode(NOTHING); - - return(ret); -} - -/* - - regpiece - something followed by possible [*+?] - * - * Note that the branching code sequences used for ? and the general cases - * of * and + are somewhat optimized: they use the same NOTHING node as - * both the endmarker for their branch list and the body of the last branch. - * It might seem that this node could be dispensed with entirely, but the - * endmarker role is not redundant. - */ -static char * -regpiece(flagp) -int *flagp; -{ - register char *ret; - register char op; - register char *next; - int flags; - - ret = regatom(&flags); - if (ret == NULL) - return(NULL); - - op = *regparse; - if (!ISMULT(op)) { - *flagp = flags; - return(ret); - } - - if (!(flags&HASWIDTH) && op != '?') - FAIL("*+ operand could be empty"); - *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); - - if (op == '*' && (flags&SIMPLE)) - reginsert(STAR, ret); - else if (op == '*') { - /* Emit x* as (x&|), where & means "self". */ - reginsert(BRANCH, ret); /* Either x */ - regoptail(ret, regnode(BACK)); /* and loop */ - regoptail(ret, ret); /* back */ - regtail(ret, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '+' && (flags&SIMPLE)) - reginsert(PLUS, ret); - else if (op == '+') { - /* Emit x+ as x(&|), where & means "self". */ - next = regnode(BRANCH); /* Either */ - regtail(ret, next); - regtail(regnode(BACK), ret); /* loop back */ - regtail(next, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '?') { - /* Emit x? as (x|) */ - reginsert(BRANCH, ret); /* Either x */ - regtail(ret, regnode(BRANCH)); /* or */ - next = regnode(NOTHING); /* null. */ - regtail(ret, next); - regoptail(ret, next); - } - regparse++; - if (ISMULT(*regparse)) - FAIL("nested *?+"); - - return(ret); -} - -/* - - regatom - the lowest level - * - * Optimization: gobbles an entire sequence of ordinary characters so that - * it can turn them into a single node, which is smaller to store and - * faster to run. Backslashed characters are exceptions, each becoming a - * separate node; the code is simpler that way and it's not worth fixing. - */ -static char * -regatom(flagp) -int *flagp; -{ - register char *ret; - int flags; - - *flagp = WORST; /* Tentatively. */ - - switch (*regparse++) { - /* FIXME: these chars only have meaning at beg/end of pat? */ - case '^': - ret = regnode(BOL); - break; - case '$': - ret = regnode(EOL); - break; - case '.': - ret = regnode(ANY); - *flagp |= HASWIDTH|SIMPLE; - break; - case '[': { - register int class; - register int classend; - - if (*regparse == '^') { /* Complement of range. */ - ret = regnode(ANYBUT); - regparse++; - } else - ret = regnode(ANYOF); - if (*regparse == ']' || *regparse == '-') - regc(*regparse++); - while (*regparse != '\0' && *regparse != ']') { - if (*regparse == '-') { - regparse++; - if (*regparse == ']' || *regparse == '\0') - regc('-'); - else { - class = UCHARAT(regparse-2)+1; - classend = UCHARAT(regparse); - if (class > classend+1) - FAIL("invalid [] range"); - for (; class <= classend; class++) - regc(class); - regparse++; - } - } else - regc(*regparse++); - } - regc('\0'); - if (*regparse != ']') - FAIL("unmatched []"); - regparse++; - *flagp |= HASWIDTH|SIMPLE; - } - break; - case '(': - ret = reg(1, &flags); - if (ret == NULL) - return(NULL); - *flagp |= flags&(HASWIDTH|SPSTART); - break; - case '\0': - case '|': - case '\n': - case ')': - FAIL("internal urp"); /* Supposed to be caught earlier. */ - break; - case '?': - case '+': - case '*': - FAIL("?+* follows nothing"); - break; - case '\\': - switch (*regparse++) { - case '\0': - FAIL("trailing \\"); - break; - case '<': - ret = regnode(WORDA); - break; - case '>': - ret = regnode(WORDZ); - break; - /* FIXME: Someday handle \1, \2, ... */ - default: - /* Handle general quoted chars in exact-match routine */ - goto de_fault; - } - break; - de_fault: - default: - /* - * Encode a string of characters to be matched exactly. - * - * This is a bit tricky due to quoted chars and due to - * '*', '+', and '?' taking the SINGLE char previous - * as their operand. - * - * On entry, the char at regparse[-1] is going to go - * into the string, no matter what it is. (It could be - * following a \ if we are entered from the '\' case.) - * - * Basic idea is to pick up a good char in ch and - * examine the next char. If it's *+? then we twiddle. - * If it's \ then we frozzle. If it's other magic char - * we push ch and terminate the string. If none of the - * above, we push ch on the string and go around again. - * - * regprev is used to remember where "the current char" - * starts in the string, if due to a *+? we need to back - * up and put the current char in a separate, 1-char, string. - * When regprev is NULL, ch is the only char in the - * string; this is used in *+? handling, and in setting - * flags |= SIMPLE at the end. - */ - { - char *regprev; - register char ch; - - regparse--; /* Look at cur char */ - ret = regnode(EXACTLY); - for ( regprev = 0 ; ; ) { - ch = *regparse++; /* Get current char */ - switch (*regparse) { /* look at next one */ - - default: - regc(ch); /* Add cur to string */ - break; - - case '.': case '[': case '(': - case ')': case '|': case '\n': - case '$': case '^': - case '\0': - /* FIXME, $ and ^ should not always be magic */ - magic: - regc(ch); /* dump cur char */ - goto done; /* and we are done */ - - case '?': case '+': case '*': - if (!regprev) /* If just ch in str, */ - goto magic; /* use it */ - /* End mult-char string one early */ - regparse = regprev; /* Back up parse */ - goto done; - - case '\\': - regc(ch); /* Cur char OK */ - switch (regparse[1]){ /* Look after \ */ - case '\0': - case '<': - case '>': - /* FIXME: Someday handle \1, \2, ... */ - goto done; /* Not quoted */ - default: - /* Backup point is \, scan * point is after it. */ - regprev = regparse; - regparse++; - continue; /* NOT break; */ - } - } - regprev = regparse; /* Set backup point */ - } - done: - regc('\0'); - *flagp |= HASWIDTH; - if (!regprev) /* One char? */ - *flagp |= SIMPLE; - } - break; - } - - return(ret); -} - -/* - - regnode - emit a node - */ -static char * /* Location. */ -regnode(op) -char op; -{ - register char *ret; - register char *ptr; - - ret = regcode; - if (ret == ®dummy) { - regsize += 3; - return(ret); - } - - ptr = ret; - *ptr++ = op; - *ptr++ = '\0'; /* Null "next" pointer. */ - *ptr++ = '\0'; - regcode = ptr; - - return(ret); -} - -/* - - regc - emit (if appropriate) a byte of code - */ -static void -regc(b) -char b; -{ - if (regcode != ®dummy) - *regcode++ = b; - else - regsize++; -} - -/* - - reginsert - insert an operator in front of already-emitted operand - * - * Means relocating the operand. - */ -static void -reginsert(op, opnd) -char op; -char *opnd; -{ - register char *src; - register char *dst; - register char *place; - - if (regcode == ®dummy) { - regsize += 3; - return; - } - - src = regcode; - regcode += 3; - dst = regcode; - while (src > opnd) - *--dst = *--src; - - place = opnd; /* Op node, where operand used to be. */ - *place++ = op; - *place++ = '\0'; - *place++ = '\0'; -} - -/* - - regtail - set the next-pointer at the end of a node chain - */ -static void -regtail(p, val) -char *p; -char *val; -{ - register char *scan; - register char *temp; - register int offset; - - if (p == ®dummy) - return; - - /* Find last node. */ - scan = p; - for (;;) { - temp = regnext(scan); - if (temp == NULL) - break; - scan = temp; - } - - if (OP(scan) == BACK) - offset = scan - val; - else - offset = val - scan; - *(scan+1) = (offset>>8)&0377; - *(scan+2) = offset&0377; -} - -/* - - regoptail - regtail on operand of first argument; nop if operandless - */ -static void -regoptail(p, val) -char *p; -char *val; -{ - /* "Operandless" and "op != BRANCH" are synonymous in practice. */ - if (p == NULL || p == ®dummy || OP(p) != BRANCH) - return; - regtail(OPERAND(p), val); -} - -/* - * regexec and friends - */ - -/* - * Global work variables for regexec(). - */ -static char *reginput; /* String-input pointer. */ -static char *regbol; /* Beginning of input, for ^ check. */ -static char **regstartp; /* Pointer to startp array. */ -static char **regendp; /* Ditto for endp. */ - -/* - * Forwards. - */ -STATIC int regtry(); -STATIC int regmatch(); -STATIC int regrepeat(); - -#ifdef DEBUG -int regnarrate = 0; -void regdump(); -STATIC char *regprop(); -#endif - -/* - - regexec - match a regexp against a string - */ -int -regexec(prog, string) -register const regexp *prog; -register const char *string; -{ - register char *s; - extern char *strchr(); - - /* Be paranoid... */ - if (prog == NULL || string == NULL) { - regerror("NULL parameter"); - return(0); - } - - /* Check validity of program. */ - if (UCHARAT(prog->program) != MAGIC) { - regerror("corrupted program"); - return(0); - } - - /* If there is a "must appear" string, look for it. */ - if (prog->regmust != NULL) { - s = (char *)string; - while ((s = strchr(s, prog->regmust[0])) != NULL) { - if (strncmp(s, prog->regmust, prog->regmlen) == 0) - break; /* Found it. */ - s++; - } - if (s == NULL) /* Not present. */ - return(0); - } - - /* Mark beginning of line for ^ . */ - regbol = (char *)string; - - /* Simplest case: anchored match need be tried only once. */ - if (prog->reganch) - return(regtry(prog, string)); - - /* Messy cases: unanchored match. */ - s = (char *)string; - if (prog->regstart != '\0') - /* We know what char it must start with. */ - while ((s = strchr(s, prog->regstart)) != NULL) { - if (regtry(prog, s)) - return(1); - s++; - } - else - /* We don't -- general case. */ - do { - if (regtry(prog, s)) - return(1); - } while (*s++ != '\0'); - - /* Failure. */ - return(0); -} - -/* - - regtry - try match at specific point - */ -static int /* 0 failure, 1 success */ -regtry(prog, string) -regexp *prog; -char *string; -{ - register int i; - register char **sp; - register char **ep; - - reginput = string; - regstartp = prog->startp; - regendp = prog->endp; - - sp = prog->startp; - ep = prog->endp; - for (i = NSUBEXP; i > 0; i--) { - *sp++ = NULL; - *ep++ = NULL; - } - if (regmatch(prog->program + 1)) { - prog->startp[0] = string; - prog->endp[0] = reginput; - return(1); - } else - return(0); -} - -/* - - regmatch - main matching routine - * - * Conceptually the strategy is simple: check to see whether the current - * node matches, call self recursively to see whether the rest matches, - * and then act accordingly. In practice we make some effort to avoid - * recursion, in particular by going through "ordinary" nodes (that don't - * need to know whether the rest of the match failed) by a loop instead of - * by recursion. - */ -static int /* 0 failure, 1 success */ -regmatch(prog) -char *prog; -{ - register char *scan; /* Current node. */ - char *next; /* Next node. */ - extern char *strchr(); - - scan = prog; -#ifdef DEBUG - if (scan != NULL && regnarrate) - fprintf(stderr, "%s(\n", regprop(scan)); -#endif - while (scan != NULL) { -#ifdef DEBUG - if (regnarrate) - fprintf(stderr, "%s...\n", regprop(scan)); -#endif - next = regnext(scan); - - switch (OP(scan)) { - case BOL: - if (reginput != regbol) - return(0); - break; - case EOL: - if (*reginput != '\0') - return(0); - break; - case WORDA: - /* Must be looking at a letter, digit, or _ */ - if ((!isalnum(*reginput)) && *reginput != '_') - return(0); - /* Prev must be BOL or nonword */ - if (reginput > regbol && - (isalnum(reginput[-1]) || reginput[-1] == '_')) - return(0); - break; - case WORDZ: - /* Must be looking at non letter, digit, or _ */ - if (isalnum(*reginput) || *reginput == '_') - return(0); - /* We don't care what the previous char was */ - break; - case ANY: - if (*reginput == '\0') - return(0); - reginput++; - break; - case EXACTLY: { - register int len; - register char *opnd; - - opnd = OPERAND(scan); - /* Inline the first character, for speed. */ - if (*opnd != *reginput) - return(0); - len = strlen(opnd); - if (len > 1 && strncmp(opnd, reginput, len) != 0) - return(0); - reginput += len; - } - break; - case ANYOF: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) - return(0); - reginput++; - break; - case ANYBUT: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) - return(0); - reginput++; - break; - case NOTHING: - break; - case BACK: - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: { - register int no; - register char *save; - - no = OP(scan) - OPEN; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set startp if some later - * invocation of the same parentheses - * already has. - */ - if (regstartp[no] == NULL) - regstartp[no] = save; - return(1); - } else - return(0); - } - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: { - register int no; - register char *save; - - no = OP(scan) - CLOSE; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set endp if some later - * invocation of the same parentheses - * already has. - */ - if (regendp[no] == NULL) - regendp[no] = save; - return(1); - } else - return(0); - } - break; - case BRANCH: { - register char *save; - - if (OP(next) != BRANCH) /* No choice. */ - next = OPERAND(scan); /* Avoid recursion. */ - else { - do { - save = reginput; - if (regmatch(OPERAND(scan))) - return(1); - reginput = save; - scan = regnext(scan); - } while (scan != NULL && OP(scan) == BRANCH); - return(0); - /* NOTREACHED */ - } - } - break; - case STAR: - case PLUS: { - register char nextch; - register int no; - register char *save; - register int min; - - /* - * Lookahead to avoid useless match attempts - * when we know what character comes next. - */ - nextch = '\0'; - if (OP(next) == EXACTLY) - nextch = *OPERAND(next); - min = (OP(scan) == STAR) ? 0 : 1; - save = reginput; - no = regrepeat(OPERAND(scan)); - while (no >= min) { - /* If it could work, try it. */ - if (nextch == '\0' || *reginput == nextch) - if (regmatch(next)) - return(1); - /* Couldn't or didn't -- back up. */ - no--; - reginput = save + no; - } - return(0); - } - break; - case END: - return(1); /* Success! */ - break; - default: - regerror("memory corruption"); - return(0); - break; - } - - scan = next; - } - - /* - * We get here only if there's trouble -- normally "case END" is - * the terminating point. - */ - regerror("corrupted pointers"); - return(0); -} - -/* - - regrepeat - repeatedly match something simple, report how many - */ -static int -regrepeat(p) -char *p; -{ - register int count = 0; - register char *scan; - register char *opnd; - - scan = reginput; - opnd = OPERAND(p); - switch (OP(p)) { - case ANY: - count = strlen(scan); - scan += count; - break; - case EXACTLY: - while (*opnd == *scan) { - count++; - scan++; - } - break; - case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != NULL) { - count++; - scan++; - } - break; - case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == NULL) { - count++; - scan++; - } - break; - default: /* Oh dear. Called inappropriately. */ - regerror("internal foulup"); - count = 0; /* Best compromise. */ - break; - } - reginput = scan; - - return(count); -} - -/* - - regnext - dig the "next" pointer out of a node - */ -static char * -regnext(p) -register char *p; -{ - register int offset; - - if (p == ®dummy) - return(NULL); - - offset = NEXT(p); - if (offset == 0) - return(NULL); - - if (OP(p) == BACK) - return(p-offset); - else - return(p+offset); -} - -#ifdef DEBUG - -STATIC char *regprop(); - -/* - - regdump - dump a regexp onto stdout in vaguely comprehensible form - */ -void -regdump(r) -regexp *r; -{ - register char *s; - register char op = EXACTLY; /* Arbitrary non-END op. */ - register char *next; - extern char *strchr(); - - - s = r->program + 1; - while (op != END) { /* While that wasn't END last time... */ - op = OP(s); - printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ - next = regnext(s); - if (next == NULL) /* Next ptr. */ - printf("(0)"); - else - printf("(%d)", (s-r->program)+(next-s)); - s += 3; - if (op == ANYOF || op == ANYBUT || op == EXACTLY) { - /* Literal string, where present. */ - while (*s != '\0') { - putchar(*s); - s++; - } - s++; - } - putchar('\n'); - } - - /* Header fields of interest. */ - if (r->regstart != '\0') - printf("start `%c' ", r->regstart); - if (r->reganch) - printf("anchored "); - if (r->regmust != NULL) - printf("must have \"%s\"", r->regmust); - printf("\n"); -} - -/* - - regprop - printable representation of opcode - */ -static char * -regprop(op) -char *op; -{ - register char *p; - static char buf[50]; - - (void) strcpy(buf, ":"); - - switch (OP(op)) { - case BOL: - p = "BOL"; - break; - case EOL: - p = "EOL"; - break; - case ANY: - p = "ANY"; - break; - case ANYOF: - p = "ANYOF"; - break; - case ANYBUT: - p = "ANYBUT"; - break; - case BRANCH: - p = "BRANCH"; - break; - case EXACTLY: - p = "EXACTLY"; - break; - case NOTHING: - p = "NOTHING"; - break; - case BACK: - p = "BACK"; - break; - case END: - p = "END"; - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: - sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); - p = NULL; - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: - sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); - p = NULL; - break; - case STAR: - p = "STAR"; - break; - case PLUS: - p = "PLUS"; - break; - case WORDA: - p = "WORDA"; - break; - case WORDZ: - p = "WORDZ"; - break; - default: - regerror("corrupted opcode"); - break; - } - if (p != NULL) - (void) strcat(buf, p); - return(buf); -} -#endif - -/* - * The following is provided for those people who do not have strcspn() in - * their C libraries. They should get off their butts and do something - * about it; at least one public-domain implementation of those (highly - * useful) string routines has been published on Usenet. - */ -#ifdef STRCSPN -/* - * strcspn - find length of initial segment of s1 consisting entirely - * of characters not from s2 - */ - -static int -strcspn(s1, s2) -char *s1; -char *s2; -{ - register char *scan1; - register char *scan2; - register int count; - - count = 0; - for (scan1 = s1; *scan1 != '\0'; scan1++) { - for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ - if (*scan1 == *scan2++) - return(count); - count++; - } - return(count); -} -#endif diff --git a/lib/libc/gen/regexp/regexp.h b/lib/libc/gen/regexp/regexp.h deleted file mode 100644 index 73d6bf412424..000000000000 --- a/lib/libc/gen/regexp/regexp.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Definitions etc. for regexp(3) routines. - * - * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], - * not the System V one. - */ -#define NSUBEXP 10 -typedef struct regexp { - char *startp[NSUBEXP]; - char *endp[NSUBEXP]; - char regstart; /* Internal use only. */ - char reganch; /* Internal use only. */ - char *regmust; /* Internal use only. */ - int regmlen; /* Internal use only. */ - char program[1]; /* Unwarranted chumminess with compiler. */ -} regexp; - -extern regexp *regcomp(); -extern int regexec(); -extern void regsub(); -extern void regerror(); diff --git a/lib/libc/gen/regexp/regmagic.h b/lib/libc/gen/regexp/regmagic.h deleted file mode 100644 index 5acf4478ff71..000000000000 --- a/lib/libc/gen/regexp/regmagic.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * The first byte of the regexp internal "program" is actually this magic - * number; the start node begins in the second byte. - */ -#define MAGIC 0234 diff --git a/lib/libc/gen/regexp/regsub.c b/lib/libc/gen/regexp/regsub.c deleted file mode 100644 index e55b9b624d1d..000000000000 --- a/lib/libc/gen/regexp/regsub.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * regsub - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - */ -#include <regexp.h> -#include <stdio.h> -#include <string.h> -#include "regmagic.h" - -#ifndef CHARBITS -#define UCHARAT(p) ((int)*(unsigned char *)(p)) -#else -#define UCHARAT(p) ((int)*(p)&CHARBITS) -#endif - -/* - - regsub - perform substitutions after a regexp match - */ -void -regsub(prog, source, dest) -const regexp *prog; -const char *source; -char *dest; -{ - register char *src; - register char *dst; - register char c; - register int no; - register int len; - extern char *strncpy(); - - if (prog == NULL || source == NULL || dest == NULL) { - regerror("NULL parm to regsub"); - return; - } - if (UCHARAT(prog->program) != MAGIC) { - regerror("damaged regexp fed to regsub"); - return; - } - - src = (char *)source; - dst = dest; - while ((c = *src++) != '\0') { - if (c == '&') - no = 0; - else if (c == '\\' && '0' <= *src && *src <= '9') - no = *src++ - '0'; - else - no = -1; - if (no < 0) { /* Ordinary character. */ - if (c == '\\' && (*src == '\\' || *src == '&')) - c = *src++; - *dst++ = c; - } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { - len = prog->endp[no] - prog->startp[no]; - (void) strncpy(dst, prog->startp[no], len); - dst += len; - if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ - regerror("damaged match string"); - return; - } - } - } - *dst++ = '\0'; -} diff --git a/lib/libc/gen/semconfig.c b/lib/libc/gen/semconfig.c new file mode 100644 index 000000000000..66fbb2d93398 --- /dev/null +++ b/lib/libc/gen/semconfig.c @@ -0,0 +1,13 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> + +#if __STDC__ +int semconfig(int cmd, int p1, int p2, int p3) +#else +int semctl(cmd, p1, p2, p3) + int cmd, p1, p2, p3; +#endif +{ + return (semsys(3, cmd, p1, p2, p3)); +} diff --git a/lib/libc/gen/semctl.c b/lib/libc/gen/semctl.c new file mode 100644 index 000000000000..313a1dbeda8f --- /dev/null +++ b/lib/libc/gen/semctl.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> + +#if __STDC__ +int semctl(int semid, int semnum, int cmd, union semun semun) +#else +int semctl(semid, int semnum, cmd, semun) + int semid, semnum; + int cmd; + union semun semun; +#endif +{ + return (semsys(0, semid, semnum, cmd, &semun)); +} diff --git a/lib/libc/gen/semget.c b/lib/libc/gen/semget.c new file mode 100644 index 000000000000..81c6a86e438c --- /dev/null +++ b/lib/libc/gen/semget.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> + +#if __STDC__ +int semget(key_t key, int nsems, int semflg) +#else +int semget(key, nsems, semflg) + key_t key; + int nsems; + int semflg; +#endif +{ + return (semsys(1, key, nsems, semflg)); +} diff --git a/lib/libc/gen/semop.c b/lib/libc/gen/semop.c new file mode 100644 index 000000000000..0b97c6aacb2f --- /dev/null +++ b/lib/libc/gen/semop.c @@ -0,0 +1,15 @@ +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> + +#if __STDC__ +int semop(int semid, struct sembuf *sops, unsigned nsops) +#else +int semop(semid, sops, nsops) + int semid; + struct sembuf *sops; + unsigned nsops; +#endif +{ + return (semsys(2, semid, sops, nsops, 0)); +} diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c index fa688a77b264..12f7c1ab1ca7 100644 --- a/lib/libc/gen/setmode.c +++ b/lib/libc/gen/setmode.c @@ -215,7 +215,7 @@ setmode(p) mode_t mask; struct bitcmd *set, *saveset, *endset; int permXbits, setlen; - static int compress_mode(); + static void compress_mode(); /* * Get a copy of the mask for the permissions that are mask relative. @@ -321,7 +321,7 @@ setmode(p) * to flush out any partial mode that we have, * and then do the copying of the mode bits. */ - if (perm) { + if (perm || op == '=') { ADDCMD(op, who, perm, mask); perm = 0; } @@ -337,7 +337,7 @@ setmode(p) * Add any permissions that we haven't already * done. */ - if (perm) { + if (perm || op == '=') { ADDCMD(op, who, perm, mask); perm = 0; } @@ -389,7 +389,7 @@ dumpmode(set) * 'g' and 'o' commands continue to be separate. They could probably be * compacted, but it's not worth the effort. */ -static +static void compress_mode(set) register struct bitcmd *set; { diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3 index 7f6570625824..b78797c572bd 100644 --- a/lib/libc/gen/signal.3 +++ b/lib/libc/gen/signal.3 @@ -79,7 +79,7 @@ and signals, the .Fn signal function allows for a signal to be caught, to be ignored, or to generate -an interupt. +an interrupt. These signals are defined in the file .Aq Pa signal.h : .Bl -column SIGVTALARMXX "create core imagexxx" @@ -150,7 +150,7 @@ is called. .Pp The handled signal is unblocked with the function returns and -the process continues from where it left off when the signal occured. +the process continues from where it left off when the signal occurred. .Bf -symbolic Unlike previous signal facilities, the handler func() remains installed after a signal has been delivered. diff --git a/lib/libc/gen/tcgetpgrp.3 b/lib/libc/gen/tcgetpgrp.3 new file mode 100644 index 000000000000..03396104caf6 --- /dev/null +++ b/lib/libc/gen/tcgetpgrp.3 @@ -0,0 +1,79 @@ +.\" 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. +.\" +.\" @(#)tcgetpgrp.3 5.3 (Berkeley) 3/29/92 +.\" +.Dd "March 29, 1992" +.Dt TCGETPGRP 3 +.Os +.Sh NAME +.Nm tcgetpgrp +.Nd get foreground process group ID +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Fd #include <unistd.h> +.Ft pid_t +.Fn tcgetpgrp "int fd" +.Sh DESCRIPTION +The +.Nm tcgetpgrp +function returns the value of the process group ID of the foreground +process group associated with the terminal device. +If there is no foreground process group, +.Nm tcgetpgrp +returns an invalid process ID. +.Sh ERRORS +If an error occurs, +.Nm tcgetpgrp +returns -1 and the global variable +.Va errno +is set to indicate the error, as follows: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument is not a valid file descriptor. +.It Bq Er ENOTTY +The calling process does not have a controlling terminal or the +underlying terminal device represented by +.Fa fd +is not the controlling terminal. +.El +.Sh SEE ALSO +.Xr setpgid 3 , +.Xr setsid 2 , +.Xr tcsetpgrp 3 +.Sh STANDARDS +The +.Nm tcgetpgrp +function is expected to be compliant with the +.St -p1003.1-88 +specification. diff --git a/lib/libc/gen/tcsetattr.3 b/lib/libc/gen/tcsetattr.3 new file mode 100644 index 000000000000..b206beec6b91 --- /dev/null +++ b/lib/libc/gen/tcsetattr.3 @@ -0,0 +1,330 @@ +.\" 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. +.\" +.\" @(#)tcsetattr.3 5.2 (Berkeley) 3/4/92 +.\" +.Dd "March 4, 1992" +.Dt TCSETATTR 3 +.Os +.Sh NAME +.Nm cfgetispeed , +.Nm cfsetispeed , +.Nm cfgetospeed , +.Nm cfsetospeed , +.Nm cfsetspeed , +.Nm cfmakeraw , +.Nm tcgetattr , +.Nm tcsetattr +.Nd manipulating the termios structure +.Sh SYNOPSIS +.Fd #include <termios.h> +.Ft speed_t +.Fn cfgetispeed "struct termios *t" +.Ft int +.Fn cfsetispeed "struct termios *t" "speed_t speed" +.Ft speed_t +.Fn cfgetospeed "struct termios *t" +.Ft int +.Fn cfsetospeed "struct termios *t" "speed_t speed" +.Ft void +.Fn cfsetspeed "struct termios *t" "speed_t speed" +.Ft void +.Fn cfmakeraw "struct termios *t" +.Ft int +.Fn tcgetattr "int fd" "struct termios *t" +.Ft int +.Fn tcsetattr "int fd" "int action" "struct termios *t" +.Sh DESCRIPTION +The +.Nm cfmakeraw , +.Nm tcgetattr +and +.Nm tcsetattr +functions are provided for getting and setting the termios structure. +.Pp +The +.Nm cfgetispeed , +.Nm cfsetispeed , +.Nm cfgetospeed , +.Nm cfsetospeed +and +.Nm cfsetspeed +functions are provided for getting and setting the baud rate values in +the termios structure. +The effects of the functions on the terminal as described below +do not become effective, nor are all errors detected, until the +.Nm tcsetattr +function is called. +Certain values for baud rates set in the termios structure and passed to +.Nm tcsetattr +have special meanings. +These are discussed in the portion of the manual page that describes the +.Nm tcsetattr +function. +.Sh GETTING AND SETTING THE BAUD RATE +The input and output baud rates are found in the termios structure. +The unsigned integer +.Li speed_t +is typdef'd in the include file +.Aq Pa termios.h . +The value of the integer corresponds directly to the baud rate being +represented, however, the following symbolic values are defined. +.Bd -literal +#define B0 0 +#define B50 50 +#define B75 75 +#define B110 110 +#define B134 134 +#define B150 150 +#define B200 200 +#define B300 300 +#define B600 600 +#define B1200 1200 +#define B1800 1800 +#define B2400 2400 +#define B4800 4800 +#define B9600 9600 +#define B19200 19200 +#define B38400 38400 +#ifndef _POSIX_SOURCE +#define EXTA 19200 +#define EXTB 38400 +#endif /*_POSIX_SOURCE */ +.Ed +.Pp +The +.Nm cfgetispeed +function returns the input baud rate in the termios structure referenced by +.Fa tp . +.Pp +The +.Nm cfsetispeed +function sets the input baud rate in the termios structure referenced by +.Fa tp +to +.Fa speed . +.Pp +The +.Nm cfgetospeed +function returns the output baud rate in the termios structure referenced by +.Fa tp . +.Pp +The +.Nm cfsetospeed +function sets the output baud rate in the termios structure referenced by +.Fa tp +to +.Fa speed . +.Pp +The +.Nm cfsetspeed +function sets both the input and output baud rate in the termios structure +referenced by +.Fa tp +to +.Fa speed . +.Pp +Upon successful completion, the functions +.Nm cfsetispeed , +.Nm cfsetospeed , +and +.Nm cfsetspeed +return a value of 0. +Otherwise, a value of -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh GETTING AND SETTING THE TERMIOS STATE +This section describes the functions that are used to control the general +terminal interface. +Unless otherwise noted for a specific command, these functions are restricted +from use by background processes. +Attempts to perform these operations shall cause the process group to be sent +a SIGTTOU signal. +If the calling process is blocking or ignoring SIGTTOU signals, the process +is allowed to perform the operation and the SIGTTOU signal is not sent. +.Pp +In all the functions, although +.Fa fd +is an open file descriptor, the functions affect the underlying terminal +file, not just the open file description associated with the particular +file descriptor. +.Pp +The +.Nm cfmakeraw +function sets the flags stored in the termios structure to a state disabling +all input and output processing, giving a +.Dq raw I/O path. +It should be noted that there is no function to reverse this effect. +This is because there are a variety of processing options that could be +re-enabled and the correct method is for an application to snapshot the +current terminal state using the function +.Nm tcgetattr , +setting raw mode with +.Nm cfmakeraw +and the subsequent +.Nm tcsetattr , +and then using another +.Nm tcsetattr +with the saved state to revert to the previous terminal state. +.Pp +The +.Nm tcgetattr +function copies the parameters associated with the terminal referenced +by +.Fa fd +in the termios structure referenced by +.Fa tp . +This function is allowed from a background process, however, the terminal +attributes may be subsequently changed by a foreground process. +.Pp +The +.Nm tcsetattr +function sets the parameters associated with the terminal from the +termios structure referenced by +.Fa tp . +The +.Fa action +field is created by +.Em or Ns 'ing +the following values, as specified in the include file +.Aq Pa termios.h . +.Bl -tag -width "TCSADRAIN" +.It Fa TCSANOW +The change occurs immediately. +.It Fa TCSADRAIN +The change occurs after all output written to +.Fa fd +has been transmitted to the terminal. +This value of +.Fa action +should be used when changing parameters that affect output. +.It Fa TCSAFLUSH +The change occurs after all output written to +.Fa fd +has been transmitted to the terminal +Additionally, any input that has been received but not read is discarded. +.It Fa TCSASOFT +If this value is +.Em or Ns 'ed +into the +.Fa action +value, the values of the +.Em c_cflag , +.Em c_ispeed , +and +.Em c_ospeed +fields are ignored. +.El +.Pp +The 0 baud rate is used to terminate the connection. +If 0 is specified as the output speed to the function +.Nm tcsetattr , +modem control will no longer be asserted on the terminal, disconnecting +the terminal. +.Pp +If zero is specified as the input speed to the function +.Nm tcsetattr , +the input baud rate will be set to the same value as that specified by +the output baud rate. +.Pp +If +.Nm tcsetattr +is unable able to make any of the requested changes, it returns -1 and +sets errno. +Otherwise, it makes all of the requested changes it can. +If the specified input and output baud rates differ and are a combination +that is not supported, neither baud rate is changed. +.Pp +Upon successful completion, the functions +.Nm tcgetattr +and +.Nm tcsetattr +return a value of 0. +Otherwise, they +return -1 and the global variable +.Va errno +is set to indicate the error, as follows: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument to +.Nm tcgetattr +or +.Nm tcsetattr +was not a valid file descriptor. +.It Bq Er EINTR +The +.Nm tcsetattr +function was interrupted by a signal. +.It Bq Er EINVAL +The +.Fa action +argument to the +.Nm tcsetattr +function was not valid, or an attempt was made to change an attribute +represented in the termios structure to an unsupported value. +.It Bq Er ENOTTY +The file associated with the +.Fa fd +argument to +.Nm tcgetattr +or +.Nm tcsetattr +is not a terminal. +.El +.Sh SEE ALSO +.Xr tcsendbreak 3 , +.Xr termios 4 +.Sh STANDARDS +The +.Nm cfgetispeed , +.Nm cfsetispeed , +.Nm cfgetospeed , +.Nm cfsetospeed , +.Nm tcgetattr +and +.Nm tcsetattr +functions are expected to be compliant with the +.St -p1003.1-88 +specification. +The +.Nm cfmakeraw +and +.Nm cfsetspeed +functions, +as well as the +.Li TCSASOFT +option to the +.Nm tcsetattr +function are extensions to the +.St -p1003.1-88 +specification. diff --git a/lib/libc/gen/tcsetpgrp.3 b/lib/libc/gen/tcsetpgrp.3 new file mode 100644 index 000000000000..ff881cb437d8 --- /dev/null +++ b/lib/libc/gen/tcsetpgrp.3 @@ -0,0 +1,100 @@ +.\" 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. +.\" +.\" @(#)tcsetpgrp.3 5.3 (Berkeley) 3/29/92 +.\" +.Dd "March 29, 1992" +.Dt TCSETPGRP +.Os +.Sh NAME +.Nm tcsetpgrp +.Nd set foreground process group ID +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Fd #include <unistd.h> +.Ft int +.Fn tcsetpgrp "int fd" "pid_t pgrp_id" +.Sh DESCRIPTION +If the process has a controlling terminal, the +.Nm tcsetpgrp +function sets the foreground process group ID associated with the +terminal device to +.Fa pgrp_id . +The terminal device associated with +.Fa fd +must be the controlling terminal of the calling process and the +controlling terminal must be currently associated with the session +of the calling process. +The value of +.Fa pgrp_id +must be the same as the process group ID of a process in the same +session as the calling process. +.Pp +Upon successful completion, +.Nm tcsetpgrp +returns a value of zero. +.Sh ERRORS +If an error occurs, +.Nm tcgetpgrp +returns -1 and the global variable +.Va errno +is set to indicate the error, as follows: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument is not a valid file descriptor. +.It Bq Er EINVAL +An invalid value of +.Fa pgrp_id +was specified. +.It Bq Er ENOTTY +The calling process does not have a controlling terminal, or the file +represented by +.Fa fd +is not the controlling terminal, or the controlling terminal is no +longer associated with the session of the calling process. +.It Bq Er EPERM +The +.Fa pgrp_id +argument does not match the process group ID of a process in the same +session as the calling process. +.El +.Sh SEE ALSO +.Xr setpgid 3 , +.Xr setsid 2 , +.Xr tcgetpgrp 3 +.Sh STANDARDS +The +.Nm tcsetpgprp +function is expected to be compliant with the +.St -p1003.1-88 +specification. diff --git a/lib/libc/gen/timezone.3 b/lib/libc/gen/timezone.3 index bfd460eda664..bafa0154427e 100644 --- a/lib/libc/gen/timezone.3 +++ b/lib/libc/gen/timezone.3 @@ -49,7 +49,7 @@ See ctime(3). .Pp The .Fn timezone -function returns a pointer to a time zone abbreviation for the specifed +function returns a pointer to a time zone abbreviation for the specified .Ar zone and .Ar dst diff --git a/lib/libc/gen/timezone.c b/lib/libc/gen/timezone.c index de12f8ff9e5c..9339d5e151a2 100644 --- a/lib/libc/gen/timezone.c +++ b/lib/libc/gen/timezone.c @@ -84,6 +84,7 @@ static struct zone { } zonetab[] = { -1*60, "MET", "MET DST", /* Middle European */ -2*60, "EET", "EET DST", /* Eastern European */ + -3*60, "MSK", "MSD", /* Moscow */ 4*60, "AST", "ADT", /* Atlantic */ 5*60, "EST", "EDT", /* Eastern */ 6*60, "CST", "CDT", /* Central */ diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3 index 19fd216fd8b5..dbdc1344a82f 100644 --- a/lib/libc/gen/ualarm.3 +++ b/lib/libc/gen/ualarm.3 @@ -70,7 +70,7 @@ microseconds have passed). When the signal has successfully been caught, .Fn alarm returns the amount of time left on the clock. -The maximum mumber of +The maximum number of .Ar microseconds allowed is 2147483647. diff --git a/lib/libc/i386/DEFS.h b/lib/libc/i386/DEFS.h index a07b090d90f0..4b4df3e68ccb 100644 --- a/lib/libc/i386/DEFS.h +++ b/lib/libc/i386/DEFS.h @@ -35,28 +35,49 @@ * * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 * - * $Id: DEFS.h,v 1.2 1993/10/09 08:30:43 davidg Exp $ + * $Id: DEFS.h,v 1.3.2.1 1994/05/04 08:44:15 rgrimes Exp $ */ +/* XXX should use align 4,0x90 for -m486. */ +#define _START_ENTRY .align 2,0x90; +#if 0 +/* Data is not used, except perhaps by non-g prof, which we don't support. */ +#define _MID_ENTRY .data; .align 2; 8:; .long 0; \ + .text; lea 8b,%eax; +#else +#define _MID_ENTRY +#endif + #ifdef PROF -#define ALTENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x:; \ - .data; .align 2; 1:; .long 0; \ - .text; lea 1b,%eax; call mcount; jmp 2f -#define ENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x:; \ - .data; .align 2; 1:; .long 0; \ - .text; lea 1b,%eax ; call mcount; 2: +#define ALTENTRY(x) _START_ENTRY \ + .globl _/**/x; .type _/**/x,@function; _/**/x:; \ + _MID_ENTRY \ + call mcount; jmp 9f -#define ALTASENTRY(x) .align 2,0x90; .globl x; x:; \ - .data; .align 2; 1:; .long 0; \ - .text; lea 1b,%eax; call mcount; jmp 2f +#define ENTRY(x) _START_ENTRY \ + .globl _/**/x; .type _/**/x,@function; _/**/x:; \ + _MID_ENTRY \ + call mcount; 9: + + +#define ALTASENTRY(x) _START_ENTRY \ + .globl x; .type x,@function; x:; \ + _MID_ENTRY \ + call mcount; jmp 9f + +#define ASENTRY(x) _START_ENTRY \ + .globl x; .type x,@function; x:; \ + _MID_ENTRY \ + call mcount; 9: + +#else /* !PROF */ + +#define ENTRY(x) _START_ENTRY .globl _/**/x; .type _/**/x,@function; \ + _/**/x: +#define ALTENTRY(x) ENTRY(x) + +#define ASENTRY(x) _START_ENTRY .globl x; .type x,@function; x: +#define ALTASENTRY(x) ASENTRY(x) -#define ASENTRY(x) .align 2,0x90; .globl x; x:; \ - .data; .align 2; 1:; .long 0; \ - .text; lea 1b,%eax; call mcount; 2: -#else -#define ALTENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x: -#define ENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x: -#define ALTASENTRY(x) .align 2,0x90; .globl x; x: -#define ASENTRY(x) .align 2,0x90; .globl x; x: #endif diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h index 1c7f3994049f..51d828141c7d 100644 --- a/lib/libc/i386/SYS.h +++ b/lib/libc/i386/SYS.h @@ -35,18 +35,32 @@ * * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91 * - * $Id: SYS.h,v 1.2 1993/10/09 08:30:48 davidg Exp $ + * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $ */ #include <syscall.h> +#include "DEFS.h" -#ifdef PROF -#define ENTRY(x) .globl _/**/x; \ - .data; 1:; .long 0; .text; .align 2,0x90; _/**/x: \ - movl $1b,%eax; call mcount +#ifdef PIC +#define PIC_PROLOGUE \ + pushl %ebx; \ + call 1f; \ +1: \ + popl %ebx; \ + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx +#define PIC_EPILOGUE \ + popl %ebx +#define PIC_PLT(x) x@PLT +#define PIC_GOT(x) x@GOT(%ebx) +#define PIC_GOTOFF(x) x@GOTOFF(%ebx) #else -#define ENTRY(x) .globl _/**/x; .text; .align 2,0x90; _/**/x: -#endif PROF +#define PIC_PROLOGUE +#define PIC_EPILOGUE +#define PIC_PLT(x) x +#define PIC_GOT(x) x +#define PIC_GOTOFF(x) x +#endif + #define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b #define RSYSCALL(x) SYSCALL(x); ret #define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret diff --git a/lib/libc/i386/gen/_setjmp.s b/lib/libc/i386/gen/_setjmp.S index 7aa3e69f84fb..7aa3e69f84fb 100644 --- a/lib/libc/i386/gen/_setjmp.s +++ b/lib/libc/i386/gen/_setjmp.S diff --git a/lib/libc/i386/gen/alloca.s b/lib/libc/i386/gen/alloca.S index 65378f5ff22b..65378f5ff22b 100644 --- a/lib/libc/i386/gen/alloca.s +++ b/lib/libc/i386/gen/alloca.S diff --git a/lib/libc/i386/gen/divsi3.s b/lib/libc/i386/gen/divsi3.S index a3731eca0247..b08319eaa659 100644 --- a/lib/libc/i386/gen/divsi3.s +++ b/lib/libc/i386/gen/divsi3.S @@ -39,6 +39,7 @@ #endif /* LIBC_SCCS and not lint */ .globl ___divsi3 + .type ___divsi3,@function ___divsi3: movl 4(%esp),%eax cltd diff --git a/lib/libc/i386/gen/fabs.s b/lib/libc/i386/gen/fabs.S index 2519e8b8abcf..2519e8b8abcf 100644 --- a/lib/libc/i386/gen/fabs.s +++ b/lib/libc/i386/gen/fabs.S diff --git a/lib/libc/i386/gen/fixdfsi.s b/lib/libc/i386/gen/fixdfsi.S index a264e83a37f2..a61c667c482c 100644 --- a/lib/libc/i386/gen/fixdfsi.s +++ b/lib/libc/i386/gen/fixdfsi.S @@ -2,6 +2,7 @@ .text .align 2 .globl ___fixdfsi +.type ___fixdfsi,@function ___fixdfsi: pushl %ebp movl %esp,%ebp diff --git a/lib/libc/i386/gen/fixunsdfsi.S b/lib/libc/i386/gen/fixunsdfsi.S new file mode 100644 index 000000000000..f61daeeea27c --- /dev/null +++ b/lib/libc/i386/gen/fixunsdfsi.S @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * + * from: @(#)fixunsdfsi.s 5.1 12/17/90 + * $Id: fixunsdfsi.S,v 1.1 1993/12/05 13:01:03 ats Exp $ + */ + +#if defined(LIBC_SCCS) + .text + .asciz "$Id: fixunsdfsi.S,v 1.1 1993/12/05 13:01:03 ats Exp $" +#endif + +#include "DEFS.h" +#include "SYS.h" + +ENTRY(__fixunsdfsi) + fldl 4(%esp) /* argument double to accum stack */ + frndint /* create integer */ +#ifdef PIC + PIC_PROLOGUE + leal PIC_GOTOFF(fbiggestsigned),%eax + PIC_EPILOGUE + fcoml (%eax) +#else + fcoml PIC_GOTOFF(fbiggestsigned) /* bigger than biggest signed? */ +#endif + fstsw %ax + sahf + jnb 1f + + fistpl 4(%esp) + movl 4(%esp),%eax + ret + +1: +#ifdef PIC + PIC_PROLOGUE + leal PIC_GOTOFF(fbiggestsigned),%eax + PIC_EPILOGUE + fsubl (%eax) +#else + fsubl PIC_GOTOFF(fbiggestsigned) /* reduce for proper conversion */ +#endif + fistpl 4(%esp) /* convert */ + movl 4(%esp),%eax + orl $0x80000000,%eax /* restore bias */ + PIC_EPILOGUE + ret + +fbiggestsigned: .double 0r2147483648.0 diff --git a/lib/libc/i386/gen/fixunsdfsi.s b/lib/libc/i386/gen/fixunsdfsi.s deleted file mode 100644 index 9f31df35d290..000000000000 --- a/lib/libc/i386/gen/fixunsdfsi.s +++ /dev/null @@ -1,50 +0,0 @@ - .file "__fixdfsi.s" -.text - .align 2 -.globl ___fixunsdfsi -___fixunsdfsi: - pushl %ebp - movl %esp,%ebp - subl $12,%esp - fstcw -4(%ebp) - movw -4(%ebp),%ax - orw $0x0c00,%ax - movw %ax,-2(%ebp) - fldcw -2(%ebp) - fldl 8(%ebp) - - fcoml fbiggestsigned /* bigger than biggest signed? */ - fstsw %ax - sahf - jnb 1f - - fistpl -12(%ebp) - movl -12(%ebp),%eax - jmp 2f - -1: fsubl fbiggestsigned /* reduce for proper conversion */ - fistpl -12(%ebp) /* convert */ - movl -12(%ebp),%eax - orl $0x80000000,%eax /* restore bias */ - -2: fldcw -4(%ebp) - leave - ret - - fcoml fbiggestsigned /* bigger than biggest signed? */ - fstsw %ax - sahf - jnb 1f - - fistpl 4(%esp) - movl 4(%esp),%eax - ret - -1: fsubl fbiggestsigned /* reduce for proper conversion */ - fistpl 4(%esp) /* convert */ - movl 4(%esp),%eax - orl $0x80000000,%eax /* restore bias */ - ret - - .data -fbiggestsigned: .double 0r2147483648.0 diff --git a/lib/libc/i386/gen/modf.s b/lib/libc/i386/gen/modf.S index 978782a50d03..246729f13e95 100644 --- a/lib/libc/i386/gen/modf.s +++ b/lib/libc/i386/gen/modf.S @@ -49,6 +49,7 @@ /* With CHOP mode on, frndint behaves as TRUNC does. Useful. */ .text .globl _modf +.type _modf,@function _modf: pushl %ebp movl %esp,%ebp diff --git a/lib/libc/i386/gen/setjmp.s b/lib/libc/i386/gen/setjmp.S index 5482caa24541..d9fc66e6f991 100644 --- a/lib/libc/i386/gen/setjmp.s +++ b/lib/libc/i386/gen/setjmp.S @@ -50,10 +50,11 @@ */ #include "DEFS.h" +#include "SYS.h" ENTRY(setjmp) pushl $0 - call _sigblock + call PIC_PLT(_sigblock) popl %edx movl 4(%esp),%ecx movl 0(%esp),%edx @@ -71,7 +72,7 @@ ENTRY(setjmp) ENTRY(longjmp) movl 4(%esp),%edx pushl 24(%edx) - call _sigsetmask /* XXX this is not reentrant */ + call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */ popl %eax movl 4(%esp),%edx movl 8(%esp),%eax diff --git a/lib/libc/i386/gen/sigsetjmp.s b/lib/libc/i386/gen/sigsetjmp.S index a2f8d4269214..6c243869daad 100644 --- a/lib/libc/i386/gen/sigsetjmp.s +++ b/lib/libc/i386/gen/sigsetjmp.S @@ -35,15 +35,16 @@ * * * from: @(#)setjmp.s 5.1 (Berkeley) 4/23/90" - * $Id: sigsetjmp.s,v 1.2 1993/10/20 17:37:41 jtc Exp $ + * $Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) .text - .asciz "$Id: sigsetjmp.s,v 1.2 1993/10/20 17:37:41 jtc Exp $" + .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $" #endif /* LIBC_SCCS and not lint */ #include "DEFS.h" +#include "SYS.h" ENTRY(sigsetjmp) movl 8(%esp),%eax @@ -52,7 +53,7 @@ ENTRY(sigsetjmp) testl %eax,%eax jz 1f pushl $0 - call _sigblock + call PIC_PLT(_sigblock) addl $4,%esp movl 4(%esp),%ecx movl %eax,28(%ecx) @@ -71,7 +72,7 @@ ENTRY(siglongjmp) cmpl $0,24(%edx) jz 1f pushl 28(%edx) - call _sigsetmask + call PIC_PLT(_sigsetmask) addl $4,%esp 1: movl 4(%esp),%edx movl 8(%esp),%eax diff --git a/lib/libc/i386/gen/udivsi3.s b/lib/libc/i386/gen/udivsi3.S index da395d34490e..f05e004b10c6 100644 --- a/lib/libc/i386/gen/udivsi3.s +++ b/lib/libc/i386/gen/udivsi3.S @@ -39,6 +39,7 @@ #endif /* LIBC_SCCS and not lint */ .globl ___udivsi3 + .type ___udivsi3,@function ___udivsi3: movl 4(%esp),%eax xorl %edx,%edx diff --git a/lib/libc/i386/net/htonl.s b/lib/libc/i386/net/htonl.S index a65e3f086412..a65e3f086412 100644 --- a/lib/libc/i386/net/htonl.s +++ b/lib/libc/i386/net/htonl.S diff --git a/lib/libc/i386/net/htons.s b/lib/libc/i386/net/htons.S index 6b3fbb05a6e5..6b3fbb05a6e5 100644 --- a/lib/libc/i386/net/htons.s +++ b/lib/libc/i386/net/htons.S diff --git a/lib/libc/i386/net/ntohl.s b/lib/libc/i386/net/ntohl.S index 5748f9ec8e97..5748f9ec8e97 100644 --- a/lib/libc/i386/net/ntohl.s +++ b/lib/libc/i386/net/ntohl.S diff --git a/lib/libc/i386/net/ntohs.s b/lib/libc/i386/net/ntohs.S index 084c8620bd87..084c8620bd87 100644 --- a/lib/libc/i386/net/ntohs.s +++ b/lib/libc/i386/net/ntohs.S diff --git a/lib/libc/i386/stdlib/abs.s b/lib/libc/i386/stdlib/abs.S index 3122fcb84f6f..3122fcb84f6f 100644 --- a/lib/libc/i386/stdlib/abs.s +++ b/lib/libc/i386/stdlib/abs.S diff --git a/lib/libc/i386/stdlib/div.s b/lib/libc/i386/stdlib/div.S index 9b90e768de2d..b4f89d280955 100644 --- a/lib/libc/i386/stdlib/div.s +++ b/lib/libc/i386/stdlib/div.S @@ -27,12 +27,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: div.s,v 1.1 1993/10/08 20:13:38 jtc Exp $ + * $Id: div.S,v 1.1 1993/12/04 21:46:15 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) .text - .asciz "$Id: div.s,v 1.1 1993/10/08 20:13:38 jtc Exp $" + .asciz "$Id: div.S,v 1.1 1993/12/04 21:46:15 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/stdlib/labs.s b/lib/libc/i386/stdlib/labs.S index b7a1c5dceebb..b7a1c5dceebb 100644 --- a/lib/libc/i386/stdlib/labs.s +++ b/lib/libc/i386/stdlib/labs.S diff --git a/lib/libc/i386/stdlib/ldiv.s b/lib/libc/i386/stdlib/ldiv.S index f203b41a1787..de7bb948ab4c 100644 --- a/lib/libc/i386/stdlib/ldiv.s +++ b/lib/libc/i386/stdlib/ldiv.S @@ -27,12 +27,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ldiv.s,v 1.1 1993/10/08 20:13:41 jtc Exp $ + * $Id: ldiv.S,v 1.1 1993/12/04 21:46:17 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) .text - .asciz "$Id: ldiv.s,v 1.1 1993/10/08 20:13:41 jtc Exp $" + .asciz "$Id: ldiv.S,v 1.1 1993/12/04 21:46:17 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/bcmp.s b/lib/libc/i386/string/bcmp.S index 4bf83346b46c..21027dadd8b4 100644 --- a/lib/libc/i386/string/bcmp.s +++ b/lib/libc/i386/string/bcmp.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: bcmp.s,v 1.2 1993/10/09 08:31:09 davidg Exp $ + * $Id: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: bcmp.s,v 1.2 1993/10/09 08:31:09 davidg Exp $" + .asciz "$Id: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/bcopy.s b/lib/libc/i386/string/bcopy.S index 7958d3f40972..b68cdf3c4805 100644 --- a/lib/libc/i386/string/bcopy.s +++ b/lib/libc/i386/string/bcopy.S @@ -32,11 +32,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bcopy.s,v 1.3 1993/10/09 08:31:14 davidg Exp $ + * $Id: bcopy.S,v 1.1 1993/12/05 13:01:41 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: bcopy.s,v 1.3 1993/10/09 08:31:14 davidg Exp $" + .asciz "$Id: bcopy.S,v 1.1 1993/12/05 13:01:41 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/bzero.s b/lib/libc/i386/string/bzero.S index 9349954fe80c..7e0dcdc3c785 100644 --- a/lib/libc/i386/string/bzero.s +++ b/lib/libc/i386/string/bzero.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: bzero.s,v 1.2 1993/08/16 18:40:26 jtc Exp $ + * $Id: bzero.S,v 1.1 1993/12/05 13:01:42 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: bzero.s,v 1.2 1993/08/16 18:40:26 jtc Exp $" + .asciz "$Id: bzero.S,v 1.1 1993/12/05 13:01:42 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/ffs.s b/lib/libc/i386/string/ffs.S index 5be6f3b988d6..42b635768bec 100644 --- a/lib/libc/i386/string/ffs.s +++ b/lib/libc/i386/string/ffs.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ffs.s,v 1.1 1993/08/16 18:40:28 jtc Exp $ + * $Id: ffs.S,v 1.1 1993/12/05 13:01:43 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: ffs.s,v 1.1 1993/08/16 18:40:28 jtc Exp $" + .asciz "$Id: ffs.S,v 1.1 1993/12/05 13:01:43 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/index.s b/lib/libc/i386/string/index.S index 8fb3ec016d1d..1ac847341fe6 100644 --- a/lib/libc/i386/string/index.s +++ b/lib/libc/i386/string/index.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: index.s,v 1.1 1993/08/16 18:40:30 jtc Exp $ + * $Id: index.S,v 1.1 1993/12/05 13:01:46 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: index.s,v 1.1 1993/08/16 18:40:30 jtc Exp $" + .asciz "$Id: index.S,v 1.1 1993/12/05 13:01:46 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/memchr.s b/lib/libc/i386/string/memchr.S index 6b519d9033fd..5ff0a34dc1ee 100644 --- a/lib/libc/i386/string/memchr.s +++ b/lib/libc/i386/string/memchr.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: memchr.s,v 1.1 1993/08/16 18:40:32 jtc Exp $ + * $Id: memchr.S,v 1.1 1993/12/05 13:01:47 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: memchr.s,v 1.1 1993/08/16 18:40:32 jtc Exp $" + .asciz "$Id: memchr.S,v 1.1 1993/12/05 13:01:47 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/memcmp.s b/lib/libc/i386/string/memcmp.S index 8e285651e4af..e1fdaaa31f6e 100644 --- a/lib/libc/i386/string/memcmp.s +++ b/lib/libc/i386/string/memcmp.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: memcmp.s,v 1.2 1993/10/09 08:31:18 davidg Exp $ + * $Id: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: memcmp.s,v 1.2 1993/10/09 08:31:18 davidg Exp $" + .asciz "$Id: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" @@ -73,8 +73,8 @@ L5: movl $4,%ecx /* We know that one of the next */ subl %ecx,%esi /* match. */ repe cmpsb -L6: movsbl -1(%edi),%eax /* Perform unsigned comparison */ - movsbl -1(%esi),%edx +L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */ + movzbl -1(%esi),%edx subl %edx,%eax popl %esi popl %edi diff --git a/lib/libc/i386/string/memmove.s b/lib/libc/i386/string/memmove.S index 8ca0e300d262..57e52ad04295 100644 --- a/lib/libc/i386/string/memmove.s +++ b/lib/libc/i386/string/memmove.S @@ -32,11 +32,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: memmove.s,v 1.2 1993/10/09 08:31:22 davidg Exp $ + * $Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: memmove.s,v 1.2 1993/10/09 08:31:22 davidg Exp $" + .asciz "$Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/memset.s b/lib/libc/i386/string/memset.S index 8c1a8c8b722d..47e763781932 100644 --- a/lib/libc/i386/string/memset.s +++ b/lib/libc/i386/string/memset.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: memset.s,v 1.1 1993/08/16 18:40:38 jtc Exp $ + * $Id: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: memset.s,v 1.1 1993/08/16 18:40:38 jtc Exp $" + .asciz "$Id: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/rindex.s b/lib/libc/i386/string/rindex.S index 4fe028c36f2f..3e95f5f0b853 100644 --- a/lib/libc/i386/string/rindex.s +++ b/lib/libc/i386/string/rindex.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rindex.s,v 1.1 1993/08/16 18:40:39 jtc Exp $ + * $Id: rindex.S,v 1.1 1993/12/05 13:01:55 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: rindex.s,v 1.1 1993/08/16 18:40:39 jtc Exp $" + .asciz "$Id: rindex.S,v 1.1 1993/12/05 13:01:55 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/strcat.s b/lib/libc/i386/string/strcat.S index 0e4a3e27adf4..5bb6fc4074c2 100644 --- a/lib/libc/i386/string/strcat.s +++ b/lib/libc/i386/string/strcat.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strcat.s,v 1.1 1993/08/16 18:40:41 jtc Exp $ + * $Id: strcat.S,v 1.1 1993/12/05 13:01:56 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strcat.s,v 1.1 1993/08/16 18:40:41 jtc Exp $" + .asciz "$Id: strcat.S,v 1.1 1993/12/05 13:01:56 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/strchr.s b/lib/libc/i386/string/strchr.S index aa35dfb4c50a..1b44b2824395 100644 --- a/lib/libc/i386/string/strchr.s +++ b/lib/libc/i386/string/strchr.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strchr.s,v 1.1 1993/08/16 18:40:42 jtc Exp $ + * $Id: strchr.S,v 1.1 1993/12/05 13:01:56 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strchr.s,v 1.1 1993/08/16 18:40:42 jtc Exp $" + .asciz "$Id: strchr.S,v 1.1 1993/12/05 13:01:56 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/strcmp.s b/lib/libc/i386/string/strcmp.S index 8050234aaca4..015c21aa7fa3 100644 --- a/lib/libc/i386/string/strcmp.s +++ b/lib/libc/i386/string/strcmp.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strcmp.s,v 1.2 1993/10/08 20:42:24 jtc Exp $ + * $Id: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strcmp.s,v 1.2 1993/10/08 20:42:24 jtc Exp $" + .asciz "$Id: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" @@ -118,7 +118,7 @@ L2: movb (%eax),%cl cmpb %cl,(%edx) je L1 .align 2, 0x90 -L3: movsbl (%eax),%eax /* unsigned comparison */ - movsbl (%edx),%edx +L3: movzbl (%eax),%eax /* unsigned comparison */ + movzbl (%edx),%edx subl %edx,%eax ret diff --git a/lib/libc/i386/string/strcpy.s b/lib/libc/i386/string/strcpy.S index 6f2596a4d593..07983f9c2539 100644 --- a/lib/libc/i386/string/strcpy.s +++ b/lib/libc/i386/string/strcpy.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strcpy.s,v 1.1 1993/08/16 18:40:44 jtc Exp $ + * $Id: strcpy.S,v 1.1 1993/12/05 13:01:58 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strcpy.s,v 1.1 1993/08/16 18:40:44 jtc Exp $" + .asciz "$Id: strcpy.S,v 1.1 1993/12/05 13:01:58 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/strlen.s b/lib/libc/i386/string/strlen.S index 877ab6440934..3729fa52fefd 100644 --- a/lib/libc/i386/string/strlen.s +++ b/lib/libc/i386/string/strlen.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strlen.s,v 1.2 1993/10/09 08:31:25 davidg Exp $ + * $Id: strlen.S,v 1.1 1993/12/05 13:01:59 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strlen.s,v 1.2 1993/10/09 08:31:25 davidg Exp $" + .asciz "$Id: strlen.S,v 1.1 1993/12/05 13:01:59 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/string/strncmp.s b/lib/libc/i386/string/strncmp.S index ada9a80cbc13..72922fb30fec 100644 --- a/lib/libc/i386/string/strncmp.s +++ b/lib/libc/i386/string/strncmp.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strncmp.s,v 1.2 1993/10/08 20:42:25 jtc Exp $ + * $Id: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strncmp.s,v 1.2 1993/10/08 20:42:25 jtc Exp $" + .asciz "$Id: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" @@ -145,8 +145,8 @@ L2: testl %edx,%edx /* Have we compared n chars yet? */ cmpb %bl,(%ecx) je L1 .align 2,0x90 -L3: movsbl (%eax),%eax /* unsigned comparision */ - movsbl (%ecx),%ecx +L3: movzbl (%eax),%eax /* unsigned comparision */ + movzbl (%ecx),%ecx subl %ecx,%eax popl %ebx ret diff --git a/lib/libc/i386/string/strrchr.s b/lib/libc/i386/string/strrchr.S index c3728602e7b7..ef4d776ea471 100644 --- a/lib/libc/i386/string/strrchr.s +++ b/lib/libc/i386/string/strrchr.S @@ -27,11 +27,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: strrchr.s,v 1.1 1993/08/16 18:40:50 jtc Exp $ + * $Id: strrchr.S,v 1.1 1993/12/05 13:02:01 ats Exp $ */ #if defined(LIBC_RCS) && !defined(lint) - .asciz "$Id: strrchr.s,v 1.1 1993/08/16 18:40:50 jtc Exp $" + .asciz "$Id: strrchr.S,v 1.1 1993/12/05 13:02:01 ats Exp $" #endif /* LIBC_RCS and not lint */ #include "DEFS.h" diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc new file mode 100644 index 000000000000..4bbec8b7a7b6 --- /dev/null +++ b/lib/libc/i386/sys/Makefile.inc @@ -0,0 +1,10 @@ +# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp +# $Id: Makefile.inc,v 1.2 1994/02/21 05:19:06 rgrimes Exp $ + +.PATH: ${.CURDIR}/${MACHINE}/sys + +SRCS+= i386_get_ldt.c i386_set_ldt.c + +MAN2+= i386/sys/i386_get_ldt.2 + +MLINKS+=i386_get_ldt.2 i386_set_ldt.2 diff --git a/lib/libc/i386/sys/Ovfork.s b/lib/libc/i386/sys/Ovfork.S index bb44ee899eb3..181dae564286 100644 --- a/lib/libc/i386/sys/Ovfork.s +++ b/lib/libc/i386/sys/Ovfork.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: Ovfork.S,v 1.3 1994/02/21 05:19:08 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) @@ -49,6 +51,7 @@ */ .set vfork,66 .globl _vfork +.type _vfork,@function _vfork: popl %ecx /* my rta into ecx */ @@ -61,7 +64,14 @@ vforkok: jmp parent .globl _errno verror: +#ifdef PIC + PIC_PROLOGUE + movl PIC_GOT(_errno), %edx + movl %eax,(%edx) + PIC_EPILOGUE +#else movl %eax,_errno +#endif movl $-1,%eax jmp %ecx child: diff --git a/lib/libc/i386/sys/brk.s b/lib/libc/i386/sys/brk.S index ce4717409f84..e884ac267514 100644 --- a/lib/libc/i386/sys/brk.s +++ b/lib/libc/i386/sys/brk.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: brk.S,v 1.3 1994/02/21 05:13:26 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) @@ -48,6 +50,29 @@ ENTRY(_brk) jmp ok ENTRY(brk) +#ifdef PIC + movl 4(%esp),%eax + PIC_PROLOGUE + movl PIC_GOT(curbrk),%edx # set up GOT addressing + movl PIC_GOT(minbrk),%ecx # + cmpl %eax,(%ecx) + PIC_EPILOGUE + jl ok + movl (%ecx),%eax + movl %eax,4(%esp) +ok: + lea SYS_brk,%eax + LCALL(7,0) + jb err + movl 4(%esp),%eax + movl %eax,(%edx) + movl $0,%eax + ret +err: + jmp PIC_PLT(cerror) + +#else + movl 4(%esp),%eax cmpl %eax,minbrk jl ok @@ -63,3 +88,4 @@ ok: ret err: jmp cerror +#endif diff --git a/lib/libc/i386/sys/cerror.s b/lib/libc/i386/sys/cerror.S index 6021fe2dd0f2..27fec0aecbb9 100644 --- a/lib/libc/i386/sys/cerror.s +++ b/lib/libc/i386/sys/cerror.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: cerror.S,v 1.2 1994/02/21 05:19:09 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) @@ -42,6 +44,13 @@ .globl _errno cerror: +#ifdef PIC + PIC_PROLOGUE + movl PIC_GOT(_errno),%ecx + movl %eax,(%ecx) + PIC_EPILOGUE +#else movl %eax,_errno +#endif movl $-1,%eax ret diff --git a/lib/libc/i386/sys/exect.s b/lib/libc/i386/sys/exect.S index 3a17aacbbe2d..1739760f887a 100644 --- a/lib/libc/i386/sys/exect.s +++ b/lib/libc/i386/sys/exect.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: exect.S,v 1.2 1994/02/21 05:19:10 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/fork.s b/lib/libc/i386/sys/fork.S index 0bfa6627edfe..15b7c46dfe96 100644 --- a/lib/libc/i386/sys/fork.s +++ b/lib/libc/i386/sys/fork.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: fork.S,v 1.2 1994/02/21 05:19:11 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/i386_get_ldt.2 b/lib/libc/i386/sys/i386_get_ldt.2 new file mode 100644 index 000000000000..8d131c9628a3 --- /dev/null +++ b/lib/libc/i386/sys/i386_get_ldt.2 @@ -0,0 +1,98 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91 +.\" $Id: i386_get_ldt.2,v 1.1 1994/01/31 12:05:30 davidg Exp $ +.\" +.Dd September 20, 1993 +.Dt I386_GET_LDT 2 +.Os FreeBSD +.Sh NAME +.Nm i386_get_ldt , +.Nm i386_set_ldt +.Nd manage i386 per-process Local Descriptor Table entries +.Sh SYNOPSIS +.Fd #include <machine/segments.h> +.Fd #include <machine/sysarch.h> +.Ft int +.Fn i386_get_ldt "int start_sel" "union descriptor *descs" "int num_sels" +.Ft int +.Fn i386_set_ldt "int start_sel" "union descriptor *descs" "int num_sels" +.Sh DESCRIPTION +.Fn i386_get_ldt +will return the list of i386 descriptors that the process has in its +LDT. +.Fn i386_set_ldt +will set a list of i386 descriptors for the current process in its +LDT. +Both routines accept a starting selector number +.Fa start_sel +, an array of memory that +will contain the descriptors to be set or returned +.Fa descs +, and the number of entries to set or return +.Fa num_sels . +.Pp +The argument +.Fa descs +can be either segment_descriptor or gate_descriptor and are defined in +.Fd <i386/segments.h> . +These structures are defined by the architecure +as disjoint bit-fields, so care must be taken in constructing them. +.Sh RETURN VALUES +Upon successful completion, +.Fn i386_get_ldt +returns the number of descriptors currently in the LDT. +.Fn i386_set_ldt +returns the first selector set. +Otherwise, a value of -1 is returned and the global +variable +.Va errno +is set to indicate the error. +.Sh ERRORS +.Fn i386_get_ldt +and +.Fn i386_set_ldt +will fail if: +.Bl -tag -width [EINVAL] +.It Bq Er EINVAL +An inappropriate parameter was used for +.Fa start_sel +or +.Fa num_sels . +.It Bq Er EACESS +The caller attempted to use a descriptor that would +circumvent protection or cause a failure. +.El +.Sh REFERENCES +i386 Microprocessor Programmer's Reference Manual, Intel +.Sh WARNING +You can really hose your process using this. diff --git a/lib/libc/i386/sys/i386_get_ldt.c b/lib/libc/i386/sys/i386_get_ldt.c new file mode 100644 index 000000000000..989c6b6bb4f4 --- /dev/null +++ b/lib/libc/i386/sys/i386_get_ldt.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1993 John Brezak + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +#include <machine/segments.h> +#include <machine/sysarch.h> + +struct parms { + int start; + union descriptor *descs; + int num; +}; + +int +i386_get_ldt(int start, union descriptor *descs, int num) +{ + struct parms p; + + p.start = start; + p.descs = descs; + p.num = num; + + return sysarch(I386_GET_LDT, (char *)&p); +} diff --git a/lib/libc/i386/sys/i386_set_ldt.c b/lib/libc/i386/sys/i386_set_ldt.c new file mode 100644 index 000000000000..377437eaf9ce --- /dev/null +++ b/lib/libc/i386/sys/i386_set_ldt.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1993 John Brezak + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +#include <machine/segments.h> +#include <machine/sysarch.h> + +struct parms { + int start; + union descriptor *descs; + int num; +}; + +int +i386_set_ldt(int start, union descriptor *descs, int num) +{ + struct parms p; + + p.start = start; + p.descs = descs; + p.num = num; + + return sysarch(I386_SET_LDT, (char *)&p); +} diff --git a/lib/libc/i386/sys/mount.s b/lib/libc/i386/sys/mount.S index 2a719f9a9fbb..e0366db6b750 100644 --- a/lib/libc/i386/sys/mount.s +++ b/lib/libc/i386/sys/mount.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: mount.S,v 1.2 1994/02/21 05:19:12 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/pipe.s b/lib/libc/i386/sys/pipe.S index 60d6cd402cad..2aeae5813958 100644 --- a/lib/libc/i386/sys/pipe.s +++ b/lib/libc/i386/sys/pipe.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: pipe.S,v 1.2 1994/02/21 05:19:13 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/ptrace.s b/lib/libc/i386/sys/ptrace.S index 703c4249f7c8..6137098fcdf5 100644 --- a/lib/libc/i386/sys/ptrace.s +++ b/lib/libc/i386/sys/ptrace.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: ptrace.S,v 1.2 1994/02/21 05:19:14 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) @@ -42,7 +44,14 @@ ENTRY(ptrace) xorl %eax,%eax - movl %eax,_errno +#ifdef PIC + PIC_PROLOGUE + movl PIC_GOT(_errno),%edx + movl %eax,(%edx) + PIC_EPILOGUE +#else + movl %eax,_errno +#endif lea SYS_ptrace,%eax LCALL(7,0) jb err diff --git a/lib/libc/i386/sys/reboot.s b/lib/libc/i386/sys/reboot.S index 74c3633d2e1a..47e2f0a4b15a 100644 --- a/lib/libc/i386/sys/reboot.s +++ b/lib/libc/i386/sys/reboot.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: reboot.S,v 1.2 1994/02/21 05:19:15 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/sbrk.s b/lib/libc/i386/sys/sbrk.S index ccafa2936acc..fef35cb529c8 100644 --- a/lib/libc/i386/sys/sbrk.s +++ b/lib/libc/i386/sys/sbrk.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: sbrk.S,v 1.2 1994/02/21 05:19:16 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) @@ -52,6 +54,27 @@ curbrk: .long _end .text ENTRY(sbrk) +#ifdef PIC + movl 4(%esp),%ecx + PIC_PROLOGUE + movl PIC_GOT(curbrk),%edx + movl (%edx),%eax + PIC_EPILOGUE + addl %eax,4(%esp) + lea SYS_brk,%eax + LCALL(7,0) + jb err + PIC_PROLOGUE + movl PIC_GOT(curbrk),%edx + movl (%edx),%eax + addl %ecx,(%edx) + PIC_EPILOGUE + ret +err: + jmp PIC_PLT(cerror) + +#else + movl 4(%esp),%ecx movl curbrk,%eax addl %eax,4(%esp) @@ -63,3 +86,4 @@ ENTRY(sbrk) ret err: jmp cerror +#endif diff --git a/lib/libc/i386/sys/setlogin.s b/lib/libc/i386/sys/setlogin.S index 227e40382889..92d761a53577 100644 --- a/lib/libc/i386/sys/setlogin.s +++ b/lib/libc/i386/sys/setlogin.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: setlogin.S,v 1.2 1994/02/21 05:19:17 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) @@ -43,5 +45,14 @@ .globl __logname_valid /* in getlogin() */ SYSCALL(setlogin) +#ifdef PIC + PIC_PROLOGUE + pushl %eax + movl PIC_GOT(__logname_valid),%eax + movl $0,(%eax) + popl %eax + PIC_EPILOGUE +#else movl $0,__logname_valid +#endif ret /* setlogin(name) */ diff --git a/lib/libc/i386/sys/sigpending.s b/lib/libc/i386/sys/sigpending.S index a0b643536f86..4318b6d9aabd 100644 --- a/lib/libc/i386/sys/sigpending.s +++ b/lib/libc/i386/sys/sigpending.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: sigpending.S,v 1.2 1994/02/21 05:19:19 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/sigprocmask.s b/lib/libc/i386/sys/sigprocmask.S index 2872c1faef11..ce929a03b081 100644 --- a/lib/libc/i386/sys/sigprocmask.s +++ b/lib/libc/i386/sys/sigprocmask.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: sigprocmask.S,v 1.2 1994/02/21 05:19:20 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/sigreturn.s b/lib/libc/i386/sys/sigreturn.S index f64d5e6e6da9..b98c9508e8d8 100644 --- a/lib/libc/i386/sys/sigreturn.s +++ b/lib/libc/i386/sys/sigreturn.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: sigreturn.S,v 1.2 1994/02/21 05:19:21 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/i386/sys/sigsuspend.s b/lib/libc/i386/sys/sigsuspend.S index 1db4c1a3543c..1db4c1a3543c 100644 --- a/lib/libc/i386/sys/sigsuspend.s +++ b/lib/libc/i386/sys/sigsuspend.S diff --git a/lib/libc/i386/sys/syscall.s b/lib/libc/i386/sys/syscall.S index 32274930a022..37d180410e0c 100644 --- a/lib/libc/i386/sys/syscall.s +++ b/lib/libc/i386/sys/syscall.S @@ -32,6 +32,8 @@ * 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. + * + * $Id: syscall.S,v 1.2 1994/02/21 05:19:22 rgrimes Exp $ */ #if defined(SYSLIBC_SCCS) && !defined(lint) diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc index 23b89e27eb7b..55ca82824e52 100644 --- a/lib/libc/net/Makefile.inc +++ b/lib/libc/net/Makefile.inc @@ -14,7 +14,7 @@ SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ .if (${MACHINE} == "hp300") SRCS+= htonl.s htons.s ntohl.s ntohs.s .elif (${MACHINE} == "i386") -SRCS+= htonl.s htons.s ntohl.s ntohs.s +SRCS+= htonl.S htons.S ntohl.S ntohs.S .elif (${MACHINE} == "tahoe") SRCS+= htonl.s htons.s ntohl.s ntohs.s .elif (${MACHINE} == "vax") diff --git a/lib/libc/net/gethostbyname.3 b/lib/libc/net/gethostbyname.3 index 61d1017166b5..df0a9c9f9cc6 100644 --- a/lib/libc/net/gethostbyname.3 +++ b/lib/libc/net/gethostbyname.3 @@ -97,7 +97,7 @@ Host addresses are returned in network byte order. .It Fa h_addr The first address in .Fa h_addr_list ; -this is for backward compatiblity. +this is for backward compatibility. .Pp When using the nameserver, .Fn gethostbyname diff --git a/lib/libc/quad/Makefile.inc b/lib/libc/quad/Makefile.inc new file mode 100644 index 000000000000..ef690dc4a0bf --- /dev/null +++ b/lib/libc/quad/Makefile.inc @@ -0,0 +1,10 @@ +# @(#)Makefile.inc 5.3 (Berkeley) 7/7/92 + +# Quad support +SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \ + fixsfdi.c fixunsdfdi.c fixunssfdi.c floatdidf.c floatdisf.c \ + floatunsdidf.c iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c \ + negdi2.c notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \ + xordi3.c + +.PATH: ${.CURDIR}/${MACHINE}/quad ${.CURDIR}/quad diff --git a/lib/libc/quad/TESTS/Makefile b/lib/libc/quad/TESTS/Makefile new file mode 100644 index 000000000000..f5e3d6e215c7 --- /dev/null +++ b/lib/libc/quad/TESTS/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 5.1 (Berkeley) 6/2/92 + +all: mul divrem + +MUL= mul.c ../muldi3.c +mul: ${MUL} + gcc -g -DSPARC_XXX ${MUL} -o $@ + +DIVREM= divrem.c ../qdivrem.c +divrem: ${DIVREM} + gcc -g -DSPARC_XXX ${DIVREM} -o $@ diff --git a/lib/libtelnet/getent.c b/lib/libc/quad/TESTS/divrem.c index 83b885773f91..903eecb4c246 100644 --- a/lib/libtelnet/getent.c +++ b/lib/libc/quad/TESTS/divrem.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 1991 The Regents of the University of California. + * Copyright (c) 1992 The Regents of the University of California. * All rights reserved. * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,39 +36,43 @@ */ #ifndef lint -static char sccsid[] = "@(#)getent.c 5.1 (Berkeley) 2/28/91"; +char copyright[] = +"@(#) Copyright (c) 1992 The Regents of the University of California.\n\ + All rights reserved.\n"; #endif /* not lint */ -/* - * Copyright (c) 1991 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ +#ifndef lint +static char sccsid[] = "@(#)divrem.c 5.1 (Berkeley) 6/2/92"; +#endif /* not lint */ -/*ARGSUSED*/ -getent(cp, name) -char *cp, *name; -{ - return(0); -} +#include <stdio.h> -/*ARGSUSED*/ -char * -getstr(cp, cpp) -char *cp, **cpp; +main() { - return(0); + union { long long q; unsigned long v[2]; } a, b, q, r; + char buf[300]; + extern long long __qdivrem(unsigned long long, unsigned long long, + unsigned long long *); + + for (;;) { + printf("> "); + if (fgets(buf, sizeof buf, stdin) == NULL) + break; + if (sscanf(buf, "%lu:%lu %lu:%lu", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && + sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { + printf("eh?\n"); + continue; + } + q.q = __qdivrem(a.q, b.q, &r.q); + printf("%lx:%lx /%% %lx:%lx => q=%lx:%lx r=%lx:%lx\n", + a.v[0], a.v[1], b.v[0], b.v[1], + q.v[0], q.v[1], r.v[0], r.v[1]); + printf(" = %lX%08lX / %lX%08lX => %lX%08lX\n\ + = %lX%08lX %% %lX%08lX => %lX%08lX\n", + a.v[0], a.v[1], b.v[0], b.v[1], q.v[0], q.v[1], + a.v[0], a.v[1], b.v[0], b.v[1], r.v[0], r.v[1]); + } + exit(0); } diff --git a/lib/libcurses/mvprintw.c b/lib/libc/quad/TESTS/mul.c index 63aa58fefd34..07eff09dac95 100644 --- a/lib/libcurses/mvprintw.c +++ b/lib/libc/quad/TESTS/mul.c @@ -1,7 +1,11 @@ -/* - * Copyright (c) 1981 Regents of the University of California. +/*- + * Copyright (c) 1992 The Regents of the University of California. * All rights reserved. * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,66 +36,39 @@ */ #ifndef lint -static char sccsid[] = "@(#)mvprintw.c 5.8 (Berkeley) 6/19/91"; +char copyright[] = +"@(#) Copyright (c) 1992 The Regents of the University of California.\n\ + All rights reserved.\n"; #endif /* not lint */ -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "curses.ext" - -/* - * implement the mvprintw commands. Due to the variable number of - * arguments, they cannot be macros. Sigh.... - */ - -#if __STDC__ -mvprintw(reg int y, reg int x, const char *fmt, ...) -#else -mvprintw(y, x, fmt, va_alist) - reg int y, x; - char *fmt; - va_dcl -#endif -{ - va_list ap; - int ret; +#ifndef lint +static char sccsid[] = "@(#)mul.c 5.1 (Berkeley) 6/2/92"; +#endif /* not lint */ - if (move(y, x) != OK) - return ERR; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = _sprintw(stdscr, fmt, ap); - va_end(ap); - return ret; -} +#include <stdio.h> -#if __STDC__ -mvwprintw(reg WINDOW *win, reg int y, reg int x, const char *fmt, ...) -#else -mvwprintw(win, y, x, fmt, va_alist) - reg WINDOW *win; - reg int y, x; - char *fmt; - va_dcl -#endif +main() { - va_list ap; - int ret; + union { long long q; unsigned long v[2]; } a, b, m; + char buf[300]; + extern long long __muldi3(long long, long long); - if (wmove(win, y, x) != OK) - return ERR; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = _sprintw(win, fmt, ap); - va_end(ap); - return ret; + for (;;) { + printf("> "); + if (fgets(buf, sizeof buf, stdin) == NULL) + break; + if (sscanf(buf, "%lu:%lu %lu:%lu", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && + sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { + printf("eh?\n"); + continue; + } + m.q = __muldi3(a.q, b.q); + printf("%lx:%lx * %lx:%lx => %lx:%lx\n", + a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); + printf(" = %lX%08lX * %lX%08lX => %lX%08lX\n", + a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); + } + exit(0); } diff --git a/lib/libc/quad/adddi3.c b/lib/libc/quad/adddi3.c new file mode 100644 index 000000000000..dd5e7d19a2b8 --- /dev/null +++ b/lib/libc/quad/adddi3.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)adddi3.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Add two quads. This is trivial since a one-bit carry from a single + * u_long addition x+y occurs if and only if the sum x+y is less than + * either x or y (the choice to compare with x or y is arbitrary). + */ +quad_t +__adddi3(a, b) + quad_t a, b; +{ + union uu aa, bb, sum; + + aa.q = a; + bb.q = b; + sum.ul[L] = aa.ul[L] + bb.ul[L]; + sum.ul[H] = aa.ul[H] + bb.ul[H] + (sum.ul[L] < bb.ul[L]); + return (sum.q); +} diff --git a/lib/libc/quad/anddi3.c b/lib/libc/quad/anddi3.c new file mode 100644 index 000000000000..c2c6cbf5ab39 --- /dev/null +++ b/lib/libc/quad/anddi3.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)anddi3.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return a & b, in quad. + */ +quad_t +__anddi3(a, b) + quad_t a, b; +{ + union uu aa, bb; + + aa.q = a; + bb.q = b; + aa.ul[0] &= bb.ul[0]; + aa.ul[1] &= bb.ul[1]; + return (aa.q); +} diff --git a/lib/libc/quad/ashldi3.c b/lib/libc/quad/ashldi3.c new file mode 100644 index 000000000000..2566aef0835e --- /dev/null +++ b/lib/libc/quad/ashldi3.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)ashldi3.c 5.7 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Shift a (signed) quad value left (arithmetic shift left). + * This is the same as logical shift left! + */ +quad_t +__ashldi3(a, shift) + quad_t a; + qshift_t shift; +{ + union uu aa; + + aa.q = a; + if (shift >= LONG_BITS) { + aa.ul[H] = shift >= QUAD_BITS ? 0 : + aa.ul[L] << (shift - LONG_BITS); + aa.ul[L] = 0; + } else if (shift > 0) { + aa.ul[H] = (aa.ul[H] << shift) | + (aa.ul[L] >> (LONG_BITS - shift)); + aa.ul[L] <<= shift; + } + return (aa.q); +} diff --git a/lib/libc/quad/ashrdi3.c b/lib/libc/quad/ashrdi3.c new file mode 100644 index 000000000000..29c2e95af273 --- /dev/null +++ b/lib/libc/quad/ashrdi3.c @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)ashrdi3.c 5.7 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Shift a (signed) quad value right (arithmetic shift right). + */ +quad_t +__ashrdi3(a, shift) + quad_t a; + qshift_t shift; +{ + union uu aa; + + aa.q = a; + if (shift >= LONG_BITS) { + long s; + + /* + * Smear bits rightward using the machine's right-shift + * method, whether that is sign extension or zero fill, + * to get the `sign word' s. Note that shifting by + * LONG_BITS is undefined, so we shift (LONG_BITS-1), + * then 1 more, to get our answer. + */ + s = (aa.sl[H] >> (LONG_BITS - 1)) >> 1; + aa.ul[L] = shift >= QUAD_BITS ? s : + aa.sl[H] >> (shift - LONG_BITS); + aa.ul[H] = s; + } else if (shift > 0) { + aa.ul[L] = (aa.ul[L] >> shift) | + (aa.ul[H] << (LONG_BITS - shift)); + aa.sl[H] >>= shift; + } + return (aa.q); +} diff --git a/lib/libc/quad/cmpdi2.c b/lib/libc/quad/cmpdi2.c new file mode 100644 index 000000000000..b33b9a542e18 --- /dev/null +++ b/lib/libc/quad/cmpdi2.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)cmpdi2.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return 0, 1, or 2 as a <, =, > b respectively. + * Both a and b are considered signed---which means only the high word is + * signed. + */ +int +__cmpdi2(a, b) + quad_t a, b; +{ + union uu aa, bb; + + aa.q = a; + bb.q = b; + return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 : + aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1); +} diff --git a/lib/libc/quad/divdi3.c b/lib/libc/quad/divdi3.c new file mode 100644 index 000000000000..3529d18a0534 --- /dev/null +++ b/lib/libc/quad/divdi3.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)divdi3.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Divide two signed quads. + * ??? if -1/2 should produce -1 on this machine, this code is wrong + */ +quad_t +__divdi3(a, b) + quad_t a, b; +{ + u_quad_t ua, ub, uq; + int neg; + + if (a < 0) + ua = -(u_quad_t)a, neg = 1; + else + ua = a, neg = 0; + if (b < 0) + ub = -(u_quad_t)b, neg ^= 1; + else + ub = b; + uq = __qdivrem(ua, ub, (u_quad_t *)0); + return (neg ? -uq : uq); +} diff --git a/lib/libc/quad/fixdfdi.c b/lib/libc/quad/fixdfdi.c new file mode 100644 index 000000000000..1e9930cdf8cb --- /dev/null +++ b/lib/libc/quad/fixdfdi.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)fixdfdi.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Convert double to (signed) quad. + * We clamp anything that is out of range. + */ +quad_t +__fixdfdi(x) + double x; +{ + if (x < 0) + if (x <= QUAD_MIN) + return (QUAD_MIN); + else + return ((quad_t)-(u_quad_t)-x); + else + if (x >= QUAD_MAX) + return (QUAD_MAX); + else + return ((quad_t)(u_quad_t)x); +} diff --git a/lib/libc/quad/fixsfdi.c b/lib/libc/quad/fixsfdi.c new file mode 100644 index 000000000000..448109fae8fb --- /dev/null +++ b/lib/libc/quad/fixsfdi.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)fixsfdi.c 5.1 (Berkeley) 7/7/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Convert float to (signed) quad. + * We clamp anything that is out of range. + * + * N.B.: must use new ANSI syntax (sorry). + */ +long long +__fixsfdi(float x) +{ + if (x < 0) + if (x <= QUAD_MIN) + return (QUAD_MIN); + else + return ((quad_t)-(u_quad_t)-x); + else + if (x >= QUAD_MAX) + return (QUAD_MAX); + else + return ((quad_t)(u_quad_t)x); +} diff --git a/lib/libc/quad/fixunsdfdi.c b/lib/libc/quad/fixunsdfdi.c new file mode 100644 index 000000000000..84a2f7336177 --- /dev/null +++ b/lib/libc/quad/fixunsdfdi.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)fixunsdfdi.c 5.5 (Berkeley) 7/13/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +#define ONE_FOURTH (1 << (LONG_BITS - 2)) +#define ONE_HALF (ONE_FOURTH * 2.0) +#define ONE (ONE_FOURTH * 4.0) + +/* + * Convert double to (unsigned) quad. + * Not sure what to do with negative numbers---for now, anything out + * of range becomes UQUAD_MAX. + */ +u_quad_t +__fixunsdfdi(x) + double x; +{ + double toppart; + union uu t; + + if (x < 0) + return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */ +#ifdef notdef /* this falls afoul of a GCC bug */ + if (x >= UQUAD_MAX) + return (UQUAD_MAX); +#else /* so we wire in 2^64-1 instead */ + if (x >= 18446744073709551615.0) + return (UQUAD_MAX); +#endif + /* + * Get the upper part of the result. Note that the divide + * may round up; we want to avoid this if possible, so we + * subtract `1/2' first. + */ + toppart = (x - ONE_HALF) / ONE; + /* + * Now build a u_quad_t out of the top part. The difference + * between x and this is the bottom part (this may introduce + * a few fuzzy bits, but what the heck). With any luck this + * difference will be nonnegative: x should wind up in the + * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN.. + * 2*ULONG_MAX] instead. + */ + t.ul[H] = (unsigned long)toppart; + t.ul[L] = 0; + x -= (double)t.uq; + if (x < 0) { + t.ul[H]--; + x += ULONG_MAX; + } + if (x > ULONG_MAX) { + t.ul[H]++; + x -= ULONG_MAX; + } + t.ul[L] = (u_long)x; + return (t.uq); +} diff --git a/lib/libc/quad/fixunssfdi.c b/lib/libc/quad/fixunssfdi.c new file mode 100644 index 000000000000..85798adb61de --- /dev/null +++ b/lib/libc/quad/fixunssfdi.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)fixunssfdi.c 5.2 (Berkeley) 7/13/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +#define ONE_FOURTH (1 << (LONG_BITS - 2)) +#define ONE_HALF (ONE_FOURTH * 2.0) +#define ONE (ONE_FOURTH * 4.0) + +/* + * Convert float to (unsigned) quad. We do most of our work in double, + * out of sheer paranoia. + * + * Not sure what to do with negative numbers---for now, anything out + * of range becomes UQUAD_MAX. + * + * N.B.: must use new ANSI syntax (sorry). + */ +u_quad_t +__fixunssfdi(float f) +{ + double x, toppart; + union uu t; + + if (f < 0) + return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */ +#ifdef notdef /* this falls afoul of a GCC bug */ + if (f >= UQUAD_MAX) + return (UQUAD_MAX); +#else /* so we wire in 2^64-1 instead */ + if (f >= 18446744073709551615.0) + return (UQUAD_MAX); +#endif + x = f; + /* + * Get the upper part of the result. Note that the divide + * may round up; we want to avoid this if possible, so we + * subtract `1/2' first. + */ + toppart = (x - ONE_HALF) / ONE; + /* + * Now build a u_quad_t out of the top part. The difference + * between x and this is the bottom part (this may introduce + * a few fuzzy bits, but what the heck). With any luck this + * difference will be nonnegative: x should wind up in the + * range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN.. + * 2*ULONG_MAX] instead. + */ + t.ul[H] = (unsigned long)toppart; + t.ul[L] = 0; + x -= (double)t.uq; + if (x < 0) { + t.ul[H]--; + x += ULONG_MAX; + } + if (x > ULONG_MAX) { + t.ul[H]++; + x -= ULONG_MAX; + } + t.ul[L] = (u_long)x; + return (t.uq); +} diff --git a/lib/libc/quad/floatdidf.c b/lib/libc/quad/floatdidf.c new file mode 100644 index 000000000000..a0cd536fd50e --- /dev/null +++ b/lib/libc/quad/floatdidf.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)floatdidf.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Convert (signed) quad to double. + */ +double +__floatdidf(x) + quad_t x; +{ + double d; + union uu u; + int neg; + + /* + * Get an unsigned number first, by negating if necessary. + */ + if (x < 0) + u.q = -x, neg = 1; + else + u.q = x, neg = 0; + + /* + * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L] + * has the units. Ideally we could just set d, add LONG_BITS to + * its exponent, and then add the units, but this is portable + * code and does not know how to get at an exponent. Machine- + * specific code may be able to do this more efficiently. + */ + d = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0); + d += u.ul[L]; + + return (neg ? -d : d); +} diff --git a/lib/libc/quad/floatdisf.c b/lib/libc/quad/floatdisf.c new file mode 100644 index 000000000000..c359e4ce60cc --- /dev/null +++ b/lib/libc/quad/floatdisf.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)floatdisf.c 5.1 (Berkeley) 7/7/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Convert (signed) quad to float. + */ +float +__floatdisf(x) + quad_t x; +{ + float f; + union uu u; + int neg; + + /* + * Get an unsigned number first, by negating if necessary. + */ + if (x < 0) + u.q = -x, neg = 1; + else + u.q = x, neg = 0; + + /* + * Now u.ul[H] has the factor of 2^32 (or whatever) and u.ul[L] + * has the units. Ideally we could just set f, add LONG_BITS to + * its exponent, and then add the units, but this is portable + * code and does not know how to get at an exponent. Machine- + * specific code may be able to do this more efficiently. + * + * Using double here may be excessive paranoia. + */ + f = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0); + f += u.ul[L]; + + return (neg ? -f : f); +} diff --git a/lib/libc/quad/floatunsdidf.c b/lib/libc/quad/floatunsdidf.c new file mode 100644 index 000000000000..814cccaf9767 --- /dev/null +++ b/lib/libc/quad/floatunsdidf.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)floatunsdidf.c 5.2 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Convert (unsigned) quad to double. + * This is exactly like floatdidf.c except that negatives never occur. + */ +double +__floatunsdidf(x) + u_quad_t x; +{ + double d; + union uu u; + + u.uq = x; + d = (double)u.ul[H] * ((1 << (LONG_BITS - 2)) * 4.0); + d += u.ul[L]; + return (d); +} diff --git a/lib/libc/quad/iordi3.c b/lib/libc/quad/iordi3.c new file mode 100644 index 000000000000..84064b767a87 --- /dev/null +++ b/lib/libc/quad/iordi3.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)iordi3.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return a | b, in quad. + */ +quad_t +__iordi3(a, b) + quad_t a, b; +{ + union uu aa, bb; + + aa.q = a; + bb.q = b; + aa.ul[0] |= bb.ul[0]; + aa.ul[1] |= bb.ul[1]; + return (aa.q); +} diff --git a/lib/libc/quad/lshldi3.c b/lib/libc/quad/lshldi3.c new file mode 100644 index 000000000000..64587068f0db --- /dev/null +++ b/lib/libc/quad/lshldi3.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)lshldi3.c 5.7 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Shift an (unsigned) quad value left (logical shift left). + * This is the same as arithmetic shift left! + */ +quad_t +__lshldi3(a, shift) + quad_t a; + qshift_t shift; +{ + union uu aa; + + aa.q = a; + if (shift >= LONG_BITS) { + aa.ul[H] = shift >= QUAD_BITS ? 0 : + aa.ul[L] << (shift - LONG_BITS); + aa.ul[L] = 0; + } else if (shift > 0) { + aa.ul[H] = (aa.ul[H] << shift) | + (aa.ul[L] >> (LONG_BITS - shift)); + aa.ul[L] <<= shift; + } + return (aa.q); +} diff --git a/lib/libc/quad/lshrdi3.c b/lib/libc/quad/lshrdi3.c new file mode 100644 index 000000000000..f09268cd3e8d --- /dev/null +++ b/lib/libc/quad/lshrdi3.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)lshrdi3.c 5.7 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Shift an (unsigned) quad value right (logical shift right). + */ +quad_t +__lshrdi3(a, shift) + quad_t a; + qshift_t shift; +{ + union uu aa; + + aa.q = a; + if (shift >= LONG_BITS) { + aa.ul[L] = shift >= QUAD_BITS ? 0 : + aa.ul[H] >> (shift - LONG_BITS); + aa.ul[H] = 0; + } else if (shift > 0) { + aa.ul[L] = (aa.ul[L] >> shift) | + (aa.ul[H] << (LONG_BITS - shift)); + aa.ul[H] >>= shift; + } + return (aa.q); +} diff --git a/lib/libc/quad/moddi3.c b/lib/libc/quad/moddi3.c new file mode 100644 index 000000000000..961d6a62c2a3 --- /dev/null +++ b/lib/libc/quad/moddi3.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)moddi3.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return remainder after dividing two signed quads. + * + * XXX + * If -1/2 should produce -1 on this machine, this code is wrong. + */ +quad_t +__moddi3(a, b) + quad_t a, b; +{ + u_quad_t ua, ub, ur; + int neg; + + if (a < 0) + ua = -(u_quad_t)a, neg = 1; + else + ua = a, neg = 0; + if (b < 0) + ub = -(u_quad_t)b, neg ^= 1; + else + ub = b; + (void)__qdivrem(ua, ub, &ur); + return (neg ? -ur : ur); +} diff --git a/lib/libc/quad/muldi3.c b/lib/libc/quad/muldi3.c new file mode 100644 index 000000000000..6b0d10be4f93 --- /dev/null +++ b/lib/libc/quad/muldi3.c @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)muldi3.c 5.8 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Multiply two quads. + * + * Our algorithm is based on the following. Split incoming quad values + * u and v (where u,v >= 0) into + * + * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32) + * + * and + * + * v = 2^n v1 * v0 + * + * Then + * + * uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0 + * = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0 + * + * Now add 2^n u1 v1 to the first term and subtract it from the middle, + * and add 2^n u0 v0 to the last term and subtract it from the middle. + * This gives: + * + * uv = (2^2n + 2^n) (u1 v1) + + * (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) + + * (2^n + 1) (u0 v0) + * + * Factoring the middle a bit gives us: + * + * uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high] + * (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid] + * (2^n + 1) (u0 v0) [u0v0 = low] + * + * The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done + * in just half the precision of the original. (Note that either or both + * of (u1 - u0) or (v0 - v1) may be negative.) + * + * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278. + * + * Since C does not give us a `long * long = quad' operator, we split + * our input quads into two longs, then split the two longs into two + * shorts. We can then calculate `short * short = long' in native + * arithmetic. + * + * Our product should, strictly speaking, be a `long quad', with 128 + * bits, but we are going to discard the upper 64. In other words, + * we are not interested in uv, but rather in (uv mod 2^2n). This + * makes some of the terms above vanish, and we get: + * + * (2^n)(high) + (2^n)(mid) + (2^n + 1)(low) + * + * or + * + * (2^n)(high + mid + low) + low + * + * Furthermore, `high' and `mid' can be computed mod 2^n, as any factor + * of 2^n in either one will also vanish. Only `low' need be computed + * mod 2^2n, and only because of the final term above. + */ +static quad_t __lmulq(u_long, u_long); + +quad_t +__muldi3(a, b) + quad_t a, b; +{ + union uu u, v, low, prod; + register u_long high, mid, udiff, vdiff; + register int negall, negmid; +#define u1 u.ul[H] +#define u0 u.ul[L] +#define v1 v.ul[H] +#define v0 v.ul[L] + + /* + * Get u and v such that u, v >= 0. When this is finished, + * u1, u0, v1, and v0 will be directly accessible through the + * longword fields. + */ + if (a >= 0) + u.q = a, negall = 0; + else + u.q = -a, negall = 1; + if (b >= 0) + v.q = b; + else + v.q = -b, negall ^= 1; + + if (u1 == 0 && v1 == 0) { + /* + * An (I hope) important optimization occurs when u1 and v1 + * are both 0. This should be common since most numbers + * are small. Here the product is just u0*v0. + */ + prod.q = __lmulq(u0, v0); + } else { + /* + * Compute the three intermediate products, remembering + * whether the middle term is negative. We can discard + * any upper bits in high and mid, so we can use native + * u_long * u_long => u_long arithmetic. + */ + low.q = __lmulq(u0, v0); + + if (u1 >= u0) + negmid = 0, udiff = u1 - u0; + else + negmid = 1, udiff = u0 - u1; + if (v0 >= v1) + vdiff = v0 - v1; + else + vdiff = v1 - v0, negmid ^= 1; + mid = udiff * vdiff; + + high = u1 * v1; + + /* + * Assemble the final product. + */ + prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] + + low.ul[H]; + prod.ul[L] = low.ul[L]; + } + return (negall ? -prod.q : prod.q); +#undef u1 +#undef u0 +#undef v1 +#undef v0 +} + +/* + * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half + * the number of bits in a long (whatever that is---the code below + * does not care as long as quad.h does its part of the bargain---but + * typically N==16). + * + * We use the same algorithm from Knuth, but this time the modulo refinement + * does not apply. On the other hand, since N is half the size of a long, + * we can get away with native multiplication---none of our input terms + * exceeds (ULONG_MAX >> 1). + * + * Note that, for u_long l, the quad-precision result + * + * l << N + * + * splits into high and low longs as HHALF(l) and LHUP(l) respectively. + */ +static quad_t +__lmulq(u_long u, u_long v) +{ + u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low; + u_long prodh, prodl, was; + union uu prod; + int neg; + + u1 = HHALF(u); + u0 = LHALF(u); + v1 = HHALF(v); + v0 = LHALF(v); + + low = u0 * v0; + + /* This is the same small-number optimization as before. */ + if (u1 == 0 && v1 == 0) + return (low); + + if (u1 >= u0) + udiff = u1 - u0, neg = 0; + else + udiff = u0 - u1, neg = 1; + if (v0 >= v1) + vdiff = v0 - v1; + else + vdiff = v1 - v0, neg ^= 1; + mid = udiff * vdiff; + + high = u1 * v1; + + /* prod = (high << 2N) + (high << N); */ + prodh = high + HHALF(high); + prodl = LHUP(high); + + /* if (neg) prod -= mid << N; else prod += mid << N; */ + if (neg) { + was = prodl; + prodl -= LHUP(mid); + prodh -= HHALF(mid) + (prodl > was); + } else { + was = prodl; + prodl += LHUP(mid); + prodh += HHALF(mid) + (prodl < was); + } + + /* prod += low << N */ + was = prodl; + prodl += LHUP(low); + prodh += HHALF(low) + (prodl < was); + /* ... + low; */ + if ((prodl += low) < low) + prodh++; + + /* return 4N-bit product */ + prod.ul[H] = prodh; + prod.ul[L] = prodl; + return (prod.q); +} diff --git a/lib/libc/quad/negdi2.c b/lib/libc/quad/negdi2.c new file mode 100644 index 000000000000..75ea1f7005b6 --- /dev/null +++ b/lib/libc/quad/negdi2.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)negdi2.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return -a (or, equivalently, 0 - a), in quad. See subdi3.c. + */ +quad_t +__negdi2(a) + quad_t a; +{ + union uu aa, res; + + aa.q = a; + res.ul[L] = -aa.ul[L]; + res.ul[H] = -aa.ul[H] - (res.ul[L] > 0); + return (res.q); +} diff --git a/lib/libc/quad/notdi2.c b/lib/libc/quad/notdi2.c new file mode 100644 index 000000000000..f0bc258141f6 --- /dev/null +++ b/lib/libc/quad/notdi2.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)notdi2.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return ~a. For some reason gcc calls this `one's complement' rather + * than `not'. + */ +quad_t +__one_cmpldi2(a) + quad_t a; +{ + union uu aa; + + aa.q = a; + aa.ul[0] = ~aa.ul[0]; + aa.ul[1] = ~aa.ul[1]; + return (aa.q); +} diff --git a/lib/libc/quad/qdivrem.c b/lib/libc/quad/qdivrem.c new file mode 100644 index 000000000000..c61b5e2be535 --- /dev/null +++ b/lib/libc/quad/qdivrem.c @@ -0,0 +1,279 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)qdivrem.c 5.7 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed), + * section 4.3.1, pp. 257--259. + */ + +#include "quad.h" + +#define B (1 << HALF_BITS) /* digit base */ + +/* Combine two `digits' to make a single two-digit number. */ +#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b)) + +/* select a type for digits in base B: use unsigned short if they fit */ +#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff +typedef unsigned short digit; +#else +typedef u_long digit; +#endif + +/* + * Shift p[0]..p[len] left `sh' bits, ignoring any bits that + * `fall out' the left (there never will be any such anyway). + * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS. + */ +static void +shl(register digit *p, register int len, register int sh) +{ + register int i; + + for (i = 0; i < len; i++) + p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh)); + p[i] = LHALF(p[i] << sh); +} + +/* + * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v. + * + * We do this in base 2-sup-HALF_BITS, so that all intermediate products + * fit within u_long. As a consequence, the maximum length dividend and + * divisor are 4 `digits' in this base (they are shorter if they have + * leading zeros). + */ +u_quad_t +__qdivrem(uq, vq, arq) + u_quad_t uq, vq, *arq; +{ + union uu tmp; + digit *u, *v, *q; + register digit v1, v2; + u_long qhat, rhat, t; + int m, n, d, j, i; + digit uspace[5], vspace[5], qspace[5]; + + /* + * Take care of special cases: divide by zero, and u < v. + */ + if (vq == 0) { + /* divide by zero. */ + static volatile const unsigned int zero = 0; + + tmp.ul[H] = tmp.ul[L] = 1 / zero; + if (arq) + *arq = uq; + return (tmp.q); + } + if (uq < vq) { + if (arq) + *arq = uq; + return (0); + } + u = &uspace[0]; + v = &vspace[0]; + q = &qspace[0]; + + /* + * Break dividend and divisor into digits in base B, then + * count leading zeros to determine m and n. When done, we + * will have: + * u = (u[1]u[2]...u[m+n]) sub B + * v = (v[1]v[2]...v[n]) sub B + * v[1] != 0 + * 1 < n <= 4 (if n = 1, we use a different division algorithm) + * m >= 0 (otherwise u < v, which we already checked) + * m + n = 4 + * and thus + * m = 4 - n <= 2 + */ + tmp.uq = uq; + u[0] = 0; + u[1] = HHALF(tmp.ul[H]); + u[2] = LHALF(tmp.ul[H]); + u[3] = HHALF(tmp.ul[L]); + u[4] = LHALF(tmp.ul[L]); + tmp.uq = vq; + v[1] = HHALF(tmp.ul[H]); + v[2] = LHALF(tmp.ul[H]); + v[3] = HHALF(tmp.ul[L]); + v[4] = LHALF(tmp.ul[L]); + for (n = 4; v[1] == 0; v++) { + if (--n == 1) { + u_long rbj; /* r*B+u[j] (not root boy jim) */ + digit q1, q2, q3, q4; + + /* + * Change of plan, per exercise 16. + * r = 0; + * for j = 1..4: + * q[j] = floor((r*B + u[j]) / v), + * r = (r*B + u[j]) % v; + * We unroll this completely here. + */ + t = v[2]; /* nonzero, by definition */ + q1 = u[1] / t; + rbj = COMBINE(u[1] % t, u[2]); + q2 = rbj / t; + rbj = COMBINE(rbj % t, u[3]); + q3 = rbj / t; + rbj = COMBINE(rbj % t, u[4]); + q4 = rbj / t; + if (arq) + *arq = rbj % t; + tmp.ul[H] = COMBINE(q1, q2); + tmp.ul[L] = COMBINE(q3, q4); + return (tmp.q); + } + } + + /* + * By adjusting q once we determine m, we can guarantee that + * there is a complete four-digit quotient at &qspace[1] when + * we finally stop. + */ + for (m = 4 - n; u[1] == 0; u++) + m--; + for (i = 4 - m; --i >= 0;) + q[i] = 0; + q += 4 - m; + + /* + * Here we run Program D, translated from MIX to C and acquiring + * a few minor changes. + * + * D1: choose multiplier 1 << d to ensure v[1] >= B/2. + */ + d = 0; + for (t = v[1]; t < B / 2; t <<= 1) + d++; + if (d > 0) { + shl(&u[0], m + n, d); /* u <<= d */ + shl(&v[1], n - 1, d); /* v <<= d */ + } + /* + * D2: j = 0. + */ + j = 0; + v1 = v[1]; /* for D3 -- note that v[1..n] are constant */ + v2 = v[2]; /* for D3 */ + do { + register digit uj0, uj1, uj2; + + /* + * D3: Calculate qhat (\^q, in TeX notation). + * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and + * let rhat = (u[j]*B + u[j+1]) mod v[1]. + * While rhat < B and v[2]*qhat > rhat*B+u[j+2], + * decrement qhat and increase rhat correspondingly. + * Note that if rhat >= B, v[2]*qhat < rhat*B. + */ + uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */ + uj1 = u[j + 1]; /* for D3 only */ + uj2 = u[j + 2]; /* for D3 only */ + if (uj0 == v1) { + qhat = B; + rhat = uj1; + goto qhat_too_big; + } else { + u_long n = COMBINE(uj0, uj1); + qhat = n / v1; + rhat = n % v1; + } + while (v2 * qhat > COMBINE(rhat, uj2)) { + qhat_too_big: + qhat--; + if ((rhat += v1) >= B) + break; + } + /* + * D4: Multiply and subtract. + * The variable `t' holds any borrows across the loop. + * We split this up so that we do not require v[0] = 0, + * and to eliminate a final special case. + */ + for (t = 0, i = n; i > 0; i--) { + t = u[i + j] - v[i] * qhat - t; + u[i + j] = LHALF(t); + t = (B - HHALF(t)) & (B - 1); + } + t = u[j] - t; + u[j] = LHALF(t); + /* + * D5: test remainder. + * There is a borrow if and only if HHALF(t) is nonzero; + * in that (rare) case, qhat was too large (by exactly 1). + * Fix it by adding v[1..n] to u[j..j+n]. + */ + if (HHALF(t)) { + qhat--; + for (t = 0, i = n; i > 0; i--) { /* D6: add back. */ + t += u[i + j] + v[i]; + u[i + j] = LHALF(t); + t = HHALF(t); + } + u[j] = LHALF(u[j] + t); + } + q[j] = qhat; + } while (++j <= m); /* D7: loop on j. */ + + /* + * If caller wants the remainder, we have to calculate it as + * u[m..m+n] >> d (this is at most n digits and thus fits in + * u[m+1..m+n], but we may need more source digits). + */ + if (arq) { + if (d) { + for (i = m + n; i > m; --i) + u[i] = (u[i] >> d) | + LHALF(u[i - 1] << (HALF_BITS - d)); + u[i] = 0; + } + tmp.ul[H] = COMBINE(uspace[1], uspace[2]); + tmp.ul[L] = COMBINE(uspace[3], uspace[4]); + *arq = tmp.q; + } + + tmp.ul[H] = COMBINE(qspace[1], qspace[2]); + tmp.ul[L] = COMBINE(qspace[3], qspace[4]); + return (tmp.q); +} diff --git a/lib/libc/quad/quad.h b/lib/libc/quad/quad.h new file mode 100644 index 000000000000..8f1ee163b959 --- /dev/null +++ b/lib/libc/quad/quad.h @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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. + * + * @(#)quad.h 5.9 (Berkeley) 7/28/92 + */ + +/* + * Quad arithmetic. + * + * This library makes the following assumptions: + * + * - The type long long (aka quad_t) exists. + * + * - A quad variable is exactly twice as long as `long'. + * + * - The machine's arithmetic is two's complement. + * + * This library can provide 128-bit arithmetic on a machine with 128-bit + * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines + * with 48-bit longs. + */ + +#include <machine/endian.h> +#include <sys/types.h> +#include <sys/cdefs.h> +#include <limits.h> + +/* + * Depending on the desired operation, we view a `long long' (aka quad_t) in + * one or more of the following formats. + */ +union uu { + quad_t q; /* as a (signed) quad */ + quad_t uq; /* as an unsigned quad */ + long sl[2]; /* as two signed longs */ + u_long ul[2]; /* as two unsigned longs */ +}; + +/* + * Define high and low longwords. + */ +#define H _QUAD_HIGHWORD +#define L _QUAD_LOWWORD + +/* + * Total number of bits in a quad_t and in the pieces that make it up. + * These are used for shifting, and also below for halfword extraction + * and assembly. + */ +#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT) +#define LONG_BITS (sizeof(long) * CHAR_BIT) +#define HALF_BITS (sizeof(long) * CHAR_BIT / 2) + +/* + * Extract high and low shortwords from longword, and move low shortword of + * longword to upper half of long, i.e., produce the upper longword of + * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.) + * + * These are used in the multiply code, to split a longword into upper + * and lower halves, and to reassemble a product as a quad_t, shifted left + * (sizeof(long)*CHAR_BIT/2). + */ +#define HHALF(x) ((x) >> HALF_BITS) +#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) +#define LHUP(x) ((x) << HALF_BITS) + +extern u_quad_t __qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem)); + +/* + * XXX + * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument + * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use + * both compilers. + */ +#if __GNUC__ >= 2 +typedef unsigned int qshift_t; +#else +typedef u_quad_t qshift_t; +#endif diff --git a/lib/libc/quad/subdi3.c b/lib/libc/quad/subdi3.c new file mode 100644 index 000000000000..3f9a83becb46 --- /dev/null +++ b/lib/libc/quad/subdi3.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)subdi3.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Subtract two quad values. This is trivial since a one-bit carry + * from a single u_long difference x-y occurs if and only if (x-y) > x. + */ +quad_t +__subdi3(a, b) + quad_t a, b; +{ + union uu aa, bb, diff; + + aa.q = a; + bb.q = b; + diff.ul[L] = aa.ul[L] - bb.ul[L]; + diff.ul[H] = aa.ul[H] - bb.ul[H] - (diff.ul[L] > aa.ul[L]); + return (diff.q); +} diff --git a/lib/libc/quad/ucmpdi2.c b/lib/libc/quad/ucmpdi2.c new file mode 100644 index 000000000000..fbfc57533ab8 --- /dev/null +++ b/lib/libc/quad/ucmpdi2.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)ucmpdi2.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return 0, 1, or 2 as a <, =, > b respectively. + * Neither a nor b are considered signed. + */ +int +__ucmpdi2(a, b) + u_quad_t a, b; +{ + union uu aa, bb; + + aa.uq = a; + bb.uq = b; + return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 : + aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1); +} diff --git a/lib/libc/quad/udivdi3.c b/lib/libc/quad/udivdi3.c new file mode 100644 index 000000000000..7c860e70d8a9 --- /dev/null +++ b/lib/libc/quad/udivdi3.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)udivdi3.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Divide two unsigned quads. + */ +u_quad_t +__udivdi3(a, b) + u_quad_t a, b; +{ + + return (__qdivrem(a, b, (u_quad_t *)0)); +} diff --git a/lib/libc/quad/umoddi3.c b/lib/libc/quad/umoddi3.c new file mode 100644 index 000000000000..a4f918eab4b2 --- /dev/null +++ b/lib/libc/quad/umoddi3.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)umoddi3.c 5.5 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return remainder after dividing two unsigned quads. + */ +u_quad_t +__umoddi3(a, b) + u_quad_t a, b; +{ + u_quad_t r; + + (void)__qdivrem(a, b, &r); + return (r); +} diff --git a/lib/libc/quad/xordi3.c b/lib/libc/quad/xordi3.c new file mode 100644 index 000000000000..07ed29fdd322 --- /dev/null +++ b/lib/libc/quad/xordi3.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1992 The Regents of the University of California. + * All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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[] = "@(#)xordi3.c 5.4 (Berkeley) 6/25/92"; +#endif /* LIBC_SCCS and not lint */ + +#include "quad.h" + +/* + * Return a ^ b, in quad. + */ +quad_t +__xordi3(a, b) + quad_t a, b; +{ + union uu aa, bb; + + aa.q = a; + bb.q = b; + aa.ul[0] ^= bb.ul[0]; + aa.ul[1] ^= bb.ul[1]; + return (aa.q); +} diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc new file mode 100644 index 000000000000..673f4749a657 --- /dev/null +++ b/lib/libc/regex/Makefile.inc @@ -0,0 +1,13 @@ +# @(#)Makefile 5.11 (Berkeley) 9/6/90 + +# regex sources +.PATH: ${.CURDIR}/regex + +SRCS+= regfree.c regcomp.c regerror.c regexec.c +CFLAGS+=-I${.CURDIR}/regex -DPOSIX_MISTAKE + +MAN3+= regex/regex.3 +MAN7+= regex/regex.7 + +MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 +MLINK+= regex.3 regfree.3 diff --git a/lib/libc/regex/WHATSNEW b/lib/libc/regex/WHATSNEW new file mode 100644 index 000000000000..0bc7589c32e1 --- /dev/null +++ b/lib/libc/regex/WHATSNEW @@ -0,0 +1,72 @@ +New in alpha3.2: Assorted bits of cleanup and portability improvement +(the development base is now a BSDI system using GCC instead of an ancient +Sun system, and the newer compiler exposed some glitches). Fix for a +serious bug that affected REs using many [] (including REG_ICASE REs +because of the way they are implemented), *sometimes*, depending on +memory-allocation patterns. The header-file prototypes no longer name +the parameters, avoiding possible name conflicts. The possibility that +some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is +now handled gracefully. "uchar" is no longer used as an internal type +name (too many people have the same idea). Still the same old lousy +performance, alas. + +New in alpha3.1: Basically nothing, this release is just a bookkeeping +convenience. Stay tuned. + +New in alpha3.0: Performance is no better, alas, but some fixes have been +made and some functionality has been added. (This is basically the "get +it out the door in time for 4.4" release.) One bug fix: regfree() didn't +free the main internal structure (how embarrassing). It is now possible +to put NULs in either the RE or the target string, using (resp.) a new +REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to +regcomp() makes all characters ordinary, so you can match a literal +string easily (this will become more useful when performance improves!). +There are now primitives to match beginnings and ends of words, although +the syntax is disgusting and so is the implementation. The REG_ATOI +debugging interface has changed a bit. And there has been considerable +internal cleanup of various kinds. + +New in alpha2.3: Split change list out of README, and moved flags notes +into Makefile. Macro-ized the name of regex(7) in regex(3), since it has +to change for 4.4BSD. Cleanup work in engine.c, and some new regression +tests to catch tricky cases thereof. + +New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two +small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges +in my own test program and might be useful to others for similar purposes. +The regression test will now compile (and run) without REDEBUG. The +BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now. +Char/uchar parameters are now written int/unsigned, to avoid possible +portability problems with unpromoted parameters. Some unsigned casts have +been introduced to minimize portability problems with shifting into sign +bits. + +New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big +thing is that regex.h is now generated, using mkh, rather than being +supplied in the distribution; due to circularities in dependencies, +you have to build regex.h explicitly by "make h". The two known bugs +have been fixed (and the regression test now checks for them), as has a +problem with assertions not being suppressed in the absence of REDEBUG. +No performance work yet. + +New in alpha2: Backslash-anything is an ordinary character, not an +error (except, of course, for the handful of backslashed metacharacters +in BREs), which should reduce script breakage. The regression test +checks *where* null strings are supposed to match, and has generally +been tightened up somewhat. Small bug fixes in parameter passing (not +harmful, but technically errors) and some other areas. Debugging +invoked by defining REDEBUG rather than not defining NDEBUG. + +New in alpha+3: full prototyping for internal routines, using a little +helper program, mkh, which extracts prototypes given in stylized comments. +More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple +pre-screening of input when a literal string is known to be part of the +RE; this does wonders for performance. + +New in alpha+2: minor bits of cleanup. Notably, the number "32" for the +word width isn't hardwired into regexec.c any more, the public header +file prototypes the functions if __STDC__ is defined, and some small typos +in the manpages have been fixed. + +New in alpha+1: improvements to the manual pages, and an important +extension, the REG_STARTEND option to regexec(). diff --git a/lib/libc/regex/cclass.h b/lib/libc/regex/cclass.h new file mode 100644 index 000000000000..04cf4b1c27b9 --- /dev/null +++ b/lib/libc/regex/cclass.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)cclass.h 8.1 (Berkeley) 6/4/93 + */ + +/* character-class table */ +static struct cclass { + char *name; + char *chars; + char *multis; +} cclasses[] = { + "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ +0123456789", "", + "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + "", + "blank", " \t", "", + "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\ +\25\26\27\30\31\32\33\34\35\36\37\177", "", + "digit", "0123456789", "", + "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ +0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + "", + "lower", "abcdefghijklmnopqrstuvwxyz", + "", + "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ +0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ", + "", + "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + "", + "space", "\t\n\v\f\r ", "", + "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "", + "xdigit", "0123456789ABCDEFabcdef", + "", + NULL, 0, "" +}; diff --git a/lib/libc/regex/cname.h b/lib/libc/regex/cname.h new file mode 100644 index 000000000000..7f22903b1c05 --- /dev/null +++ b/lib/libc/regex/cname.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)cname.h 8.1 (Berkeley) 6/4/93 + */ + +/* character-name table */ +static struct cname { + char *name; + char code; +} cnames[] = { + "NUL", '\0', + "SOH", '\001', + "STX", '\002', + "ETX", '\003', + "EOT", '\004', + "ENQ", '\005', + "ACK", '\006', + "BEL", '\007', + "alert", '\007', + "BS", '\010', + "backspace", '\b', + "HT", '\011', + "tab", '\t', + "LF", '\012', + "newline", '\n', + "VT", '\013', + "vertical-tab", '\v', + "FF", '\014', + "form-feed", '\f', + "CR", '\015', + "carriage-return", '\r', + "SO", '\016', + "SI", '\017', + "DLE", '\020', + "DC1", '\021', + "DC2", '\022', + "DC3", '\023', + "DC4", '\024', + "NAK", '\025', + "SYN", '\026', + "ETB", '\027', + "CAN", '\030', + "EM", '\031', + "SUB", '\032', + "ESC", '\033', + "IS4", '\034', + "FS", '\034', + "IS3", '\035', + "GS", '\035', + "IS2", '\036', + "RS", '\036', + "IS1", '\037', + "US", '\037', + "space", ' ', + "exclamation-mark", '!', + "quotation-mark", '"', + "number-sign", '#', + "dollar-sign", '$', + "percent-sign", '%', + "ampersand", '&', + "apostrophe", '\'', + "left-parenthesis", '(', + "right-parenthesis", ')', + "asterisk", '*', + "plus-sign", '+', + "comma", ',', + "hyphen", '-', + "hyphen-minus", '-', + "period", '.', + "full-stop", '.', + "slash", '/', + "solidus", '/', + "zero", '0', + "one", '1', + "two", '2', + "three", '3', + "four", '4', + "five", '5', + "six", '6', + "seven", '7', + "eight", '8', + "nine", '9', + "colon", ':', + "semicolon", ';', + "less-than-sign", '<', + "equals-sign", '=', + "greater-than-sign", '>', + "question-mark", '?', + "commercial-at", '@', + "left-square-bracket", '[', + "backslash", '\\', + "reverse-solidus", '\\', + "right-square-bracket", ']', + "circumflex", '^', + "circumflex-accent", '^', + "underscore", '_', + "low-line", '_', + "grave-accent", '`', + "left-brace", '{', + "left-curly-bracket", '{', + "vertical-line", '|', + "right-brace", '}', + "right-curly-bracket", '}', + "tilde", '~', + "DEL", '\177', + NULL, 0, +}; diff --git a/lib/libc/regex/engine.c b/lib/libc/regex/engine.c new file mode 100644 index 000000000000..e1296db582cc --- /dev/null +++ b/lib/libc/regex/engine.c @@ -0,0 +1,1075 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)engine.c 8.1 (Berkeley) 6/4/93 + */ + +/* + * The matching engine and friends. This file is #included by regexec.c + * after suitable #defines of a variety of macros used herein, so that + * different state representations can be used without duplicating masses + * of code. + */ + +#ifdef SNAMES +#define matcher smatcher +#define fast sfast +#define slow sslow +#define dissect sdissect +#define backref sbackref +#define step sstep +#define print sprint +#define at sat +#define match smat +#endif +#ifdef LNAMES +#define matcher lmatcher +#define fast lfast +#define slow lslow +#define dissect ldissect +#define backref lbackref +#define step lstep +#define print lprint +#define at lat +#define match lmat +#endif + +/* another structure passed up and down to avoid zillions of parameters */ +struct match { + struct re_guts *g; + int eflags; + regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ + char *offp; /* offsets work from here */ + char *beginp; /* start of string -- virtual NUL precedes */ + char *endp; /* end of string -- virtual NUL here */ + char *coldp; /* can be no match starting before here */ + char **lastpos; /* [nplus+1] */ + STATEVARS; + states st; /* current states */ + states fresh; /* states for a fresh start */ + states tmp; /* temporary */ + states empty; /* empty set of states */ +}; + +static int matcher(/*register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags*/); +static char *dissect(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/); +static char *backref(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev*/); +static char *fast(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/); +static char *slow(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/); +static states step(/*register struct re_guts *g, int start, int stop, register states bef, int ch, register states aft*/); +#define BOL (OUT+1) +#define EOL (BOL+1) +#define BOLEOL (BOL+2) +#define NOTHING (BOL+3) +#define BOW (BOL+4) +#define EOW (BOL+5) +#define CODEMAX (BOL+5) /* highest code used */ +#define NONCHAR(c) ((c) > CHAR_MAX) +#define NNONCHAR (CODEMAX-CHAR_MAX) +#ifdef REDEBUG +static void print(/*struct match *m, char *caption, states st, int ch, FILE *d*/); +#endif +#ifdef REDEBUG +static void at(/*struct match *m, char *title, char *start, char *stop, sopno startst, stopno stopst*/); +#endif +#ifdef REDEBUG +static char *pchar(/*int ch*/); +#endif + +#ifdef REDEBUG +#define SP(t, s, c) print(m, t, s, c, stdout) +#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) +#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } +#else +#define SP(t, s, c) /* nothing */ +#define AT(t, p1, p2, s1, s2) /* nothing */ +#define NOTE(s) /* nothing */ +#endif + +/* + - matcher - the actual matching engine + == static int matcher(register struct re_guts *g, char *string, \ + == size_t nmatch, regmatch_t pmatch[], int eflags); + */ +static int /* 0 success, REG_NOMATCH failure */ +matcher(g, string, nmatch, pmatch, eflags) +register struct re_guts *g; +char *string; +size_t nmatch; +regmatch_t pmatch[]; +int eflags; +{ + register char *endp; + register int i; + struct match mv; + register struct match *m = &mv; + register char *dp; + const register sopno gf = g->firststate+1; /* +1 for OEND */ + const register sopno gl = g->laststate; + char *start; + char *stop; + + /* simplify the situation where possible */ + if (g->cflags®_NOSUB) + nmatch = 0; + if (eflags®_STARTEND) { + start = string + pmatch[0].rm_so; + stop = string + pmatch[0].rm_eo; + } else { + start = string; + stop = start + strlen(start); + } + if (stop < start) + return(REG_INVARG); + + /* prescreening; this does wonders for this rather slow code */ + if (g->must != NULL) { + for (dp = start; dp < stop; dp++) + if (*dp == g->must[0] && stop - dp >= g->mlen && + memcmp(dp, g->must, (size_t)g->mlen) == 0) + break; + if (dp == stop) /* we didn't find g->must */ + return(REG_NOMATCH); + } + + /* match struct setup */ + m->g = g; + m->eflags = eflags; + m->pmatch = NULL; + m->lastpos = NULL; + m->offp = string; + m->beginp = start; + m->endp = stop; + STATESETUP(m, 4); + SETUP(m->st); + SETUP(m->fresh); + SETUP(m->tmp); + SETUP(m->empty); + CLEAR(m->empty); + + /* this loop does only one repetition except for backrefs */ + for (;;) { + endp = fast(m, start, stop, gf, gl); + if (endp == NULL) { /* a miss */ + STATETEARDOWN(m); + return(REG_NOMATCH); + } + if (nmatch == 0 && !g->backrefs) + break; /* no further info needed */ + + /* where? */ + assert(m->coldp != NULL); + for (;;) { + NOTE("finding start"); + endp = slow(m, m->coldp, stop, gf, gl); + if (endp != NULL) + break; + assert(m->coldp < m->endp); + m->coldp++; + } + if (nmatch == 1 && !g->backrefs) + break; /* no further info needed */ + + /* oh my, he wants the subexpressions... */ + if (m->pmatch == NULL) + m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * + sizeof(regmatch_t)); + if (m->pmatch == NULL) { + STATETEARDOWN(m); + return(REG_ESPACE); + } + for (i = 1; i <= m->g->nsub; i++) + m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; + if (!g->backrefs && !(m->eflags®_BACKR)) { + NOTE("dissecting"); + dp = dissect(m, m->coldp, endp, gf, gl); + } else { + if (g->nplus > 0 && m->lastpos == NULL) + m->lastpos = (char **)malloc((g->nplus+1) * + sizeof(char *)); + if (g->nplus > 0 && m->lastpos == NULL) { + free(m->pmatch); + STATETEARDOWN(m); + return(REG_ESPACE); + } + NOTE("backref dissect"); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + } + if (dp != NULL) + break; + + /* uh-oh... we couldn't find a subexpression-level match */ + assert(g->backrefs); /* must be back references doing it */ + assert(g->nplus == 0 || m->lastpos != NULL); + for (;;) { + if (dp != NULL || endp <= m->coldp) + break; /* defeat */ + NOTE("backoff"); + endp = slow(m, m->coldp, endp-1, gf, gl); + if (endp == NULL) + break; /* defeat */ + /* try it on a shorter possibility */ +#ifndef NDEBUG + for (i = 1; i <= m->g->nsub; i++) { + assert(m->pmatch[i].rm_so == -1); + assert(m->pmatch[i].rm_eo == -1); + } +#endif + NOTE("backoff dissect"); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); + } + assert(dp == NULL || dp == endp); + if (dp != NULL) /* found a shorter one */ + break; + + /* despite initial appearances, there is no match here */ + NOTE("false alarm"); + start = m->coldp + 1; /* recycle starting later */ + assert(start <= stop); + } + + /* fill in the details if requested */ + if (nmatch > 0) { + pmatch[0].rm_so = m->coldp - m->offp; + pmatch[0].rm_eo = endp - m->offp; + } + if (nmatch > 1) { + assert(m->pmatch != NULL); + for (i = 1; i < nmatch; i++) + if (i <= m->g->nsub) + pmatch[i] = m->pmatch[i]; + else { + pmatch[i].rm_so = -1; + pmatch[i].rm_eo = -1; + } + } + + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); + STATETEARDOWN(m); + return(0); +} + +/* + - dissect - figure out what matched what, no back references + == static char *dissect(register struct match *m, char *start, \ + == char *stop, sopno startst, sopno stopst); + */ +static char * /* == stop (success) always */ +dissect(m, start, stop, startst, stopst) +register struct match *m; +char *start; +char *stop; +sopno startst; +sopno stopst; +{ + register int i; + register sopno ss; /* start sop of current subRE */ + register sopno es; /* end sop of current subRE */ + register char *sp; /* start of string matched by it */ + register char *stp; /* string matched by it cannot pass here */ + register char *rest; /* start of rest of string */ + register char *tail; /* string unmatched by rest of RE */ + register sopno ssub; /* start sop of subsubRE */ + register sopno esub; /* end sop of subsubRE */ + register char *ssp; /* start of string matched by subsubRE */ + register char *sep; /* end of string matched by subsubRE */ + register char *oldssp; /* previous ssp */ + register char *dp; + + AT("diss", start, stop, startst, stopst); + sp = start; + for (ss = startst; ss < stopst; ss = es) { + /* identify end of subRE */ + es = ss; + switch (OP(m->g->strip[es])) { + case OPLUS_: + case OQUEST_: + es += OPND(m->g->strip[es]); + break; + case OCH_: + while (OP(m->g->strip[es]) != O_CH) + es += OPND(m->g->strip[es]); + break; + } + es++; + + /* figure out what it matched */ + switch (OP(m->g->strip[ss])) { + case OEND: + assert(nope); + break; + case OCHAR: + sp++; + break; + case OBOL: + case OEOL: + case OBOW: + case OEOW: + break; + case OANY: + case OANYOF: + sp++; + break; + case OBACK_: + case O_BACK: + assert(nope); + break; + /* cases where length of match is hard to find */ + case OQUEST_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + /* did innards match? */ + if (slow(m, sp, rest, ssub, esub) != NULL) { + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + } else /* no */ + assert(sp == rest); + sp = rest; + break; + case OPLUS_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + ssp = sp; + oldssp = ssp; + for (;;) { /* find last match of innards */ + sep = slow(m, ssp, rest, ssub, esub); + if (sep == NULL || sep == ssp) + break; /* failed or matched null */ + oldssp = ssp; /* on to next try */ + ssp = sep; + } + if (sep == NULL) { + /* last successful match */ + sep = ssp; + ssp = oldssp; + } + assert(sep == rest); /* must exhaust substring */ + assert(slow(m, ssp, sep, ssub, esub) == rest); + dp = dissect(m, ssp, sep, ssub, esub); + assert(dp == sep); + sp = rest; + break; + case OCH_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = ss + OPND(m->g->strip[ss]) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) { /* find first matching branch */ + if (slow(m, sp, rest, ssub, esub) == rest) + break; /* it matched all of it */ + /* that one missed, try next one */ + assert(OP(m->g->strip[esub]) == OOR1); + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + sp = rest; + break; + case O_PLUS: + case O_QUEST: + case OOR1: + case OOR2: + case O_CH: + assert(nope); + break; + case OLPAREN: + i = OPND(m->g->strip[ss]); + m->pmatch[i].rm_so = sp - m->offp; + break; + case ORPAREN: + i = OPND(m->g->strip[ss]); + m->pmatch[i].rm_eo = sp - m->offp; + break; + default: /* uh oh */ + assert(nope); + break; + } + } + + assert(sp == stop); + return(sp); +} + +/* + - backref - figure out what matched what, figuring in back references + == static char *backref(register struct match *m, char *start, \ + == char *stop, sopno startst, sopno stopst, sopno lev); + */ +static char * /* == stop (success) or NULL (failure) */ +backref(m, start, stop, startst, stopst, lev) +register struct match *m; +char *start; +char *stop; +sopno startst; +sopno stopst; +sopno lev; /* PLUS nesting level */ +{ + register int i; + register sopno ss; /* start sop of current subRE */ + register char *sp; /* start of string matched by it */ + register sopno ssub; /* start sop of subsubRE */ + register sopno esub; /* end sop of subsubRE */ + register char *ssp; /* start of string matched by subsubRE */ + register char *dp; + register size_t len; + register int hard; + register sop s; + register regoff_t offsave; + register cset *cs; + + AT("back", start, stop, startst, stopst); + sp = start; + + /* get as far as we can with easy stuff */ + hard = 0; + for (ss = startst; !hard && ss < stopst; ss++) + switch (OP(s = m->g->strip[ss])) { + case OCHAR: + if (sp == stop || *sp++ != (char)OPND(s)) + return(NULL); + break; + case OANY: + if (sp == stop) + return(NULL); + sp++; + break; + case OANYOF: + cs = &m->g->sets[OPND(s)]; + if (sp == stop || !CHIN(cs, *sp++)) + return(NULL); + break; + case OBOL: + if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp < m->endp && *(sp-1) == '\n' && + (m->g->cflags®_NEWLINE)) ) + { /* yes */ } + else + return(NULL); + break; + case OEOL: + if ( (sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE)) ) + { /* yes */ } + else + return(NULL); + break; + case OBOW: + if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp < m->endp && *(sp-1) == '\n' && + (m->g->cflags®_NEWLINE)) || + (sp > m->beginp && + !ISWORD(*(sp-1))) ) && + (sp < m->endp && ISWORD(*sp)) ) + { /* yes */ } + else + return(NULL); + break; + case OEOW: + if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE)) || + (sp < m->endp && !ISWORD(*sp)) ) && + (sp > m->beginp && ISWORD(*(sp-1))) ) + { /* yes */ } + else + return(NULL); + break; + case O_QUEST: + break; + case OOR1: /* matches null but needs to skip */ + ss++; + s = m->g->strip[ss]; + do { + assert(OP(s) == OOR2); + ss += OPND(s); + } while (OP(s = m->g->strip[ss]) != O_CH); + /* note that the ss++ gets us past the O_CH */ + break; + default: /* have to make a choice */ + hard = 1; + break; + } + if (!hard) { /* that was it! */ + if (sp != stop) + return(NULL); + return(sp); + } + ss--; /* adjust for the for's final increment */ + + /* the hard stuff */ + AT("hard", sp, stop, ss, stopst); + s = m->g->strip[ss]; + switch (OP(s)) { + case OBACK_: /* the vilest depths */ + i = OPND(s); + if (m->pmatch[i].rm_eo == -1) + return(NULL); + assert(m->pmatch[i].rm_so != -1); + len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + assert(stop - m->beginp >= len); + if (sp > stop - len) + return(NULL); /* not enough left to match */ + ssp = m->offp + m->pmatch[i].rm_so; + if (memcmp(sp, ssp, len) != 0) + return(NULL); + while (m->g->strip[ss] != SOP(O_BACK, i)) + ss++; + return(backref(m, sp+len, stop, ss+1, stopst, lev)); + break; + case OQUEST_: /* to null or not */ + dp = backref(m, sp, stop, ss+1, stopst, lev); + if (dp != NULL) + return(dp); /* not */ + return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); + break; + case OPLUS_: + assert(m->lastpos != NULL); + assert(lev+1 <= m->g->nplus); + m->lastpos[lev+1] = sp; + return(backref(m, sp, stop, ss+1, stopst, lev+1)); + break; + case O_PLUS: + if (sp == m->lastpos[lev]) /* last pass matched null */ + return(backref(m, sp, stop, ss+1, stopst, lev-1)); + /* try another pass */ + m->lastpos[lev] = sp; + dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); + if (dp == NULL) + return(backref(m, sp, stop, ss+1, stopst, lev-1)); + else + return(dp); + break; + case OCH_: /* find the right one, if any */ + ssub = ss + 1; + esub = ss + OPND(s) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) { /* find first matching branch */ + dp = backref(m, sp, stop, ssub, esub, lev); + if (dp != NULL) + return(dp); + /* that one missed, try next one */ + if (OP(m->g->strip[esub]) == O_CH) + return(NULL); /* there is none */ + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + break; + case OLPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + offsave = m->pmatch[i].rm_so; + m->pmatch[i].rm_so = sp - m->offp; + dp = backref(m, sp, stop, ss+1, stopst, lev); + if (dp != NULL) + return(dp); + m->pmatch[i].rm_so = offsave; + return(NULL); + break; + case ORPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + offsave = m->pmatch[i].rm_eo; + m->pmatch[i].rm_eo = sp - m->offp; + dp = backref(m, sp, stop, ss+1, stopst, lev); + if (dp != NULL) + return(dp); + m->pmatch[i].rm_eo = offsave; + return(NULL); + break; + default: /* uh oh */ + assert(nope); + break; + } + + /* "can't happen" */ + assert(nope); + /* NOTREACHED */ +} + +/* + - fast - step through the string at top speed + == static char *fast(register struct match *m, char *start, \ + == char *stop, sopno startst, sopno stopst); + */ +static char * /* where tentative match ended, or NULL */ +fast(m, start, stop, startst, stopst) +register struct match *m; +char *start; +char *stop; +sopno startst; +sopno stopst; +{ + register states st = m->st; + register states fresh = m->fresh; + register states tmp = m->tmp; + register char *p = start; + register int c = (start == m->beginp) ? OUT : *(start-1); + register int lastc; /* previous c */ + register int flagch; + register int i; + register char *coldp; /* last p after which no match was underway */ + + CLEAR(st); + SET1(st, startst); + st = step(m->g, startst, stopst, st, NOTHING, st); + ASSIGN(fresh, st); + SP("start", st, *p); + coldp = NULL; + for (;;) { + /* next character */ + lastc = c; + c = (p == m->endp) ? OUT : *p; + if (EQ(st, fresh)) + coldp = p; + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL)) ) { + flagch = BOL; + i = m->g->nbol; + } + if ( (c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL)) ) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, flagch, st); + SP("boleol", st, c); + } + + /* how about a word boundary? */ + if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && + (c != OUT && ISWORD(c)) ) { + flagch = BOW; + } + if ( (lastc != OUT && ISWORD(lastc)) && + (flagch == EOL || (c != OUT && !ISWORD(c))) ) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("boweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst) || p == stop) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, fresh); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("aft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p++; + } + + assert(coldp != NULL); + m->coldp = coldp; + if (ISSET(st, stopst)) + return(p+1); + else + return(NULL); +} + +/* + - slow - step through the string more deliberately + == static char *slow(register struct match *m, char *start, \ + == char *stop, sopno startst, sopno stopst); + */ +static char * /* where it ended */ +slow(m, start, stop, startst, stopst) +register struct match *m; +char *start; +char *stop; +sopno startst; +sopno stopst; +{ + register states st = m->st; + register states empty = m->empty; + register states tmp = m->tmp; + register char *p = start; + register int c = (start == m->beginp) ? OUT : *(start-1); + register int lastc; /* previous c */ + register int flagch; + register int i; + register char *matchp; /* last p at which a match ended */ + + AT("slow", start, stop, startst, stopst); + CLEAR(st); + SET1(st, startst); + SP("sstart", st, *p); + st = step(m->g, startst, stopst, st, NOTHING, st); + matchp = NULL; + for (;;) { + /* next character */ + lastc = c; + c = (p == m->endp) ? OUT : *p; + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL)) ) { + flagch = BOL; + i = m->g->nbol; + } + if ( (c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL)) ) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, flagch, st); + SP("sboleol", st, c); + } + + /* how about a word boundary? */ + if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && + (c != OUT && ISWORD(c)) ) { + flagch = BOW; + } + if ( (lastc != OUT && ISWORD(lastc)) && + (flagch == EOL || (c != OUT && !ISWORD(c))) ) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("sboweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst)) + matchp = p; + if (EQ(st, empty) || p == stop) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, empty); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("saft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p++; + } + + return(matchp); +} + + +/* + - step - map set of states reachable before char to set reachable after + == static states step(register struct re_guts *g, int start, int stop, \ + == register states bef, int ch, register states aft); + == #define BOL (OUT+1) + == #define EOL (BOL+1) + == #define BOLEOL (BOL+2) + == #define NOTHING (BOL+3) + == #define BOW (BOL+4) + == #define EOW (BOL+5) + == #define CODEMAX (BOL+5) // highest code used + == #define NONCHAR(c) ((c) > CHAR_MAX) + == #define NNONCHAR (CODEMAX-CHAR_MAX) + */ +static states +step(g, start, stop, bef, ch, aft) +register struct re_guts *g; +int start; /* start state within strip */ +int stop; /* state after stop state within strip */ +register states bef; /* states reachable before */ +int ch; /* character or NONCHAR code */ +register states aft; /* states already known reachable after */ +{ + register cset *cs; + register sop s; + register sopno pc; + register onestate here; /* note, macros know this name */ + register sopno look; + register int i; + + for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { + s = g->strip[pc]; + switch (OP(s)) { + case OEND: + assert(pc == stop-1); + break; + case OCHAR: + /* only characters can match */ + assert(!NONCHAR(ch) || ch != (char)OPND(s)); + if (ch == (char)OPND(s)) + FWD(aft, bef, 1); + break; + case OBOL: + if (ch == BOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OEOL: + if (ch == EOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OBOW: + if (ch == BOW) + FWD(aft, bef, 1); + break; + case OEOW: + if (ch == EOW) + FWD(aft, bef, 1); + break; + case OANY: + if (!NONCHAR(ch)) + FWD(aft, bef, 1); + break; + case OANYOF: + cs = &g->sets[OPND(s)]; + if (!NONCHAR(ch) && CHIN(cs, ch)) + FWD(aft, bef, 1); + break; + case OBACK_: /* ignored here */ + case O_BACK: + FWD(aft, aft, 1); + break; + case OPLUS_: /* forward, this is just an empty */ + FWD(aft, aft, 1); + break; + case O_PLUS: /* both forward and back */ + FWD(aft, aft, 1); + i = ISSETBACK(aft, OPND(s)); + BACK(aft, aft, OPND(s)); + if (!i && ISSETBACK(aft, OPND(s))) { + /* oho, must reconsider loop body */ + pc -= OPND(s) + 1; + INIT(here, pc); + } + break; + case OQUEST_: /* two branches, both forward */ + FWD(aft, aft, 1); + FWD(aft, aft, OPND(s)); + break; + case O_QUEST: /* just an empty */ + FWD(aft, aft, 1); + break; + case OLPAREN: /* not significant here */ + case ORPAREN: + FWD(aft, aft, 1); + break; + case OCH_: /* mark the first two branches */ + FWD(aft, aft, 1); + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + break; + case OOR1: /* done a branch, find the O_CH */ + if (ISSTATEIN(aft, here)) { + for (look = 1; + OP(s = g->strip[pc+look]) != O_CH; + look += OPND(s)) + assert(OP(s) == OOR2); + FWD(aft, aft, look); + } + break; + case OOR2: /* propagate OCH_'s marking */ + FWD(aft, aft, 1); + if (OP(g->strip[pc+OPND(s)]) != O_CH) { + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + } + break; + case O_CH: /* just empty */ + FWD(aft, aft, 1); + break; + default: /* ooooops... */ + assert(nope); + break; + } + } + + return(aft); +} + +#ifdef REDEBUG +/* + - print - print a set of states + == #ifdef REDEBUG + == static void print(struct match *m, char *caption, states st, \ + == int ch, FILE *d); + == #endif + */ +static void +print(m, caption, st, ch, d) +struct match *m; +char *caption; +states st; +int ch; +FILE *d; +{ + register struct re_guts *g = m->g; + register int i; + register int first = 1; + + if (!(m->eflags®_TRACE)) + return; + + fprintf(d, "%s", caption); + if (ch != '\0') + fprintf(d, " %s", pchar(ch)); + for (i = 0; i < g->nstates; i++) + if (ISSET(st, i)) { + fprintf(d, "%s%d", (first) ? "\t" : ", ", i); + first = 0; + } + fprintf(d, "\n"); +} + +/* + - at - print current situation + == #ifdef REDEBUG + == static void at(struct match *m, char *title, char *start, char *stop, \ + == sopno startst, stopno stopst); + == #endif + */ +static void +at(m, title, start, stop, startst, stopst) +struct match *m; +char *title; +char *start; +char *stop; +sopno startst; +sopno stopst; +{ + if (!(m->eflags®_TRACE)) + return; + + printf("%s %s-", title, pchar(*start)); + printf("%s ", pchar(*stop)); + printf("%ld-%ld\n", (long)startst, (long)stopst); +} + +#ifndef PCHARDONE +#define PCHARDONE /* never again */ +/* + - pchar - make a character printable + == #ifdef REDEBUG + == static char *pchar(int ch); + == #endif + * + * Is this identical to regchar() over in debug.c? Well, yes. But a + * duplicate here avoids having a debugging-capable regexec.o tied to + * a matching debug.o, and this is convenient. It all disappears in + * the non-debug compilation anyway, so it doesn't matter much. + */ +static char * /* -> representation */ +pchar(ch) +int ch; +{ + static char pbuf[10]; + + if (isprint(ch) || ch == ' ') + sprintf(pbuf, "%c", ch); + else + sprintf(pbuf, "\\%o", ch); + return(pbuf); +} +#endif +#endif + +#undef matcher +#undef fast +#undef slow +#undef dissect +#undef backref +#undef step +#undef print +#undef at +#undef match diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c new file mode 100644 index 000000000000..5ca038ebb108 --- /dev/null +++ b/lib/libc/regex/regcomp.c @@ -0,0 +1,1653 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)regcomp.c 8.1 (Berkeley) 6/4/93 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regcomp.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> +#include <stdlib.h> +#include <regex.h> + +#include "utils.h" +#include "regex2.h" + +#include "cclass.h" +#include "cname.h" + +/* + * parse structure, passed up and down to avoid global variables and + * other clumsinesses + */ +struct parse { + char *next; /* next character in RE */ + char *end; /* end of string (-> NUL normally) */ + int error; /* has an error been seen? */ + sop *strip; /* malloced strip */ + sopno ssize; /* malloced strip size (allocated) */ + sopno slen; /* malloced strip length (used) */ + int ncsalloc; /* number of csets allocated */ + struct re_guts *g; +# define NPAREN 10 /* we need to remember () 1-9 for back refs */ + sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ + sopno pend[NPAREN]; /* -> ) ([0] unused) */ +}; + + +static void p_ere(/*register struct parse *p, int stop*/); +static void p_ere_exp(/*register struct parse *p*/); +static void p_str(/*register struct parse *p*/); +static void p_bre(/*register struct parse *p, register int end1, register int end2*/); +static int p_simp_re(/*register struct parse *p, int starordinary*/); +static int p_count(/*register struct parse *p*/); +static void p_bracket(/*register struct parse *p*/); +static void p_b_term(/*register struct parse *p, register cset *cs*/); +static void p_b_cclass(/*register struct parse *p, register cset *cs*/); +static void p_b_eclass(/*register struct parse *p, register cset *cs*/); +static char p_b_symbol(/*register struct parse *p*/); +static char p_b_coll_elem(/*register struct parse *p, int endc*/); +static char othercase(/*int ch*/); +static void bothcases(/*register struct parse *p, int ch*/); +static void ordinary(/*register struct parse *p, register int ch*/); +static void nonnewline(/*register struct parse *p*/); +static void repeat(/*register struct parse *p, sopno start, int from, int to*/); +static int seterr(/*register struct parse *p, int e*/); +static cset *allocset(/*register struct parse *p*/); +static void freeset(/*register struct parse *p, register cset *cs*/); +static int freezeset(/*register struct parse *p, register cset *cs*/); +static int firstch(/*register struct parse *p, register cset *cs*/); +static int nch(/*register struct parse *p, register cset *cs*/); +static void mcadd(/*register struct parse *p, register cset *cs, register char *cp*/); +static void mcsub(/*register cset *cs, register char *cp*/); +static int mcin(/*register cset *cs, register char *cp*/); +static char *mcfind(/*register cset *cs, register char *cp*/); +static void mcinvert(/*register cset *cs*/); +static void mccase(/*register cset *cs*/); +static int isinsets(/*register struct re_guts *g, int c*/); +static int samesets(/*register struct re_guts *g, int c1, int c2*/); +static void categorize(/*struct parse *p, register struct re_guts *g*/); +static sopno dupl(/*register struct parse *p, sopno start, sopno finish*/); +static void doemit(/*register struct parse *p, sop op, size_t opnd*/); +static void doinsert(/*register struct parse *p, sop op, size_t opnd, sopno pos*/); +static void dofwd(/*register struct parse *p, sopno pos, sop value*/); +static void enlarge(/*register struct parse *p, sopno size*/); +static void stripsnug(/*register struct parse *p, register struct re_guts *g*/); +static void findmust(/*register struct parse *p, register struct re_guts *g*/); +static sopno pluscount(/*register struct parse *p, register struct re_guts *g*/); + +static char nuls[10]; /* place to point scanner in event of error */ + +/* + * macros for use with parse structure + * BEWARE: these know that the parse structure is named `p' !!! + */ +#define PEEK() (*p->next) +#define PEEK2() (*(p->next+1)) +#define MORE() (p->next < p->end) +#define MORE2() (p->next+1 < p->end) +#define SEE(c) (MORE() && PEEK() == (c)) +#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) +#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) +#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) +#define NEXT() (p->next++) +#define NEXT2() (p->next += 2) +#define NEXTn(n) (p->next += (n)) +#define GETNEXT() (*p->next++) +#define SETERROR(e) seterr(p, (e)) +#define REQUIRE(co, e) ((co) || SETERROR(e)) +#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) +#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) +#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) +#define EMIT(sop, sopnd) doemit(p, sop, (size_t)(sopnd)) +#define INSERT(sop, pos) doinsert(p, sop, HERE()-(pos)+1, pos) +#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) +#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) +#define HERE() (p->slen) +#define THERE() (p->slen - 1) +#define DROP(n) (p->slen -= (n)) + +static int never = 0; /* for use in asserts; shuts lint up */ + +/* + - regcomp - interface for parser and compilation + = extern int regcomp(regex_t *preg, const char *pattern, int cflags); + = #define REG_BASIC 0000 + = #define REG_EXTENDED 0001 + = #define REG_ICASE 0002 + = #define REG_NOSUB 0004 + = #define REG_NEWLINE 0010 + = #define REG_NOSPEC 0020 + = #define REG_PEND 0040 + = #define REG_DUMP 0200 + */ +int /* 0 success, otherwise REG_something */ +regcomp(preg, pattern, cflags) +regex_t *preg; +const char *pattern; +int cflags; +{ + struct parse pa; + register struct re_guts *g; + register struct parse *p = &pa; + register int i; + register size_t len; + + if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) + return(REG_INVARG); + + if (cflags®_PEND) { + if (preg->re_endp < pattern) + return(REG_INVARG); + len = preg->re_endp - pattern; + } else + len = strlen((char *)pattern); + + /* do the mallocs early so failure handling is easy */ + g = (struct re_guts *)malloc(sizeof(struct re_guts) + + (NC-1)*sizeof(cat_t)); + if (g == NULL) + return(REG_ESPACE); + p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ + p->strip = (sop *)malloc(p->ssize * sizeof(sop)); + p->slen = 0; + if (p->strip == NULL) { + free((char *)g); + return(REG_ESPACE); + } + + /* set things up */ + p->g = g; + p->next = (char *)pattern; /* convenience; we do not modify it */ + p->end = p->next + len; + p->error = 0; + p->ncsalloc = 0; + for (i = 0; i < NPAREN; i++) { + p->pbegin[i] = 0; + p->pend[i] = 0; + } + g->csetsize = NC; + g->sets = NULL; + g->setbits = NULL; + g->ncsets = 0; + g->cflags = cflags; + g->iflags = 0; + g->nbol = 0; + g->neol = 0; + g->must = NULL; + g->mlen = 0; + g->nsub = 0; + g->ncategories = 1; /* category 0 is "everything else" */ + g->categories = &g->catspace[-(CHAR_MIN)]; + (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t)); + g->backrefs = 0; + + /* do it */ + EMIT(OEND, 0); + g->firststate = THERE(); + if (cflags®_EXTENDED) + p_ere(p, OUT); + else if (cflags®_NOSPEC) + p_str(p); + else + p_bre(p, OUT, OUT); + EMIT(OEND, 0); + g->laststate = THERE(); + + /* tidy up loose ends and fill things in */ + categorize(p, g); + stripsnug(p, g); + findmust(p, g); + g->nplus = pluscount(p, g); + g->magic = MAGIC2; + preg->re_nsub = g->nsub; + preg->re_g = g; + preg->re_magic = MAGIC1; +#ifndef REDEBUG + /* not debugging, so can't rely on the assert() in regexec() */ + if (g->iflags&BAD) + SETERROR(REG_ASSERT); +#endif + + /* win or lose, we're done */ + if (p->error != 0) /* lose */ + regfree(preg); + return(p->error); +} + +/* + - p_ere - ERE parser top level, concatenation and alternation + == static void p_ere(register struct parse *p, int stop); + */ +static void +p_ere(p, stop) +register struct parse *p; +int stop; /* character this ERE should end at */ +{ + register char c; + register sopno prevback; + register sopno prevfwd; + register sopno conc; + register int first = 1; /* is this the first alternative? */ + + for (;;) { + /* do a bunch of concatenated expressions */ + conc = HERE(); + while (MORE() && (c = PEEK()) != '|' && c != stop) + p_ere_exp(p); + REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ + + if (!EAT('|')) + break; /* NOTE BREAK OUT */ + + if (first) { + INSERT(OCH_, conc); /* offset is wrong */ + prevfwd = conc; + prevback = conc; + first = 0; + } + ASTERN(OOR1, prevback); + prevback = THERE(); + AHEAD(prevfwd); /* fix previous offset */ + prevfwd = HERE(); + EMIT(OOR2, 0); /* offset is very wrong */ + } + + if (!first) { /* tail-end fixups */ + AHEAD(prevfwd); + ASTERN(O_CH, prevback); + } + + assert(!MORE() || SEE(stop)); +} + +/* + - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op + == static void p_ere_exp(register struct parse *p); + */ +static void +p_ere_exp(p) +register struct parse *p; +{ + register char c; + register sopno pos; + register int count; + register int count2; + register sopno subno; + int wascaret = 0; + + assert(MORE()); /* caller should have ensured this */ + c = GETNEXT(); + + pos = HERE(); + switch (c) { + case '(': + REQUIRE(MORE(), REG_EPAREN); + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + if (!SEE(')')) + p_ere(p, ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + MUSTEAT(')', REG_EPAREN); + break; +#ifndef POSIX_MISTAKE + case ')': /* happens only if no current unmatched ( */ + /* + * You may ask, why the ifndef? Because I didn't notice + * this until slightly too late for 1003.2, and none of the + * other 1003.2 regular-expression reviewers noticed it at + * all. So an unmatched ) is legal POSIX, at least until + * we can get it fixed. + */ + SETERROR(REG_EPAREN); + break; +#endif + case '^': + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + wascaret = 1; + break; + case '$': + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + break; + case '|': + SETERROR(REG_EMPTY); + break; + case '*': + case '+': + case '?': + SETERROR(REG_BADRPT); + break; + case '.': + if (p->g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case '\\': + REQUIRE(MORE(), REG_EESCAPE); + c = GETNEXT(); + ordinary(p, c); + break; + case '{': /* okay as ordinary except if digit follows */ + REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT); + /* FALLTHROUGH */ + default: + ordinary(p, c); + break; + } + + if (!MORE()) + return; + c = PEEK(); + /* we call { a repetition if followed by a digit */ + if (!( c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit(PEEK2())) )) + return; /* no repetition, we're done */ + NEXT(); + + REQUIRE(!wascaret, REG_BADRPT); + switch (c) { + case '*': /* implemented as +? */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + break; + case '+': + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + break; + case '?': + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + break; + case '{': + count = p_count(p); + if (EAT(',')) { + if (isdigit(PEEK())) { + count2 = p_count(p); + REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EAT('}')) { /* error heuristics */ + while (MORE() && PEEK() != '}') + NEXT(); + REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + break; + } + + if (!MORE()) + return; + c = PEEK(); + if (!( c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit(PEEK2())) ) ) + return; + SETERROR(REG_BADRPT); +} + +/* + - p_str - string (no metacharacters) "parser" + == static void p_str(register struct parse *p); + */ +static void +p_str(p) +register struct parse *p; +{ + REQUIRE(MORE(), REG_EMPTY); + while (MORE()) + ordinary(p, GETNEXT()); +} + +/* + - p_bre - BRE parser top level, anchoring and concatenation + == static void p_bre(register struct parse *p, register int end1, \ + == register int end2); + * Giving end1 as OUT essentially eliminates the end1/end2 check. + * + * This implementation is a bit of a kludge, in that a trailing $ is first + * taken as an ordinary character and then revised to be an anchor. The + * only undesirable side effect is that '$' gets included as a character + * category in such cases. This is fairly harmless; not worth fixing. + * The amount of lookahead needed to avoid this kludge is excessive. + */ +static void +p_bre(p, end1, end2) +register struct parse *p; +register int end1; /* first terminating character */ +register int end2; /* second terminating character */ +{ + register sopno start = HERE(); + register int first = 1; /* first subexpression? */ + register int wasdollar = 0; + + if (EAT('^')) { + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + } + while (MORE() && !SEETWO(end1, end2)) { + wasdollar = p_simp_re(p, first); + first = 0; + } + if (wasdollar) { /* oops, that was a trailing anchor */ + DROP(1); + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + } + + REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ +} + +/* + - p_simp_re - parse a simple RE, an atom possibly followed by a repetition + == static int p_simp_re(register struct parse *p, int starordinary); + */ +static int /* was the simple RE an unbackslashed $? */ +p_simp_re(p, starordinary) +register struct parse *p; +int starordinary; /* is a leading * an ordinary character? */ +{ + register int c; + register int count; + register int count2; + register sopno pos; + register int i; + register sopno subno; +# define BACKSL (1<<CHAR_BIT) + + pos = HERE(); /* repetion op, if any, covers from here */ + + assert(MORE()); /* caller should have ensured this */ + c = GETNEXT(); + if (c == '\\') { + REQUIRE(MORE(), REG_EESCAPE); + c = BACKSL | (unsigned char)GETNEXT(); + } + switch (c) { + case '.': + if (p->g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case BACKSL|'{': + SETERROR(REG_BADRPT); + break; + case BACKSL|'(': + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + /* the MORE here is an error heuristic */ + if (MORE() && !SEETWO('\\', ')')) + p_bre(p, '\\', ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + REQUIRE(EATTWO('\\', ')'), REG_EPAREN); + break; + case BACKSL|')': /* should not get here -- must be user */ + case BACKSL|'}': + SETERROR(REG_EPAREN); + break; + case BACKSL|'1': + case BACKSL|'2': + case BACKSL|'3': + case BACKSL|'4': + case BACKSL|'5': + case BACKSL|'6': + case BACKSL|'7': + case BACKSL|'8': + case BACKSL|'9': + i = (c&~BACKSL) - '0'; + assert(i < NPAREN); + if (p->pend[i] != 0) { + assert(i <= p->g->nsub); + EMIT(OBACK_, i); + assert(p->pbegin[i] != 0); + assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); + assert(OP(p->strip[p->pend[i]]) == ORPAREN); + (void) dupl(p, p->pbegin[i]+1, p->pend[i]); + EMIT(O_BACK, i); + } else + SETERROR(REG_ESUBREG); + p->g->backrefs = 1; + break; + case '*': + REQUIRE(starordinary, REG_BADRPT); + /* FALLTHROUGH */ + default: + ordinary(p, c &~ BACKSL); + break; + } + + if (EAT('*')) { /* implemented as +? */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + } else if (EATTWO('\\', '{')) { + count = p_count(p); + if (EAT(',')) { + if (MORE() && isdigit(PEEK())) { + count2 = p_count(p); + REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EATTWO('\\', '}')) { /* error heuristics */ + while (MORE() && !SEETWO('\\', '}')) + NEXT(); + REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */ + return(1); + + return(0); +} + +/* + - p_count - parse a repetition count + == static int p_count(register struct parse *p); + */ +static int /* the value */ +p_count(p) +register struct parse *p; +{ + register int count = 0; + register int ndigits = 0; + + while (MORE() && isdigit(PEEK()) && count <= DUPMAX) { + count = count*10 + (GETNEXT() - '0'); + ndigits++; + } + + REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); + return(count); +} + +/* + - p_bracket - parse a bracketed character list + == static void p_bracket(register struct parse *p); + * + * Note a significant property of this code: if the allocset() did SETERROR, + * no set operations are done. + */ +static void +p_bracket(p) +register struct parse *p; +{ + register char c; + register cset *cs = allocset(p); + register int invert = 0; + + /* Dept of Truly Sickening Special-Case Kludges */ + if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { + EMIT(OBOW, 0); + NEXTn(6); + return; + } + if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { + EMIT(OEOW, 0); + NEXTn(6); + return; + } + + if (EAT('^')) + invert++; /* make note to invert set at end */ + if (EAT(']')) + CHadd(cs, ']'); + else if (EAT('-')) + CHadd(cs, '-'); + while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) + p_b_term(p, cs); + if (EAT('-')) + CHadd(cs, '-'); + MUSTEAT(']', REG_EBRACK); + + if (p->error != 0) /* don't mess things up further */ + return; + + if (p->g->cflags®_ICASE) { + register int i; + register int ci; + + for (i = p->g->csetsize - 1; i >= 0; i--) + if (CHIN(cs, i) && isalpha(i)) { + ci = othercase(i); + if (ci != i) + CHadd(cs, ci); + } + if (cs->multis != NULL) + mccase(p, cs); + } + if (invert) { + register int i; + + for (i = p->g->csetsize - 1; i >= 0; i--) + if (CHIN(cs, i)) + CHsub(cs, i); + else + CHadd(cs, i); + if (p->g->cflags®_NEWLINE) + CHsub(cs, '\n'); + if (cs->multis != NULL) + mcinvert(p, cs); + } + + assert(cs->multis == NULL); /* xxx */ + + if (nch(p, cs) == 1) { /* optimize singleton sets */ + ordinary(p, firstch(p, cs)); + freeset(p, cs); + } else + EMIT(OANYOF, freezeset(p, cs)); +} + +/* + - p_b_term - parse one term of a bracketed character list + == static void p_b_term(register struct parse *p, register cset *cs); + */ +static void +p_b_term(p, cs) +register struct parse *p; +register cset *cs; +{ + register char c; + register char start, finish; + register int i; + + /* classify what we've got */ + switch ((MORE()) ? PEEK() : '\0') { + case '[': + c = (MORE2()) ? PEEK2() : '\0'; + break; + case '-': + SETERROR(REG_ERANGE); + return; /* NOTE RETURN */ + break; + default: + c = '\0'; + break; + } + + switch (c) { + case ':': /* character class */ + NEXT2(); + REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); + REQUIRE(c != '-' && c != ']', REG_ECTYPE); + p_b_cclass(p, cs); + REQUIRE(MORE(), REG_EBRACK); + REQUIRE(EATTWO(':', ']'), REG_ECTYPE); + break; + case '=': /* equivalence class */ + NEXT2(); + REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); + REQUIRE(c != '-' && c != ']', REG_ECOLLATE); + p_b_eclass(p, cs); + REQUIRE(MORE(), REG_EBRACK); + REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); + break; + default: /* symbol, ordinary character, or range */ +/* xxx revision needed for multichar stuff */ + start = p_b_symbol(p); + if (SEE('-') && MORE2() && PEEK2() != ']') { + /* range */ + NEXT(); + if (EAT('-')) + finish = '-'; + else + finish = p_b_symbol(p); + } else + finish = start; +/* xxx what about signed chars here... */ + REQUIRE(start <= finish, REG_ERANGE); + for (i = start; i <= finish; i++) + CHadd(cs, i); + break; + } +} + +/* + - p_b_cclass - parse a character-class name and deal with it + == static void p_b_cclass(register struct parse *p, register cset *cs); + */ +static void +p_b_cclass(p, cs) +register struct parse *p; +register cset *cs; +{ + register char *sp = p->next; + register struct cclass *cp; + register size_t len; + register char *u; + register char c; + + while (MORE() && isalpha(PEEK())) + NEXT(); + len = p->next - sp; + for (cp = cclasses; cp->name != NULL; cp++) + if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') + break; + if (cp->name == NULL) { + /* oops, didn't find it */ + SETERROR(REG_ECTYPE); + return; + } + + u = cp->chars; + while ((c = *u++) != '\0') + CHadd(cs, c); + for (u = cp->multis; *u != '\0'; u += strlen(u) + 1) + MCadd(cs, u); +} + +/* + - p_b_eclass - parse an equivalence-class name and deal with it + == static void p_b_eclass(register struct parse *p, register cset *cs); + * + * This implementation is incomplete. xxx + */ +static void +p_b_eclass(p, cs) +register struct parse *p; +register cset *cs; +{ + register char c; + + c = p_b_coll_elem(p, '='); + CHadd(cs, c); +} + +/* + - p_b_symbol - parse a character or [..]ed multicharacter collating symbol + == static char p_b_symbol(register struct parse *p); + */ +static char /* value of symbol */ +p_b_symbol(p) +register struct parse *p; +{ + register char value; + + REQUIRE(MORE(), REG_EBRACK); + if (!EATTWO('[', '.')) + return(GETNEXT()); + + /* collating symbol */ + value = p_b_coll_elem(p, '.'); + REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); + return(value); +} + +/* + - p_b_coll_elem - parse a collating-element name and look it up + == static char p_b_coll_elem(register struct parse *p, int endc); + */ +static char /* value of collating element */ +p_b_coll_elem(p, endc) +register struct parse *p; +int endc; /* name ended by endc,']' */ +{ + register char *sp = p->next; + register struct cname *cp; + register int len; + register char c; + + while (MORE() && !SEETWO(endc, ']')) + NEXT(); + if (!MORE()) { + SETERROR(REG_EBRACK); + return(0); + } + len = p->next - sp; + for (cp = cnames; cp->name != NULL; cp++) + if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') + return(cp->code); /* known name */ + if (len == 1) + return(*sp); /* single character */ + SETERROR(REG_ECOLLATE); /* neither */ + return(0); +} + +/* + - othercase - return the case counterpart of an alphabetic + == static char othercase(int ch); + */ +static char /* if no counterpart, return ch */ +othercase(ch) +int ch; +{ + assert(isalpha(ch)); + if (isupper(ch)) + return(tolower(ch)); + else if (islower(ch)) + return(toupper(ch)); + else /* peculiar, but could happen */ + return(ch); +} + +/* + - bothcases - emit a dualcase version of a two-case character + == static void bothcases(register struct parse *p, int ch); + * + * Boy, is this implementation ever a kludge... + */ +static void +bothcases(p, ch) +register struct parse *p; +int ch; +{ + register char *oldnext = p->next; + register char *oldend = p->end; + char bracket[3]; + + assert(othercase(ch) != ch); /* p_bracket() would recurse */ + p->next = bracket; + p->end = bracket+2; + bracket[0] = ch; + bracket[1] = ']'; + bracket[2] = '\0'; + p_bracket(p); + assert(p->next == bracket+2); + p->next = oldnext; + p->end = oldend; +} + +/* + - ordinary - emit an ordinary character + == static void ordinary(register struct parse *p, register int ch); + */ +static void +ordinary(p, ch) +register struct parse *p; +register int ch; +{ + register cat_t *cap = p->g->categories; + + if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch) + bothcases(p, ch); + else { + EMIT(OCHAR, (unsigned char)ch); + if (cap[ch] == 0) + cap[ch] = p->g->ncategories++; + } +} + +/* + - nonnewline - emit REG_NEWLINE version of OANY + == static void nonnewline(register struct parse *p); + * + * Boy, is this implementation ever a kludge... + */ +static void +nonnewline(p) +register struct parse *p; +{ + register char *oldnext = p->next; + register char *oldend = p->end; + char bracket[4]; + + p->next = bracket; + p->end = bracket+3; + bracket[0] = '^'; + bracket[1] = '\n'; + bracket[2] = ']'; + bracket[3] = '\0'; + p_bracket(p); + assert(p->next == bracket+3); + p->next = oldnext; + p->end = oldend; +} + +/* + - repeat - generate code for a bounded repetition, recursively if needed + == static void repeat(register struct parse *p, sopno start, int from, int to); + */ +static void +repeat(p, start, from, to) +register struct parse *p; +sopno start; /* operand from here to end of strip */ +int from; /* repeated from this number */ +int to; /* to this number of times (maybe INFINITY) */ +{ + register sopno finish = HERE(); +# define N 2 +# define INF 3 +# define REP(f, t) ((f)*8 + (t)) +# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) + register sopno copy; + + if (p->error != 0) /* head off possible runaway recursion */ + return; + + assert(from <= to); + + switch (REP(MAP(from), MAP(to))) { + case REP(0, 0): /* must be user doing this */ + DROP(finish-start); /* drop the operand */ + break; + case REP(0, 1): /* as x{1,1}? */ + case REP(0, N): /* as x{1,n}? */ + case REP(0, INF): /* as x{1,}? */ + INSERT(OQUEST_, start); /* offset is wrong... */ + repeat(p, start+1, 1, to); + AHEAD(start); /* ... fix it */ + ASTERN(O_QUEST, start); + break; + case REP(1, 1): /* trivial case */ + /* done */ + break; + case REP(1, N): /* as x?x{1,n-1} */ + INSERT(OQUEST_, start); + ASTERN(O_QUEST, start); + copy = dupl(p, start+1, finish+1); + assert(copy == finish+2); + repeat(p, copy, 1, to-1); + break; + case REP(1, INF): /* as x+ */ + INSERT(OPLUS_, start); + ASTERN(O_PLUS, start); + break; + case REP(N, N): /* as xx{m-1,n-1} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to-1); + break; + case REP(N, INF): /* as xx{n-1,INF} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to); + break; + default: /* "can't happen" */ + SETERROR(REG_ASSERT); /* just in case */ + break; + } +} + +/* + - seterr - set an error condition + == static int seterr(register struct parse *p, int e); + */ +static int /* useless but makes type checking happy */ +seterr(p, e) +register struct parse *p; +int e; +{ + if (p->error == 0) /* keep earliest error condition */ + p->error = e; + p->next = nuls; /* try to bring things to a halt */ + p->end = nuls; + return(0); /* make the return value well-defined */ +} + +/* + - allocset - allocate a set of characters for [] + == static cset *allocset(register struct parse *p); + */ +static cset * +allocset(p) +register struct parse *p; +{ + register int no = p->g->ncsets++; + register size_t nc; + register size_t nbytes; + register cset *cs; + register size_t css = (size_t)p->g->csetsize; + + if (no >= p->ncsalloc) { /* need another column of space */ + p->ncsalloc += CHAR_BIT; + nc = p->ncsalloc; + assert(nc % CHAR_BIT == 0); + nbytes = nc / CHAR_BIT * css; + if (p->g->sets == NULL) + p->g->sets = (cset *)malloc(nc * sizeof(cset)); + else + p->g->sets = (cset *)realloc((char *)p->g->sets, + nc * sizeof(cset)); + if (p->g->setbits == NULL) + p->g->setbits = (unsigned char *)malloc(nbytes); + else + p->g->setbits = + (unsigned char *)realloc((char *)p->g->setbits, + nbytes); + if (p->g->sets != NULL && p->g->setbits != NULL) + (void) memset((char *)p->g->setbits + (nbytes - css), + 0, css); + else { + no = 0; + SETERROR(REG_ESPACE); + /* caller's responsibility not to do set ops */ + } + } + + assert(p->g->sets != NULL); /* xxx */ + cs = &p->g->sets[no]; + cs->ptr = p->g->setbits + css*((no)/CHAR_BIT); + cs->mask = 1 << ((no) % CHAR_BIT); + cs->hash = 0; + cs->smultis = 0; + cs->multis = NULL; + + return(cs); +} + +/* + - freeset - free a now-unused set + == static void freeset(register struct parse *p, register cset *cs); + */ +static void +freeset(p, cs) +register struct parse *p; +register cset *cs; +{ + register int i; + register cset *top = &p->g->sets[p->g->ncsets]; + register size_t css = (size_t)p->g->csetsize; + + for (i = 0; i < css; i++) + CHsub(cs, i); + if (cs == top-1) /* recover only the easy case */ + p->g->ncsets--; +} + +/* + - freezeset - final processing on a set of characters + == static int freezeset(register struct parse *p, register cset *cs); + * + * The main task here is merging identical sets. This is usually a waste + * of time (although the hash code minimizes the overhead), but can win + * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash + * is done using addition rather than xor -- all ASCII [aA] sets xor to + * the same value! + */ +static int /* set number */ +freezeset(p, cs) +register struct parse *p; +register cset *cs; +{ + register unsigned char h = cs->hash; + register int i; + register cset *top = &p->g->sets[p->g->ncsets]; + register cset *cs2; + register size_t css = (size_t)p->g->csetsize; + + /* look for an earlier one which is the same */ + for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) + if (cs2->hash == h && cs2 != cs) { + /* maybe */ + for (i = 0; i < css; i++) + if (!!CHIN(cs2, i) != !!CHIN(cs, i)) + break; /* no */ + if (i == css) + break; /* yes */ + } + + if (cs2 < top) { /* found one */ + freeset(p, cs); + cs = cs2; + } + + return((int)(cs - p->g->sets)); +} + +/* + - firstch - return first character in a set (which must have at least one) + == static int firstch(register struct parse *p, register cset *cs); + */ +static int /* character; there is no "none" value */ +firstch(p, cs) +register struct parse *p; +register cset *cs; +{ + register int i; + register size_t css = (size_t)p->g->csetsize; + + for (i = 0; i < css; i++) + if (CHIN(cs, i)) + return((char)i); + assert(never); + return(0); /* arbitrary */ +} + +/* + - nch - number of characters in a set + == static int nch(register struct parse *p, register cset *cs); + */ +static int +nch(p, cs) +register struct parse *p; +register cset *cs; +{ + register int i; + register size_t css = (size_t)p->g->csetsize; + register int n = 0; + + for (i = 0; i < css; i++) + if (CHIN(cs, i)) + n++; + return(n); +} + +/* + - mcadd - add a collating element to a cset + == static void mcadd(register struct parse *p, register cset *cs, \ + == register char *cp); + */ +static void +mcadd(p, cs, cp) +register struct parse *p; +register cset *cs; +register char *cp; +{ + register size_t oldend = cs->smultis; + + cs->smultis += strlen(cp) + 1; + if (cs->multis == NULL) + cs->multis = malloc(cs->smultis); + else + cs->multis = realloc(cs->multis, cs->smultis); + if (cs->multis == NULL) { + SETERROR(REG_ESPACE); + return; + } + + (void) strcpy(cs->multis + oldend - 1, cp); + cs->multis[cs->smultis - 1] = '\0'; +} + +/* + - mcsub - subtract a collating element from a cset + == static void mcsub(register cset *cs, register char *cp); + */ +static void +mcsub(cs, cp) +register cset *cs; +register char *cp; +{ + register char *fp = mcfind(cs, cp); + register size_t len = strlen(fp); + + assert(fp != NULL); + (void) memmove(fp, fp + len + 1, + cs->smultis - (fp + len + 1 - cs->multis)); + cs->smultis -= len; + + if (cs->smultis == 0) { + free(cs->multis); + cs->multis = NULL; + return; + } + + cs->multis = realloc(cs->multis, cs->smultis); + assert(cs->multis != NULL); +} + +/* + - mcin - is a collating element in a cset? + == static int mcin(register cset *cs, register char *cp); + */ +static int +mcin(cs, cp) +register cset *cs; +register char *cp; +{ + return(mcfind(cs, cp) != NULL); +} + +/* + - mcfind - find a collating element in a cset + == static char *mcfind(register cset *cs, register char *cp); + */ +static char * +mcfind(cs, cp) +register cset *cs; +register char *cp; +{ + register char *p; + + if (cs->multis == NULL) + return(NULL); + for (p = cs->multis; *p != '\0'; p += strlen(p) + 1) + if (strcmp(cp, p) == 0) + return(p); + return(NULL); +} + +/* + - mcinvert - invert the list of collating elements in a cset + == static void mcinvert(register cset *cs); + * + * This would have to know the set of possibilities. Implementation + * is deferred. + */ +static void +mcinvert(cs) +register cset *cs; +{ + assert(cs->multis == NULL); /* xxx */ +} + +/* + - mccase - add case counterparts of the list of collating elements in a cset + == static void mccase(register cset *cs); + * + * This would have to know the set of possibilities. Implementation + * is deferred. + */ +static void +mccase(cs) +register cset *cs; +{ + assert(cs->multis == NULL); /* xxx */ +} + +/* + - isinsets - is this character in any sets? + == static int isinsets(register struct re_guts *g, int c); + */ +static int /* predicate */ +isinsets(g, c) +register struct re_guts *g; +int c; +{ + register unsigned char *col; + register int i; + register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; + register unsigned uc = (unsigned char)c; + + for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) + if (col[uc] != 0) + return(1); + return(0); +} + +/* + - samesets - are these two characters in exactly the same sets? + == static int samesets(register struct re_guts *g, int c1, int c2); + */ +static int /* predicate */ +samesets(g, c1, c2) +register struct re_guts *g; +int c1; +int c2; +{ + register unsigned char *col; + register int i; + register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; + register unsigned uc1 = (unsigned char)c1; + register unsigned uc2 = (unsigned char)c2; + + for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) + if (col[uc1] != col[uc2]) + return(0); + return(1); +} + +/* + - categorize - sort out character categories + == static void categorize(struct parse *p, register struct re_guts *g); + */ +static void +categorize(p, g) +struct parse *p; +register struct re_guts *g; +{ + register cat_t *cats = g->categories; + register int c; + register int c2; + register cat_t cat; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (cats[c] == 0 && isinsets(g, c)) { + cat = g->ncategories++; + cats[c] = cat; + for (c2 = c+1; c2 <= CHAR_MAX; c2++) + if (cats[c2] == 0 && samesets(g, c, c2)) + cats[c2] = cat; + } +} + +/* + - dupl - emit a duplicate of a bunch of sops + == static sopno dupl(register struct parse *p, sopno start, sopno finish); + */ +static sopno /* start of duplicate */ +dupl(p, start, finish) +register struct parse *p; +sopno start; /* from here */ +sopno finish; /* to this less one */ +{ + register sopno ret = HERE(); + register sopno len = finish - start; + + assert(finish >= start); + if (len == 0) + return(ret); + enlarge(p, p->ssize + len); /* this many unexpected additions */ + assert(p->ssize >= p->slen + len); + (void) memcpy((char *)(p->strip + p->slen), + (char *)(p->strip + start), (size_t)len*sizeof(sop)); + p->slen += len; + return(ret); +} + +/* + - doemit - emit a strip operator + == static void doemit(register struct parse *p, sop op, size_t opnd); + * + * It might seem better to implement this as a macro with a function as + * hard-case backup, but it's just too big and messy unless there are + * some changes to the data structures. Maybe later. + */ +static void +doemit(p, op, opnd) +register struct parse *p; +sop op; +size_t opnd; +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* deal with oversize operands ("can't happen", more or less) */ + assert(opnd < 1<<OPSHIFT); + + /* deal with undersized strip */ + if (p->slen >= p->ssize) + enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */ + assert(p->slen < p->ssize); + + /* finally, it's all reduced to the easy case */ + p->strip[p->slen++] = SOP(op, opnd); +} + +/* + - doinsert - insert a sop into the strip + == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos); + */ +static void +doinsert(p, op, opnd, pos) +register struct parse *p; +sop op; +size_t opnd; +sopno pos; +{ + register sopno sn; + register sop s; + register int i; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + sn = HERE(); + EMIT(op, opnd); /* do checks, ensure space */ + assert(HERE() == sn+1); + s = p->strip[sn]; + + /* adjust paren pointers */ + assert(pos > 0); + for (i = 1; i < NPAREN; i++) { + if (p->pbegin[i] >= pos) { + p->pbegin[i]++; + } + if (p->pend[i] >= pos) { + p->pend[i]++; + } + } + + memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], + (HERE()-pos-1)*sizeof(sop)); + p->strip[pos] = s; +} + +/* + - dofwd - complete a forward reference + == static void dofwd(register struct parse *p, sopno pos, sop value); + */ +static void +dofwd(p, pos, value) +register struct parse *p; +register sopno pos; +sop value; +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + assert(value < 1<<OPSHIFT); + p->strip[pos] = OP(p->strip[pos]) | value; +} + +/* + - enlarge - enlarge the strip + == static void enlarge(register struct parse *p, sopno size); + */ +static void +enlarge(p, size) +register struct parse *p; +register sopno size; +{ + register sop *sp; + + if (p->ssize >= size) + return; + + sp = (sop *)realloc(p->strip, size*sizeof(sop)); + if (sp == NULL) { + SETERROR(REG_ESPACE); + return; + } + p->strip = sp; + p->ssize = size; +} + +/* + - stripsnug - compact the strip + == static void stripsnug(register struct parse *p, register struct re_guts *g); + */ +static void +stripsnug(p, g) +register struct parse *p; +register struct re_guts *g; +{ + g->nstates = p->slen; + g->strip = (sop *)realloc((sop *)p->strip, p->slen * sizeof(sop)); + if (g->strip == NULL) { + SETERROR(REG_ESPACE); + g->strip = p->strip; + } +} + +/* + - findmust - fill in must and mlen with longest mandatory literal string + == static void findmust(register struct parse *p, register struct re_guts *g); + * + * This algorithm could do fancy things like analyzing the operands of | + * for common subsequences. Someday. This code is simple and finds most + * of the interesting cases. + * + * Note that must and mlen got initialized during setup. + */ +static void +findmust(p, g) +struct parse *p; +register struct re_guts *g; +{ + register sop *scan; + sop *start; + register sop *newstart; + register sopno newlen; + register sop s; + register char *cp; + register sopno i; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* find the longest OCHAR sequence in strip */ + newlen = 0; + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OCHAR: /* sequence member */ + if (newlen == 0) /* new sequence */ + newstart = scan - 1; + newlen++; + break; + case OPLUS_: /* things that don't break one */ + case OLPAREN: + case ORPAREN: + break; + case OQUEST_: /* things that must be skipped */ + case OCH_: + scan--; + do { + scan += OPND(s); + s = *scan; + /* assert() interferes w debug printouts */ + if (OP(s) != O_QUEST && OP(s) != O_CH && + OP(s) != OOR2) { + g->iflags |= BAD; + return; + } + } while (OP(s) != O_QUEST && OP(s) != O_CH); + /* fallthrough */ + default: /* things that break a sequence */ + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + } + newlen = 0; + break; + } + } while (OP(s) != OEND); + + if (g->mlen == 0) /* there isn't one */ + return; + + /* turn it into a character string */ + g->must = malloc((size_t)g->mlen + 1); + if (g->must == NULL) { /* argh; just forget it */ + g->mlen = 0; + return; + } + cp = g->must; + scan = start; + for (i = g->mlen; i > 0; i--) { + while (OP(s = *scan++) != OCHAR) + continue; + *cp++ = (char)OPND(s); + } + *cp++ = '\0'; /* just on general principles */ +} + +/* + - pluscount - count + nesting + == static sopno pluscount(register struct parse *p, register struct re_guts *g); + */ +static sopno /* nesting depth */ +pluscount(p, g) +struct parse *p; +register struct re_guts *g; +{ + register sop *scan; + register sop s; + register sopno plusnest = 0; + register sopno maxnest = 0; + + if (p->error != 0) + return(0); /* there may not be an OEND */ + + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OPLUS_: + plusnest++; + break; + case O_PLUS: + if (plusnest > maxnest) + maxnest = plusnest; + plusnest--; + break; + } + } while (OP(s) != OEND); + if (plusnest != 0) + g->iflags |= BAD; + return(maxnest); +} diff --git a/lib/libc/regex/regerror.c b/lib/libc/regex/regerror.c new file mode 100644 index 000000000000..c1b71eec8c8d --- /dev/null +++ b/lib/libc/regex/regerror.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)regerror.c 8.1 (Berkeley) 6/4/93 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regerror.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> +#include <stdlib.h> +#include <regex.h> + +#include "utils.h" + +static char *regatoi __P((const regex_t *, char *)); + +/* + = #define REG_NOMATCH 1 + = #define REG_BADPAT 2 + = #define REG_ECOLLATE 3 + = #define REG_ECTYPE 4 + = #define REG_EESCAPE 5 + = #define REG_ESUBREG 6 + = #define REG_EBRACK 7 + = #define REG_EPAREN 8 + = #define REG_EBRACE 9 + = #define REG_BADBR 10 + = #define REG_ERANGE 11 + = #define REG_ESPACE 12 + = #define REG_BADRPT 13 + = #define REG_EMPTY 14 + = #define REG_ASSERT 15 + = #define REG_INVARG 16 + = #define REG_ATOI 255 // convert name to number (!) + = #define REG_ITOA 0400 // convert number to name (!) + */ +static struct rerr { + int code; + char *name; + char *explain; +} rerrs[] = { + REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match", + REG_BADPAT, "REG_BADPAT", "invalid regular expression", + REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element", + REG_ECTYPE, "REG_ECTYPE", "invalid character class", + REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)", + REG_ESUBREG, "REG_ESUBREG", "invalid backreference number", + REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced", + REG_EPAREN, "REG_EPAREN", "parentheses not balanced", + REG_EBRACE, "REG_EBRACE", "braces not balanced", + REG_BADBR, "REG_BADBR", "invalid repetition count(s)", + REG_ERANGE, "REG_ERANGE", "invalid character range", + REG_ESPACE, "REG_ESPACE", "out of memory", + REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid", + REG_EMPTY, "REG_EMPTY", "empty (sub)expression", + REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug", + REG_INVARG, "REG_INVARG", "invalid argument to regex routine", + 0, "", "*** unknown regexp error code ***", +}; + +/* + - regerror - the interface to error numbers + = extern size_t regerror(int errcode, const regex_t *preg, char *errbuf, \ + = size_t errbuf_size); + */ +/* ARGSUSED */ +size_t +regerror(errcode, preg, errbuf, errbuf_size) +int errcode; +const regex_t *preg; +char *errbuf; +size_t errbuf_size; +{ + register struct rerr *r; + register size_t len; + register int target = errcode &~ REG_ITOA; + register char *s; + char convbuf[50]; + + if (errcode == REG_ATOI) + s = regatoi(preg, convbuf); + else { + for (r = rerrs; r->code != 0; r++) + if (r->code == target) + break; + + if (errcode®_ITOA) { + if (r->code != 0) + (void) strcpy(convbuf, r->name); + else + sprintf(convbuf, "REG_0x%x", target); + assert(strlen(convbuf) < sizeof(convbuf)); + s = convbuf; + } else + s = r->explain; + } + + len = strlen(s) + 1; + if (errbuf_size > 0) { + if (errbuf_size > len) + (void) strcpy(errbuf, s); + else { + (void) strncpy(errbuf, s, errbuf_size-1); + errbuf[errbuf_size-1] = '\0'; + } + } + + return(len); +} + +/* + - regatoi - internal routine to implement REG_ATOI + = static char *regatoi(const regex_t *preg, char *localbuf); + */ +static char * +regatoi(preg, localbuf) +const regex_t *preg; +char *localbuf; +{ + register struct rerr *r; + register size_t siz; + register char *p; + + for (r = rerrs; r->code != 0; r++) + if (strcmp(r->name, preg->re_endp) == 0) + break; + if (r->code == 0) + return("0"); + + sprintf(localbuf, "%d", r->code); + return(localbuf); +} diff --git a/lib/libc/regex/regex.3 b/lib/libc/regex/regex.3 new file mode 100644 index 000000000000..100c8a7f71c7 --- /dev/null +++ b/lib/libc/regex/regex.3 @@ -0,0 +1,502 @@ +.TH REGEX 3 "17 May 1993" +.BY "Henry Spencer" +.de ZR +.\" one other place knows this name: the SEE ALSO section +.IR regex (7) \\$1 +.. +.SH NAME +regcomp, regexec, regerror, regfree \- regular-expression library +.SH SYNOPSIS +.ft B +.\".na +#include <sys/types.h> +.br +#include <regex.h> +.HP 10 +int regcomp(regex_t\ *preg, const\ char\ *pattern, int\ cflags); +.HP +int\ regexec(const\ regex_t\ *preg, const\ char\ *string, +size_t\ nmatch, regmatch_t\ pmatch[], int\ eflags); +.HP +size_t\ regerror(int\ errcode, const\ regex_t\ *preg, +char\ *errbuf, size_t\ errbuf_size); +.HP +void\ regfree(regex_t\ *preg); +.\".ad +.ft +.SH DESCRIPTION +These routines implement POSIX 1003.2 regular expressions (``RE''s); +see +.ZR . +.I Regcomp +compiles an RE written as a string into an internal form, +.I regexec +matches that internal form against a string and reports results, +.I regerror +transforms error codes from either into human-readable messages, +and +.I regfree +frees any dynamically-allocated storage used by the internal form +of an RE. +.PP +The header +.I <regex.h> +declares two structure types, +.I regex_t +and +.IR regmatch_t , +the former for compiled internal forms and the latter for match reporting. +It also declares the four functions, +a type +.IR regoff_t , +and a number of constants with names starting with ``REG_''. +.PP +.I Regcomp +compiles the regular expression contained in the +.I pattern +string, +subject to the flags in +.IR cflags , +and places the results in the +.I regex_t +structure pointed to by +.IR preg . +.I Cflags +is the bitwise OR of zero or more of the following flags: +.IP REG_EXTENDED \w'REG_EXTENDED'u+2n +Compile modern (``extended'') REs, +rather than the obsolete (``basic'') REs that +are the default. +.IP REG_BASIC +This is a synonym for 0, +provided as a counterpart to REG_EXTENDED to improve readability. +.IP REG_NOSPEC +Compile with recognition of all special characters turned off. +All characters are thus considered ordinary, +so the ``RE'' is a literal string. +This is an extension, +compatible with but not specified by POSIX 1003.2, +and should be used with +caution in software intended to be portable to other systems. +REG_EXTENDED and REG_NOSPEC may not be used +in the same call to +.IR regcomp . +.IP REG_ICASE +Compile for matching that ignores upper/lower case distinctions. +See +.ZR . +.IP REG_NOSUB +Compile for matching that need only report success or failure, +not what was matched. +.IP REG_NEWLINE +Compile for newline-sensitive matching. +By default, newline is a completely ordinary character with no special +meaning in either REs or strings. +With this flag, +`[^' bracket expressions and `.' never match newline, +a `^' anchor matches the null string after any newline in the string +in addition to its normal function, +and the `$' anchor matches the null string before any newline in the +string in addition to its normal function. +.IP REG_PEND +The regular expression ends, +not at the first NUL, +but just before the character pointed to by the +.I re_endp +member of the structure pointed to by +.IR preg . +The +.I re_endp +member is of type +.IR const\ char\ * . +This flag permits inclusion of NULs in the RE; +they are considered ordinary characters. +This is an extension, +compatible with but not specified by POSIX 1003.2, +and should be used with +caution in software intended to be portable to other systems. +.PP +When successful, +.I regcomp +returns 0 and fills in the structure pointed to by +.IR preg . +One member of that structure +(other than +.IR re_endp ) +is publicized: +.IR re_nsub , +of type +.IR size_t , +contains the number of parenthesized subexpressions within the RE +(except that the value of this member is undefined if the +REG_NOSUB flag was used). +If +.I regcomp +fails, it returns a non-zero error code; +see DIAGNOSTICS. +.PP +.I Regexec +matches the compiled RE pointed to by +.I preg +against the +.IR string , +subject to the flags in +.IR eflags , +and reports results using +.IR nmatch , +.IR pmatch , +and the returned value. +The RE must have been compiled by a previous invocation of +.IR regcomp . +The compiled form is not altered during execution of +.IR regexec , +so a single compiled RE can be used simultaneously by multiple threads. +.PP +By default, +the NUL-terminated string pointed to by +.I string +is considered to be the text of an entire line, minus any terminating +newline. +The +.I eflags +argument is the bitwise OR of zero or more of the following flags: +.IP REG_NOTBOL \w'REG_STARTEND'u+2n +The first character of +the string +is not the beginning of a line, so the `^' anchor should not match before it. +This does not affect the behavior of newlines under REG_NEWLINE. +.IP REG_NOTEOL +The NUL terminating +the string +does not end a line, so the `$' anchor should not match before it. +This does not affect the behavior of newlines under REG_NEWLINE. +.IP REG_STARTEND +The string is considered to start at +\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_so\fR +and to have a terminating NUL located at +\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_eo\fR +(there need not actually be a NUL at that location), +regardless of the value of +.IR nmatch . +See below for the definition of +.IR pmatch +and +.IR nmatch . +This is an extension, +compatible with but not specified by POSIX 1003.2, +and should be used with +caution in software intended to be portable to other systems. +Note that a non-zero \fIrm_so\fR does not imply REG_NOTBOL; +REG_STARTEND affects only the location of the string, +not how it is matched. +.PP +See +.ZR +for a discussion of what is matched in situations where an RE or a +portion thereof could match any of several substrings of +.IR string . +.PP +Normally, +.I regexec +returns 0 for success and the non-zero code REG_NOMATCH for failure. +Other non-zero error codes may be returned in exceptional situations; +see DIAGNOSTICS. +.PP +If REG_NOSUB was specified in the compilation of the RE, +or if +.I nmatch +is 0, +.I regexec +ignores the +.I pmatch +argument (but see below for the case where REG_STARTEND is specified). +Otherwise, +.I pmatch +points to an array of +.I nmatch +structures of type +.IR regmatch_t . +Such a structure has at least the members +.I rm_so +and +.IR rm_eo , +both of type +.I regoff_t +(a signed arithmetic type at least as large as an +.I off_t +and a +.IR ssize_t ), +containing respectively the offset of the first character of a substring +and the offset of the first character after the end of the substring. +Offsets are measured from the beginning of the +.I string +argument given to +.IR regexec . +An empty substring is denoted by equal offsets, +both indicating the character following the empty substring. +.PP +The 0th member of the +.I pmatch +array is filled in to indicate what substring of +.I string +was matched by the entire RE. +Remaining members report what substring was matched by parenthesized +subexpressions within the RE; +member +.I i +reports subexpression +.IR i , +with subexpressions counted (starting at 1) by the order of their opening +parentheses in the RE, left to right. +Unused entries in the array\(emcorresponding either to subexpressions that +did not participate in the match at all, or to subexpressions that do not +exist in the RE (that is, \fIi\fR\ > \fIpreg\fR\->\fIre_nsub\fR)\(emhave both +.I rm_so +and +.I rm_eo +set to \-1. +If a subexpression participated in the match several times, +the reported substring is the last one it matched. +(Note, as an example in particular, that when the RE `(b*)+' matches `bbb', +the parenthesized subexpression matches each of the three `b's and then +an infinite number of empty strings following the last `b', +so the reported substring is one of the empties.) +.PP +If REG_STARTEND is specified, +.I pmatch +must point to at least one +.I regmatch_t +(even if +.I nmatch +is 0 or REG_NOSUB was specified), +to hold the input offsets for REG_STARTEND. +Use for output is still entirely controlled by +.IR nmatch ; +if +.I nmatch +is 0 or REG_NOSUB was specified, +the value of +.IR pmatch [0] +will not be changed by a successful +.IR regexec . +.PP +.I Regerror +maps a non-zero +.I errcode +from either +.I regcomp +or +.I regexec +to a human-readable, printable message. +If +.I preg +is non-NULL, +the error code should have arisen from use of +the +.I regex_t +pointed to by +.IR preg , +and if the error code came from +.IR regcomp , +it should have been the result from the most recent +.I regcomp +using that +.IR regex_t . +.RI ( Regerror +may be able to supply a more detailed message using information +from the +.IR regex_t .) +.I Regerror +places the NUL-terminated message into the buffer pointed to by +.IR errbuf , +limiting the length (including the NUL) to at most +.I errbuf_size +bytes. +If the whole message won't fit, +as much of it as will fit before the terminating NUL is supplied. +In any case, +the returned value is the size of buffer needed to hold the whole +message (including terminating NUL). +If +.I errbuf_size +is 0, +.I errbuf +is ignored but the return value is still correct. +.PP +If the +.I errcode +given to +.I regerror +is first ORed with REG_ITOA, +the ``message'' that results is the printable name of the error code, +e.g. ``REG_NOMATCH'', +rather than an explanation thereof. +If +.I errcode +is REG_ATOI, +then +.I preg +shall be non-NULL and the +.I re_endp +member of the structure it points to +must point to the printable name of an error code; +in this case, the result in +.I errbuf +is the decimal digits of +the numeric value of the error code +(0 if the name is not recognized). +REG_ITOA and REG_ATOI are intended primarily as debugging facilities; +they are extensions, +compatible with but not specified by POSIX 1003.2, +and should be used with +caution in software intended to be portable to other systems. +Be warned also that they are considered experimental and changes are possible. +.PP +.I Regfree +frees any dynamically-allocated storage associated with the compiled RE +pointed to by +.IR preg . +The remaining +.I regex_t +is no longer a valid compiled RE +and the effect of supplying it to +.I regexec +or +.I regerror +is undefined. +.PP +None of these functions references global variables except for tables +of constants; +all are safe for use from multiple threads if the arguments are safe. +.SH IMPLEMENTATION CHOICES +There are a number of decisions that 1003.2 leaves up to the implementor, +either by explicitly saying ``undefined'' or by virtue of them being +forbidden by the RE grammar. +This implementation treats them as follows. +.PP +See +.ZR +for a discussion of the definition of case-independent matching. +.PP +There is no particular limit on the length of REs, +except insofar as memory is limited. +Memory usage is approximately linear in RE size, and largely insensitive +to RE complexity, except for bounded repetitions. +See BUGS for one short RE using them +that will run almost any system out of memory. +.PP +A backslashed character other than one specifically given a magic meaning +by 1003.2 (such magic meanings occur only in obsolete [``basic''] REs) +is taken as an ordinary character. +.PP +Any unmatched [ is a REG_EBRACK error. +.PP +Equivalence classes cannot begin or end bracket-expression ranges. +The endpoint of one range cannot begin another. +.PP +RE_DUP_MAX, the limit on repetition counts in bounded repetitions, is 255. +.PP +A repetition operator (?, *, +, or bounds) cannot follow another +repetition operator. +A repetition operator cannot begin an expression or subexpression +or follow `^' or `|'. +.PP +`|' cannot appear first or last in a (sub)expression or after another `|', +i.e. an operand of `|' cannot be an empty subexpression. +An empty parenthesized subexpression, `()', is legal and matches an +empty (sub)string. +An empty string is not a legal RE. +.PP +A `{' followed by a digit is considered the beginning of bounds for a +bounded repetition, which must then follow the syntax for bounds. +A `{' \fInot\fR followed by a digit is considered an ordinary character. +.PP +`^' and `$' beginning and ending subexpressions in obsolete (``basic'') +REs are anchors, not ordinary characters. +.SH SEE ALSO +grep(1), regex(7) +.PP +POSIX 1003.2, sections 2.8 (Regular Expression Notation) +and +B.5 (C Binding for Regular Expression Matching). +.SH DIAGNOSTICS +Non-zero error codes from +.I regcomp +and +.I regexec +include the following: +.PP +.nf +.ta \w'REG_ECOLLATE'u+3n +REG_NOMATCH regexec() failed to match +REG_BADPAT invalid regular expression +REG_ECOLLATE invalid collating element +REG_ECTYPE invalid character class +REG_EESCAPE \e applied to unescapable character +REG_ESUBREG invalid backreference number +REG_EBRACK brackets [ ] not balanced +REG_EPAREN parentheses ( ) not balanced +REG_EBRACE braces { } not balanced +REG_BADBR invalid repetition count(s) in { } +REG_ERANGE invalid character range in [ ] +REG_ESPACE ran out of memory +REG_BADRPT ?, *, or + operand invalid +REG_EMPTY empty (sub)expression +REG_ASSERT ``can't happen''\(emyou found a bug +REG_INVARG invalid argument, e.g. negative-length string +.fi +.SH HISTORY +Written by Henry Spencer at University of Toronto, +henry@zoo.toronto.edu. +.SH BUGS +This is an alpha release with known defects. +Please report problems. +.PP +There is one known functionality bug. +The implementation of internationalization is incomplete: +the locale is always assumed to be the default one of 1003.2, +and only the collating elements etc. of that locale are available. +.PP +The back-reference code is subtle and doubts linger about its correctness +in complex cases. +.PP +.I Regexec +performance is poor. +This will improve with later releases. +.I Nmatch +exceeding 0 is expensive; +.I nmatch +exceeding 1 is worse. +.I Regexec +is largely insensitive to RE complexity \fIexcept\fR that back +references are massively expensive. +RE length does matter; in particular, there is a strong speed bonus +for keeping RE length under about 30 characters, +with most special characters counting roughly double. +.PP +.I Regcomp +implements bounded repetitions by macro expansion, +which is costly in time and space if counts are large +or bounded repetitions are nested. +An RE like, say, +`((((a{1,100}){1,100}){1,100}){1,100}){1,100}' +will (eventually) run almost any existing machine out of swap space. +.PP +There are suspected problems with response to obscure error conditions. +Notably, +certain kinds of internal overflow, +produced only by truly enormous REs or by multiply nested bounded repetitions, +are probably not handled well. +.PP +Due to a mistake in 1003.2, things like `a)b' are legal REs because `)' is +a special character only in the presence of a previous unmatched `('. +This can't be fixed until the spec is fixed. +.PP +The standard's definition of back references is vague. +For example, does +`a\e(\e(b\e)*\e2\e)*d' match `abbbd'? +Until the standard is clarified, +behavior in such cases should not be relied on. +.PP +The implementation of word-boundary matching is a bit of a kludge, +and bugs may lurk in combinations of word-boundary matching and anchoring. diff --git a/lib/libc/regex/regex.7 b/lib/libc/regex/regex.7 new file mode 100644 index 000000000000..ca9092ff217f --- /dev/null +++ b/lib/libc/regex/regex.7 @@ -0,0 +1,231 @@ +.TH REGEX 7 "6 Nov 1993" +.BY "Henry Spencer" +.SH NAME +regex \- POSIX 1003.2 regular expressions +.SH DESCRIPTION +Regular expressions (``RE''s), +as defined in POSIX 1003.2, come in two forms: +modern REs (roughly those of +.IR egrep ; +1003.2 calls these ``extended'' REs) +and obsolete REs (roughly those of +.IR ed ; +1003.2 ``basic'' REs). +Obsolete REs mostly exist for backward compatibility in some old programs; +they will be discussed at the end. +1003.2 leaves some aspects of RE syntax and semantics open; +`\(dg' marks decisions on these aspects that +may not be fully portable to other 1003.2 implementations. +.PP +A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR, +separated by `|'. +It matches anything that matches one of the branches. +.PP +A branch is one\(dg or more \fIpieces\fR, concatenated. +It matches a match for the first, followed by a match for the second, etc. +.PP +A piece is an \fIatom\fR possibly followed +by a single\(dg `*', `+', `?', or \fIbound\fR. +An atom followed by `*' matches a sequence of 0 or more matches of the atom. +An atom followed by `+' matches a sequence of 1 or more matches of the atom. +An atom followed by `?' matches a sequence of 0 or 1 matches of the atom. +.PP +A \fIbound\fR is `{' followed by an unsigned decimal integer, +possibly followed by `,' +possibly followed by another unsigned decimal integer, +always followed by `}'. +The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive, +and if there are two of them, the first may not exceed the second. +An atom followed by a bound containing one integer \fIi\fR +and no comma matches +a sequence of exactly \fIi\fR matches of the atom. +An atom followed by a bound +containing one integer \fIi\fR and a comma matches +a sequence of \fIi\fR or more matches of the atom. +An atom followed by a bound +containing two integers \fIi\fR and \fIj\fR matches +a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom. +.PP +An atom is a regular expression enclosed in `()' (matching a match for the +regular expression), +an empty set of `()' (matching the null string)\(dg, +a \fIbracket expression\fR (see below), `.' +(matching any single character), `^' (matching the null string at the +beginning of a line), `$' (matching the null string at the +end of a line), a `\e' followed by one of the characters +`^.[$()|*+?{\e' +(matching that character taken as an ordinary character), +a `\e' followed by any other character\(dg +(matching that character taken as an ordinary character, +as if the `\e' had not been present\(dg), +or a single character with no other significance (matching that character). +A `{' followed by a character other than a digit is an ordinary +character, not the beginning of a bound\(dg. +It is illegal to end an RE with `\e'. +.PP +A \fIbracket expression\fR is a list of characters enclosed in `[]'. +It normally matches any single character from the list (but see below). +If the list begins with `^', +it matches any single character +(but see below) \fInot\fR from the rest of the list. +If two characters in the list are separated by `\-', this is shorthand +for the full \fIrange\fR of characters between those two (inclusive) in the +collating sequence, +e.g. `[0-9]' in ASCII matches any decimal digit. +It is illegal\(dg for two ranges to share an +endpoint, e.g. `a-c-e'. +Ranges are very collating-sequence-dependent, +and portable programs should avoid relying on them. +.PP +To include a literal `]' in the list, make it the first character +(following a possible `^'). +To include a literal `\-', make it the first or last character, +or the second endpoint of a range. +To use a literal `\-' as the first endpoint of a range, +enclose it in `[.' and `.]' to make it a collating element (see below). +With the exception of these and some combinations using `[' (see next +paragraphs), all other special characters, including `\e', lose their +special significance within a bracket expression. +.PP +Within a bracket expression, a collating element (a character, +a multi-character sequence that collates as if it were a single character, +or a collating-sequence name for either) +enclosed in `[.' and `.]' stands for the +sequence of characters of that collating element. +The sequence is a single element of the bracket expression's list. +A bracket expression containing a multi-character collating element +can thus match more than one character, +e.g. if the collating sequence includes a `ch' collating element, +then the RE `[[.ch.]]*c' matches the first five characters +of `chchcc'. +.PP +Within a bracket expression, a collating element enclosed in `[=' and +`=]' is an equivalence class, standing for the sequences of characters +of all collating elements equivalent to that one, including itself. +(If there are no other equivalent collating elements, +the treatment is as if the enclosing delimiters were `[.' and `.]'.) +For example, if o and \o'o^' are the members of an equivalence class, +then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous. +An equivalence class may not\(dg be an endpoint +of a range. +.PP +Within a bracket expression, the name of a \fIcharacter class\fR enclosed +in `[:' and `:]' stands for the list of all characters belonging to that +class. +Standard character class names are: +.PP +.RS +.nf +.ta 3c 6c 9c +alnum digit punct +alpha graph space +blank lower upper +cntrl print xdigit +.fi +.RE +.PP +These stand for the character classes defined in +.IR ctype (3). +A locale may provide others. +A character class may not be used as an endpoint of a range. +.PP +There are two special cases\(dg of bracket expressions: +the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at +the beginning and end of a word respectively. +A word is defined as a sequence of +.I alnum +characters (as defined by +.IR ctype (3)) +which is neither preceded nor followed by +.I alnum +characters. +This is an extension, +compatible with but not specified by POSIX 1003.2, +and should be used with +caution in software intended to be portable to other systems. +.PP +In the event that an RE could match more than one substring of a given +string, +the RE matches the one starting earliest in the string. +If the RE could match more than one substring starting at that point, +it matches the longest. +Subexpressions also match the longest possible substrings, subject to +the constraint that the whole match be as long as possible, +with subexpressions starting earlier in the RE taking priority over +ones starting later. +Note that higher-level subexpressions thus take priority over +their lower-level component subexpressions. +.PP +Match lengths are measured in characters, not collating elements. +A null string is considered longer than no match at all. +For example, +`bb*' matches the three middle characters of `abbbc', +`(wee|week)(knights|nights)' matches all ten characters of `weeknights', +when `(.*).*' is matched against `abc' the parenthesized subexpression +matches all three characters, and +when `(a*)*' is matched against `bc' both the whole RE and the parenthesized +subexpression match the null string. +.PP +If case-independent matching is specified, +the effect is much as if all case distinctions had vanished from the +alphabet. +When an alphabetic that exists in multiple cases appears as an +ordinary character outside a bracket expression, it is effectively +transformed into a bracket expression containing both cases, +e.g. `x' becomes `[xX]'. +When it appears inside a bracket expression, all case counterparts +of it are added to the bracket expression, so that (e.g.) `[x]' +becomes `[xX]' and `[^x]' becomes `[^xX]'. +.PP +No particular limit is imposed on the length of REs\(dg. +Programs intended to be portable should not employ REs longer +than 256 bytes, +as an implementation can refuse to accept such REs and remain +POSIX-compliant. +.PP +Obsolete (``basic'') regular expressions differ in several respects. +`|', `+', and `?' are ordinary characters and there is no equivalent +for their functionality. +The delimiters for bounds are `\e{' and `\e}', +with `{' and `}' by themselves ordinary characters. +The parentheses for nested subexpressions are `\e(' and `\e)', +with `(' and `)' by themselves ordinary characters. +`^' is an ordinary character except at the beginning of the +RE or\(dg the beginning of a parenthesized subexpression, +`$' is an ordinary character except at the end of the +RE or\(dg the end of a parenthesized subexpression, +and `*' is an ordinary character if it appears at the beginning of the +RE or the beginning of a parenthesized subexpression +(after a possible leading `^'). +Finally, there is one new type of atom, a \fIback reference\fR: +`\e' followed by a non-zero decimal digit \fId\fR +matches the same sequence of characters +matched by the \fId\fRth parenthesized subexpression +(numbering subexpressions by the positions of their opening parentheses, +left to right), +so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'. +.SH SEE ALSO +regex(3) +.PP +POSIX 1003.2, section 2.8 (Regular Expression Notation). +.SH BUGS +Having two kinds of REs is a botch. +.PP +The current 1003.2 spec says that `)' is an ordinary character in +the absence of an unmatched `('; +this was an unintentional result of a wording error, +and change is likely. +Avoid relying on it. +.PP +Back references are a dreadful botch, +posing major problems for efficient implementations. +They are also somewhat vaguely defined +(does +`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?). +Avoid using them. +.PP +1003.2's specification of case-independent matching is vague. +The ``one case implies all cases'' definition given above +is current consensus among implementors as to the right interpretation. +.PP +The syntax for word boundaries is incredibly ugly. diff --git a/lib/libc/regex/regex.h b/lib/libc/regex/regex.h new file mode 100644 index 000000000000..81cf1700f7e4 --- /dev/null +++ b/lib/libc/regex/regex.h @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)regex.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _REGEX_H_ +#define _REGEX_H_ + +#include <sys/cdefs.h> + +#include <machine/endian.h> + +/* types */ +typedef off_t regoff_t; + +typedef struct { + int re_magic; + size_t re_nsub; /* number of parenthesized subexpressions */ + const char *re_endp; /* end pointer for REG_PEND */ + struct re_guts *re_g; /* none of your business :-) */ +} regex_t; + +typedef struct { + regoff_t rm_so; /* start of match */ + regoff_t rm_eo; /* end of match */ +} regmatch_t; + +/* regcomp() flags */ +#define REG_BASIC 0000 +#define REG_EXTENDED 0001 +#define REG_ICASE 0002 +#define REG_NOSUB 0004 +#define REG_NEWLINE 0010 +#define REG_NOSPEC 0020 +#define REG_PEND 0040 +#define REG_DUMP 0200 + +/* regerror() flags */ +#define REG_NOMATCH 1 +#define REG_BADPAT 2 +#define REG_ECOLLATE 3 +#define REG_ECTYPE 4 +#define REG_EESCAPE 5 +#define REG_ESUBREG 6 +#define REG_EBRACK 7 +#define REG_EPAREN 8 +#define REG_EBRACE 9 +#define REG_BADBR 10 +#define REG_ERANGE 11 +#define REG_ESPACE 12 +#define REG_BADRPT 13 +#define REG_EMPTY 14 +#define REG_ASSERT 15 +#define REG_INVARG 16 +#define REG_ATOI 255 /* convert name to number (!) */ +#define REG_ITOA 0400 /* convert number to name (!) */ + +/* regexec() flags */ +#define REG_NOTBOL 00001 +#define REG_NOTEOL 00002 +#define REG_STARTEND 00004 +#define REG_TRACE 00400 /* tracing of execution */ +#define REG_LARGE 01000 /* force large representation */ +#define REG_BACKR 02000 /* force use of backref code */ + +__BEGIN_DECLS +int regcomp __P((regex_t *, const char *, int)); +size_t regerror __P((int, const regex_t *, char *, size_t)); +int regexec __P((const regex_t *, + const char *, size_t, regmatch_t [], int)); +void regfree __P((regex_t *)); +__END_DECLS + +#endif /* !_REGEX_H_ */ diff --git a/lib/libc/regex/regex2.h b/lib/libc/regex/regex2.h new file mode 100644 index 000000000000..2bbb04529438 --- /dev/null +++ b/lib/libc/regex/regex2.h @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)regex2.h 8.1 (Berkeley) 6/4/93 + */ + +/* + * First, the stuff that ends up in the outside-world include file + = typedef off_t regoff_t; + = typedef struct { + = int re_magic; + = size_t re_nsub; // number of parenthesized subexpressions + = const char *re_endp; // end pointer for REG_PEND + = struct re_guts *re_g; // none of your business :-) + = } regex_t; + = typedef struct { + = regoff_t rm_so; // start of match + = regoff_t rm_eo; // end of match + = } regmatch_t; + */ +/* + * internals of regex_t + */ +#define MAGIC1 ((('r'^0200)<<8) | 'e') + +/* + * The internal representation is a *strip*, a sequence of + * operators ending with an endmarker. (Some terminology etc. is a + * historical relic of earlier versions which used multiple strips.) + * Certain oddities in the representation are there to permit running + * the machinery backwards; in particular, any deviation from sequential + * flow must be marked at both its source and its destination. Some + * fine points: + * + * - OPLUS_ and O_PLUS are *inside* the loop they create. + * - OQUEST_ and O_QUEST are *outside* the bypass they create. + * - OCH_ and O_CH are *outside* the multi-way branch they create, while + * OOR1 and OOR2 are respectively the end and the beginning of one of + * the branches. Note that there is an implicit OOR2 following OCH_ + * and an implicit OOR1 preceding O_CH. + * + * In state representations, an operator's bit is on to signify a state + * immediately *preceding* "execution" of that operator. + */ +typedef unsigned long sop; /* strip operator */ +typedef long sopno; +#define OPRMASK 0xf8000000 +#define OPDMASK 0x07ffffff +#define OPSHIFT ((unsigned)27) +#define OP(n) ((n)&OPRMASK) +#define OPND(n) ((n)&OPDMASK) +#define SOP(op, opnd) ((op)|(opnd)) +/* operators meaning operand */ +/* (back, fwd are offsets) */ +#define OEND (1<<OPSHIFT) /* endmarker - */ +#define OCHAR (2<<OPSHIFT) /* character unsigned char */ +#define OBOL (3<<OPSHIFT) /* left anchor - */ +#define OEOL (4<<OPSHIFT) /* right anchor - */ +#define OANY (5<<OPSHIFT) /* . - */ +#define OANYOF (6<<OPSHIFT) /* [...] set number */ +#define OBACK_ (7<<OPSHIFT) /* begin \d paren number */ +#define O_BACK (8<<OPSHIFT) /* end \d paren number */ +#define OPLUS_ (9<<OPSHIFT) /* + prefix fwd to suffix */ +#define O_PLUS (10<<OPSHIFT) /* + suffix back to prefix */ +#define OQUEST_ (11<<OPSHIFT) /* ? prefix fwd to suffix */ +#define O_QUEST (12<<OPSHIFT) /* ? suffix back to prefix */ +#define OLPAREN (13<<OPSHIFT) /* ( fwd to ) */ +#define ORPAREN (14<<OPSHIFT) /* ) back to ( */ +#define OCH_ (15<<OPSHIFT) /* begin choice fwd to OOR2 */ +#define OOR1 (16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */ +#define OOR2 (17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */ +#define O_CH (18<<OPSHIFT) /* end choice back to OOR1 */ +#define OBOW (19<<OPSHIFT) /* begin word - */ +#define OEOW (20<<OPSHIFT) /* end word - */ + +/* + * Structure for [] character-set representation. Character sets are + * done as bit vectors, grouped 8 to a byte vector for compactness. + * The individual set therefore has both a pointer to the byte vector + * and a mask to pick out the relevant bit of each byte. A hash code + * simplifies testing whether two sets could be identical. + * + * This will get trickier for multicharacter collating elements. As + * preliminary hooks for dealing with such things, we also carry along + * a string of multi-character elements, and decide the size of the + * vectors at run time. + */ +typedef struct { + unsigned char *ptr; /* -> uchar [csetsize] */ + unsigned char mask; /* bit within array */ + unsigned char hash; /* hash code */ + size_t smultis; + char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */ +} cset; +/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */ +#define CHadd(cs, c) ((cs)->ptr[(unsigned char)(c)] |= (cs)->mask, (cs)->hash += (c)) +#define CHsub(cs, c) ((cs)->ptr[(unsigned char)(c)] &= ~(cs)->mask, (cs)->hash -= (c)) +#define CHIN(cs, c) ((cs)->ptr[(unsigned char)(c)] & (cs)->mask) +#define MCadd(cs, cp) mcadd(cs, cp) /* regcomp() internal fns */ +#define MCsub(cs, cp) mcsub(cs, cp) +#define MCin(cs, cp) mcin(cs, cp) + +/* stuff for character categories */ +typedef unsigned char cat_t; + +/* + * main compiled-expression structure + */ +struct re_guts { + int magic; +# define MAGIC2 ((('R'^0200)<<8)|'E') + sop *strip; /* malloced area for strip */ + int csetsize; /* number of bits in a cset vector */ + int ncsets; /* number of csets in use */ + cset *sets; /* -> cset [ncsets] */ + unsigned char *setbits; /* -> uchar[csetsize][ncsets/CHAR_BIT] */ + int cflags; /* copy of regcomp() cflags argument */ + sopno nstates; /* = number of sops */ + sopno firststate; /* the initial OEND (normally 0) */ + sopno laststate; /* the final OEND */ + int iflags; /* internal flags */ +# define USEBOL 01 /* used ^ */ +# define USEEOL 02 /* used $ */ +# define BAD 04 /* something wrong */ + int nbol; /* number of ^ used */ + int neol; /* number of $ used */ + int ncategories; /* how many character categories */ + cat_t *categories; /* ->catspace[-CHAR_MIN] */ + char *must; /* match must contain this string */ + int mlen; /* length of must */ + size_t nsub; /* copy of re_nsub */ + int backrefs; /* does it use back references? */ + sopno nplus; /* how deep does it nest +s? */ + /* catspace must be last */ + cat_t catspace[1]; /* actually [NC] */ +}; + +/* misc utilities */ +#define OUT (CHAR_MAX+1) /* a non-character value */ +#define ISWORD(c) (isalnum(c) || (c) == '_') diff --git a/lib/libc/regex/regexec.c b/lib/libc/regex/regexec.c new file mode 100644 index 000000000000..c1b9075df4a3 --- /dev/null +++ b/lib/libc/regex/regexec.c @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)regexec.c 8.1 (Berkeley) 6/4/93 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regexec.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* + * the outer shell of regexec() + * + * This file includes engine.c *twice*, after muchos fiddling with the + * macros that code uses. This lets the same code operate on two different + * representations for state sets. + */ +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <ctype.h> +#include <regex.h> + +#include "utils.h" +#include "regex2.h" + +static int nope = 0; /* for use in asserts; shuts lint up */ + +/* macros for manipulating states, small version */ +#define states long +#define states1 states /* for later use in regexec() decision */ +#define CLEAR(v) ((v) = 0) +#define SET0(v, n) ((v) &= ~(1 << (n))) +#define SET1(v, n) ((v) |= 1 << (n)) +#define ISSET(v, n) ((v) & (1 << (n))) +#define ASSIGN(d, s) ((d) = (s)) +#define EQ(a, b) ((a) == (b)) +#define STATEVARS int dummy /* dummy version */ +#define STATESETUP(m, n) /* nothing */ +#define STATETEARDOWN(m) /* nothing */ +#define SETUP(v) ((v) = 0) +#define onestate int +#define INIT(o, n) ((o) = (unsigned)1 << (n)) +#define INC(o) ((o) <<= 1) +#define ISSTATEIN(v, o) ((v) & (o)) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n)) +#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n)) +#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n))) +/* function names */ +#define SNAMES /* engine.c looks after details */ + +#include "engine.c" + +/* now undo things */ +#undef states +#undef CLEAR +#undef SET0 +#undef SET1 +#undef ISSET +#undef ASSIGN +#undef EQ +#undef STATEVARS +#undef STATESETUP +#undef STATETEARDOWN +#undef SETUP +#undef onestate +#undef INIT +#undef INC +#undef ISSTATEIN +#undef FWD +#undef BACK +#undef ISSETBACK +#undef SNAMES + +/* macros for manipulating states, large version */ +#define states char * +#define CLEAR(v) memset(v, 0, m->g->nstates) +#define SET0(v, n) ((v)[n] = 0) +#define SET1(v, n) ((v)[n] = 1) +#define ISSET(v, n) ((v)[n]) +#define ASSIGN(d, s) memcpy(d, s, m->g->nstates) +#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) +#define STATEVARS int vn; char *space +#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ + if ((m)->space == NULL) return(REG_ESPACE); \ + (m)->vn = 0; } +#define STATETEARDOWN(m) { free((m)->space); } +#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) +#define onestate int +#define INIT(o, n) ((o) = (n)) +#define INC(o) ((o)++) +#define ISSTATEIN(v, o) ((v)[o]) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) +#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) +#define ISSETBACK(v, n) ((v)[here - (n)]) +/* function names */ +#define LNAMES /* flag */ + +#include "engine.c" + +/* + - regexec - interface for matching + = extern int regexec(const regex_t *preg, const char *string, size_t nmatch, \ + = regmatch_t pmatch[], int eflags); + = #define REG_NOTBOL 00001 + = #define REG_NOTEOL 00002 + = #define REG_STARTEND 00004 + = #define REG_TRACE 00400 // tracing of execution + = #define REG_LARGE 01000 // force large representation + = #define REG_BACKR 02000 // force use of backref code + * + * We put this here so we can exploit knowledge of the state representation + * when choosing which matcher to call. Also, by this point the matchers + * have been prototyped. + */ +int /* 0 success, REG_NOMATCH failure */ +regexec(preg, string, nmatch, pmatch, eflags) +const regex_t *preg; +const char *string; +size_t nmatch; +regmatch_t pmatch[]; +int eflags; +{ + register struct re_guts *g = preg->re_g; +#ifdef REDEBUG +# define GOODFLAGS(f) (f) +#else +# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) +#endif + + if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) + return(REG_BADPAT); + assert(!(g->iflags&BAD)); + if (g->iflags&BAD) /* backstop for no-debug case */ + return(REG_BADPAT); + if (eflags != GOODFLAGS(eflags)) + return(REG_INVARG); + + if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE)) + return(smatcher(g, (char *)string, nmatch, pmatch, eflags)); + else + return(lmatcher(g, (char *)string, nmatch, pmatch, eflags)); +} diff --git a/lib/libc/db/PORT/include/ndbm.h b/lib/libc/regex/regfree.c index a545bca1326e..4bd618d9b473 100644 --- a/lib/libc/db/PORT/include/ndbm.h +++ b/lib/libc/regex/regfree.c @@ -1,9 +1,10 @@ /*- - * Copyright (c) 1990, 1993 + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by - * Margo Seltzer. + * Henry Spencer of the University of Toronto. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,45 +34,47 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)ndbm.h 8.1 (Berkeley) 6/2/93 + * @(#)regfree.c 8.1 (Berkeley) 6/4/93 */ -#ifndef _NDBM_H_ -#define _NDBM_H_ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)regfree.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ -#include <db.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <regex.h> -/* Map dbm interface onto db(3). */ -#define DBM_RDONLY O_RDONLY - -/* Flags to dbm_store(). */ -#define DBM_INSERT 0 -#define DBM_REPLACE 1 +#include "utils.h" +#include "regex2.h" /* - * The db(3) support for ndbm(3) always appends this suffix to the - * file name to avoid overwriting the user's original database. + - regfree - free everything + = extern void regfree(regex_t *preg); */ -#define DBM_SUFFIX ".db" - -typedef struct { - char *dptr; - int dsize; -} datum; +void +regfree(preg) +regex_t *preg; +{ + register struct re_guts *g; -typedef DB DBM; -#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE + if (preg->re_magic != MAGIC1) /* oops */ + return; /* nice to complain, but hard */ -__BEGIN_DECLS -void dbm_close __P((DBM *)); -int dbm_delete __P((DBM *, datum)); -datum dbm_fetch __P((DBM *, datum)); -datum dbm_firstkey __P((DBM *)); -long dbm_forder __P((DBM *, datum)); -datum dbm_nextkey __P((DBM *)); -DBM *dbm_open __P((const char *, int, int)); -int dbm_store __P((DBM *, datum, datum, int)); -int dbm_dirfno __P((DBM *)); -__END_DECLS + g = preg->re_g; + if (g == NULL || g->magic != MAGIC2) /* oops again */ + return; + preg->re_magic = 0; /* mark it invalid */ + g->magic = 0; /* mark it invalid */ -#endif /* !_NDBM_H_ */ + if (g->strip != NULL) + free((char *)g->strip); + if (g->sets != NULL) + free((char *)g->sets); + if (g->setbits != NULL) + free((char *)g->setbits); + if (g->must != NULL) + free(g->must); + free((char *)g); +} diff --git a/lib/libc/regex/tests b/lib/libc/regex/tests new file mode 100644 index 000000000000..5412bfcbd69f --- /dev/null +++ b/lib/libc/regex/tests @@ -0,0 +1,448 @@ +# regular expression test set +# Lines are at least three fields, separated by one or more tabs. "" stands +# for an empty field. First field is an RE. Second field is flags. If +# C flag given, regcomp() is expected to fail, and the third field is the +# error name (minus the leading REG_). +# +# Otherwise it is expected to succeed, and the third field is the string to +# try matching it against. If there is no fourth field, the match is +# expected to fail. If there is a fourth field, it is the substring that +# the RE is expected to match. If there is a fifth field, it is a comma- +# separated list of what the subexpressions should match, with - indicating +# no match for that one. In both the fourth and fifth fields, a (sub)field +# starting with @ indicates that the (sub)expression is expected to match +# a null string followed by the stuff after the @; this provides a way to +# test where null strings match. The character `N' in REs and strings +# is newline, `S' is space, `T' is tab, `Z' is NUL. +# +# The full list of flags: +# - placeholder, does nothing +# b RE is a BRE, not an ERE +# & try it as both an ERE and a BRE +# C regcomp() error expected, third field is error name +# i REG_ICASE +# m ("mundane") REG_NOSPEC +# s REG_NOSUB (not really testable) +# n REG_NEWLINE +# ^ REG_NOTBOL +# $ REG_NOTEOL +# # REG_STARTEND (see below) +# p REG_PEND +# +# For REG_STARTEND, the start/end offsets are those of the substring +# enclosed in (). + +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a + +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) - a) a) +) - ) ) +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab + +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b + +# certain syntax errors and non-errors +| C EMPTY +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C EMPTY +() - abc @abc +\(\) b abc @abc +a||b C EMPTY +|ab C EMPTY +ab| C EMPTY +(|a)b C EMPTY +(a|)b C EMPTY +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT + +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ + +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd + +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT + +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a + +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT + +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b + +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq + +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc + +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- + +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc + +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC EMPTY + +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb + +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc + +# past problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 diff --git a/lib/libc/regex/utils.h b/lib/libc/regex/utils.h new file mode 100644 index 000000000000..2e1fce210519 --- /dev/null +++ b/lib/libc/regex/utils.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 1992 Henry Spencer. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer of the University of Toronto. + * + * 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. + * + * @(#)utils.h 8.1 (Berkeley) 6/4/93 + */ + +/* utility definitions */ +#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ +#define INFINITY (DUPMAX+1) +#define NC ((CHAR_MAX)-(CHAR_MIN)+1) + +#ifndef REDEBUG +#ifndef NDEBUG +#define NDEBUG /* no assertions please */ +#endif +#endif +#include <assert.h> diff --git a/lib/librpc/DISCLAIMER b/lib/libc/rpc/DISCLAIMER index 1a66d5f4c9cd..1a66d5f4c9cd 100644 --- a/lib/librpc/DISCLAIMER +++ b/lib/libc/rpc/DISCLAIMER diff --git a/lib/librpc/rpc/Makefile b/lib/libc/rpc/Makefile.inc index 160cbbe9ddc4..8776d9d8eee9 100644 --- a/lib/librpc/rpc/Makefile +++ b/lib/libc/rpc/Makefile.inc @@ -1,8 +1,8 @@ # @(#)Makefile 5.11 (Berkeley) 9/6/90 -LIB= rpc -CFLAGS+=-I${.CURDIR}/.. -SRCS= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ +.PATH: ${.CURDIR}/rpc ${.CURDIR}/. +CFLAGS+=-I${.CURDIR} -I${.CURDIR}/rpc +SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \ clnt_udp.c rpc_dtablesize.c get_myaddress.c getrpcent.c getrpcport.c \ pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \ @@ -11,12 +11,23 @@ SRCS= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_mem.c \ xdr_rec.c xdr_reference.c xdr_stdio.c -UNSUPPORTED= xdr_float.c +# +# XXX -- rstat.1 and rstat_svc.8 shouldn't really be here +# but there's no rstat command, don't know why, so I'm +# leaving them here in case they're needed sometime later. +# Paul. +# + +MAN1+= rpc/rstat.1 +MAN3+= rpc/bindresvport.3 rpc/getrpcent.3 rpc/getrpcport.3 rpc/rpc.3 rpc/xdr.3 +MAN5+= rpc/rpc.5 +MAN8+= rpc/rstat_svc.8 -HDRS= auth.h auth_unix.h clnt.h pmap_clnt.h \ - pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h -all: librpc.a +UNSUPPORTED+= xdr_float.c + +HDRS+= auth.h auth_unix.h clnt.h pmap_clnt.h \ + pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h beforeinstall: ${HDRS} @-if [ ! -d ${DESTDIR}/usr/include/rpc ]; then \ @@ -24,7 +35,5 @@ beforeinstall: ${HDRS} chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/rpc; \ chmod 755 ${DESTDIR}/usr/include/rpc; \ fi - cd ${.CURDIR}; install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HDRS} \ + cd ${.CURDIR}/rpc; install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HDRS} \ ${DESTDIR}/usr/include/rpc - -.include <bsd.lib.mk> diff --git a/lib/librpc/README b/lib/libc/rpc/README index ad9d70f99056..ad9d70f99056 100644 --- a/lib/librpc/README +++ b/lib/libc/rpc/README diff --git a/lib/librpc/rpc/auth.h b/lib/libc/rpc/auth.h index b6b80128e755..e7db1d01fcb4 100644 --- a/lib/librpc/rpc/auth.h +++ b/lib/libc/rpc/auth.h @@ -28,7 +28,7 @@ * * from: @(#)auth.h 1.17 88/02/08 SMI * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC - * $Id: auth.h,v 1.2 1993/09/14 17:28:41 jtc Exp $ + * $Id: auth.h,v 1.1 1993/10/27 05:40:09 paul Exp $ */ /* diff --git a/lib/librpc/rpc/auth_none.c b/lib/libc/rpc/auth_none.c index b422865e679f..9c5a664795f6 100644 --- a/lib/librpc/rpc/auth_none.c +++ b/lib/libc/rpc/auth_none.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: auth_none.c,v 1.2 1993/09/14 17:28:42 jtc Exp $"; +static char *rcsid = "$Id: auth_none.c,v 1.1 1993/10/27 05:40:10 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/auth_unix.c b/lib/libc/rpc/auth_unix.c index 24c7fde83dec..334dc56c265a 100644 --- a/lib/librpc/rpc/auth_unix.c +++ b/lib/libc/rpc/auth_unix.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: auth_unix.c,v 1.2 1993/09/14 17:28:43 jtc Exp $"; +static char *rcsid = "$Id: auth_unix.c,v 1.1 1993/10/27 05:40:11 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/auth_unix.h b/lib/libc/rpc/auth_unix.h index b8e6fae16d83..e9da2644c7d8 100644 --- a/lib/librpc/rpc/auth_unix.h +++ b/lib/libc/rpc/auth_unix.h @@ -28,7 +28,7 @@ * * from: @(#)auth_unix.h 1.8 88/02/08 SMI * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC - * $Id: auth_unix.h,v 1.2 1993/09/14 17:28:44 jtc Exp $ + * $Id: auth_unix.h,v 1.1 1993/10/27 05:40:12 paul Exp $ */ /* diff --git a/lib/librpc/rpc/authunix_prot.c b/lib/libc/rpc/authunix_prot.c index 3a185cf9b885..15faf184cfb5 100644 --- a/lib/librpc/rpc/authunix_prot.c +++ b/lib/libc/rpc/authunix_prot.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: authunix_prot.c,v 1.2 1993/09/14 17:28:45 jtc Exp $"; +static char *rcsid = "$Id: authunix_prot.c,v 1.1 1993/10/27 05:40:15 paul Exp $"; #endif /* diff --git a/lib/librpc/man/man3/bindresvport.3n b/lib/libc/rpc/bindresvport.3 index 1fb1f9a30600..1fb1f9a30600 100644 --- a/lib/librpc/man/man3/bindresvport.3n +++ b/lib/libc/rpc/bindresvport.3 diff --git a/lib/librpc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c index fb46c3c9cdfb..a085c910c3c3 100644 --- a/lib/librpc/rpc/bindresvport.c +++ b/lib/libc/rpc/bindresvport.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/ /*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: bindresvport.c,v 1.2 1993/09/14 17:28:46 jtc Exp $"; +static char *rcsid = "$Id: bindresvport.c,v 1.1 1993/10/27 05:40:17 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt.h b/lib/libc/rpc/clnt.h index f9d243800fa5..71d36bc97fdb 100644 --- a/lib/librpc/rpc/clnt.h +++ b/lib/libc/rpc/clnt.h @@ -28,7 +28,7 @@ * * from: @(#)clnt.h 1.31 88/02/08 SMI * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC - * $Id: clnt.h,v 1.2 1993/09/14 17:28:47 jtc Exp $ + * $Id: clnt.h,v 1.1 1993/10/27 05:40:18 paul Exp $ */ /* diff --git a/lib/librpc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c index 7a5832bfd942..ad9c22bb7191 100644 --- a/lib/librpc/rpc/clnt_generic.c +++ b/lib/libc/rpc/clnt_generic.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/ /*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_generic.c,v 1.2 1993/09/14 17:28:48 jtc Exp $"; +static char *rcsid = "$Id: clnt_generic.c,v 1.1 1993/10/27 05:40:19 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt_perror.c b/lib/libc/rpc/clnt_perror.c index 4c5e8d08d461..9a7d76cbc200 100644 --- a/lib/librpc/rpc/clnt_perror.c +++ b/lib/libc/rpc/clnt_perror.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_perror.c,v 1.2 1993/09/14 17:28:48 jtc Exp $"; +static char *rcsid = "$Id: clnt_perror.c,v 1.1 1993/10/27 05:40:20 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c index 7ca88c2ade35..9ee87b225701 100644 --- a/lib/librpc/rpc/clnt_raw.c +++ b/lib/libc/rpc/clnt_raw.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_raw.c,v 1.2 1993/09/14 17:28:49 jtc Exp $"; +static char *rcsid = "$Id: clnt_raw.c,v 1.1 1993/10/27 05:40:22 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt_simple.c b/lib/libc/rpc/clnt_simple.c index 172baa5378cd..671e2eb61a93 100644 --- a/lib/librpc/rpc/clnt_simple.c +++ b/lib/libc/rpc/clnt_simple.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_simple.c,v 1.2 1993/09/14 17:28:50 jtc Exp $"; +static char *rcsid = "$Id: clnt_simple.c,v 1.1 1993/10/27 05:40:23 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt_tcp.c b/lib/libc/rpc/clnt_tcp.c index 59fdee9c3bfd..efc041ab8db3 100644 --- a/lib/librpc/rpc/clnt_tcp.c +++ b/lib/libc/rpc/clnt_tcp.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_tcp.c,v 1.2 1993/09/14 17:28:51 jtc Exp $"; +static char *rcsid = "$Id: clnt_tcp.c,v 1.1 1993/10/27 05:40:24 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c index 4903167b95ef..4df4631079a7 100644 --- a/lib/librpc/rpc/clnt_udp.c +++ b/lib/libc/rpc/clnt_udp.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: clnt_udp.c,v 1.2 1993/09/14 17:28:52 jtc Exp $"; +static char *rcsid = "$Id: clnt_udp.c,v 1.1 1993/10/27 05:40:25 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/get_myaddress.c b/lib/libc/rpc/get_myaddress.c index 6c846f4161b6..2b0b20d96f0e 100644 --- a/lib/librpc/rpc/get_myaddress.c +++ b/lib/libc/rpc/get_myaddress.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: get_myaddress.c,v 1.2 1993/09/14 17:28:53 jtc Exp $"; +static char *rcsid = "$Id: get_myaddress.c,v 1.1 1993/10/27 05:40:27 paul Exp $"; #endif /* diff --git a/lib/librpc/man/man3/getrpcent.3n b/lib/libc/rpc/getrpcent.3 index f500c01b075f..f500c01b075f 100644 --- a/lib/librpc/man/man3/getrpcent.3n +++ b/lib/libc/rpc/getrpcent.3 diff --git a/lib/librpc/rpc/getrpcent.c b/lib/libc/rpc/getrpcent.c index 5e657246849d..a495278f8d27 100644 --- a/lib/librpc/rpc/getrpcent.c +++ b/lib/libc/rpc/getrpcent.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/ -static char *rcsid = "$Id: getrpcent.c,v 1.2 1993/09/14 17:28:54 jtc Exp $"; +static char *rcsid = "$Id: getrpcent.c,v 1.1 1993/10/27 05:40:29 paul Exp $"; #endif /* diff --git a/lib/librpc/man/man3/getrpcport.3r b/lib/libc/rpc/getrpcport.3 index 0323d34a07c8..0323d34a07c8 100644 --- a/lib/librpc/man/man3/getrpcport.3r +++ b/lib/libc/rpc/getrpcport.3 diff --git a/lib/librpc/rpc/getrpcport.c b/lib/libc/rpc/getrpcport.c index 4858f52016f8..f1d58f9eb718 100644 --- a/lib/librpc/rpc/getrpcport.c +++ b/lib/libc/rpc/getrpcport.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/ /*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: getrpcport.c,v 1.2 1993/09/14 17:28:55 jtc Exp $"; +static char *rcsid = "$Id: getrpcport.c,v 1.1 1993/10/27 05:40:31 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c index 706d42164183..4ef44ec3144c 100644 --- a/lib/librpc/rpc/pmap_clnt.c +++ b/lib/libc/rpc/pmap_clnt.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_clnt.c,v 1.2 1993/09/14 17:28:56 jtc Exp $"; +static char *rcsid = "$Id: pmap_clnt.c,v 1.1 1993/10/27 05:40:32 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_clnt.h b/lib/libc/rpc/pmap_clnt.h index fb5cbec6b141..f080ec50956f 100644 --- a/lib/librpc/rpc/pmap_clnt.h +++ b/lib/libc/rpc/pmap_clnt.h @@ -28,7 +28,7 @@ * * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC - * $Id: pmap_clnt.h,v 1.2 1993/09/14 17:28:56 jtc Exp $ + * $Id: pmap_clnt.h,v 1.1 1993/10/27 05:40:33 paul Exp $ */ /* diff --git a/lib/librpc/rpc/pmap_getmaps.c b/lib/libc/rpc/pmap_getmaps.c index abf91f8f859f..5af52106454b 100644 --- a/lib/librpc/rpc/pmap_getmaps.c +++ b/lib/libc/rpc/pmap_getmaps.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_getmaps.c,v 1.2 1993/09/14 17:28:57 jtc Exp $"; +static char *rcsid = "$Id: pmap_getmaps.c,v 1.1 1993/10/27 05:40:35 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_getport.c b/lib/libc/rpc/pmap_getport.c index 315c9ec4e9bf..06ed4d409fbb 100644 --- a/lib/librpc/rpc/pmap_getport.c +++ b/lib/libc/rpc/pmap_getport.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_getport.c,v 1.2 1993/09/14 17:28:58 jtc Exp $"; +static char *rcsid = "$Id: pmap_getport.c,v 1.1 1993/10/27 05:40:36 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_prot.c b/lib/libc/rpc/pmap_prot.c index 0263e7aff29a..ea0a20dfb144 100644 --- a/lib/librpc/rpc/pmap_prot.c +++ b/lib/libc/rpc/pmap_prot.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_prot.c,v 1.2 1993/09/14 17:28:59 jtc Exp $"; +static char *rcsid = "$Id: pmap_prot.c,v 1.1 1993/10/27 05:40:37 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_prot.h b/lib/libc/rpc/pmap_prot.h index 7ce51d5ee8fa..1c10c368d187 100644 --- a/lib/librpc/rpc/pmap_prot.h +++ b/lib/libc/rpc/pmap_prot.h @@ -28,7 +28,7 @@ * * from: @(#)pmap_prot.h 1.14 88/02/08 SMI * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC - * $Id: pmap_prot.h,v 1.2 1993/09/14 17:29:00 jtc Exp $ + * $Id: pmap_prot.h,v 1.1 1993/10/27 05:40:38 paul Exp $ */ /* diff --git a/lib/librpc/rpc/pmap_prot2.c b/lib/libc/rpc/pmap_prot2.c index 49dff7d5d8bd..71ab21a7103b 100644 --- a/lib/librpc/rpc/pmap_prot2.c +++ b/lib/libc/rpc/pmap_prot2.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_prot2.c,v 1.2 1993/09/14 17:29:01 jtc Exp $"; +static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c index 80b79030f397..339860c2c153 100644 --- a/lib/librpc/rpc/pmap_rmt.c +++ b/lib/libc/rpc/pmap_rmt.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: pmap_rmt.c,v 1.2 1993/09/14 17:29:02 jtc Exp $"; +static char *rcsid = "$Id: pmap_rmt.c,v 1.1 1993/10/27 05:40:40 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/pmap_rmt.h b/lib/libc/rpc/pmap_rmt.h index 221ebe077aa6..c8c06ecb584d 100644 --- a/lib/librpc/rpc/pmap_rmt.h +++ b/lib/libc/rpc/pmap_rmt.h @@ -28,7 +28,7 @@ * * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC - * $Id: pmap_rmt.h,v 1.2 1993/09/14 17:29:03 jtc Exp $ + * $Id: pmap_rmt.h,v 1.1 1993/10/27 05:40:41 paul Exp $ */ /* diff --git a/lib/librpc/man/man3/rpc.3n b/lib/libc/rpc/rpc.3 index b5a2b92fce76..b5a2b92fce76 100644 --- a/lib/librpc/man/man3/rpc.3n +++ b/lib/libc/rpc/rpc.3 diff --git a/lib/librpc/man/man5/rpc.5 b/lib/libc/rpc/rpc.5 index 324ecb153a83..324ecb153a83 100644 --- a/lib/librpc/man/man5/rpc.5 +++ b/lib/libc/rpc/rpc.5 diff --git a/lib/librpc/rpc/rpc.h b/lib/libc/rpc/rpc.h index 6bcf24051177..5f8d23ea3d6e 100644 --- a/lib/librpc/rpc/rpc.h +++ b/lib/libc/rpc/rpc.h @@ -28,7 +28,7 @@ * * from: @(#)rpc.h 1.9 88/02/08 SMI * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC - * $Id: rpc.h,v 1.2 1993/09/14 17:29:03 jtc Exp $ + * $Id: rpc.h,v 1.1 1993/10/27 05:40:45 paul Exp $ */ /* diff --git a/lib/librpc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c index d40abe04c6be..4ec59dbc7855 100644 --- a/lib/librpc/rpc/rpc_callmsg.c +++ b/lib/libc/rpc/rpc_callmsg.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: rpc_callmsg.c,v 1.2 1993/09/14 17:29:04 jtc Exp $"; +static char *rcsid = "$Id: rpc_callmsg.c,v 1.1 1993/10/27 05:40:46 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/rpc_commondata.c b/lib/libc/rpc/rpc_commondata.c index d18fc3a75885..e870ab8dde7c 100644 --- a/lib/librpc/rpc/rpc_commondata.c +++ b/lib/libc/rpc/rpc_commondata.c @@ -29,7 +29,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: rpc_commondata.c,v 1.2 1993/09/14 17:29:05 jtc Exp $"; +static char *rcsid = "$Id: rpc_commondata.c,v 1.1 1993/10/27 05:40:47 paul Exp $"; #endif #include <rpc/rpc.h> diff --git a/lib/librpc/rpc/rpc_dtablesize.c b/lib/libc/rpc/rpc_dtablesize.c index ef8f317fe570..c4a2ac411b33 100644 --- a/lib/librpc/rpc/rpc_dtablesize.c +++ b/lib/libc/rpc/rpc_dtablesize.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/ /*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: rpc_dtablesize.c,v 1.2 1993/09/14 17:29:07 jtc Exp $"; +static char *rcsid = "$Id: rpc_dtablesize.c,v 1.1 1993/10/27 05:40:48 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/rpc_msg.h b/lib/libc/rpc/rpc_msg.h index 9d9186cd86bc..f3697fa8a02f 100644 --- a/lib/librpc/rpc/rpc_msg.h +++ b/lib/libc/rpc/rpc_msg.h @@ -28,7 +28,7 @@ * * from: @(#)rpc_msg.h 1.7 86/07/16 SMI * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC - * $Id: rpc_msg.h,v 1.2 1993/09/14 17:29:07 jtc Exp $ + * $Id: rpc_msg.h,v 1.1 1993/10/27 05:40:49 paul Exp $ */ /* diff --git a/lib/librpc/rpc/rpc_prot.c b/lib/libc/rpc/rpc_prot.c index 01758b7c12dd..7fbb36fd7557 100644 --- a/lib/librpc/rpc/rpc_prot.c +++ b/lib/libc/rpc/rpc_prot.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/ -static char *rcsid = "$Id: rpc_prot.c,v 1.2 1993/09/14 17:29:08 jtc Exp $"; +static char *rcsid = "$Id: rpc_prot.c,v 1.1 1993/10/27 05:40:50 paul Exp $"; #endif /* diff --git a/lib/librpc/man/man1/rstat.1 b/lib/libc/rpc/rstat.1 index 61d9999116f8..61d9999116f8 100644 --- a/lib/librpc/man/man1/rstat.1 +++ b/lib/libc/rpc/rstat.1 diff --git a/lib/librpc/man/man8/rstat_svc.8c b/lib/libc/rpc/rstat_svc.8 index a10b71dbacad..a10b71dbacad 100644 --- a/lib/librpc/man/man8/rstat_svc.8c +++ b/lib/libc/rpc/rstat_svc.8 diff --git a/lib/librpc/rpc/svc.c b/lib/libc/rpc/svc.c index 8ba14c175c99..55ad25e92ad0 100644 --- a/lib/librpc/rpc/svc.c +++ b/lib/libc/rpc/svc.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc.c,v 1.2 1993/09/14 17:29:09 jtc Exp $"; +static char *rcsid = "$Id: svc.c,v 1.1 1993/10/27 05:40:54 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc.h b/lib/libc/rpc/svc.h index f498731d4c29..b525d8232dea 100644 --- a/lib/librpc/rpc/svc.h +++ b/lib/libc/rpc/svc.h @@ -28,7 +28,7 @@ * * from: @(#)svc.h 1.20 88/02/08 SMI * from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC - * $Id: svc.h,v 1.2 1993/09/14 17:29:10 jtc Exp $ + * $Id: svc.h,v 1.1 1993/10/27 05:40:55 paul Exp $ */ /* diff --git a/lib/librpc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c index 93f16ac747d1..0a9f2765bf6a 100644 --- a/lib/librpc/rpc/svc_auth.c +++ b/lib/libc/rpc/svc_auth.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_auth.c,v 1.2 1993/09/14 17:29:11 jtc Exp $"; +static char *rcsid = "$Id: svc_auth.c,v 1.1 1993/10/27 05:40:56 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_auth.h b/lib/libc/rpc/svc_auth.h index 5020e9fee7c7..c6db4404e25d 100644 --- a/lib/librpc/rpc/svc_auth.h +++ b/lib/libc/rpc/svc_auth.h @@ -28,7 +28,7 @@ * * from: @(#)svc_auth.h 1.6 86/07/16 SMI * from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC - * $Id: svc_auth.h,v 1.2 1993/09/14 17:29:12 jtc Exp $ + * $Id: svc_auth.h,v 1.1 1993/10/27 05:40:57 paul Exp $ */ /* diff --git a/lib/librpc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c index b0c4eca79694..5cf825f6f8ab 100644 --- a/lib/librpc/rpc/svc_auth_unix.c +++ b/lib/libc/rpc/svc_auth_unix.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_auth_unix.c,v 1.2 1993/09/14 17:29:13 jtc Exp $"; +static char *rcsid = "$Id: svc_auth_unix.c,v 1.1 1993/10/27 05:40:58 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c index a86cd6d3dff0..e34ea9e32608 100644 --- a/lib/librpc/rpc/svc_raw.c +++ b/lib/libc/rpc/svc_raw.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_raw.c,v 1.2 1993/09/14 17:29:14 jtc Exp $"; +static char *rcsid = "$Id: svc_raw.c,v 1.1 1993/10/27 05:40:59 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_run.c b/lib/libc/rpc/svc_run.c index dffe1fe602cd..52fddf226382 100644 --- a/lib/librpc/rpc/svc_run.c +++ b/lib/libc/rpc/svc_run.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_run.c,v 1.2 1993/09/14 17:29:15 jtc Exp $"; +static char *rcsid = "$Id: svc_run.c,v 1.1 1993/10/27 05:41:00 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c index 3a9cff9f0501..eacf859f5ca9 100644 --- a/lib/librpc/rpc/svc_simple.c +++ b/lib/libc/rpc/svc_simple.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_simple.c,v 1.2 1993/09/14 17:29:15 jtc Exp $"; +static char *rcsid = "$Id: svc_simple.c,v 1.1 1993/10/27 05:41:01 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_tcp.c b/lib/libc/rpc/svc_tcp.c index 3479d3ec765f..9d19504858fb 100644 --- a/lib/librpc/rpc/svc_tcp.c +++ b/lib/libc/rpc/svc_tcp.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_tcp.c,v 1.2 1993/09/14 17:29:16 jtc Exp $"; +static char *rcsid = "$Id: svc_tcp.c,v 1.1 1993/10/27 05:41:02 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/svc_udp.c b/lib/libc/rpc/svc_udp.c index 7655dd1abee3..d7c7bb2dd825 100644 --- a/lib/librpc/rpc/svc_udp.c +++ b/lib/libc/rpc/svc_udp.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: svc_udp.c,v 1.2 1993/09/14 17:29:17 jtc Exp $"; +static char *rcsid = "$Id: svc_udp.c,v 1.1 1993/10/27 05:41:03 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/types.h b/lib/libc/rpc/types.h index 697410cdd305..b12221d0d3b2 100644 --- a/lib/librpc/rpc/types.h +++ b/lib/libc/rpc/types.h @@ -28,7 +28,7 @@ * * from: @(#)types.h 1.18 87/07/24 SMI * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC - * $Id: types.h,v 1.2 1993/09/14 17:29:18 jtc Exp $ + * $Id: types.h,v 1.1 1993/10/27 05:41:04 paul Exp $ */ /* diff --git a/lib/librpc/man/man3/xdr.3n b/lib/libc/rpc/xdr.3 index b656ea804da8..b656ea804da8 100644 --- a/lib/librpc/man/man3/xdr.3n +++ b/lib/libc/rpc/xdr.3 diff --git a/lib/librpc/rpc/xdr.c b/lib/libc/rpc/xdr.c index 35e1eac7d162..9f402047aa5a 100644 --- a/lib/librpc/rpc/xdr.c +++ b/lib/libc/rpc/xdr.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/ /*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr.c,v 1.2 1993/09/14 17:29:19 jtc Exp $"; +static char *rcsid = "$Id: xdr.c,v 1.1 1993/10/27 05:41:06 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr.h b/lib/libc/rpc/xdr.h index 6e45fff2d9cd..c29cc4816c22 100644 --- a/lib/librpc/rpc/xdr.h +++ b/lib/libc/rpc/xdr.h @@ -28,7 +28,7 @@ * * from: @(#)xdr.h 1.19 87/04/22 SMI * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC - * $Id: xdr.h,v 1.2 1993/09/14 17:29:20 jtc Exp $ + * $Id: xdr.h,v 1.1 1993/10/27 05:41:07 paul Exp $ */ /* diff --git a/lib/librpc/rpc/xdr_array.c b/lib/libc/rpc/xdr_array.c index 3eca269c31ac..a17b534a92e7 100644 --- a/lib/librpc/rpc/xdr_array.c +++ b/lib/libc/rpc/xdr_array.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_array.c,v 1.2 1993/09/14 17:29:21 jtc Exp $"; +static char *rcsid = "$Id: xdr_array.c,v 1.1 1993/10/27 05:41:09 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr_float.c b/lib/libc/rpc/xdr_float.c index d8d975a01ad5..fae0c8b7f8e3 100644 --- a/lib/librpc/rpc/xdr_float.c +++ b/lib/libc/rpc/xdr_float.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_float.c,v 1.2 1993/09/14 17:29:22 jtc Exp $"; +static char *rcsid = "$Id: xdr_float.c,v 1.1 1993/10/27 05:41:10 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr_mem.c b/lib/libc/rpc/xdr_mem.c index 121cb5b8210f..3909edda4ee8 100644 --- a/lib/librpc/rpc/xdr_mem.c +++ b/lib/libc/rpc/xdr_mem.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_mem.c,v 1.2 1993/09/14 17:29:23 jtc Exp $"; +static char *rcsid = "$Id: xdr_mem.c,v 1.1 1993/10/27 05:41:11 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr_rec.c b/lib/libc/rpc/xdr_rec.c index ba040077abbc..f2559d4b4f6b 100644 --- a/lib/librpc/rpc/xdr_rec.c +++ b/lib/libc/rpc/xdr_rec.c @@ -29,7 +29,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_rec.c,v 1.2 1993/09/14 17:29:24 jtc Exp $"; +static char *rcsid = "$Id: xdr_rec.c,v 1.1 1993/10/27 05:41:12 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr_reference.c b/lib/libc/rpc/xdr_reference.c index cd6d18c183f6..c955f8820256 100644 --- a/lib/librpc/rpc/xdr_reference.c +++ b/lib/libc/rpc/xdr_reference.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/ /*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_reference.c,v 1.2 1993/09/14 17:29:25 jtc Exp $"; +static char *rcsid = "$Id: xdr_reference.c,v 1.1 1993/10/27 05:41:13 paul Exp $"; #endif /* diff --git a/lib/librpc/rpc/xdr_stdio.c b/lib/libc/rpc/xdr_stdio.c index e762135f2148..9761b13d5f2a 100644 --- a/lib/librpc/rpc/xdr_stdio.c +++ b/lib/libc/rpc/xdr_stdio.c @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/ /*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/ -static char *rcsid = "$Id: xdr_stdio.c,v 1.2 1993/09/14 17:29:25 jtc Exp $"; +static char *rcsid = "$Id: xdr_stdio.c,v 1.1 1993/10/27 05:41:14 paul Exp $"; #endif /* diff --git a/lib/libc/stdio/ferror.3 b/lib/libc/stdio/ferror.3 index e90af8fc7167..a4e367835201 100644 --- a/lib/libc/stdio/ferror.3 +++ b/lib/libc/stdio/ferror.3 @@ -82,7 +82,7 @@ The function .Fn fileno examines the argument .Fa stream -and returns its integer desciptor. +and returns its integer descriptor. .Sh ERRORS These functions should not fail and do not set the external variable diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3 index 8676aee498ab..89a5cdbe8c62 100644 --- a/lib/libc/stdio/fgets.3 +++ b/lib/libc/stdio/fgets.3 @@ -93,8 +93,8 @@ they return The .Fn fgets and -functions .Fn gets +functions do not distinguish between end-of-file and error, and callers must use .Xr feof 3 and diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c index 1928ae14160b..78e616387269 100644 --- a/lib/libc/stdio/setvbuf.c +++ b/lib/libc/stdio/setvbuf.c @@ -137,11 +137,14 @@ nbf: flags |= __SLBF; if (flags & __SRW) flags &= ~(__SRD | __SWR); - fp->_w = 0; fp->_flags = flags; fp->_bf._base = fp->_p = (unsigned char *)buf; fp->_bf._size = size; fp->_lbfsize = 0; + if (flags & __SWR) + __swsetup(fp); + else + fp->_w = 0; __cleanup = _cleanup; return (ret); diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3 index 60fcb2e57173..98143dc62928 100644 --- a/lib/libc/stdio/stdio.3 +++ b/lib/libc/stdio/stdio.3 @@ -77,7 +77,7 @@ function. A file is disassociated from a stream by .Em closing the file. -Ouput streams are flushed (any unwritten buffer contents are transfered +Ouput streams are flushed (any unwritten buffer contents are transferred to the host environment) before the stream is disassociated from the file. The value of a pointer to a .Dv FILE diff --git a/lib/libc/stdio/strerror.3 b/lib/libc/stdio/strerror.3 index 3f590e5d35b2..7989ea798e7d 100644 --- a/lib/libc/stdio/strerror.3 +++ b/lib/libc/stdio/strerror.3 @@ -47,7 +47,7 @@ .Sh SYNOPSIS .Vt extern int errno; .Vt extern char *sys_errlist[]; -.Fd #include <stdio.h> +.Fd #include <string.h> .Ft void .Fn perror "const char *string" .Ft char * @@ -61,7 +61,7 @@ functions lookup the error message string affiliated with an error number. .Pp The -.Fn sterror +.Fn strerror function accepts an error number argument .Fa errnum and diff --git a/lib/libc/stdio/tempnam.c b/lib/libc/stdio/tempnam.c index 988763aac5b8..e3ee6c072f05 100644 --- a/lib/libc/stdio/tempnam.c +++ b/lib/libc/stdio/tempnam.c @@ -48,6 +48,8 @@ tempnam(dir, pfx) { int sverrno; char *f, *name; + static char unique[] = "@AA"; + int idx; if (!(name = malloc(MAXPATHLEN))) return(NULL); @@ -55,27 +57,35 @@ tempnam(dir, pfx) if (!pfx) pfx = "tmp."; + /* Bump up the unique counter. The following is also a gross abuse + * of C, but I don't really care. This whole function is superceeded + * by mkstemp() anyway. + */ + idx = unique[0] < 'Z' ? 0 : unique[1] < 'Z' ? 1 : unique[2] < 'Z' ? + 2 : (int)strcpy(unique, "AAA"), 0; + ++unique[idx]; + if (f = getenv("TMPDIR")) { - (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, - *(f + strlen(f) - 1) == '/'? "": "/", pfx); + (void)snprintf(name, MAXPATHLEN, "%s%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx, unique); if (f = mktemp(name)) return(f); } if (f = (char *)dir) { - (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, - *(f + strlen(f) - 1) == '/'? "": "/", pfx); + (void)snprintf(name, MAXPATHLEN, "%s%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx, unique); if (f = mktemp(name)) return(f); } f = P_tmpdir; - (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, pfx, unique); if (f = mktemp(name)) return(f); f = _PATH_TMP; - (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, pfx, unique); if (f = mktemp(name)) return(f); diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 8d064c696c2e..dea8a5620da6 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -35,7 +35,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)vfprintf.c 5.50 (Berkeley) 12/16/92"; +/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ +static char *rcsid = "$Id: vfprintf.c,v 1.5 1994/02/06 07:35:02 wollman Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -120,6 +121,7 @@ __sbprintf(fp, fmt, ap) #ifdef FLOATING_POINT +#include <locale.h> #include <math.h> #include "floatio.h" @@ -159,7 +161,7 @@ int vfprintf(fp, fmt0, ap) FILE *fp; const char *fmt0; - va_list ap; + _VA_LIST_ ap; { register char *fmt; /* format string */ register int ch; /* character from fmt */ @@ -382,20 +384,23 @@ reswitch: switch (ch) { base = DEC; goto number; #ifdef FLOATING_POINT - case 'e': /* anomalous precision */ + case 'e': case 'E': - prec = (prec == -1) ? - DEFPREC + 1 : prec + 1; - /* FALLTHROUGH */ - goto fp_begin; - case 'f': /* always print trailing zeroes */ - if (prec != 0) - flags |= ALT; + case 'f': case 'g': case 'G': - if (prec == -1) + if (prec == -1) { prec = DEFPREC; -fp_begin: _double = va_arg(ap, double); + } else if ((ch == 'g' || ch == 'G') && prec == 0) { + prec = 1; + } + + if (flags & LONGDBL) { + _double = (double) va_arg(ap, long double); + } else { + _double = va_arg(ap, double); + } + /* do this before tricky precision changes */ if (isinf(_double)) { if (_double < 0) @@ -409,6 +414,7 @@ fp_begin: _double = va_arg(ap, double); size = 3; break; } + flags |= FPT; cp = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig); @@ -469,7 +475,12 @@ fp_begin: _double = va_arg(ap, double); * -- ANSI X3J11 */ /* NOSTRICT */ + /* no easy way to tell in cpp how big a type is */ +#if defined(__i386) + _uquad = (u_quad_t)(u_long)va_arg(ap, void *); +#else _uquad = (u_quad_t)va_arg(ap, void *); +#endif base = HEX; xdigs = "0123456789abcdef"; flags |= HEXPREFIX; @@ -631,9 +642,8 @@ number: if ((dprec = prec) >= 0) } else { /* glue together f_p fragments */ if (ch >= 'f') { /* 'f' or 'g' */ if (_double == 0) { - /* kludge for __dtoa irregularity */ - if (prec == 0 || - (flags & ALT) == 0) { + /* kludge for __dtoa irregularity */ + if (expt >= ndig && (flags & ALT) == 0) { PRINT("0", 1); } else { PRINT("0.", 2); @@ -701,18 +711,26 @@ cvt(value, ndigits, flags, sign, decpt, ch, length) int mode, dsgn; char *digits, *bp, *rve; - if (ch == 'f') - mode = 3; - else { - mode = 2; + if (ch == 'f') { + mode = 3; /* ndigits after the decimal point */ + } else { + /* To obtain ndigits after the decimal point for the 'e' + * and 'E' formats, round to ndigits + 1 significant + * figures. + */ + if (ch == 'e' || ch == 'E') { + ndigits++; + } + mode = 2; /* ndigits significant digits */ } + if (value < 0) { value = -value; *sign = '-'; } else *sign = '\000'; digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); - if (flags & ALT) { /* Print trailing zeros */ + if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ bp = digits + ndigits; if (ch == 'f') { if (*digits == '0' && value) diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 972887fbd82a..0bd1a90ab56a 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -3,17 +3,17 @@ # stdlib sources .PATH: ${.CURDIR}/${MACHINE}/stdlib ${.CURDIR}/stdlib -SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c div.c exit.c \ +SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c exit.c \ getenv.c getopt.c heapsort.c malloc.c multibyte.c \ putenv.c qsort.c radixsort.c rand.c random.c setenv.c strtod.c \ strtol.c strtoul.c system.c \ _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ - mrand48.c nrand48.c seed48.c srand48.c + mrand48.c nrand48.c seed48.c srand48.c strtoq.c strtouq.c .if (${MACHINE} == "hp300") SRCS+= abs.s div.c labs.c ldiv.c atof.c .elif (${MACHINE} == "i386") -SRCS+= abs.s div.s labs.s ldiv.s atof.c +SRCS+= abs.S div.S labs.S ldiv.S atof.c .elif (${MACHINE} == "tahoe") SRCS+= abs.s div.c labs.c ldiv.c atof.c .elif (${MACHINE} == "vax") diff --git a/lib/libc/stdlib/bsearch.3 b/lib/libc/stdlib/bsearch.3 index 35c5a426f522..b1de330f2429 100644 --- a/lib/libc/stdlib/bsearch.3 +++ b/lib/libc/stdlib/bsearch.3 @@ -50,7 +50,7 @@ The .Fn bsearch function searches an array of .Fa nmemb -objects, the inital member of which is +objects, the initial member of which is pointed to by .Fa base , for a member that matches the object pointed to by diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c index 0d3c72520f46..50c872afe529 100644 --- a/lib/libc/stdlib/exit.c +++ b/lib/libc/stdlib/exit.c @@ -57,4 +57,6 @@ exit(status) if (__cleanup) (*__cleanup)(); _exit(status); + /* We'll never get here; this just surpresses a warning. */ + while(1) { ; } } diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3 index c21a0a725faf..c028465b992f 100644 --- a/lib/libc/stdlib/getopt.3 +++ b/lib/libc/stdlib/getopt.3 @@ -29,7 +29,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getopt.3 6.16 (Berkeley) 4/19/91 +.\" from: @(#)getopt.3 6.16 (Berkeley) 4/19/91 +.\" $Id: getopt.3,v 1.2 1993/11/23 00:08:36 jtc Exp $ .\" .Dd April 19, 1991 .Dt GETOPT 3 @@ -38,12 +39,13 @@ .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 +.Fd #include <unistd.h> .Ft int .Fn getopt "int argc" "char * const *argv" "const char *optstring" +.Vt extern char *optarg; +.Vt extern int optind; +.Vt extern int opterr; +.Vt extern int optopt; .Sh DESCRIPTION The .Fn getopt @@ -93,68 +95,137 @@ evaluation. The .Fn getopt function -returns an -.Dv EOF -when the argument list is exhausted, or a non-recognized -option is encountered. +returns \-1 +when the argument list is exhausted. 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 . +to signal the end of argument processing and return \-1. When all options have been processed (i.e., up to the first non-option argument), .Fn getopt -returns -.Dv EOF . +returns \-1. .Sh DIAGNOSTICS -If the +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 +function encounters an option character that is not contained in +.Fa optstring , +it returns a question mark +.Pq ? +character. +If it detects a missing option argument, it returns a colon +.Pq \: +character if the first character of +.Fa optstring +is a colon, otherwise it returns a question mark. +In either case, a diagnostic message is written to +.Em stderr +unless the application has set .Va opterr -to a zero will disable these error messages. +to zero or the first character of +.Fa optstring +is a colon. .Sh EXAMPLE +.\" The following example comes from section E.9.7 of the IEEE 1003.2-90 +.\" standard (POSIX.2). +The following code fragment shows how one might process the arguments for +a utility that can take the mutually exclusive options +.Em a +and +.Em b +and the options +.Em f +and +.Em o , +both of which require arguments: +.Pp .Bd -literal -compact -extern char *optarg; -extern int optind; -int bflag, ch, fd; +#include <unistd.h> -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) ; +int +main (argc, argv) + int argc; + char *argv[]; +{ + int c, bflg, aflg, errflg = 0; + char *ifile, *ofile; + extern char *optarg; + extern int optind, optopt; + + . . . + + while ((c = getopt(argc, argv, ":abf:o:")) != -1) { + switch(ch) { + case 'a': + if (bflg) + errflg = 1; + else + aflg = 1; + break; + case 'b': + if (aflg) + errflg = 1; + else + bflg = 1; + break; + case 'f': + ifile = optarg; + break; + case 'o': + ofile = optarg; + break; + case ':': /* -f or -o without option-arg */ + fprintf (stderr, + "Option -%c requires an option-argument\\n", + optopt); + errflg = 1; + break; + case '?': + fprintf (stderr, + "Unrecognized option: -%c\\n", + optopt); + errflg = 1; + break; } - break; - case '?': - default: - usage(); + } + + if (errflg) { + fprintf (stderr, "usage: . . .\\n"); + exit (2); + } + + argc -= optind; + argv += optind; + + . . . + } -argc -= optind; -argv += optind; .Ed +.Sh STANDARDS +The +.Fn getopt +function conforms to +.St -p1003.2-92 . .Sh HISTORY The .Fn getopt function appeared .Bx 4.3 . .Sh BUGS +The +.Fn getopt +function was once specified to return +.Dv EOF +instead of \-1. +This was changed by +.St -p1003.2-92 +to decouple +.Fn getopt +from +.Pa <stdio.h> . +.Pp Option arguments are allowed to begin with .Dq Li \- ; this is reasonable but @@ -177,8 +248,7 @@ It is provided for backward compatibility .Em only . By default, a single dash causes .Fn getopt -to return -.Dv EOF . +to returns \-1. This is, we believe, compatible with System V. .Pp It is also possible to handle digits as option letters. @@ -195,7 +265,7 @@ The following code fragment works fairly well. int length; char *p; -while ((c = getopt(argc, argv, "0123456789")) != EOF) +while ((c = getopt(argc, argv, "0123456789")) != -1) switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': diff --git a/lib/libc/stdlib/getopt.c b/lib/libc/stdlib/getopt.c index 7126cc1da95a..7d1d9802156f 100644 --- a/lib/libc/stdlib/getopt.c +++ b/lib/libc/stdlib/getopt.c @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; +/*static char *sccsid = "from: @(#)getopt.c 4.13 (Berkeley) 2/23/91";*/ +static char *rcsid = "$Id: getopt.c,v 1.2 1993/11/23 00:08:37 jtc Exp $"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> @@ -42,11 +43,12 @@ static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; /* * 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 */ +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt; /* character checked for validity */ char *optarg; /* argument associated with option */ +#define NOOPT (int)':' /* No option */ #define BADCH (int)'?' #define EMSG "" @@ -63,26 +65,27 @@ getopt(nargc, nargv, ostr) if (!*place) { /* update scanning pointer */ if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; - return(EOF); + return(-1); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; - return(EOF); + return(-1); } - } /* option letter okay? */ + } + /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || - !(oli = index(ostr, optopt))) { + !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, - * assume it means EOF. + * assume it means -1. */ if (optopt == (int)'-') - return(EOF); + return(-1); if (!*place) ++optind; - if (opterr) { - if (!(p = rindex(*nargv, '/'))) + if (opterr && *ostr != ':') { + if (!(p = strrchr(*nargv, '/'))) p = *nargv; else ++p; @@ -91,25 +94,26 @@ getopt(nargc, nargv, ostr) } return(BADCH); } + if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; - } - else { /* need an argument */ + } 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) + if (opterr && *ostr != ':') { + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; (void)fprintf(stderr, "%s: option requires an argument -- %c\n", p, optopt); - return(BADCH); + } + return((*ostr == ':') ? NOOPT : BADCH); } else /* white space */ optarg = nargv[optind]; diff --git a/lib/libc/stdlib/rand48.3 b/lib/libc/stdlib/rand48.3 index fead60db46e2..176303dcf795 100644 --- a/lib/libc/stdlib/rand48.3 +++ b/lib/libc/stdlib/rand48.3 @@ -158,6 +158,3 @@ Martin Birgmeier .Sh SEE ALSO .Xr rand 3 , .Xr random 3 . -============================== cut here ============================== - - diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3 index 872983cd9e86..17a31b2aae45 100644 --- a/lib/libc/stdlib/random.3 +++ b/lib/libc/stdlib/random.3 @@ -41,7 +41,7 @@ .Nm setstate .Nd better random number generator; routines for changing generators .Sh SYNOPSIS -.Fd #include <stdlib> +.Fd #include <stdlib.h> .Ft long .Fn random void .Ft void diff --git a/lib/libc/stdlib/realloc.3 b/lib/libc/stdlib/realloc.3 index ee3e64018fc7..ba2ccc9180fb 100644 --- a/lib/libc/stdlib/realloc.3 +++ b/lib/libc/stdlib/realloc.3 @@ -72,7 +72,7 @@ by a call to the or .Fn realloc function, unpredictable and usually detrimental -behaviour will occur. +behavior will occur. If the space cannot be allocated, the object pointed to by .Fa ptr diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c index 14efac37b37c..9cade228c687 100644 --- a/lib/libc/stdlib/setenv.c +++ b/lib/libc/stdlib/setenv.c @@ -39,6 +39,8 @@ static char sccsid[] = "@(#)setenv.c 5.6 (Berkeley) 6/4/91"; #include <stdlib.h> #include <string.h> +extern char *_findenv(); + /* * setenv -- * Set the value of the environmental variable "name" to be @@ -53,7 +55,6 @@ setenv(name, value, rewrite) static int alloced; /* if allocated space before */ register char *C; int l_value, offset; - char *_findenv(); if (*value == '=') /* no `=' in value */ ++value; diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index 000d87647af6..1c1d5c96ee9a 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -124,6 +124,6 @@ strtol(nptr, endptr, base) } else if (neg) acc = -acc; if (endptr != 0) - *endptr = any ? s - 1 : (char *)nptr; + *endptr = any ? (char *)s - 1 : (char *)nptr; return (acc); } diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c new file mode 100644 index 000000000000..af02765d6c98 --- /dev/null +++ b/lib/libc/stdlib/strtoq.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 1992 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[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> + +#include <limits.h> +#include <errno.h> +#include <ctype.h> +#include <stdlib.h> + +/* + * Convert a string to a quad integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +quad_t +strtoq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, 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. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + 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 quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, 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. + */ + qbase = (unsigned)base; + cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + 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 *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? QUAD_MIN : QUAD_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = any ? (char *)s - 1 : (char *)nptr; + return (acc); +} diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index ed8c1080ba6e..284c182ef71c 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -102,6 +102,6 @@ strtoul(nptr, endptr, base) } else if (neg) acc = -acc; if (endptr != 0) - *endptr = any ? s - 1 : (char *)nptr; + *endptr = any ? (char *)s - 1 : (char *)nptr; return (acc); } diff --git a/lib/libc/stdlib/strtouq.c b/lib/libc/stdlib/strtouq.c new file mode 100644 index 000000000000..14e37e07f324 --- /dev/null +++ b/lib/libc/stdlib/strtouq.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 1992 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[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> + +#include <limits.h> +#include <errno.h> +#include <ctype.h> +#include <stdlib.h> + +/* + * Convert a string to an unsigned quad integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +u_quad_t +strtouq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s = nptr; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + 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; + qbase = (unsigned)base; + cutoff = (u_quad_t)UQUAD_MAX / qbase; + cutlim = (u_quad_t)UQUAD_MAX % qbase; + 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 *= qbase; + acc += c; + } + } + if (any < 0) { + acc = UQUAD_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = any ? (char *)s - 1 : (char *)nptr; + return (acc); +} diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index edd26209a1e2..bb5f703b6573 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -12,11 +12,11 @@ SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.s memchr.c memcmp.c memset.c \ strncat.c strncmp.s strncpy.s strpbrk.c strsep.c \ strspn.c strstr.c .elif (${MACHINE} == "i386") -SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.s memchr.s memcmp.s memset.s \ - rindex.s strcat.s strcmp.s strcpy.s strcspn.c strlen.s \ - strncat.c strncmp.s strncpy.c strpbrk.c strsep.c \ +SRCS+= bcmp.S bcopy.S bzero.S ffs.S index.S memchr.S memcmp.S memset.S \ + rindex.S strcat.S strcmp.S strcpy.S strcspn.c strlen.S \ + strncat.c strncmp.S strncpy.c strpbrk.c strsep.c \ strspn.c strstr.c -SRCS+= memmove.s strchr.s strrchr.s +SRCS+= memmove.S strchr.S strrchr.S .elif (${MACHINE} == "tahoe") SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.c memchr.c memcmp.s memset.c \ rindex.c strcat.s strcmp.s strcpy.s strcspn.c strlen.s \ @@ -33,7 +33,9 @@ SRCS+= memmove.s strchr.s strrchr.s # if no machine specific memmove(3), build one out of bcopy(3). .if empty(SRCS:Mmemcpy.s) +.if empty(SRCS:Mmemcpy.S) .if empty(SRCS:Mmemmove.s) +.if empty(SRCS:Mmemmove.S) OBJS+= memmove.o memmove.o: bcopy.c ${CC} -DMEMMOVE ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} @@ -46,9 +48,12 @@ memmove.po: bcopy.c @mv a.out ${.TARGET} .endif .endif +.endif +.endif # if no machine specific strchr(3), build one out of index(3). .if empty(SRCS:Mstrchr.s) +.if empty(SRCS:Mstrchr.S) OBJS+= strchr.o strchr.o: index.c ${CC} -DSTRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} @@ -60,9 +65,11 @@ strchr.po: index.c @${LD} -X -r ${.TARGET} @mv a.out ${.TARGET} .endif +.endif # if no machine specific strrchr(3), build one out of rindex(3). .if empty(SRCS:Mstrrchr.s) +.if empty(SRCS:Mstrrchr.S) OBJS+= strrchr.o strrchr.o: rindex.c ${CC} -DSTRRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} @@ -74,6 +81,7 @@ strrchr.po: rindex.c @${LD} -X -r ${.TARGET} @mv a.out ${.TARGET} .endif +.endif MAN3+= string/bcmp.3 string/bcopy.3 string/bstring.3 string/bzero.3 \ string/ffs.3 string/index.3 string/memccpy.3 string/memchr.3 \ diff --git a/lib/libc/string/bzero.3 b/lib/libc/string/bzero.3 index f3fadba8d929..6f6acb65b1f0 100644 --- a/lib/libc/string/bzero.3 +++ b/lib/libc/string/bzero.3 @@ -35,7 +35,7 @@ .\" .Dd April 19, 1991 .Dt BZERO 3 -.Os BDS 4.3 +.Os BSD 4.3 .Sh NAME .Nm bzero .Nd write zeroes to a byte string diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3 index 53ed88af0b3c..482b13b77fad 100644 --- a/lib/libc/string/ffs.3 +++ b/lib/libc/string/ffs.3 @@ -46,7 +46,7 @@ .Sh DESCRIPTION The .Fn ffs -fucntion +function finds the first bit set in .Fa value and returns the index of that bit. diff --git a/lib/libc/string/strchr.3 b/lib/libc/string/strchr.3 index 1e53b530c1d4..34744d94882b 100644 --- a/lib/libc/string/strchr.3 +++ b/lib/libc/string/strchr.3 @@ -48,7 +48,7 @@ .Sh DESCRIPTION The .Fn strchr -function locates the first occurence of +function locates the first occurrence of .Ar c in the string pointed to by .Ar s . diff --git a/lib/libc/string/strsep.3 b/lib/libc/string/strsep.3 index 0901722d49f2..a4283ff849c0 100644 --- a/lib/libc/string/strsep.3 +++ b/lib/libc/string/strsep.3 @@ -48,7 +48,7 @@ The .Fn strsep locates in the null-terminated string at .Fa *stringp -the first occurence of any character in +the first occurrence of any character in .Fa delim and replaces this with a .Ql \e0 , diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index e138dce490e9..3deb3bbcc702 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -4,9 +4,9 @@ .PATH: ${.CURDIR}/${MACHINE}/sys ${.CURDIR}/sys # modules with non-default implementations on at least one architecture: -SRCS+= Ovfork.s brk.s cerror.s exect.s fork.s pipe.s ptrace.s reboot.s \ - sbrk.s setlogin.s sigpending.s sigprocmask.s sigreturn.s \ - sigsuspend.s syscall.s +SRCS+= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S reboot.S \ + sbrk.S setlogin.S sigpending.S sigprocmask.S sigreturn.S \ + sigsuspend.S syscall.S # modules with default implementations on all architectures: ASM= accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \ @@ -19,51 +19,66 @@ ASM= accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \ getpriority.o getrlimit.o getrusage.o getsockname.o getsockopt.o \ gettimeofday.o getuid.o ioctl.o kill.o ktrace.o link.o listen.o \ lseek.o lstat.o madvise.o mincore.o mkdir.o mkfifo.o mknod.o \ - mmap.o mount.o mprotect.o msync.o munmap.o nfssvc.o open.o \ + mmap.o mount.o mprotect.o msgsys.o msync.o munmap.o nfssvc.o open.o \ profil.o quotactl.o read.o readlink.o readv.o recvfrom.o recvmsg.o \ - rename.o revoke.o rmdir.o select.o sendmsg.o sendto.o setdomainname.o \ - setegid.o seteuid.o setgid.o setgroups.o sethostid.o sethostname.o \ - setitimer.o setpgid.o setpriority.o setregid.o setreuid.o \ - setrlimit.o setsid.o setsockopt.o settimeofday.o setuid.o shmsys.o \ - shutdown.o sigaction.o sigstack.o socket.o socketpair.o stat.o \ - statfs.o swapon.o symlink.o sync.o truncate.o umask.o uname.o unlink.o \ - unmount.o utimes.o vadvise.o wait4.o write.o writev.o + rename.o revoke.o rmdir.o select.o semsys.o sendmsg.o sendto.o \ + setdomainname.o setegid.o seteuid.o setgid.o setgroups.o sethostid.o \ + sethostname.o setitimer.o setpgid.o setpriority.o setregid.o \ + setreuid.o setrlimit.o setsid.o setsockopt.o settimeofday.o setuid.o \ + shmsys.o shutdown.o sigaction.o sigstack.o socket.o socketpair.o \ + stat.o statfs.o swapon.o symlink.o sync.o sysarch.o truncate.o \ + umask.o uname.o unlink.o unmount.o utimes.o vadvise.o vm_allocate.o \ + vm_deallocate.o vm_inherit.o vm_protect.o wait4.o write.o writev.o -PSEUDO= _exit.o _getlogin.o PASM= ${ASM:.o=.po} +SASM= ${ASM:.o=.so} + +PSEUDO= _exit.o _getlogin.o PPSEUDO= ${PSEUDO:.o=.po} +SPSEUDO= ${PSEUDO:.o=.so} OBJS+= ${ASM} ${PSEUDO} POBJS+= ${PASM} ${PPSEUDO} +SOBJS+= ${SASM} ${SPSEUDO} ${ASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h @echo creating ${.PREFIX}.o @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \ ${CPP} ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.o - @${LD} -x -r ${.PREFIX}.o - @mv a.out ${.PREFIX}.o +# @${LD} -x -r ${.PREFIX}.o +# @mv a.out ${.PREFIX}.o ${PASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h @echo creating ${.PREFIX}.po @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \ ${CPP} -DPROF ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.po - @${LD} -x -r ${.PREFIX}.po - @mv a.out ${.PREFIX}.po +# @${LD} -x -r ${.PREFIX}.po +# @mv a.out ${.PREFIX}.po + +${SASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h + @echo creating ${.TARGET} + @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \ + ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.TARGET} ${PSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h @echo creating ${.PREFIX}.o @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \ ${CPP} ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.o - @${LD} -x -r ${.PREFIX}.o - @mv a.out ${.PREFIX}.o +# @${LD} -x -r ${.PREFIX}.o +# @mv a.out ${.PREFIX}.o ${PPSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h @echo creating ${.PREFIX}.po @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \ ${CPP} -DPROF ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.po - @${LD} -x -r ${.PREFIX}.po - @mv a.out ${.PREFIX}.po +# @${LD} -x -r ${.PREFIX}.po +# @mv a.out ${.PREFIX}.po + +${SPSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h + @echo creating ${.TARGET} + @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \ + ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.TARGET} MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/async_daemon.2 \ sys/bind.2 sys/brk.2 sys/chdir.2 sys/chflags.2 sys/chmod.2 sys/chown.2 \ @@ -81,12 +96,12 @@ MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/async_daemon.2 \ sys/msync.2 sys/munmap.2 sys/nfssvc.2 sys/open.2 sys/pipe.2 \ sys/quotactl.2 sys/read.2 sys/readlink.2 sys/reboot.2 sys/recv.2 \ sys/rename.2 sys/rmdir.2 sys/select.2 sys/send.2 sys/setgroups.2 \ - sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/shutdown.2 \ - sys/sigaction.2 sys/sigprocmask.2 sys/sigreturn.2 sys/sigstack.2 \ - sys/sigsuspend.2 sys/socket.2 sys/socketpair.2 sys/stat.2 \ - sys/statfs.2 sys/swapon.2 sys/symlink.2 sys/sync.2 sys/syscall.2 \ - sys/truncate.2 sys/umask.2 sys/uname.2 sys/unlink.2 sys/utimes.2 \ - sys/vfork.2 sys/wait.2 sys/write.2 + sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/setsid.2 \ + sys/shutdown.2 sys/sigaction.2 sys/sigprocmask.2 sys/sigreturn.2 \ + sys/sigstack.2 sys/sigsuspend.2 sys/socket.2 sys/socketpair.2 \ + sys/stat.2 sys/statfs.2 sys/swapon.2 sys/symlink.2 sys/sync.2 \ + sys/syscall.2 sys/truncate.2 sys/umask.2 sys/uname.2 sys/unlink.2 \ + sys/utimes.2 sys/vfork.2 sys/wait.2 sys/write.2 MLINKS+=brk.2 sbrk.2 MLINKS+=dup.2 dup2.2 @@ -112,6 +127,7 @@ MLINKS+=mount.2 unmount.2 MLINKS+=read.2 readv.2 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2 MLINKS+=send.2 sendmsg.2 send.2 sendto.2 +MLINKS+=setpgid.2 setpgrp.2 MLINKS+=stat.2 fstat.2 stat.2 lstat.2 MLINKS+=statfs.2 fstatfs.2 MLINKS+=truncate.2 ftruncate.2 diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2 index 6a0feb356069..5f257776166d 100644 --- a/lib/libc/sys/accept.2 +++ b/lib/libc/sys/accept.2 @@ -110,7 +110,7 @@ can be thought of as merely dequeueing the next connection request and not implying confirmation. Confirmation can be implied by a normal read or write on the new -file desciptor, and rejection can be implied by closing the +file descriptor, and rejection can be implied by closing the new socket. .Pp One can obtain user connection request data without confirming diff --git a/lib/libc/sys/acct.2 b/lib/libc/sys/acct.2 index 0a36e7be149c..42cb1eb7c83c 100644 --- a/lib/libc/sys/acct.2 +++ b/lib/libc/sys/acct.2 @@ -112,4 +112,5 @@ An I/O error occurred while reading from or writing to the file system. .Sh HISTORY An .Nm -function call appeared in Version 7 AT&T UNIX. +function call appeared in +.At v7 . diff --git a/lib/libc/sys/brk.2 b/lib/libc/sys/brk.2 index 79cf8cd74c51..d580b6aea757 100644 --- a/lib/libc/sys/brk.2 +++ b/lib/libc/sys/brk.2 @@ -40,10 +40,10 @@ .Nd change data segment size .Sh SYNOPSIS .Fd #include <sys/types.h> -.Ft char -.Fn *brk "const char *addr" +.Ft int +.Fn brk "const char *addr" .Ft char * -.Fn *sbrk "int incr" +.Fn sbrk "int incr" .Sh DESCRIPTION .Bf -symbolic The brk and sbrk functions are historical curiosities @@ -107,8 +107,7 @@ returns 0 if successful; -1 if the process requests more memory than than allowed by the system limit. The .Nm sbrk -function returns 0 if successful, otherwise the error -.Er EOPNOTSUPP +function returns the old break value if successful, otherwise a -1 is returned. .\" .Sh ERRORS .\" .Xr Sbrk @@ -141,4 +140,5 @@ the data segment without consulting .Sh HISTORY A .Nm -function call appeared in Version 7 AT&T UNIX. +function call appeared in +.At v7 . diff --git a/lib/libc/sys/chown.2 b/lib/libc/sys/chown.2 index 257e1d09b2ba..4eca4f5248f9 100644 --- a/lib/libc/sys/chown.2 +++ b/lib/libc/sys/chown.2 @@ -65,7 +65,7 @@ capability is restricted to the super-user. .Fn Chown clears the set-user-id and set-group-id bits on the file -to prevent accidental or mischievious creation of +to prevent accidental or mischievous creation of set-user-id and set-group-id programs. .Pp .Fn Fchown diff --git a/lib/libc/sys/close.2 b/lib/libc/sys/close.2 index 8400214dbac3..16ca1dc3725d 100644 --- a/lib/libc/sys/close.2 +++ b/lib/libc/sys/close.2 @@ -64,7 +64,7 @@ all associated file descriptors are freed, but since there is a limit on active descriptors per processes, the .Fn close function call -is useful when a large quanitity of file descriptors are being handled. +is useful when a large quantity of file descriptors are being handled. .Pp When a process forks (see .Xr fork 2 ) , @@ -103,7 +103,7 @@ will fail if: .Fa D is not an active descriptor. .It Bq Er EINTR -An interupt was received. +An interrupt was received. .El .Sh SEE ALSO .Xr accept 2 , diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2 index 63cda1443b46..726de1f88448 100644 --- a/lib/libc/sys/execve.2 +++ b/lib/libc/sys/execve.2 @@ -29,18 +29,19 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)execve.2 6.9 (Berkeley) 3/10/91 +.\" From: @(#)execve.2 6.9 (Berkeley) 3/10/91 +.\" $Id: execve.2,v 1.2.2.1 1994/05/01 16:06:05 jkh Exp $ .\" -.Dd March 10, 1991 +.Dd March 16, 1994 .Dt EXECVE 2 -.Os BSD 4 +.Os .Sh NAME .Nm execve .Nd execute a file .Sh SYNOPSIS .Fd #include <unistd.h> .Ft int -.Fn execve "const char *path" "const * char *argv" "const * char *envp" +.Fn execve "const char *path" "char *const *argv" "char *const *envp" .Sh DESCRIPTION .Fn Execve transforms the calling process into a new process. @@ -134,6 +135,15 @@ of the new process image file. The real user ID, real group ID and supplementary group IDs of the new process image remain the same as the calling process image. +In either case, the +.Dv SUGID +process flag bit is set, and remains set until +cleared by another call to +.Nm +which does not execute a set-id executable. This flag can be inspected +by the +.Xr ps 1 +utility. .Pp The new process also inherits the following attributes from the calling process: @@ -224,10 +234,10 @@ is allowed by the imposed maximum .It Bq Er E2BIG The number of bytes in the new process's argument list is larger than the system-imposed limit. -The limit in the system as released is 20480 bytes -.Pf ( Dv NCARGS +The limit in the system as released is 32768 bytes +.Pf ( Dv ARG_MAX in -.Ao Pa sys/param.h Ac ) . +.Ao Pa limits.h Ac ) . .It Bq Er EFAULT The new process file is not as long as indicated by the size values in its header. @@ -250,6 +260,7 @@ the real is ``root'', then the program has some of the powers of a super-user as well. .Sh SEE ALSO +.Xr ps 1 , .Xr exit 2 , .Xr fork 2 , .Xr execl 3 , diff --git a/lib/libc/sys/fork.2 b/lib/libc/sys/fork.2 index 8c16ae7eda11..8b4419a4612c 100644 --- a/lib/libc/sys/fork.2 +++ b/lib/libc/sys/fork.2 @@ -104,4 +104,5 @@ There is insufficient swap space for the new process. .Sh HISTORY A .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2 index ceab2b6abe11..8f075a80af2f 100644 --- a/lib/libc/sys/getsockopt.2 +++ b/lib/libc/sys/getsockopt.2 @@ -207,7 +207,7 @@ to the appropriate network interface according to the network portion of the destination address. .Pp .Dv SO_LINGER -controls the action taken when unsent messags +controls the action taken when unsent messages are queued on socket and a .Xr close 2 is performed. diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2 index a05db39f4bc3..ca29ec5333b8 100644 --- a/lib/libc/sys/intro.2 +++ b/lib/libc/sys/intro.2 @@ -93,7 +93,7 @@ or .Dv SIGQUIT ) was caught by the process during the execution of an interruptible function. If the signal handler performs a normal return, the -interupted function call will seem to have returned the error condition. +interrupted function call will seem to have returned the error condition. .It Er 5 EIO Em "Input/output error" . Some physical input or output error occurred. This error not be reported until a subsequent operation on the same file @@ -376,7 +376,7 @@ which is now unavailable as referenced by the file descriptor. This may indicate the file was deleted on the .Tn NFS server or some -other catastrophic event occured. +other catastrophic event occurred. .It Er 72 EBADRPC Em "RPC struct is bad" . Exchange of .Tn RPC diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2 index a90d0b8e9380..9e16641afe89 100644 --- a/lib/libc/sys/ioctl.2 +++ b/lib/libc/sys/ioctl.2 @@ -103,4 +103,5 @@ is not valid. .Sh HISTORY An .Nm -function call appeared in Version 7 AT&T UNIX. +function call appeared in +.At v7 . diff --git a/lib/libc/sys/kill.2 b/lib/libc/sys/kill.2 index bdb553d96eb6..4f16c45c226d 100644 --- a/lib/libc/sys/kill.2 +++ b/lib/libc/sys/kill.2 @@ -62,7 +62,7 @@ This can be used to check the validity of For a process to have permission to send a signal to a process designated by .Fa pid , -the real or effective user ID of the receving process must match +the real or effective user ID of the receiving process must match that of the sending process or the user must have appropriate privileges (such as given by a set-user-ID program or the user is the super-user). A single exception is the signal SIGCONT, which may always be sent diff --git a/lib/libc/sys/ktrace.2 b/lib/libc/sys/ktrace.2 new file mode 100644 index 000000000000..81d5b95f3bf2 --- /dev/null +++ b/lib/libc/sys/ktrace.2 @@ -0,0 +1,66 @@ +.\" Copyright (c) 1983 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. +.\" +.\" @(#)ktrace.2 1.0 (Berkeley) 1/4/94 +.\" +.Dd Jan 4, 1994 +.Dt KTRACE 2 +.Os BSD 4.3 +.Sh NAME +.Nm ktrace +.Nd kernel call trace +.Sh SYNOPSIS +.Fd #include <sys/ktrace.h> +.Ft int +.Fn ktrace "const char *file" "int op" "int flag" "pid_t pid" +.Sh DESCRIPTION +.Fn Ktrace +enables kernel trace logging for the specified processes. +Kernel trace data is logged to the file +.Pa file . +The kernel operations that are traced include system calls, namei +translations, signal processing, and +.Tn I/O . + +needs to be written. +.Sh RETURN VALUES +needs to be written. +.Sh ERRORS +.Fn Ktrace +will fail if: +.Bl -tag -width Er +.It Bq Er EACCESS +.It Bq Er EPERM +.It Bq Er EINVAL +.It Bq Er ESRCH +The pid doesn't exist. +.Sh SEE ALSO +.Xr ktrace 1 diff --git a/lib/libc/sys/lseek.2 b/lib/libc/sys/lseek.2 index f6d8e88425c1..53db4c32da4a 100644 --- a/lib/libc/sys/lseek.2 +++ b/lib/libc/sys/lseek.2 @@ -92,7 +92,7 @@ The function allows the file offset to be set beyond the end of the existing end-of-file of the file. If data is later written at this point, subsequent reads of the data in the gap return -bytes of zeros (until data is actualy written into the gap). +bytes of zeros (until data is actually written into the gap). .Pp Some devices are incapable of seeking. The value of the pointer associated with such a device is undefined. @@ -100,7 +100,7 @@ associated with such a device is undefined. Upon successful completion, .Fn lseek returns the resulting offset location as measured in bytes from the -begining of the file. +beginning of the file. Otherwise, a value of -1 is returned and .Va errno diff --git a/lib/libc/sys/mknod.2 b/lib/libc/sys/mknod.2 index edd5926863ce..da8e870ea188 100644 --- a/lib/libc/sys/mknod.2 +++ b/lib/libc/sys/mknod.2 @@ -124,4 +124,5 @@ points outside the process's allocated address space. .Sh HISTORY A .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/mount.2 b/lib/libc/sys/mount.2 index d830f5f8b924..1c32a25957cf 100644 --- a/lib/libc/sys/mount.2 +++ b/lib/libc/sys/mount.2 @@ -314,4 +314,5 @@ Some of the error codes need translation to more obvious messages. .Fn Mount and .Fn umount -function calls appeared in Version 6 AT&T UNIX. +function calls appeared in +.At v6 . diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2 index 21160c688b1a..b2234a37cc2d 100644 --- a/lib/libc/sys/open.2 +++ b/lib/libc/sys/open.2 @@ -251,4 +251,5 @@ An attempt was made to open a socket (not currently implemented). .Sh HISTORY An .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2 index a34cd34ee817..8844fe5caf90 100644 --- a/lib/libc/sys/pipe.2 +++ b/lib/libc/sys/pipe.2 @@ -112,4 +112,5 @@ space. .Sh HISTORY A .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/read.2 b/lib/libc/sys/read.2 index e96a27329242..9bea77c73f76 100644 --- a/lib/libc/sys/read.2 +++ b/lib/libc/sys/read.2 @@ -185,4 +185,4 @@ A .Nm read function call appeared in -Version 6 AT&T UNIX. +.At v6 . diff --git a/lib/libc/sys/setpgid.2 b/lib/libc/sys/setpgid.2 index cdf4fcca418c..8d2592de1025 100644 --- a/lib/libc/sys/setpgid.2 +++ b/lib/libc/sys/setpgid.2 @@ -32,7 +32,7 @@ .\" @(#)setpgid.2 6.3 (Berkeley) 3/10/91 .\" .Dd March 10, 1991 -.Dt SETPGRP 2 +.Dt SETPGID 2 .Os BSD 4 .Sh NAME .Nm setpgid , diff --git a/lib/libc/sys/setregid.2 b/lib/libc/sys/setregid.2 index 70a368ee5172..86b0aa7949be 100644 --- a/lib/libc/sys/setregid.2 +++ b/lib/libc/sys/setregid.2 @@ -29,11 +29,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)setregid.2 6.4 (Berkeley) 3/10/91 +.\" From: @(#)setregid.2 6.4 (Berkeley) 3/10/91 +.\" $Id: setregid.2,v 1.1.1.1.2.1 1994/05/01 16:06:13 jkh Exp $ .\" -.Dd March 10, 1991 +.Dd March 16, 1994 .Dt SETREGID 2 -.Os BSD 4.2 +.Os .Sh NAME .Nm setregid .Nd set real and effective group ID @@ -42,15 +43,42 @@ .Ft int .Fn setregid "int rgid" "int egid" .Sh DESCRIPTION -The real and effective group ID's of the current process -are set to the arguments. -Unprivileged users may change the real group -ID to the effective group ID and vice-versa; only the super-user may -make other changes. +NB: In +.Fx 1.0.2 +and earlier versions, this function would set the real and effective +group ID's of the current process according to the arguments. In +.Fx 1.1 , +we have adopted the behavior of +.Bx 4.4 . .Pp -Supplying a value of -1 for either the real or effective -group ID forces the system to substitute the current -ID in place of the -1 parameter. +The +.Nm +function is normally used by programs which wish to temporarily +renounce special privileges they have gained (usually as a result of +being set-gid executables), by swapping real and effective +group ID's, so that the renunciation is reversible. +This can result in a security hole, and does not integrate well with +the +.Tn POSIX +saved group ID. In +.Fx 1.1 , +the +.Nm +function will never actually set the real group ID; however, it will +check its value to ensure that a future +.Xr setegid 2 +call with the +.Fa rgid +argument will succeed. +.Pp +If +.Fa rgid +or +.Fa egid +is -1, the current ID is filled in by the system. +The effective group ID is set, if requested, as if +.Xr setegid 2 +had been called. .Sh RETURN VALUES Upon successful completion, a value of 0 is returned. Otherwise, a value of -1 is returned and diff --git a/lib/libc/sys/setreuid.2 b/lib/libc/sys/setreuid.2 index 061141ef278a..de34b029ab57 100644 --- a/lib/libc/sys/setreuid.2 +++ b/lib/libc/sys/setreuid.2 @@ -29,11 +29,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)setreuid.2 6.4 (Berkeley) 3/10/91 +.\" From: @(#)setreuid.2 6.4 (Berkeley) 3/10/91 +.\" $Id: setreuid.2,v 1.1.1.1.2.1 1994/05/01 16:06:14 jkh Exp $ .\" -.Dd March 10, 1991 +.Dd March 16, 1994 .Dt SETREUID 2 -.Os BSD 4 +.Os .Sh NAME .Nm setreuid .Nd set real and effective user ID's @@ -42,16 +43,42 @@ .Ft int .Fn setreuid "int ruid" "int euid" .Sh DESCRIPTION -The real and effective user ID's of the -current process are set according to the arguments. +Note: In +.Fx 1.0.2 +and earlier versions, this function would set the real and effective +user ID's of the current process according to the arguments. In +.Fx 1.1 +we have adopted the behavior of +.Bx 4.4 . +.Pp +The +.Nm +function is normally used by programs which wish to temporarily +renounce special privileges they have gained (usually as a result of +being set-uid executables), by swapping real and effective +user ID's, so that the renunciation is reversible. +This can result in a security hole, and does not integrate well with +the +.Tn POSIX +saved user ID. In +.Fx 1.1 , +the +.Nm +function will never actually set the real user ID; however, it will +check its value to ensure that a future +.Xr seteuid 2 +call with the +.Fa ruid +argument will succeed. +.Pp If .Fa ruid or .Fa euid -is -1, the current uid is filled in by the system. -Unprivileged users may change the real user -ID to the effective user ID and vice-versa; only the super-user may -make other changes. +is -1, the current ID is filled in by the system. +The effective user ID is set, if requested, as if +.Xr seteuid 2 +had been called. .Sh RETURN VALUES Upon successful completion, a value of 0 is returned. Otherwise, a value of -1 is returned and diff --git a/lib/libc/sys/setsid.2 b/lib/libc/sys/setsid.2 new file mode 100644 index 000000000000..b4ff4db9a961 --- /dev/null +++ b/lib/libc/sys/setsid.2 @@ -0,0 +1,67 @@ +.\" Copyright (c) 1994 Christoph M. Robitschko +.\" 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 Christoph M. Robitschko +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software withough specific prior written permission +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.Dd January 28, 1994 +.Dt SETSID 2 +.Os FreeBSD +.Sh NAME +.Nm setsid +.Nd create session and set process group ID +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Ft pid_t +.Fn setsid +.Sh DESCRIPTION +If the calling process is not a process group leader, the +.Fn setsid +function creates a new session and a new process group. +The calling process is the session leader and process group leader, and +has no controlling terminal. +The ID of the process group is set to the process ID of the calling process. +The calling process is the only member of the new session and of the new +process group. +.Sh RETURN VALUES +.Fn Setsid +returns the value of the new process group ID when the operation was successful. +If the request failed, -1 is returned and the global variable +.Va errno +indicates the reason. +.Sh ERRORS +.Fn Setsid +will fail if: +.Bl -tag -width indent +.It Bq Er EPERM +The calling process is already a process group leader, or the process group ID +of another process matches the process ID of the calling process. +.El +.Sh SEE ALSO +.Xr getpid 2 , +.Xr setpgid 2 +.Sh STANDARDS +.Fn Setpgid +conforms to IEEE Std 1003.1-1988 +.Pq Dq Tn POSIX . diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2 index 13c2c5020e58..635512126614 100644 --- a/lib/libc/sys/sigaction.2 +++ b/lib/libc/sys/sigaction.2 @@ -49,7 +49,7 @@ struct sigaction { .Fn sigaction "int sig" "struct sigaction *act" "struct sigaction *oact" .Sh DESCRIPTION The system defines a set of signals that may be delivered to a process. -Signal delivery resembles the occurence of a hardware interrupt: +Signal delivery resembles the occurrence of a hardware interrupt: the signal is blocked from further occurrence, the current process context is saved, and a new one is built. A process may specify a .Em handler diff --git a/lib/libc/sys/sigsuspend.2 b/lib/libc/sys/sigsuspend.2 index f4167dc9784b..8e0c73001c10 100644 --- a/lib/libc/sys/sigsuspend.2 +++ b/lib/libc/sys/sigsuspend.2 @@ -36,7 +36,7 @@ .Os .Sh NAME .Nm sigsuspend -.Nd atomically release blocked signals and wait for interrupt +.Nd automatically release blocked signals and wait for interrupt .Sh SYNOPSIS .Fd #include <sys/signal.h> .Ft int diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2 index 48427b4a9459..6738badd82d1 100644 --- a/lib/libc/sys/socket.2 +++ b/lib/libc/sys/socket.2 @@ -56,11 +56,11 @@ These families are defined in the include file The currently understood formats are .Pp .Bd -literal -offset indent -compact -AF_UNIX (UNIX internal protocols), +AF_UNIX (operating-system internal protocols), AF_INET (ARPA Internet protocols), AF_ISO (ISO protocols), AF_NS (Xerox Network Systems protocols), and -AF_IMPLINK (IMP \*(lqhost at IMP\*(rq link layer). +AF_CCITT (ITU-T X.25 protocols). .Ed .Pp The socket has the indicated diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2 index 8509716aef41..b99b79e46123 100644 --- a/lib/libc/sys/stat.2 +++ b/lib/libc/sys/stat.2 @@ -55,7 +55,7 @@ function obtains information about the file pointed to by .Fa path . Read, write or execute permission of the named file is not required, but all directories -listed in the path name leading to the file must be seachable. +listed in the path name leading to the file must be searchable. .Pp .Fn Lstat is like @@ -91,7 +91,7 @@ struct stat { dev_t st_dev; /* device inode resides on */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ - nlink_t st_nlink; /* number or hard links to the file */ + nlink_t st_nlink; /* number of hard links to the file */ uid_t st_uid; /* user-id of owner */ gid_t st_gid; /* group-id of owner */ dev_t st_rdev; /* device type, for special file inode */ diff --git a/lib/libc/sys/statfs.2 b/lib/libc/sys/statfs.2 index 8a870878e250..4433e56152f9 100644 --- a/lib/libc/sys/statfs.2 +++ b/lib/libc/sys/statfs.2 @@ -79,7 +79,10 @@ char f_mntfromname[MNAMELEN]; /* mounted filesystem */ #define MOUNT_UFS 1 #define MOUNT_NFS 2 #define MOUNT_MFS 3 -#define MOUNT_PC 4 +#define MOUNT_MSDOS 4 +#define MOUNT_ISOFS 5 +#define MOUNT_PROCFS 6 +#define MOUNT_DEVFS 7 .Ed .Pp Fields that are undefined for a particular file system are set to -1. diff --git a/lib/libc/sys/sync.2 b/lib/libc/sys/sync.2 index dd945e528415..02be22148dbd 100644 --- a/lib/libc/sys/sync.2 +++ b/lib/libc/sys/sync.2 @@ -70,4 +70,5 @@ may return before the buffers are completely flushed. .Sh HISTORY A .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/uname.2 b/lib/libc/sys/uname.2 index 4097375188ed..bb4c7edcd41f 100644 --- a/lib/libc/sys/uname.2 +++ b/lib/libc/sys/uname.2 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)uname.2 6.6 (Berkeley) 3/10/91 -.\" $Id: uname.2,v 1.1 1993/10/08 01:06:55 jkh Exp $ +.\" $Id: uname.2,v 1.2 1994/02/03 00:51:14 wollman Exp $ .\" .Dd March 29, 1993 .Dt UNAME 2 @@ -43,8 +43,10 @@ .Ft int .Fn uname "struct utsname *name" .Sh DESCRIPTION -.Fn Uname -returns the information identifying the current UNIX system +The +.Fn uname +function +returns the information identifying the current operating system in the structure pointed to by .Fa name. .Pp @@ -62,25 +64,33 @@ struct utsname { }; .Ed .Pp -.Fn Uname +The +.Fn uname +function returns a null-terminated character string naming the -current UNIX system in the character array +current operating system in the character array .Fa sysname . Similarly, .Fa nodename contains the name that the system is known by on a communication network. -.Fa Release +The +.Fa release and .Fa version +fields further identify the operating system. -.Fa Machine +The +.Fa machine +field contains the standard name that identifies the hardware -that the UNIX system is running on. +that the operating system is running on. .Sn ERRORS .Bl -tag -width ENAMETOOLONGAA .It Bq Er EFAULT -.Fn Uname +The +.Fn uname +function will fail if .Fa name points to an invalid address. @@ -97,4 +107,4 @@ is set to indicate the error. The .Nm uname function call appeared in -System V.2 AT&T UNIX. +.At V.2 . diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2 index 304b284c1935..668c2814086b 100644 --- a/lib/libc/sys/unlink.2 +++ b/lib/libc/sys/unlink.2 @@ -108,4 +108,5 @@ points outside the process's allocated address space. .Sh HISTORY An .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/wait.2 b/lib/libc/sys/wait.2 index b5a2a7cd11c5..004872f9b2ab 100644 --- a/lib/libc/sys/wait.2 +++ b/lib/libc/sys/wait.2 @@ -39,7 +39,7 @@ .Nm waitpid , .Nm wait4 , .Nm wait3 -.Nd wait for process terminatation +.Nd wait for process termination .Sh SYNOPSIS .Fd #include <sys/types.h> .Fd #include <sys/wait.h> @@ -72,7 +72,7 @@ The .Fn wait4 call provides a more general interface for programs that need to wait for certain child processes, -that need resource utilization statistics accummulated by child processes, +that need resource utilization statistics accumulated by child processes, or that require options. The other wait functions are implemented using .Fn wait4 . @@ -292,4 +292,5 @@ call are extensions to the POSIX interface. .Sh HISTORY A .Nm -function call appeared in Version 6 AT&T UNIX. +function call appeared in +.At v6 . diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2 index f7d1f0533917..4b00e3d21079 100644 --- a/lib/libc/sys/write.2 +++ b/lib/libc/sys/write.2 @@ -200,4 +200,4 @@ A .Nm write function call appeared in -Version 6 AT&T UNIX. +.At v6 . diff --git a/lib/libc/yp/Makefile.inc b/lib/libc/yp/Makefile.inc new file mode 100644 index 000000000000..c3d565f5a35f --- /dev/null +++ b/lib/libc/yp/Makefile.inc @@ -0,0 +1,8 @@ +# from: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91 +# $Id: Makefile.inc,v 1.1 1993/11/01 23:56:27 paul Exp $ + +# yp sources +.PATH: ${.CURDIR}/arch/${MACHINE}/yp ${.CURDIR}/yp + +SRCS+= xdryp.c yplib.c + diff --git a/lib/libc/yp/xdryp.c b/lib/libc/yp/xdryp.c new file mode 100644 index 000000000000..ba2d8d0749c0 --- /dev/null +++ b/lib/libc/yp/xdryp.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LINT +static char *rcsid = "$Id: xdryp.c,v 1.1 1993/11/01 23:56:28 paul Exp $"; +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <ctype.h> +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> + +extern int (*ypresp_allfn)(); +extern void *ypresp_data; + +struct ypresp_all { + bool_t more; + union { + struct ypresp_key_val val; + } ypresp_all_u; +}; + +bool_t +xdr_domainname(xdrs, objp) +XDR *xdrs; +char *objp; +{ + if (!xdr_string(xdrs, &objp, YPMAXDOMAIN)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_peername(xdrs, objp) +XDR *xdrs; +char *objp; +{ + if (!xdr_string(xdrs, &objp, YPMAXPEER)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_datum(xdrs, objp) +XDR *xdrs; +datum *objp; +{ + if (!xdr_bytes(xdrs, (char **)&objp->dptr, (u_int *)&objp->dsize, YPMAXRECORD)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_mapname(xdrs, objp) +XDR *xdrs; +char *objp; +{ + if (!xdr_string(xdrs, &objp, YPMAXMAP)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypreq_key(xdrs, objp) +XDR *xdrs; +struct ypreq_key *objp; +{ + if (!xdr_domainname(xdrs, objp->domain)) { + return (FALSE); + } + if (!xdr_mapname(xdrs, objp->map)) { + return (FALSE); + } + if (!xdr_datum(xdrs, &objp->keydat)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypreq_nokey(xdrs, objp) +XDR *xdrs; +struct ypreq_nokey *objp; +{ + if (!xdr_domainname(xdrs, objp->domain)) { + return (FALSE); + } + if (!xdr_mapname(xdrs, objp->map)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_yp_inaddr(xdrs, objp) +XDR *xdrs; +struct in_addr *objp; +{ + if (!xdr_opaque(xdrs, (caddr_t)&objp->s_addr, sizeof objp->s_addr)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypbind_binding(xdrs, objp) +XDR *xdrs; +struct ypbind_binding *objp; +{ + if (!xdr_yp_inaddr(xdrs, &objp->ypbind_binding_addr)) { + return (FALSE); + } + if (!xdr_opaque(xdrs, (void *)&objp->ypbind_binding_port, + sizeof objp->ypbind_binding_port)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypbind_resptype(xdrs, objp) +XDR *xdrs; +enum ypbind_resptype *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypstat(xdrs, objp) +XDR *xdrs; +enum ypbind_resptype *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypbind_resp(xdrs, objp) +XDR *xdrs; +struct ypbind_resp *objp; +{ + if (!xdr_ypbind_resptype(xdrs, &objp->ypbind_status)) { + return (FALSE); + } + switch (objp->ypbind_status) { + case YPBIND_FAIL_VAL: + if (!xdr_u_int(xdrs, (u_int *)&objp->ypbind_respbody.ypbind_error)) { + return (FALSE); + } + break; + case YPBIND_SUCC_VAL: + if (!xdr_ypbind_binding(xdrs, &objp->ypbind_respbody.ypbind_bindinfo)) { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_val(xdrs, objp) +XDR *xdrs; +struct ypresp_val *objp; +{ + if (!xdr_ypstat(xdrs, &objp->status)) { + return (FALSE); + } + if (!xdr_datum(xdrs, &objp->valdat)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypbind_setdom(xdrs, objp) +XDR *xdrs; +struct ypbind_setdom *objp; +{ + if (!xdr_domainname(xdrs, objp->ypsetdom_domain)) { + return (FALSE); + } + if (!xdr_ypbind_binding(xdrs, &objp->ypsetdom_binding)) { + return (FALSE); + } + if (!xdr_u_short(xdrs, &objp->ypsetdom_vers)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_key_val(xdrs, objp) +XDR *xdrs; +struct ypresp_key_val *objp; +{ + if (!xdr_ypstat(xdrs, &objp->status)) { + return (FALSE); + } + if (!xdr_datum(xdrs, &objp->valdat)) { + return (FALSE); + } + if (!xdr_datum(xdrs, &objp->keydat)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_all(xdrs, objp) +XDR *xdrs; +struct ypresp_all *objp; +{ + if (!xdr_bool(xdrs, &objp->more)) { + return (FALSE); + } + switch (objp->more) { + case TRUE: + if (!xdr_ypresp_key_val(xdrs, &objp->ypresp_all_u.val)) { + return (FALSE); + } + break; + case FALSE: + break; + default: + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_all_seq(xdrs, objp) +XDR *xdrs; +u_long *objp; +{ + struct ypresp_all out; + u_long status; + char *key, *val; + int r; + + bzero(&out, sizeof out); + while(1) { + if( !xdr_ypresp_all(xdrs, &out)) { + xdr_free(xdr_ypresp_all, (char *)&out); + *objp = YP_YPERR; + return FALSE; + } + if(out.more == 0) { + xdr_free(xdr_ypresp_all, (char *)&out); + return FALSE; + } + status = out.ypresp_all_u.val.status; + switch(status) { + case YP_TRUE: + key = (char *)malloc(out.ypresp_all_u.val.keydat.dsize + 1); + bcopy(out.ypresp_all_u.val.keydat.dptr, key, + out.ypresp_all_u.val.keydat.dsize); + key[out.ypresp_all_u.val.keydat.dsize] = '\0'; + val = (char *)malloc(out.ypresp_all_u.val.valdat.dsize + 1); + bcopy(out.ypresp_all_u.val.valdat.dptr, val, + out.ypresp_all_u.val.valdat.dsize); + val[out.ypresp_all_u.val.valdat.dsize] = '\0'; + xdr_free(xdr_ypresp_all, (char *)&out); + + r = (*ypresp_allfn)(status, + key, out.ypresp_all_u.val.keydat.dsize, + val, out.ypresp_all_u.val.valdat.dsize, + ypresp_data); + *objp = status; + free(key); + free(val); + if(r) + return TRUE; + break; + case YP_NOMORE: + xdr_free(xdr_ypresp_all, (char *)&out); + return TRUE; + default: + xdr_free(xdr_ypresp_all, (char *)&out); + *objp = status; + return TRUE; + } + } +} + +bool_t +xdr_ypresp_master(xdrs, objp) +XDR *xdrs; +struct ypresp_master *objp; +{ + if (!xdr_ypstat(xdrs, &objp->status)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->master, YPMAXPEER)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypmaplist_str(xdrs, objp) +XDR *xdrs; +char *objp; +{ + if (!xdr_string(xdrs, &objp, YPMAXMAP+1)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypmaplist(xdrs, objp) +XDR *xdrs; +struct ypmaplist *objp; +{ + if (!xdr_ypmaplist_str(xdrs, objp->ypml_name)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (caddr_t *)&objp->ypml_next, + sizeof(struct ypmaplist), xdr_ypmaplist)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_maplist(xdrs, objp) +XDR *xdrs; +struct ypresp_maplist *objp; +{ + if (!xdr_ypstat(xdrs, &objp->status)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (caddr_t *)&objp->list, + sizeof(struct ypmaplist), xdr_ypmaplist)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ypresp_order(xdrs, objp) +XDR *xdrs; +struct ypresp_order *objp; +{ + if (!xdr_ypstat(xdrs, &objp->status)) { + return (FALSE); + } + if (!xdr_u_long(xdrs, &objp->ordernum)) { + return (FALSE); + } + return (TRUE); +} diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c new file mode 100644 index 000000000000..57f1df09cc96 --- /dev/null +++ b/lib/libc/yp/yplib.c @@ -0,0 +1,794 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LINT +static char *rcsid = "$Id: yplib.c,v 1.2 1994/01/11 19:01:09 nate Exp $"; +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/file.h> +#include <sys/uio.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> + +#ifndef BINDINGDIR +#define BINDINGDIR "/var/yp/binding" +#endif +#define YPMATCHCACHE + +extern bool_t xdr_domainname(), xdr_ypbind_resp(); +extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); +extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val(); +extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq(); +extern bool_t xdr_ypresp_master(); + +int (*ypresp_allfn)(); +void *ypresp_data; + +struct dom_binding *_ypbindlist; +static char _yp_domain[MAXHOSTNAMELEN]; +int _yplib_timeout = 10; + +#ifdef YPMATCHCACHE +int _yplib_cache = 5; + +static struct ypmatch_ent { + struct ypmatch_ent *next; + char *map, *key, *val; + int keylen, vallen; + time_t expire_t; +} *ypmc; + +static void +ypmatch_add(map, key, keylen, val, vallen) +char *map; +char *key; +int keylen; +char *val; +int vallen; +{ + struct ypmatch_ent *ep; + time_t t; + + time(&t); + + for(ep=ypmc; ep; ep=ep->next) + if(ep->expire_t < t) + break; + if(ep==NULL) { + ep = (struct ypmatch_ent *)malloc(sizeof *ep); + bzero((char *)ep, sizeof *ep); + if(ypmc) + ep->next = ypmc; + ypmc = ep; + } + + if(ep->key) + free(ep->key); + if(ep->val) + free(ep->val); + + ep->key = NULL; + ep->val = NULL; + + ep->key = (char *)malloc(keylen); + if(ep->key==NULL) + return; + + ep->val = (char *)malloc(vallen); + if(ep->key==NULL) { + free(ep->key); + ep->key = NULL; + return; + } + ep->keylen = keylen; + ep->vallen = vallen; + + bcopy(key, ep->key, ep->keylen); + bcopy(val, ep->val, ep->vallen); + + if(ep->map) { + if( strcmp(ep->map, map) ) { + free(ep->map); + ep->map = strdup(map); + } + } else { + ep->map = strdup(map); + } + + ep->expire_t = t + _yplib_cache; +} + +static bool_t +ypmatch_find(map, key, keylen, val, vallen) +char *map; +char *key; +int keylen; +char **val; +int *vallen; +{ + struct ypmatch_ent *ep; + time_t t; + + if(ypmc==NULL) + return 0; + + time(&t); + + for(ep=ypmc; ep; ep=ep->next) { + if(ep->keylen != keylen) + continue; + if(strcmp(ep->map, map)) + continue; + if(bcmp(ep->key, key, keylen)) + continue; + if(t > ep->expire_t) + continue; + + *val = ep->val; + *vallen = ep->vallen; + return 1; + } + return 0; +} +#endif + +int +_yp_dobind(dom, ypdb) +char *dom; +struct dom_binding **ypdb; +{ + static int pid = -1; + char path[MAXPATHLEN]; + struct dom_binding *ysd, *ysd2; + struct ypbind_resp ypbr; + struct timeval tv; + struct sockaddr_in clnt_sin; + int clnt_sock, fd, gpid; + CLIENT *client; + int new=0, r; + + gpid = getpid(); + if( !(pid==-1 || pid==gpid) ) { + ysd = _ypbindlist; + while(ysd) { + if(ysd->dom_client) + clnt_destroy(ysd->dom_client); + ysd2 = ysd->dom_pnext; + free(ysd); + ysd = ysd2; + } + _ypbindlist = NULL; + } + pid = gpid; + + if(ypdb!=NULL) + *ypdb = NULL; + + if(dom==NULL || strlen(dom)==0) + return YPERR_BADARGS; + + for(ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext) + if( strcmp(dom, ysd->dom_domain) == 0) + break; + if(ysd==NULL) { + ysd = (struct dom_binding *)malloc(sizeof *ysd); + bzero((char *)ysd, sizeof *ysd); + ysd->dom_socket = -1; + ysd->dom_vers = 0; + new = 1; + } +again: +#ifdef BINDINGDIR + if(ysd->dom_vers==0) { + sprintf(path, "%s/%s.%d", BINDINGDIR, dom, 2); + if( (fd=open(path, O_RDONLY)) == -1) { + /* no binding file, YP is dead. */ + if(new) + free(ysd); + return YPERR_YPBIND; + } + if( flock(fd, LOCK_EX|LOCK_NB) == -1 && errno==EWOULDBLOCK) { + struct iovec iov[2]; + struct ypbind_resp ybr; + u_short ypb_port; + + iov[0].iov_base = (caddr_t)&ypb_port; + iov[0].iov_len = sizeof ypb_port; + iov[1].iov_base = (caddr_t)&ybr; + iov[1].iov_len = sizeof ybr; + + r = readv(fd, iov, 2); + if(r != iov[0].iov_len + iov[1].iov_len) { + close(fd); + ysd->dom_vers = -1; + goto again; + } + + bzero(&ysd->dom_server_addr, sizeof ysd->dom_server_addr); + ysd->dom_server_addr.sin_family = AF_INET; + ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in); + ysd->dom_server_addr.sin_addr = + ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr; + ysd->dom_server_addr.sin_port = + ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; + + ysd->dom_server_port = ysd->dom_server_addr.sin_port; + close(fd); + goto gotit; + } else { + /* no lock on binding file, YP is dead. */ + close(fd); + if(new) + free(ysd); + return YPERR_YPBIND; + } + } +#endif + if(ysd->dom_vers==-1 || ysd->dom_vers==0) { + bzero((char *)&clnt_sin, sizeof clnt_sin); + clnt_sin.sin_family = AF_INET; + clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + clnt_sock = RPC_ANYSOCK; + client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock, + 0, 0); + if(client==NULL) { + clnt_pcreateerror("clnttcp_create"); + if(new) + free(ysd); + return YPERR_YPBIND; + } + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + r = clnt_call(client, YPBINDPROC_DOMAIN, + xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv); + if(r != RPC_SUCCESS) { + fprintf(stderr, + "YP: server for domain %s not responding, still trying\n", dom); + clnt_destroy(client); + ysd->dom_vers = -1; + goto again; + } + clnt_destroy(client); + + bzero((char *)&ysd->dom_server_addr, sizeof ysd->dom_server_addr); + ysd->dom_server_addr.sin_family = AF_INET; + ysd->dom_server_addr.sin_port = + ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; + ysd->dom_server_addr.sin_addr.s_addr = + ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr; + ysd->dom_server_port = + ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; +gotit: + ysd->dom_vers = YPVERS; + strcpy(ysd->dom_domain, dom); + } + + tv.tv_sec = _yplib_timeout/2; + tv.tv_usec = 0; + if(ysd->dom_client) + clnt_destroy(ysd->dom_client); + ysd->dom_socket = RPC_ANYSOCK; + ysd->dom_client = clntudp_create(&ysd->dom_server_addr, + YPPROG, YPVERS, tv, &ysd->dom_socket); + if(ysd->dom_client==NULL) { + clnt_pcreateerror("clntudp_create"); + ysd->dom_vers = -1; + goto again; + } + if( fcntl(ysd->dom_socket, F_SETFD, 1) == -1) + perror("fcntl: F_SETFD"); + + if(new) { + ysd->dom_pnext = _ypbindlist; + _ypbindlist = ysd; + } + + if(ypdb!=NULL) + *ypdb = ysd; + return 0; +} + +static void +_yp_unbind(ypb) +struct dom_binding *ypb; +{ + clnt_destroy(ypb->dom_client); + ypb->dom_client = NULL; + ypb->dom_socket = -1; +} + +int +yp_bind(dom) +char *dom; +{ + return _yp_dobind(dom, NULL); +} + +void +yp_unbind(dom) +char *dom; +{ + struct dom_binding *ypb, *ypbp; + + ypbp = NULL; + for(ypb=_ypbindlist; ypb; ypb=ypb->dom_pnext) { + if( strcmp(dom, ypb->dom_domain) == 0) { + clnt_destroy(ypb->dom_client); + if(ypbp) + ypbp->dom_pnext = ypb->dom_pnext; + else + _ypbindlist = ypb->dom_pnext; + free(ypb); + return; + } + ypbp = ypb; + } + return; +} + +int +yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen) +char *indomain; +char *inmap; +const char *inkey; +int inkeylen; +char **outval; +int *outvallen; +{ + struct dom_binding *ysd; + struct ypresp_val yprv; + struct timeval tv; + struct ypreq_key yprk; + int r; + + *outval = NULL; + *outvallen = 0; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + +#ifdef YPMATCHCACHE + if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey, + inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) { + *outvallen = yprv.valdat.dsize; + *outval = (char *)malloc(*outvallen+1); + bcopy(yprv.valdat.dptr, *outval, *outvallen); + (*outval)[*outvallen] = '\0'; + return 0; + } +#endif + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprk.domain = indomain; + yprk.map = inmap; + yprk.keydat.dptr = (char *)inkey; + yprk.keydat.dsize = inkeylen; + + bzero((char *)&yprv, sizeof yprv); + + r = clnt_call(ysd->dom_client, YPPROC_MATCH, + xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv); + if(r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_match: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if( !(r=ypprot_err(yprv.status)) ) { + *outvallen = yprv.valdat.dsize; + *outval = (char *)malloc(*outvallen+1); + bcopy(yprv.valdat.dptr, *outval, *outvallen); + (*outval)[*outvallen] = '\0'; +#ifdef YPMATCHCACHE + if( strcmp(_yp_domain, indomain)==0 ) + ypmatch_add(inmap, inkey, inkeylen, *outval, *outvallen); +#endif + } + xdr_free(xdr_ypresp_val, (char *)&yprv); + _yp_unbind(ysd); + return r; +} + +int +yp_get_default_domain(domp) +char **domp; +{ + *domp = NULL; + if(_yp_domain[0] == '\0') + if( getdomainname(_yp_domain, sizeof _yp_domain)) + return YPERR_NODOM; + *domp = _yp_domain; + return 0; +} + +int +yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen) +char *indomain; +char *inmap; +char **outkey; +int *outkeylen; +char **outval; +int *outvallen; +{ + struct ypresp_key_val yprkv; + struct ypreq_nokey yprnk; + struct dom_binding *ysd; + struct timeval tv; + int r; + + *outkey = *outval = NULL; + *outkeylen = *outvallen = 0; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = indomain; + yprnk.map = inmap; + bzero((char *)&yprkv, sizeof yprkv); + + r = clnt_call(ysd->dom_client, YPPROC_FIRST, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv); + if(r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_first: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if( !(r=ypprot_err(yprkv.status)) ) { + *outkeylen = yprkv.keydat.dsize; + *outkey = (char *)malloc(*outkeylen+1); + bcopy(yprkv.keydat.dptr, *outkey, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + *outvallen = yprkv.valdat.dsize; + *outval = (char *)malloc(*outvallen+1); + bcopy(yprkv.valdat.dptr, *outval, *outvallen); + (*outval)[*outvallen] = '\0'; + } + xdr_free(xdr_ypresp_key_val, (char *)&yprkv); + _yp_unbind(ysd); + return r; +} + +int +yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen) +char *indomain; +char *inmap; +char *inkey; +int inkeylen; +char **outkey; +int *outkeylen; +char **outval; +int *outvallen; +{ + struct ypresp_key_val yprkv; + struct ypreq_key yprk; + struct dom_binding *ysd; + struct timeval tv; + int r; + + *outkey = *outval = NULL; + *outkeylen = *outvallen = 0; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprk.domain = indomain; + yprk.map = inmap; + yprk.keydat.dptr = inkey; + yprk.keydat.dsize = inkeylen; + bzero((char *)&yprkv, sizeof yprkv); + + r = clnt_call(ysd->dom_client, YPPROC_NEXT, + xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv); + if(r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_next: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if( !(r=ypprot_err(yprkv.status)) ) { + *outkeylen = yprkv.keydat.dsize; + *outkey = (char *)malloc(*outkeylen+1); + bcopy(yprkv.keydat.dptr, *outkey, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + *outvallen = yprkv.valdat.dsize; + *outval = (char *)malloc(*outvallen+1); + bcopy(yprkv.valdat.dptr, *outval, *outvallen); + (*outval)[*outvallen] = '\0'; + } + xdr_free(xdr_ypresp_key_val, (char *)&yprkv); + _yp_unbind(ysd); + return r; +} + +int +yp_all(indomain, inmap, incallback) +char *indomain; +char *inmap; +struct ypall_callback *incallback; +{ + struct ypreq_nokey yprnk; + struct dom_binding *ysd; + struct timeval tv; + struct sockaddr_in clnt_sin; + CLIENT *clnt; + u_long status; + int clnt_sock; + + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + clnt_sock = RPC_ANYSOCK; + clnt_sin = ysd->dom_server_addr; + clnt_sin.sin_port = 0; + clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0); + if(clnt==NULL) { + printf("clnttcp_create failed\n"); + return YPERR_PMAP; + } + + yprnk.domain = indomain; + yprnk.map = inmap; + ypresp_allfn = incallback->foreach; + ypresp_data = (void *)incallback->data; + + (void) clnt_call(clnt, YPPROC_ALL, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv); + clnt_destroy(clnt); + xdr_free(xdr_ypresp_all_seq, (char *)&status); /* not really needed... */ + _yp_unbind(ysd); + + if(status != YP_FALSE) + return ypprot_err(status); + return 0; +} + +int +yp_order(indomain, inmap, outorder) +char *indomain; +char *inmap; +int *outorder; +{ + struct dom_binding *ysd; + struct ypresp_order ypro; + struct ypreq_nokey yprnk; + struct timeval tv; + int r; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = indomain; + yprnk.map = inmap; + + bzero((char *)(char *)&ypro, sizeof ypro); + + r = clnt_call(ysd->dom_client, YPPROC_ORDER, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv); + if(r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_order: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + + *outorder = ypro.ordernum; + xdr_free(xdr_ypresp_order, (char *)&ypro); + _yp_unbind(ysd); + return ypprot_err(ypro.status); +} + +int +yp_master(indomain, inmap, outname) +char *indomain; +char *inmap; +char **outname; +{ + struct dom_binding *ysd; + struct ypresp_master yprm; + struct ypreq_nokey yprnk; + struct timeval tv; + int r; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = indomain; + yprnk.map = inmap; + + bzero((char *)&yprm, sizeof yprm); + + r = clnt_call(ysd->dom_client, YPPROC_MASTER, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv); + if(r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_master: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if( !(r=ypprot_err(yprm.status)) ) { + *outname = (char *)strdup(yprm.master); + } + xdr_free(xdr_ypresp_master, (char *)&yprm); + _yp_unbind(ysd); + return r; +} + +yp_maplist(indomain, outmaplist) +char *indomain; +struct ypmaplist **outmaplist; +{ + struct dom_binding *ysd; + struct ypresp_maplist ypml; + struct timeval tv; + int r; + +again: + if( _yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + bzero((char *)&ypml, sizeof ypml); + + r = clnt_call(ysd->dom_client, YPPROC_MAPLIST, + xdr_domainname, indomain, xdr_ypresp_maplist, &ypml, tv); + if (r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_maplist: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + *outmaplist = ypml.list; + /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ + _yp_unbind(ysd); + return ypprot_err(ypml.status); +} + +char * +yperr_string(incode) +int incode; +{ + static char err[80]; + + switch(incode) { + case 0: + return "Success"; + case YPERR_BADARGS: + return "Request arguments bad"; + case YPERR_RPC: + return "RPC failure"; + case YPERR_DOMAIN: + return "Can't bind to server which serves this domain"; + case YPERR_MAP: + return "No such map in server's domain"; + case YPERR_KEY: + return "No such key in map"; + case YPERR_YPERR: + return "YP server error"; + case YPERR_RESRC: + return "Local resource allocation failure"; + case YPERR_NOMORE: + return "No more records in map database"; + case YPERR_PMAP: + return "Can't communicate with portmapper"; + case YPERR_YPBIND: + return "Can't communicate with ypbind"; + case YPERR_YPSERV: + return "Can't communicate with ypserv"; + case YPERR_NODOM: + return "Local domain name not set"; + case YPERR_BADDB: + return "Server data base is bad"; + case YPERR_VERS: + return "YP server version mismatch - server can't supply service."; + case YPERR_ACCESS: + return "Access violation"; + case YPERR_BUSY: + return "Database is busy"; + } + sprintf(err, "YP unknown error %d\n", incode); + return err; +} + +int +ypprot_err(incode) +unsigned int incode; +{ + switch(incode) { + case YP_TRUE: + return 0; + case YP_FALSE: + return YPERR_YPBIND; + case YP_NOMORE: + return YPERR_NOMORE; + case YP_NOMAP: + return YPERR_MAP; + case YP_NODOM: + return YPERR_NODOM; + case YP_NOKEY: + return YPERR_KEY; + case YP_BADOP: + return YPERR_YPERR; + case YP_BADDB: + return YPERR_BADDB; + case YP_YPERR: + return YPERR_YPERR; + case YP_BADARGS: + return YPERR_BADARGS; + case YP_VERS: + return YPERR_VERS; + } + return YPERR_YPERR; +} + +int +_yp_check(dom) +char **dom; +{ + int use_yp = 0; + char *unused; + + if( _yp_domain[0]=='\0' ) + if( yp_get_default_domain(&unused) ) + return 0; + + if(dom) + *dom = _yp_domain; + + if( yp_bind(_yp_domain)==0 ) + return 1; + return 0; +} diff --git a/lib/libcurses/Makefile b/lib/libcurses/Makefile index 1a1538da63e0..74baf7974571 100644 --- a/lib/libcurses/Makefile +++ b/lib/libcurses/Makefile @@ -1,16 +1,19 @@ -# @(#)Makefile 5.10 (Berkeley) 6/24/90 +# @(#)Makefile 8.2 (Berkeley) 1/2/94 LIB= curses -SRCS= addbytes.c addch.c addstr.c box.c clear.c clrtobot.c clrtoeol.c \ - cr_put.c cr_tty.c curses.c delch.c deleteln.c delwin.c endwin.c \ - erase.c fullname.c getch.c getstr.c idlok.c id_subwins.c initscr.c \ - insch.c insertln.c longname.c move.c mvprintw.c mvscanw.c mvwin.c \ - newwin.c overlay.c overwrite.c printw.c putchar.c refresh.c scanw.c \ - scroll.c toucholap.c standout.c touchwin.c tstp.c unctrl.c +SRCS= addbytes.c addch.c addnstr.c box.c clear.c clrtobot.c clrtoeol.c \ + cr_put.c ctrace.c cur_hash.c curses.c delch.c deleteln.c delwin.c \ + erase.c fullname.c getch.c getstr.c id_subwins.c idlok.c initscr.c \ + insch.c insertln.c longname.c move.c mvwin.c newwin.c overlay.c \ + overwrite.c printw.c putchar.c refresh.c scanw.c scroll.c setterm.c \ + standout.c toucholap.c touchwin.c tscroll.c tstp.c tty.c unctrl.c MAN3= curses.3 +CFLAGS+=-D_CURSES_PRIVATE -I${.CURDIR} + beforeinstall: - -cd ${.CURDIR}; cmp -s curses.h ${DESTDIR}/usr/include/curses.h || \ + -cd ${.CURDIR}; cmp -s curses.h ${DESTDIR}/usr/include/curses.h > \ + /dev/null 2>&1 || \ install -c -o ${BINOWN} -g ${BINGRP} -m 444 curses.h \ ${DESTDIR}/usr/include diff --git a/lib/libcurses/addbytes.c b/lib/libcurses/addbytes.c index 3d47b326acf4..dc754830636d 100644 --- a/lib/libcurses/addbytes.c +++ b/lib/libcurses/addbytes.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,117 +32,127 @@ */ #ifndef lint -static char sccsid[] = "@(#)addbytes.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)addbytes.c 8.2 (Berkeley) 1/9/94"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> -waddbytes(win, bytes, count) -reg WINDOW *win; -reg char *bytes; -int count; -{ - chtype c; - reg int i; - - for (i = 0; i < count; i++) { - c = (unsigned char) *bytes++; - if (_waddbytes(win, &c, 1) == ERR) - return ERR; - } - return OK; -} +#define SYNCH_IN {y = win->cury; x = win->curx;} +#define SYNCH_OUT {win->cury = y; win->curx = x;} /* - * This routine adds the character to the current position - * + * waddbytes -- + * Add the character to the current position in the given window. */ -_waddbytes(win, bytes, count) -reg WINDOW *win; -reg chtype *bytes; -reg int count; +int +__waddbytes(win, bytes, count, so) + register WINDOW *win; + register const char *bytes; + register int count; + int so; { -#define SYNCH_OUT() {win->_cury = y; win->_curx = x;} -#define SYNCH_IN() {y = win->_cury; x = win->_curx;} - reg int x, y; - reg int newx; + static char blanks[] = " "; + register int c, newx, x, y; + char stand; + __LINE *lp; - SYNCH_IN(); - while (count--) { - register chtype c; - static chtype blanks[] = {' ',' ',' ',' ',' ',' ',' ',' '}; + SYNCH_IN; - c = *bytes++; - switch (c) { - case '\t': - SYNCH_OUT(); - if (_waddbytes(win, blanks, 8-(x%8)) == ERR) { - return ERR; - } - SYNCH_IN(); - break; +#ifdef DEBUG + __CTRACE("ADDBYTES('%c') at (%d, %d)\n", c, y, x); +#endif + while (count--) { + c = *bytes++; + switch (c) { + case '\t': + SYNCH_OUT; + if (waddbytes(win, blanks, 8 - (x % 8)) == ERR) + return (ERR); + SYNCH_IN; + break; - default: -# ifdef FULLDEBUG - fprintf(outf, "ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n", y, x, win->_firstch[y], win->_lastch[y]); -# endif - if (win->_flags & _STANDOUT) - c |= _STANDOUT; - { -# ifdef FULLDEBUG - fprintf(outf, "ADDBYTES(%0.2o, %d, %d)\n", win, y, x); -# endif - if (win->_y[y][x] != c) { - newx = x + win->_ch_off; - if (win->_firstch[y] == _NOCHANGE) { - win->_firstch[y] = - win->_lastch[y] = newx; - } else if (newx < win->_firstch[y]) - win->_firstch[y] = newx; - else if (newx > win->_lastch[y]) - win->_lastch[y] = newx; -# ifdef FULLDEBUG - fprintf(outf, "ADDBYTES: change gives f/l: %d/%d [%d/%d]\n", - win->_firstch[y], win->_lastch[y], - win->_firstch[y] - win->_ch_off, - win->_lastch[y] - win->_ch_off); -# endif - } - } - win->_y[y][x++] = c; - if (x >= win->_maxx) { - x = 0; - newline: - if (++y >= win->_maxy) - if (win->_scroll) { - --y; - SYNCH_OUT(); - scroll(win); - SYNCH_IN(); - } - else - return ERR; - } -# ifdef FULLDEBUG - fprintf(outf, "ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n", y, x, win->_firstch[y], win->_lastch[y]); -# endif - break; - case '\n': - SYNCH_OUT(); - wclrtoeol(win); - SYNCH_IN(); - if (!NONL) - x = 0; - goto newline; - case '\r': - x = 0; - break; - case '\b': - if (--x < 0) - x = 0; - break; - } - } - SYNCH_OUT(); - return OK; + default: +#ifdef DEBUG + __CTRACE("ADDBYTES(%0.2o, %d, %d)\n", win, y, x); +#endif + + lp = win->lines[y]; + if (lp->flags & __ISPASTEOL) { + lp->flags &= ~__ISPASTEOL; +newline: if (y == win->maxy - 1) { + if (win->flags & __SCROLLOK) { + SYNCH_OUT; + scroll(win); + SYNCH_IN; + lp = win->lines[y]; + x = 0; + } + else + return ERR; + } else { + y++; + lp = win->lines[y]; + x = 0; + } + if (c == '\n') + break; + } + + stand = '\0'; + if (win->flags & __WSTANDOUT || so) + stand |= __STANDOUT; +#ifdef DEBUG + __CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n", + y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp); +#endif + if (lp->line[x].ch != c || + !(lp->line[x].attr & stand)) { + newx = x + win->ch_off; + if (!(lp->flags & __ISDIRTY)) { + lp->flags |= __ISDIRTY; + *lp->firstchp = *lp->lastchp = newx; + } + else if (newx < *lp->firstchp) + *lp->firstchp = newx; + else if (newx > *lp->lastchp) + *lp->lastchp = newx; +#ifdef DEBUG + __CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n", + *lp->firstchp, *lp->lastchp, + *lp->firstchp - win->ch_off, + *lp->lastchp - win->ch_off); +#endif + } + lp->line[x].ch = c; + if (stand) + lp->line[x].attr |= __STANDOUT; + else + lp->line[x].attr &= ~__STANDOUT; + if (x == win->maxx - 1) + lp->flags |= __ISPASTEOL; + else + x++; +#ifdef DEBUG + __CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n", + y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp); +#endif + break; + case '\n': + SYNCH_OUT; + wclrtoeol(win); + SYNCH_IN; + if (!NONL) + x = 0; + goto newline; + case '\r': + x = 0; + break; + case '\b': + if (--x < 0) + x = 0; + break; + } + } + SYNCH_OUT; + return (OK); } diff --git a/lib/libcurses/addch.c b/lib/libcurses/addch.c index 027c4bf94476..d1408c21fe92 100644 --- a/lib/libcurses/addch.c +++ b/lib/libcurses/addch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,19 +32,31 @@ */ #ifndef lint -static char sccsid[] = "@(#)addch.c 5.5 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)addch.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine adds the character to the current position + * waddch -- + * Add the character to the current position in the given window. * */ -waddch(win, c) -WINDOW *win; -char c; +int +waddch(WINDOW *win, char ch) { - chtype ch = (unsigned char) c; - return _waddbytes(win, &ch, 1); + __LDATA buf; + + buf.ch = ch; + buf.attr = 0; + return (__waddch(win, &buf)); +} + +int +__waddch(WINDOW *win, __LDATA *dp) +{ + char buf[2]; + + buf[0] = dp->ch; + return (__waddbytes(win, buf, 1, dp->attr & __STANDOUT)); } diff --git a/lib/libcurses/endwin.c b/lib/libcurses/addnstr.c index aa740e6135bf..bf607a07a1f0 100644 --- a/lib/libcurses/endwin.c +++ b/lib/libcurses/addnstr.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,26 +32,30 @@ */ #ifndef lint -static char sccsid[] = "@(#)endwin.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)addnstr.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include <curses.h> +#include <string.h> /* - * Clean things up before exiting - * + * waddnstr -- + * Add a string (at most n characters) to the given window + * starting at (_cury, _curx). If n is negative, add the + * entire string. */ - -# include "curses.ext" - -endwin() +int +waddnstr(win, s, n) + WINDOW *win; + const char *s; + int n; { - resetty(); - _puts(VE); - _puts(TE); - if (curscr) { - if (curscr->_flags & _STANDOUT) { - _puts(SE); - curscr->_flags &= ~_STANDOUT; - } - _endwin = TRUE; - } + size_t len; + const char *p; + + if (n > 0) + for (p = s, len = 0; n-- && *p++; ++len); + else + len = strlen(s); + return (waddbytes(win, s, len)); } diff --git a/lib/libcurses/box.c b/lib/libcurses/box.c index 983ed66621ca..4f165b330692 100644 --- a/lib/libcurses/box.c +++ b/lib/libcurses/box.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,34 +32,45 @@ */ #ifndef lint -static char sccsid[] = "@(#)box.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)box.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine draws a box around the given window with "vert" - * as the vertical delimiting char, and "hor", as the horizontal one. - * + * box -- + * Draw a box around the given window with "vert" as the vertical + * delimiting char, and "hor", as the horizontal one. */ -box(win, vert, hor) -reg WINDOW *win; -char vert, hor; { - - reg int i; - reg int endy, endx; - reg chtype *fp, *lp; +int +box(register WINDOW *win, char vert, char hor) +{ + register int endy, endx, i; + register __LDATA *fp, *lp; - endx = win->_maxx; - endy = win->_maxy - 1; - fp = win->_y[0]; - lp = win->_y[endy]; - for (i = 0; i < endx; i++) - fp[i] = lp[i] = (unsigned char) hor; + endx = win->maxx; + endy = win->maxy - 1; + fp = win->lines[0]->line; + lp = win->lines[endy]->line; + for (i = 0; i < endx; i++) { + fp[i].ch = lp[i].ch = hor; + fp[i].attr &= ~__STANDOUT; + lp[i].attr &= ~__STANDOUT; + } endx--; - for (i = 0; i <= endy; i++) - win->_y[i][0] = (win->_y[i][endx] = (unsigned char) vert); - if (!win->_scroll && (win->_flags&_SCROLLWIN)) - fp[0] = fp[endx] = lp[0] = lp[endx] = ' '; - touchwin(win); + for (i = 0; i <= endy; i++) { + win->lines[i]->line[0].ch = vert; + win->lines[i]->line[endx].ch = vert; + win->lines[i]->line[0].attr &= ~__STANDOUT; + win->lines[i]->line[endx].attr &= ~__STANDOUT; + } + if (!(win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN)) { + fp[0].ch = fp[endx].ch = lp[0].ch = lp[endx].ch = ' '; + fp[0].attr &= ~__STANDOUT; + fp[endx].attr &= ~__STANDOUT; + lp[0].attr &= ~__STANDOUT; + lp[endx].attr &= ~__STANDOUT; + } + __touchwin(win); + return (OK); } diff --git a/lib/libcurses/clear.c b/lib/libcurses/clear.c index a5884cbc4b11..89891e234975 100644 --- a/lib/libcurses/clear.c +++ b/lib/libcurses/clear.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,19 +32,22 @@ */ #ifndef lint -static char sccsid[] = "@(#)clear.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)clear.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine clears the window. - * + * wclear -- + * Clear the window. */ +int wclear(win) -reg WINDOW *win; { - - werase(win); - win->_clear = TRUE; - return OK; + register WINDOW *win; +{ + if (werase(win) == OK) { + win->flags |= __CLEAROK; + return (OK); + } + return (ERR); } diff --git a/lib/libcurses/clrtobot.c b/lib/libcurses/clrtobot.c index 86324389956f..0e73ef88eb85 100644 --- a/lib/libcurses/clrtobot.c +++ b/lib/libcurses/clrtobot.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,35 +32,44 @@ */ #ifndef lint -static char sccsid[] = "@(#)clrtobot.c 5.5 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)clrtobot.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine erases everything on the window. - * + * wclrtobot -- + * Erase everything on the window. */ +int wclrtobot(win) -reg WINDOW *win; { - - reg int y; - reg chtype *sp, *end, *maxx; - reg int startx, minx; + register WINDOW *win; +{ + register int minx, startx, starty, y; + register __LDATA *sp, *end, *maxx; - startx = win->_curx; - for (y = win->_cury; y < win->_maxy; y++) { - minx = _NOCHANGE; - end = &win->_y[y][win->_maxx]; - for (sp = &win->_y[y][startx]; sp < end; sp++) - if (*sp != ' ') { + if (win->lines[win->cury]->flags & __ISPASTEOL) { + starty = win->cury + 1; + startx = 0; + } else { + starty = win->cury; + startx = win->curx; + } + for (y = starty; y < win->maxy; y++) { + minx = -1; + end = &win->lines[y]->line[win->maxx]; + for (sp = &win->lines[y]->line[startx]; sp < end; sp++) + if (sp->ch != ' ' || sp->attr != 0) { maxx = sp; - if (minx == _NOCHANGE) - minx = sp - win->_y[y]; - *sp = ' '; + if (minx == -1) + minx = sp - win->lines[y]->line; + sp->ch = ' '; + sp->attr = 0; } - if (minx != _NOCHANGE) - touchline(win, y, minx, maxx - &win->_y[y][0]); + if (minx != -1) + __touchline(win, y, minx, maxx - win->lines[y]->line, + 0); startx = 0; } + return (OK); } diff --git a/lib/libcurses/clrtoeol.c b/lib/libcurses/clrtoeol.c index 6af2bfcededf..6fa63b420615 100644 --- a/lib/libcurses/clrtoeol.c +++ b/lib/libcurses/clrtoeol.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,40 +32,52 @@ */ #ifndef lint -static char sccsid[] = "@(#)clrtoeol.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)clrtoeol.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine clears up to the end of line - * + * wclrtoeol -- + * Clear up to the end of line. */ +int wclrtoeol(win) -reg WINDOW *win; { - - reg chtype *sp, *end; - reg int y, x; - reg chtype *maxx; - reg int minx; + register WINDOW *win; +{ + register int minx, x, y; + register __LDATA *end, *maxx, *sp; - y = win->_cury; - x = win->_curx; - end = &win->_y[y][win->_maxx]; - minx = _NOCHANGE; - maxx = &win->_y[y][x]; + y = win->cury; + x = win->curx; + if (win->lines[y]->flags & __ISPASTEOL) { + if (y < win->maxy - 1) { + y++; + x = 0; + } else + return (OK); + } + end = &win->lines[y]->line[win->maxx]; + minx = -1; + maxx = &win->lines[y]->line[x]; for (sp = maxx; sp < end; sp++) - if (*sp != ' ') { + if (sp->ch != ' ' || sp->attr != 0) { maxx = sp; - if (minx == _NOCHANGE) - minx = sp - win->_y[y]; - *sp = ' '; + if (minx == -1) + minx = sp - win->lines[y]->line; + sp->ch = ' '; + sp->attr = 0; } - /* - * update firstch and lastch for the line - */ - touchline(win, y, win->_curx, win->_maxx - 1); -# ifdef DEBUG - fprintf(outf, "CLRTOEOL: minx = %d, maxx = %d, firstch = %d, lastch = %d\n", minx, maxx - win->_y[y], win->_firstch[y], win->_lastch[y]); -# endif +#ifdef DEBUG + __CTRACE("CLRTOEOL: minx = %d, maxx = %d, firstch = %d, lastch = %d\n", + minx, maxx - win->lines[y]->line, *win->lines[y]->firstchp, + *win->lines[y]->lastchp); +#endif + /* Update firstch and lastch for the line. */ + return (__touchline(win, y, x, win->maxx - 1, 0)); } + + + + + diff --git a/lib/libcurses/cr_put.c b/lib/libcurses/cr_put.c index c9d0e79134f1..b50875c91211 100644 --- a/lib/libcurses/cr_put.c +++ b/lib/libcurses/cr_put.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,51 +32,62 @@ */ #ifndef lint -static char sccsid[] = "@(#)cr_put.c 5.5 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)cr_put.c 8.2 (Berkeley) 1/9/94"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <string.h> -# define HARDTABS 8 - -extern char *tgoto(); -int plodput(); +#define HARDTABS 8 /* - * Terminal driving and line formatting routines. - * Basic motion optimizations are done here as well - * as formatting of lines (printing of control characters, + * Terminal driving and line formatting routines. Basic motion optimizations + * are done here as well as formatting lines (printing of control characters, * line numbering and the like). */ -/* - * Sync the position of the output cursor. - * Most work here is rounding for terminal boundaries getting the - * column position implied by wraparound or the lack thereof and - * rolling up the screen to get destline on the screen. - */ - -static int outcol, outline, destcol, destline; +/* Stub function for the users. */ +int +mvcur(ly, lx, y, x) + int ly, lx, y, x; +{ + return (__mvcur(ly, lx, y, x, 0)); +} -WINDOW *_win; +static void fgoto __P((int)); +static int plod __P((int, int)); +static void plodput __P((int)); +static int tabcol __P((int, int)); -mvcur(ly, lx, y, x) -int ly, lx, y, x; { +static int outcol, outline, destcol, destline; +/* + * Sync the position of the output cursor. Most work here is rounding for + * terminal boundaries getting the column position implied by wraparound or + * the lack thereof and rolling up the screen to get destline on the screen. + */ +int +__mvcur(ly, lx, y, x, in_refresh) + int ly, lx, y, x, in_refresh; +{ #ifdef DEBUG - fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x); + __CTRACE("mvcur: moving cursor from (%d, %d) to (%d, %d)\n", + ly, lx, y, x); #endif destcol = x; destline = y; outcol = lx; outline = ly; - fgoto(); -} - -fgoto() + fgoto(in_refresh); + return (OK); +} + +static void +fgoto(in_refresh) + int in_refresh; { - reg char *cgp; - reg int l, c; + register int c, l; + register char *cgp; if (destcol >= COLS) { destline += destcol / COLS; @@ -88,15 +99,15 @@ fgoto() outcol %= COLS; if (AM == 0) { while (l > 0) { - if (_pfast) + if (__pfast) if (CR) - _puts(CR); + tputs(CR, 0, __cputchar); else - _putchar('\r'); + putchar('\r'); if (NL) - _puts(NL); + tputs(NL, 0, __cputchar); else - _putchar('\n'); + putchar('\n'); l--; } outcol = 0; @@ -111,36 +122,35 @@ fgoto() destline = LINES - 1; if (outline < LINES - 1) { c = destcol; - if (_pfast == 0 && !CA) + if (__pfast == 0 && !CA) destcol = 0; - fgoto(); + fgoto(in_refresh); destcol = c; } while (l >= LINES) { - /* - * The following linefeed (or simulation thereof) - * is supposed to scroll up the screen, since we - * are on the bottom line. We make the assumption - * that linefeed will scroll. If ns is in the - * capability list this won't work. We should - * probably have an sc capability but sf will - * generally take the place if it works. - * - * Superbee glitch: in the middle of the screen we - * have to use esc B (down) because linefeed screws up - * in "Efficient Paging" (what a joke) mode (which is - * essential in some SB's because CRLF mode puts garbage - * in at end of memory), but you must use linefeed to - * scroll since down arrow won't go past memory end. - * I turned this off after recieving Paul Eggert's - * Superbee description which wins better. + /* The following linefeed (or simulation thereof) is + * supposed to scroll up the screen, since we are on + * the bottom line. We make the assumption that + * linefeed will scroll. If ns is in the capability + * list this won't work. We should probably have an + * sc capability but sf will generally take the place + * if it works. + * + * Superbee glitch: in the middle of the screen have + * to use esc B (down) because linefeed screws up in + * "Efficient Paging" (what a joke) mode (which is + * essential in some SB's because CRLF mode puts + * garbage in at end of memory), but you must use + * linefeed to scroll since down arrow won't go past + * memory end. I turned this off after recieving Paul + * Eggert's Superbee description which wins better. */ - if (NL /* && !XB */ && _pfast) - _puts(NL); + if (NL /* && !XB */ && __pfast) + tputs(NL, 0, __cputchar); else - _putchar('\n'); + putchar('\n'); l--; - if (_pfast == 0) + if (__pfast == 0) outcol = 0; } } @@ -148,17 +158,20 @@ fgoto() destline = outline; if (CA) { cgp = tgoto(CM, destcol, destline); - if (plod(strlen(cgp)) > 0) - plod(0); - else - tputs(cgp, 0, _putchar); - } - else - plod(0); + + /* + * Need this condition due to inconsistent behavior + * of backspace on the last column. + */ + if (outcol != COLS - 1 && plod(strlen(cgp), in_refresh) > 0) + plod(0, in_refresh); + else + tputs(cgp, 0, __cputchar); + } else + plod(0, in_refresh); outline = destline; outcol = destcol; } - /* * Move (slowly) to destination. * Hard thing here is using home cursor on really deficient terminals. @@ -168,63 +181,63 @@ fgoto() static int plodcnt, plodflg; +static void plodput(c) + int c; { if (plodflg) - plodcnt--; + --plodcnt; else - _putchar(c); + putchar(c); } -plod(cnt) +static int +plod(cnt, in_refresh) + int cnt, in_refresh; { - register int i, j, k; - register int soutcol, soutline; - chtype ch; + register int i, j, k, soutcol, soutline; plodcnt = plodflg = cnt; soutcol = outcol; soutline = outline; /* - * Consider homing and moving down/right from there, vs moving + * Consider homing and moving down/right from there, vs. moving * directly with local motions to the right spot. */ if (HO) { /* - * i is the cost to home and tab/space to the right to - * get to the proper column. This assumes ND space costs - * 1 char. So i+destcol is cost of motion with home. + * i is the cost to home and tab/space to the right to get to + * the proper column. This assumes ND space costs 1 char. So + * i + destcol is cost of motion with home. */ if (GT) i = (destcol / HARDTABS) + (destcol % HARDTABS); else i = destcol; - /* - * j is cost to move locally without homing - */ + + /* j is cost to move locally without homing. */ if (destcol >= outcol) { /* if motion is to the right */ j = destcol / HARDTABS - outcol / HARDTABS; if (GT && j) j += destcol % HARDTABS; else j = destcol - outcol; - } - else + } else /* leftward motion only works if we can backspace. */ if (outcol - destcol <= i && (BS || BC)) - i = j = outcol - destcol; /* cheaper to backspace */ + /* Cheaper to backspace. */ + i = j = outcol - destcol; else - j = i + 1; /* impossibly expensive */ + /* Impossibly expensive. */ + j = i + 1; - /* k is the absolute value of vertical distance */ + /* k is the absolute value of vertical distance. */ k = outline - destline; if (k < 0) k = -k; j += k; - /* - * Decision. We may not have a choice if no UP. - */ + /* Decision. We may not have a choice if no UP. */ if (i + destline < j || (!UP && destline < outline)) { /* * Cheaper to home. Do it now and pretend it's a @@ -232,32 +245,29 @@ plod(cnt) */ tputs(HO, 0, plodput); outcol = outline = 0; - } - else if (LL) { + } else if (LL) { /* * Quickly consider homing down and moving from there. * Assume cost of LL is 2. */ k = (LINES - 1) - destline; - if (i + k + 2 < j && (k<=0 || UP)) { + if (i + k + 2 < j && (k <= 0 || UP)) { tputs(LL, 0, plodput); outcol = 0; outline = LINES - 1; } } - } - else - /* - * No home and no up means it's impossible. - */ + } else + /* No home and no up means it's impossible. */ if (!UP && destline < outline) - return -1; + return (-1); if (GT) i = destcol % HARDTABS + destcol / HARDTABS; else i = destcol; -/* - if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) { +#ifdef notdef + if (BT && outcol > destcol && + (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) { j *= (k = strlen(BT)); if ((k += (destcol&7)) > 4) j += 8 - (destcol&7); @@ -265,28 +275,31 @@ plod(cnt) j += k; } else -*/ +#endif j = outcol - destcol; + /* - * If we will later need a \n which will turn into a \r\n by - * the system or the terminal, then don't bother to try to \r. + * If we will later need a \n which will turn into a \r\n by the + * system or the terminal, then don't bother to try to \r. */ - if ((NONL || !_pfast) && outline < destline) + if ((NONL || !__pfast) && outline < destline) goto dontcr; + /* - * If the terminal will do a \r\n and there isn't room for it, - * then we can't afford a \r. + * If the terminal will do a \r\n and there isn't room for it, then + * we can't afford a \r. */ if (NC && outline >= destline) goto dontcr; + /* - * If it will be cheaper, or if we can't back up, then send - * a return preliminarily. + * If it will be cheaper, or if we can't back up, then send a return + * preliminarily. */ if (j > i + 1 || outcol > destcol && !BS && !BC) { /* - * BUG: this doesn't take the (possibly long) length - * of CR into account. + * BUG: this doesn't take the (possibly long) length of CR + * into account. */ if (CR) tputs(CR, 0, plodput); @@ -301,8 +314,8 @@ plod(cnt) } outcol = 0; } -dontcr: - while (outline < destline) { + +dontcr: while (outline < destline) { outline++; if (NL) tputs(NL, 0, plodput); @@ -310,7 +323,7 @@ dontcr: plodput('\n'); if (plodcnt < 0) goto out; - if (NONL || _pfast == 0) + if (NONL || __pfast == 0) outcol = 0; } if (BT) @@ -318,14 +331,14 @@ dontcr: while (outcol > destcol) { if (plodcnt < 0) goto out; -/* +#ifdef notdef if (BT && outcol - destcol > k + 4) { tputs(BT, 0, plodput); outcol--; outcol &= ~7; continue; } -*/ +#endif outcol--; if (BC) tputs(BC, 0, plodput); @@ -366,36 +379,36 @@ dontcr: } while (outcol < destcol) { /* - * move one char to the right. We don't use ND space - * because it's better to just print the char we are - * moving over. + * Move one char to the right. We don't use ND space because + * it's better to just print the char we are moving over. */ - if (_win != NULL) - if (plodflg) /* avoid a complex calculation */ + if (in_refresh) + if (plodflg) /* Avoid a complex calculation. */ plodcnt--; else { - ch = curscr->_y[outline][outcol]; - if ((ch&_STANDOUT) == (curscr->_flags&_STANDOUT)) - _putchar(ch); + i = curscr->lines[outline]->line[outcol].ch; + if ((curscr->lines[outline]->line[outcol].attr + & __STANDOUT) == + (curscr->flags & __WSTANDOUT)) + putchar(i); else goto nondes; } else -nondes: - if (ND) - tputs(ND, 0, plodput); - else - plodput(' '); +nondes: if (ND) + tputs(ND, 0, plodput); + else + plodput(' '); outcol++; if (plodcnt < 0) goto out; } -out: - if (plodflg) { + +out: if (plodflg) { outcol = soutcol; outline = soutline; } - return(plodcnt); + return (plodcnt); } /* @@ -403,16 +416,16 @@ out: * hitting a tab, where tabs are set every ts columns. Work right for * the case where col > COLS, even if ts does not divide COLS. */ +static int tabcol(col, ts) -int col, ts; + int col, ts; { - int offset, result; + int offset; if (col >= COLS) { offset = COLS * (col / COLS); col -= offset; - } - else + } else offset = 0; - return col + ts - (col % ts) + offset; + return (col + ts - (col % ts) + offset); } diff --git a/lib/libcurses/cr_tty.c b/lib/libcurses/cr_tty.c deleted file mode 100644 index c67b0765ce2b..000000000000 --- a/lib/libcurses/cr_tty.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 1981 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)cr_tty.c 5.8 (Berkeley) 6/1/90"; -#endif /* not lint */ - -/* - * Terminal initialization routines. - * - */ - -# include "curses.ext" - -static bool *sflags[] = { - &AM, &BS, &DA, &DB, &EO, &HC, &HZ, &IN, &MI, - &MS, &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, - &XX - }; - -static char *_PC, - **sstrs[] = { - &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, - &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, - &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, - &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, - &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, - &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, - &VB, &VS, &VE, &AL_PARM, &DL_PARM, &UP_PARM, - &DOWN_PARM, &LEFT_PARM, &RIGHT_PARM, - }; - -extern char *tgoto(); - -char _tspace[2048]; /* Space for capability strings */ - -static char *aoftspace; /* Address of _tspace for relocation */ - -static int destcol, destline; - -/* - * This routine does terminal type initialization routines, and - * calculation of flags at entry. It is almost entirely stolen from - * Bill Joy's ex version 2.6. - */ -short ospeed = -1; - -gettmode() { - - if (ioctl(_tty_ch, TIOCGETP, &_tty) < 0) - return; - savetty(); - if (ioctl(_tty_ch, TIOCSETP, &_tty) < 0) - _tty.sg_flags = _res_flg; - ospeed = _tty.sg_ospeed; - _res_flg = _tty.sg_flags; - UPPERCASE = (_tty.sg_flags & LCASE) != 0; - GT = ((_tty.sg_flags & XTABS) == 0); - NONL = ((_tty.sg_flags & CRMOD) == 0); - _tty.sg_flags &= ~XTABS; - ioctl(_tty_ch, TIOCSETP, &_tty); -# ifdef DEBUG - fprintf(outf, "GETTMODE: UPPERCASE = %s\n", UPPERCASE ? "TRUE":"FALSE"); - fprintf(outf, "GETTMODE: GT = %s\n", GT ? "TRUE" : "FALSE"); - fprintf(outf, "GETTMODE: NONL = %s\n", NONL ? "TRUE" : "FALSE"); - fprintf(outf, "GETTMODE: ospeed = %d\n", ospeed); -# endif -} - -setterm(type) -reg char *type; { - - reg int unknown; - static char genbuf[1024]; -# ifdef TIOCGWINSZ - struct winsize win; -# endif - -# ifdef DEBUG - fprintf(outf, "SETTERM(\"%s\")\n", type); - fprintf(outf, "SETTERM: LINES = %d, COLS = %d\n", LINES, COLS); -# endif - if (type[0] == '\0') - type = "xx"; - unknown = FALSE; - if (tgetent(genbuf, type) != 1) { - unknown++; - strcpy(genbuf, "xx|dumb:"); - } -# ifdef DEBUG - fprintf(outf, "SETTERM: tty = %s\n", type); -# endif -# ifdef TIOCGWINSZ - if (ioctl(_tty_ch, TIOCGWINSZ, &win) >= 0) { - if (LINES == 0) - LINES = win.ws_row; - if (COLS == 0) - COLS = win.ws_col; - } -# endif - - if (LINES == 0) - LINES = tgetnum("li"); - if (LINES <= 5) - LINES = 24; - - if (COLS == 0) - COLS = tgetnum("co"); - if (COLS <= 4) - COLS = 80; - -# ifdef DEBUG - fprintf(outf, "SETTERM: LINES = %d, COLS = %d\n", LINES, COLS); -# endif - aoftspace = _tspace; - zap(); /* get terminal description */ - - /* - * Handle funny termcap capabilities - */ - if (CS && SC && RC) AL=DL=""; - if (AL_PARM && AL==NULL) AL=""; - if (DL_PARM && DL==NULL) DL=""; - if (IC && IM==NULL) IM=""; - if (IC && EI==NULL) EI=""; - if (!GT) BT=NULL; /* If we can't tab, we can't backtab either */ - - if (tgoto(CM, destcol, destline)[0] == 'O') - CA = FALSE, CM = 0; - else - CA = TRUE; - - PC = _PC ? _PC[0] : FALSE; - aoftspace = _tspace; - { - /* xtype should be the same size as genbuf for longname(). */ - static char xtype[1024]; - - (void)strcpy(xtype,type); - strncpy(ttytype, longname(genbuf, xtype), sizeof(ttytype) - 1); - } - ttytype[sizeof(ttytype) - 1] = '\0'; - if (unknown) - return ERR; - return OK; -} - -/* - * This routine gets all the terminal flags from the termcap database - */ - -zap() -{ - register char *namp; - register bool **fp; - register char ***sp; -#ifdef DEBUG - register char *cp; -#endif - extern char *tgetstr(); - - namp = "ambsdadbeohchzinmimsncnsosulxbxnxtxsxx"; - fp = sflags; - do { - *(*fp++) = tgetflag(namp); -#ifdef DEBUG - fprintf(outf, "%2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); -#endif - namp += 2; - } while (*namp); - namp = "albcbtcdceclcmcrcsdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscsesfsosrtatetiucueupusvbvsveALDLUPDOLERI"; - sp = sstrs; - do { - *(*sp++) = tgetstr(namp, &aoftspace); -#ifdef DEBUG - fprintf(outf, "%2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); - if (*sp[-1] != NULL) { - for (cp = *sp[-1]; *cp; cp++) - fprintf(outf, "%s", unctrl(*cp)); - fprintf(outf, "\"\n"); - } -#endif - namp += 2; - } while (*namp); - if (XS) - SO = SE = NULL; - else { - if (tgetnum("sg") > 0) - SO = NULL; - if (tgetnum("ug") > 0) - US = NULL; - if (!SO && US) { - SO = US; - SE = UE; - } - } -} - -/* - * return a capability from termcap - */ -char * -getcap(name) -char *name; -{ - char *tgetstr(); - - return tgetstr(name, &aoftspace); -} diff --git a/lib/libcurses/curses.ext b/lib/libcurses/ctrace.c index ff362297661a..4f53906cc5ee 100644 --- a/lib/libcurses/curses.ext +++ b/lib/libcurses/ctrace.c @@ -1,6 +1,6 @@ /*- - * Copyright (c) 1981 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,30 +29,48 @@ * 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. - * - * @(#)curses.ext 5.6 (Berkeley) 4/19/91 - */ - -/* - * External variables for the curses library */ -/* LINTLIBRARY */ - -# include "curses.h" - -extern bool _echoit, _rawmode, My_term, _endwin; - -extern char ttytype[50], *_unctrl[]; +#ifndef lint +static char sccsid[] = "@(#)ctrace.c 8.2 (Berkeley) 10/5/93"; +#endif /* not lint */ -extern int _tty_ch, LINES, COLS; +#ifdef DEBUG +#include <stdio.h> -extern SGTTY _tty; +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif -char _putchar(); +#ifndef TFILE +#define TFILE "__curses.out" +#endif -#ifdef DEBUG -# define outf _outf +static FILE *tracefp; /* Curses debugging file descriptor. */ -FILE *outf; +void +#ifdef __STDC__ +__CTRACE(const char *fmt, ...) +#else +__CTRACE(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (tracefp == NULL) + tracefp = fopen(TFILE, "w"); + if (tracefp == NULL) + return; + (void)vfprintf(tracefp, fmt, ap); + va_end(ap); + (void)fflush(tracefp); +} #endif diff --git a/lib/libcurses/addstr.c b/lib/libcurses/cur_hash.c index 025fd43d4a08..3aaaa925bd93 100644 --- a/lib/libcurses/addstr.c +++ b/lib/libcurses/cur_hash.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,28 +32,31 @@ */ #ifndef lint -static char sccsid[] = "@(#)addstr.c 5.5 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)cur_hash.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include <sys/types.h> -# include "curses.ext" /* - * This routine adds a string starting at (_cury,_curx) - * + * __hash() is "hashpjw" from the Dragon Book, Aho, Sethi & Ullman, p.436. */ -waddstr(win,str) -reg WINDOW *win; -char *str; +u_int +__hash(s, len) + char *s; + int len; { - chtype c; - reg char *s; -# ifdef DEBUG - fprintf(outf, "WADDSTR(\"%s\")\n", str); -# endif - for (s = str; *s;) { - c = (unsigned char) *s++; - if (_waddbytes(win, &c, 1) == ERR) - return ERR; + register u_int h, g, i; + + h = 0; + i = 0; + while (i < len) { + h = (h << 4) + (s[i] & 0xff); + if (g = h & 0xf0000000) { + h = h ^ (g >> 24); + h = h ^ g; + } + i++; } - return OK; + return h; } diff --git a/lib/libcurses/curses.3 b/lib/libcurses/curses.3 index 37b79419f947..cd3a18f152a4 100644 --- a/lib/libcurses/curses.3 +++ b/lib/libcurses/curses.3 @@ -1,5 +1,5 @@ -.\" Copyright (c) 1985, 1991 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1985, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)curses.3 6.6 (Berkeley) 4/19/91 +.\" @(#)curses.3 8.1 (Berkeley) 6/4/93 .\" -.Dd April 19, 1991 +.Dd June 4, 1993 .Dt CURSES 3 .Os BSD 4 .Sh NAME diff --git a/lib/libcurses/curses.c b/lib/libcurses/curses.c index 3943595ca561..6a152772c750 100644 --- a/lib/libcurses/curses.c +++ b/lib/libcurses/curses.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,49 +32,47 @@ */ #ifndef lint -static char sccsid[] = "@(#)curses.c 5.7 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)curses.c 8.2 (Berkeley) 1/2/94"; #endif /* not lint */ -/* - * Define global variables - * - */ -# include "curses.h" - -bool _echoit = TRUE, /* set if stty indicates ECHO */ - _rawmode = FALSE,/* set if stty indicates RAW mode */ - My_term = FALSE,/* set if user specifies terminal type */ - _endwin = FALSE;/* set if endwin has been called */ - -char ttytype[50], /* long name of tty */ - *Def_term = "unknown"; /* default terminal type */ - -int _tty_ch = 0, /* file channel which is a tty */ - LINES, /* number of lines allowed on screen */ - COLS, /* number of columns allowed on screen */ - _res_flg; /* sgtty flags for reseting later */ - -WINDOW *stdscr = NULL, - *curscr = NULL; - -# ifdef DEBUG -FILE *outf; /* debug output file */ -# endif - -SGTTY _tty; /* tty modes */ - -bool AM, BS, CA, DA, DB, EO, HC, HZ, IN, MI, MS, NC, NS, OS, UL, XB, XN, - XT, XS, XX; -char *AL, *BC, *BT, *CD, *CE, *CL, *CM, *CR, *CS, *DC, *DL, *DM, - *DO, *ED, *EI, *K0, *K1, *K2, *K3, *K4, *K5, *K6, *K7, *K8, - *K9, *HO, *IC, *IM, *IP, *KD, *KE, *KH, *KL, *KR, *KS, *KU, - *LL, *MA, *ND, *NL, *RC, *SC, *SE, *SF, *SO, *SR, *TA, *TE, - *TI, *UC, *UE, *UP, *US, *VB, *VS, *VE, *AL_PARM, *DL_PARM, - *UP_PARM, *DOWN_PARM, *LEFT_PARM, *RIGHT_PARM; -char PC; +#include <curses.h> +/* Private. */ +int __echoit = 1; /* If stty indicates ECHO. */ +int __pfast; +int __rawmode = 0; /* If stty indicates RAW mode. */ +int __noqch = 0; /* + * If terminal doesn't have + * insert/delete line capabilities + * for quick change on refresh. + */ +int __usecs = 0; /* + * Use change scroll region, if + * no insert/delete capabilities + */ +char AM, BS, CA, DA, EO, HC, IN, MI, MS, NC, NS, OS, PC, + UL, XB, XN, XT, XS, XX; +char *AL, *BC, *BT, *CD, *CE, *CL, *CM, *CR, *CS, *DC, *DL, + *DM, *DO, *ED, *EI, *K0, *K1, *K2, *K3, *K4, *K5, *K6, + *K7, *K8, *K9, *HO, *IC, *IM, *IP, *KD, *KE, *KH, *KL, + *KR, *KS, *KU, *LL, *MA, *ND, *NL, *RC, *SC, *SE, *SF, + *SO, *SR, *TA, *TE, *TI, *UC, *UE, *UP, *US, *VB, *VS, + *VE, *al, *dl, *sf, *sr, + *AL_PARM, *DL_PARM, *UP_PARM, *DOWN_PARM, *LEFT_PARM, + *RIGHT_PARM; /* - * From the tty modes... + * Public. + * + * XXX + * UPPERCASE isn't used by libcurses, and is left for backward + * compatibility only. */ - -bool GT, NONL, UPPERCASE, normtty, _pfast; +WINDOW *curscr; /* Current screen. */ +WINDOW *stdscr; /* Standard screen. */ +int COLS; /* Columns on the screen. */ +int LINES; /* Lines on the screen. */ +int My_term = 0; /* Use Def_term regardless. */ +char *Def_term = "unknown"; /* Default terminal type. */ +char GT; /* Gtty indicates tabs. */ +char NONL; /* Term can't hack LF doing a CR. */ +char UPPERCASE; /* Terminal is uppercase only. */ diff --git a/lib/libcurses/curses.h b/lib/libcurses/curses.h index e845bb22878c..14e82deac58a 100644 --- a/lib/libcurses/curses.h +++ b/lib/libcurses/curses.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,190 +30,361 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)curses.h 5.9 (Berkeley) 7/1/90 + * @(#)curses.h 8.2 (Berkeley) 1/2/94 */ -#ifndef WINDOW +#ifndef _CURSES_H_ +#define _CURSES_H_ + +#include <sys/types.h> +#include <sys/cdefs.h> + +#include <stdio.h> + +#ifndef _BSD_VA_LIST_ +#define _BSD_VA_LIST_ char * +#endif + +/* + * The following #defines and #includes are present for backward + * compatibility only. They should not be used in future code. + * + * START BACKWARD COMPATIBILITY ONLY. + */ +#ifndef _CURSES_PRIVATE -#include <stdio.h> - -#define USE_OLD_TTY -#include <sys/ioctl.h> #undef USE_OLD_TTY +#undef B0 +#undef B50 +#undef B75 +#undef B110 +#undef B134 +#undef B150 +#undef B200 +#undef B300 +#undef B600 +#undef B1200 +#undef B1800 +#undef B2400 +#undef B4800 +#undef B9600 +#undef EXTA +#undef EXTB +#undef B57600 +#undef B115200 + +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/ioctl_compat.h> /* For sgttyb and related */ #define bool char #define reg register -typedef unsigned short chtype; - +#ifndef TRUE #define TRUE (1) +#endif +#ifndef FALSE #define FALSE (0) -#define ERR (0) -#define OK (1) +#endif -#define _ENDLINE 001 -#define _FULLWIN 002 -#define _SCROLLWIN 004 -#define _FLUSH 010 -#define _FULLLINE 020 -#define _IDLINE 040 -#define _STANDOUT 0400 -#define _NOCHANGE -1 +#define _puts(s) tputs(s, 0, _putchar) -#define _puts(s) tputs(s, 0, _putchar) +/* Old-style terminal modes access. */ +#define baudrate() (cfgetospeed(&__baset)) +#define crmode() cbreak() +#define erasechar() (__baset.c_cc[VERASE]) +#define killchar() (__baset.c_cc[VKILL]) +#define nocrmode() nocbreak() +#define ospeed (cfgetospeed(&__baset)) -typedef struct sgttyb SGTTY; +/* WINDOW structure members name compatibility */ +#define _curx curx +#define _cury cury +#define _begx begx +#define _begy begy +#define _maxx maxx +#define _maxy maxy -/* - * Capabilities from termcap - */ +#define _tty __baset + +#endif /* _CURSES_PRIVATE */ -extern bool AM, BS, CA, DA, DB, EO, HC, HZ, IN, MI, MS, NC, NS, OS, UL, - XB, XN, XT, XS, XX; +extern char GT; /* Gtty indicates tabs. */ +extern char NONL; /* Term can't hack LF doing a CR. */ +extern char UPPERCASE; /* Terminal is uppercase only. */ + +extern int My_term; /* Use Def_term regardless. */ +extern char *Def_term; /* Default terminal type. */ + +/* Termcap capabilities. */ +extern char AM, BS, CA, DA, EO, HC, IN, MI, MS, NC, NS, OS, + PC, UL, XB, XN, XT, XS, XX; extern char *AL, *BC, *BT, *CD, *CE, *CL, *CM, *CR, *CS, *DC, *DL, *DM, *DO, *ED, *EI, *K0, *K1, *K2, *K3, *K4, *K5, *K6, *K7, *K8, *K9, *HO, *IC, *IM, *IP, *KD, *KE, *KH, *KL, *KR, *KS, *KU, *LL, *MA, *ND, *NL, *RC, *SC, *SE, *SF, *SO, *SR, *TA, *TE, *TI, *UC, *UE, *UP, *US, *VB, *VS, - *VE, *AL_PARM, *DL_PARM, *UP_PARM, *DOWN_PARM, - *LEFT_PARM, *RIGHT_PARM; -extern char PC; + *VE, *al, *dl, *sf, *sr, + *AL_PARM, *DL_PARM, *UP_PARM, *DOWN_PARM, *LEFT_PARM, + *RIGHT_PARM; + +/* END BACKWARD COMPATIBILITY ONLY. */ + +/* 8-bit ASCII characters. */ +#define unctrl(c) __unctrl[(c) & 0xff] +#define unctrllen(ch) __unctrllen[(ch) & 0xff] + +extern char *__unctrl[256]; /* Control strings. */ +extern char __unctrllen[256]; /* Control strings length. */ /* - * From the tty modes... + * A window an array of __LINE structures pointed to by the 'lines' pointer. + * A line is an array of __LDATA structures pointed to by the 'line' pointer. + * + * IMPORTANT: the __LDATA structure must NOT induce any padding, so if new + * fields are added -- padding fields with *constant values* should ensure + * that the compiler will not generate any padding when storing an array of + * __LDATA structures. This is to enable consistent use of memcmp, and memcpy + * for comparing and copying arrays. */ +typedef struct { + char ch; /* the actual character */ -extern bool GT, NONL, UPPERCASE, normtty, _pfast; +#define __STANDOUT 0x01 /* Added characters are standout. */ + char attr; /* attributes of character */ +} __LDATA; -struct _win_st { - short _cury, _curx; - short _maxy, _maxx; - short _begy, _begx; - short _flags; - short _ch_off; - bool _clear; - bool _leave; - bool _scroll; - chtype **_y; - short *_firstch; - short *_lastch; - struct _win_st *_nextp, *_orig; -}; +#define __LDATASIZE (sizeof(__LDATA)) -#define WINDOW struct _win_st +typedef struct { +#define __ISDIRTY 0x01 /* Line is dirty. */ +#define __ISPASTEOL 0x02 /* Cursor is past end of line */ +#define __FORCEPAINT 0x04 /* Force a repaint of the line */ + u_int flags; + u_int hash; /* Hash value for the line. */ + size_t *firstchp, *lastchp; /* First and last chngd columns ptrs */ + size_t firstch, lastch; /* First and last changed columns. */ + __LDATA *line; /* Pointer to the line text. */ +} __LINE; -extern bool My_term, _echoit, _rawmode, _endwin; +typedef struct __window { /* Window structure. */ + struct __window *nextp, *orig; /* Subwindows list and parent. */ + size_t begy, begx; /* Window home. */ + size_t cury, curx; /* Current x, y coordinates. */ + size_t maxy, maxx; /* Maximum values for curx, cury. */ + short ch_off; /* x offset for firstch/lastch. */ + __LINE **lines; /* Array of pointers to the lines */ + __LINE *lspace; /* line space (for cleanup) */ + __LDATA *wspace; /* window space (for cleanup) */ -extern char *Def_term, ttytype[]; +#define __ENDLINE 0x001 /* End of screen. */ +#define __FLUSH 0x002 /* Fflush(stdout) after refresh. */ +#define __FULLLINE 0x004 /* Line width = terminal width. */ +#define __FULLWIN 0x008 /* Window is a screen. */ +#define __IDLINE 0x010 /* Insert/delete sequences. */ +#define __SCROLLWIN 0x020 /* Last char will scroll window. */ +#define __SCROLLOK 0x040 /* Scrolling ok. */ +#define __CLEAROK 0x080 /* Clear on next refresh. */ +#define __WSTANDOUT 0x100 /* Standout window */ +#define __LEAVEOK 0x200 /* If curser left */ + u_int flags; +} WINDOW; -extern int LINES, COLS, _tty_ch, _res_flg; +/* Curses external declarations. */ +extern WINDOW *curscr; /* Current screen. */ +extern WINDOW *stdscr; /* Standard screen. */ -extern SGTTY _tty; +typedef struct termios SGTTY; -extern WINDOW *stdscr, *curscr; +extern SGTTY __orig_termios; /* Terminal state before curses */ +extern SGTTY __baset; /* Our base terminal state */ +extern int __tcaction; /* If terminal hardware set. */ -/* - * Define VOID to stop lint from generating "null effect" - * comments. - */ -#ifdef lint -int __void__; -#define VOID(x) (__void__ = (int) (x)) -#else -#define VOID(x) (x) -#endif +extern int COLS; /* Columns on the screen. */ +extern int LINES; /* Lines on the screen. */ -/* - * psuedo functions for standard screen - */ -#define addch(ch) VOID(waddch(stdscr, ch)) -#define getch() VOID(wgetch(stdscr)) -#define addbytes(da,co) VOID(waddbytes(stdscr, da,co)) -#define addstr(str) VOID(waddstr(stdscr, str)) -#define getstr(str) VOID(wgetstr(stdscr, str)) -#define move(y, x) VOID(wmove(stdscr, y, x)) -#define clear() VOID(wclear(stdscr)) -#define erase() VOID(werase(stdscr)) -#define clrtobot() VOID(wclrtobot(stdscr)) -#define clrtoeol() VOID(wclrtoeol(stdscr)) -#define insertln() VOID(winsertln(stdscr)) -#define deleteln() VOID(wdeleteln(stdscr)) -#define refresh() VOID(wrefresh(stdscr)) -#define inch() VOID(winch(stdscr)) -#define insch(c) VOID(winsch(stdscr,c)) -#define delch() VOID(wdelch(stdscr)) -#define standout() VOID(wstandout(stdscr)) -#define standend() VOID(wstandend(stdscr)) +extern char *ttytype; /* Full name of current terminal. */ -/* - * mv functions - */ -#define mvwaddch(win,y,x,ch) VOID(wmove(win,y,x)==ERR?ERR:waddch(win,ch)) -#define mvwgetch(win,y,x) VOID(wmove(win,y,x)==ERR?ERR:wgetch(win)) -#define mvwaddbytes(win,y,x,da,co) \ - VOID(wmove(win,y,x)==ERR?ERR:waddbytes(win,da,co)) -#define mvwaddstr(win,y,x,str) \ - VOID(wmove(win,y,x)==ERR?ERR:waddstr(win,str)) -#define mvwgetstr(win,y,x,str) VOID(wmove(win,y,x)==ERR?ERR:wgetstr(win,str)) -#define mvwinch(win,y,x) VOID(wmove(win,y,x) == ERR ? ERR : winch(win)) -#define mvwdelch(win,y,x) VOID(wmove(win,y,x) == ERR ? ERR : wdelch(win)) -#define mvwinsch(win,y,x,c) VOID(wmove(win,y,x) == ERR ? ERR:winsch(win,c)) -#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch) -#define mvgetch(y,x) mvwgetch(stdscr,y,x) -#define mvaddbytes(y,x,da,co) mvwaddbytes(stdscr,y,x,da,co) -#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str) -#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str) -#define mvinch(y,x) mvwinch(stdscr,y,x) -#define mvdelch(y,x) mvwdelch(stdscr,y,x) -#define mvinsch(y,x,c) mvwinsch(stdscr,y,x,c) +#define ERR (0) /* Error return. */ +#define OK (1) /* Success return. */ -/* - * psuedo functions - */ +/* Standard screen pseudo functions. */ +#define addbytes(s, n) __waddbytes(stdscr, s, n, 0) +#define addch(ch) waddch(stdscr, ch) +#define addnstr(s, n) waddnstr(stdscr, s, n) +#define addstr(s) __waddbytes(stdscr, s, strlen(s), 0) +#define clear() wclear(stdscr) +#define clrtobot() wclrtobot(stdscr) +#define clrtoeol() wclrtoeol(stdscr) +#define delch() wdelch(stdscr) +#define deleteln() wdeleteln(stdscr) +#define erase() werase(stdscr) +#define getch() wgetch(stdscr) +#define getstr(s) wgetstr(stdscr, s) +#define inch() winch(stdscr) +#define insch(ch) winsch(stdscr, ch) +#define insertln() winsertln(stdscr) +#define move(y, x) wmove(stdscr, y, x) +#define refresh() wrefresh(stdscr) +#define standend() wstandend(stdscr) +#define standout() wstandout(stdscr) +#define waddbytes(w, s, n) __waddbytes(w, s, n, 0) +#define waddstr(w, s) __waddbytes(w, s, strlen(s), 0) -#define clearok(win,bf) (win->_clear = bf) -#define leaveok(win,bf) (win->_leave = bf) -#define scrollok(win,bf) (win->_scroll = bf) -#define flushok(win,bf) (bf ? (win->_flags |= _FLUSH):(win->_flags &= ~_FLUSH)) -#define getyx(win,y,x) y = win->_cury, x = win->_curx -#define winch(win) (win->_y[win->_cury][win->_curx] & 0xFF) - -#define raw() (_tty.sg_flags|=RAW, _pfast=_rawmode=TRUE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define noraw() (_tty.sg_flags&=~RAW,_rawmode=FALSE,\ - _pfast=!(_tty.sg_flags&CRMOD),ioctl(_tty_ch, TIOCSETP, &_tty)) -#define cbreak() (_tty.sg_flags |= CBREAK, _rawmode = TRUE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define nocbreak() (_tty.sg_flags &= ~CBREAK,_rawmode=FALSE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define crmode() cbreak() /* backwards compatability */ -#define nocrmode() nocbreak() /* backwards compatability */ -#define echo() (_tty.sg_flags |= ECHO, _echoit = TRUE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define noecho() (_tty.sg_flags &= ~ECHO, _echoit = FALSE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, \ - ioctl(_tty_ch, TIOCSETP, &_tty)) -#define savetty() ((void) ioctl(_tty_ch, TIOCGETP, &_tty), \ - _res_flg = _tty.sg_flags) -#define resetty() (_tty.sg_flags = _res_flg, \ - _echoit = ((_res_flg & ECHO) == ECHO), \ - _rawmode = ((_res_flg & (CBREAK|RAW)) != 0), \ - _pfast = ((_res_flg & CRMOD) ? _rawmode : TRUE), \ - (void) ioctl(_tty_ch, TIOCSETP, &_tty)) - -#define erasechar() (_tty.sg_erase) -#define killchar() (_tty.sg_kill) -#define baudrate() (_tty.sg_ospeed) - -WINDOW *initscr(), *newwin(), *subwin(); -char *longname(), *getcap(); +/* Standard screen plus movement pseudo functions. */ +#define mvaddbytes(y, x, s, n) mvwaddbytes(stdscr, y, x, s, n) +#define mvaddch(y, x, ch) mvwaddch(stdscr, y, x, ch) +#define mvaddnstr(y, x, s, n) mvwaddnstr(stdscr, y, x, s, n) +#define mvaddstr(y, x, s) mvwaddstr(stdscr, y, x, s) +#define mvdelch(y, x) mvwdelch(stdscr, y, x) +#define mvgetch(y, x) mvwgetch(stdscr, y, x) +#define mvgetstr(y, x, s) mvwgetstr(stdscr, y, x, s) +#define mvinch(y, x) mvwinch(stdscr, y, x) +#define mvinsch(y, x, c) mvwinsch(stdscr, y, x, c) +#define mvwaddbytes(w, y, x, s, n) \ + (wmove(w, y, x) == ERR ? ERR : __waddbytes(w, s, n, 0)) +#define mvwaddch(w, y, x, ch) \ + (wmove(w, y, x) == ERR ? ERR : waddch(w, ch)) +#define mvwaddnstr(w, y, x, s, n) \ + (wmove(w, y, x) == ERR ? ERR : waddnstr(w, s, n)) +#define mvwaddstr(w, y, x, s) \ + (wmove(w, y, x) == ERR ? ERR : __waddbytes(w, s, strlen(s), 0)) +#define mvwdelch(w, y, x) \ + (wmove(w, y, x) == ERR ? ERR : wdelch(w)) +#define mvwgetch(w, y, x) \ + (wmove(w, y, x) == ERR ? ERR : wgetch(w)) +#define mvwgetstr(w, y, x, s) \ + (wmove(w, y, x) == ERR ? ERR : wgetstr(w, s)) +#define mvwinch(w, y, x) \ + (wmove(w, y, x) == ERR ? ERR : winch(w)) +#define mvwinsch(w, y, x, c) \ + (wmove(w, y, x) == ERR ? ERR : winsch(w, c)) + +/* Psuedo functions. */ +#define clearok(w, bf) \ + ((bf) ? ((w)->flags |= __CLEAROK) : ((w)->flags &= ~__CLEAROK)) +#define flushok(w, bf) \ + ((bf) ? ((w)->flags |= __FLUSH) : ((w)->flags &= ~__FLUSH)) +#define getyx(w, y, x) \ + (y) = (w)->cury, (x) = (w)->curx +#define leaveok(w, bf) \ + ((bf) ? ((w)->flags |= __LEAVEOK) : ((w)->flags &= ~__LEAVEOK)) +#define scrollok(w, bf) \ + ((bf) ? ((w)->flags |= __SCROLLOK) : ((w)->flags &= ~__SCROLLOK)) +#define winch(w) \ + ((w)->lines[(w)->cury]->line[(w)->curx].ch & 0xff) + +/* Public function prototypes. */ +int box __P((WINDOW *, char, char)); +int cbreak __P((void)); +int delwin __P((WINDOW *)); +int echo __P((void)); +int endwin __P((void)); +char *fullname __P((char *, char *)); +char *getcap __P((char *)); +int gettmode __P((void)); +void idlok __P((WINDOW *, int)); +WINDOW *initscr __P((void)); +char *longname __P((char *, char *)); +int mvcur __P((int, int, int, int)); +int mvprintw __P((int, int, const char *, ...)); +int mvscanw __P((int, int, const char *, ...)); +int mvwin __P((WINDOW *, int, int)); +int mvwprintw __P((WINDOW *, int, int, const char *, ...)); +int mvwscanw __P((WINDOW *, int, int, const char *, ...)); +WINDOW *newwin __P((int, int, int, int)); +int nl __P((void)); +int nocbreak __P((void)); +int noecho __P((void)); +int nonl __P((void)); +int noraw __P((void)); +int overlay __P((WINDOW *, WINDOW *)); +int overwrite __P((WINDOW *, WINDOW *)); +int printw __P((const char *, ...)); +int raw __P((void)); +int resetty __P((void)); +int savetty __P((void)); +int scanw __P((const char *, ...)); +int scroll __P((WINDOW *)); +int setterm __P((char *)); +int sscans __P((WINDOW *, const char *, ...)); +WINDOW *subwin __P((WINDOW *, int, int, int, int)); +int suspendwin __P((void)); +int touchline __P((WINDOW *, int, int, int)); +int touchoverlap __P((WINDOW *, WINDOW *)); +int touchwin __P((WINDOW *)); +int vwprintw __P((WINDOW *, const char *, _BSD_VA_LIST_)); +int vwscanw __P((WINDOW *, const char *, _BSD_VA_LIST_)); +int waddch __P((WINDOW *, char)); +int waddnstr __P((WINDOW *, const char *, int)); +int wclear __P((WINDOW *)); +int wclrtobot __P((WINDOW *)); +int wclrtoeol __P((WINDOW *)); +int wdelch __P((WINDOW *)); +int wdeleteln __P((WINDOW *)); +int werase __P((WINDOW *)); +int wgetch __P((WINDOW *)); +int wgetstr __P((WINDOW *, char *)); +int winsch __P((WINDOW *, char)); +int winsertln __P((WINDOW *)); +int wmove __P((WINDOW *, int, int)); +int wprintw __P((WINDOW *, const char *, ...)); +int wrefresh __P((WINDOW *)); +int wscanw __P((WINDOW *, const char *, ...)); +int wstandend __P((WINDOW *)); +int wstandout __P((WINDOW *)); +int vwprintw __P((WINDOW *, const char *, _BSD_VA_LIST_)); + +/* Private functions that are needed for user programs prototypes. */ +int __waddbytes __P((WINDOW *, const char *, int, int)); + +/* Private functions. */ +#ifdef _CURSES_PRIVATE + +#define __cputchar _putchar +void _putchar __P((int)); + +void __CTRACE __P((const char *, ...)); +u_int __hash __P((char *, int)); +void __id_subwins __P((WINDOW *)); +int __mvcur __P((int, int, int, int, int)); +void __restore_stophandler __P((void)); +void __set_stophandler __P((void)); +void __set_subwin __P((WINDOW *, WINDOW *)); +void __set_scroll_region __P((int, int)); +void __startwin __P((void)); +void __stop_signal_handler __P((int)); +void __swflags __P((WINDOW *)); +int __touchline __P((WINDOW *, int, int, int, int)); +int __touchwin __P((WINDOW *)); +char *__tscroll __P((const char *, int)); +int __waddch __P((WINDOW *, __LDATA *)); + +/* Private #defines. */ +#define min(a,b) (a < b ? a : b) +#define max(a,b) (a > b ? a : b) + +/* Private externs. */ +extern int __echoit; +extern int __endwin; +extern int __pfast; +extern int __rawmode; +extern int __noqch; +extern int __usecs; + +int tputs __P((char *, int, void (*)(int))); + +#else + +int tputs __P((char *, int, int (*)(int))); -/* - * Used to be in unctrl.h. - */ -#define unctrl(c) _unctrl[(c) & 0177] -extern char *_unctrl[]; #endif + +/* Termcap functions. */ +int tgetent __P((char *, char *)); +int tgetnum __P((char *)); +int tgetflag __P((char *)); +char *tgetstr __P((char *, char **)); +char *tgoto __P((char *, int, int)); + +#endif /* !_CURSES_H_ */ diff --git a/lib/libcurses/delch.c b/lib/libcurses/delch.c index 23499eb55490..ad7d3526eeb1 100644 --- a/lib/libcurses/delch.c +++ b/lib/libcurses/delch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,28 +32,31 @@ */ #ifndef lint -static char sccsid[] = "@(#)delch.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)delch.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <string.h> /* - * This routine performs an insert-char on the line, leaving - * (_cury,_curx) unchanged. - * + * wdelch -- + * Do an insert-char on the line, leaving (cury, curx) unchanged. */ +int wdelch(win) -reg WINDOW *win; { - - reg chtype *temp1, *temp2; - reg chtype *end; + register WINDOW *win; +{ + register __LDATA *end, *temp1, *temp2; - end = &win->_y[win->_cury][win->_maxx - 1]; - temp1 = &win->_y[win->_cury][win->_curx]; + end = &win->lines[win->cury]->line[win->maxx - 1]; + temp1 = &win->lines[win->cury]->line[win->curx]; temp2 = temp1 + 1; - while (temp1 < end) - *temp1++ = *temp2++; - *temp1 = ' '; - touchline(win, win->_cury, win->_curx, win->_maxx - 1); - return OK; + while (temp1 < end) { + (void)memcpy(temp1, temp2, sizeof(__LDATA)); + temp1++, temp2++; + } + temp1->ch = ' '; + temp1->attr = 0; + __touchline(win, win->cury, win->curx, win->maxx - 1, 0); + return (OK); } diff --git a/lib/libcurses/deleteln.c b/lib/libcurses/deleteln.c index ba5d4819743e..6c4688acb5e7 100644 --- a/lib/libcurses/deleteln.c +++ b/lib/libcurses/deleteln.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,43 +32,50 @@ */ #ifndef lint -static char sccsid[] = "@(#)deleteln.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)deleteln.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <string.h> /* - * This routine deletes a line from the screen. It leaves - * (_cury,_curx) unchanged. - * + * wdeleteln -- + * Delete a line from the screen. It leaves (cury, curx) unchanged. */ +int wdeleteln(win) -reg WINDOW *win; + register WINDOW *win; { - reg chtype *temp; - reg int y; - reg chtype *end; - reg int x; + register int y, i; + register __LINE *temp; -# ifdef DEBUG - fprintf(outf, "DELETELN(%0.2o)\n", win); -# endif - temp = win->_y[win->_cury]; - for (y = win->_cury; y < win->_maxy - 1; y++) { - if (win->_orig == NULL) - win->_y[y] = win->_y[y + 1]; +#ifdef DEBUG + __CTRACE("deleteln: (%0.2o)\n", win); +#endif + temp = win->lines[win->cury]; + for (y = win->cury; y < win->maxy - 1; y++) { + win->lines[y]->flags &= ~__ISPASTEOL; + win->lines[y + 1]->flags &= ~__ISPASTEOL; + if (win->orig == NULL) + win->lines[y] = win->lines[y + 1]; else - bcopy(win->_y[y + 1], win->_y[y], win->_maxx * sizeof(chtype)); - touchline(win, y, 0, win->_maxx - 1); + (void) memcpy(win->lines[y]->line, + win->lines[y + 1]->line, + win->maxx * __LDATASIZE); + __touchline(win, y, 0, win->maxx - 1, 0); } - if (win->_orig == NULL) - win->_y[y] = temp; + + if (win->orig == NULL) + win->lines[y] = temp; else - temp = win->_y[y]; - for (end = &temp[win->_maxx]; temp < end; ) - *temp++ = ' '; - touchline(win, y, 0, win->_maxx - 1); - if (win->_orig == NULL) - _id_subwins(win); - return OK; + temp = win->lines[y]; + + for(i = 0; i < win->maxx; i++) { + temp->line[i].ch = ' '; + temp->line[i].attr = 0; + } + __touchline(win, y, 0, win->maxx - 1, 0); + if (win->orig == NULL) + __id_subwins(win); + return (OK); } diff --git a/lib/libcurses/delwin.c b/lib/libcurses/delwin.c index 6935f87550f1..3f6848a56b62 100644 --- a/lib/libcurses/delwin.c +++ b/lib/libcurses/delwin.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,48 +32,48 @@ */ #ifndef lint -static char sccsid[] = "@(#)delwin.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)delwin.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <stdlib.h> /* - * This routine deletes a window and releases it back to the system. - * + * delwin -- + * Delete a window and release it back to the system. */ +int delwin(win) -reg WINDOW *win; { + register WINDOW *win; +{ - reg int i; - reg WINDOW *wp, *np; + register WINDOW *wp, *np; - if (win->_orig == NULL) { + if (win->orig == NULL) { /* - * If we are the original window, delete the space for - * all the subwindows, and the array of space as well. + * If we are the original window, delete the space for all + * the subwindows, the line space and the window space. */ - for (i = 0; i < win->_maxy && win->_y[i]; i++) - free(win->_y[i]); - free(win->_firstch); - free(win->_lastch); - wp = win->_nextp; + free(win->lspace); + free(win->wspace); + free(win->lines); + wp = win->nextp; while (wp != win) { - np = wp->_nextp; + np = wp->nextp; delwin(wp); wp = np; } - } - else { + } else { /* - * If we are a subwindow, take ourselves out of the - * list. NOTE: if we are a subwindow, the minimum list - * is orig followed by this subwindow, so there are - * always at least two windows in the list. + * If we are a subwindow, take ourselves out of the list. + * NOTE: if we are a subwindow, the minimum list is orig + * followed by this subwindow, so there are always at least + * two windows in the list. */ - for (wp = win->_nextp; wp->_nextp != win; wp = wp->_nextp) + for (wp = win->nextp; wp->nextp != win; wp = wp->nextp) continue; - wp->_nextp = win->_nextp; + wp->nextp = win->nextp; } - free(win->_y); free(win); + return (OK); } diff --git a/lib/libcurses/erase.c b/lib/libcurses/erase.c index 9cbd79e7fd46..b19e15b3fc42 100644 --- a/lib/libcurses/erase.c +++ b/lib/libcurses/erase.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,38 +32,41 @@ */ #ifndef lint -static char sccsid[] = "@(#)erase.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)erase.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine erases everything on the window. - * + * werase -- + * Erases everything on the window. */ +int werase(win) -reg WINDOW *win; { + register WINDOW *win; +{ - reg int y; - reg chtype *sp, *end, *start, *maxx; - reg int minx; + register int minx, y; + register __LDATA *sp, *end, *start, *maxx; -# ifdef DEBUG - fprintf(outf, "WERASE(%0.2o)\n", win); -# endif - for (y = 0; y < win->_maxy; y++) { - minx = _NOCHANGE; - start = win->_y[y]; - end = &start[win->_maxx]; +#ifdef DEBUG + __CTRACE("werase: (%0.2o)\n", win); +#endif + for (y = 0; y < win->maxy; y++) { + minx = -1; + start = win->lines[y]->line; + end = &start[win->maxx]; for (sp = start; sp < end; sp++) - if (*sp != ' ') { - maxx = sp; - if (minx == _NOCHANGE) + if (sp->ch != ' ' || sp->attr != 0) { + maxx = sp; + if (minx == -1) minx = sp - start; - *sp = ' '; + sp->ch = ' '; + sp->attr = 0; } - if (minx != _NOCHANGE) - touchline(win, y, minx, maxx - win->_y[y]); + if (minx != -1) + __touchline(win, y, minx, maxx - win->lines[y]->line, + 0); } - win->_curx = win->_cury = 0; + return (OK); } diff --git a/lib/libcurses/fullname.c b/lib/libcurses/fullname.c index 11cf4cbe5408..3d05e5d6ef81 100644 --- a/lib/libcurses/fullname.c +++ b/lib/libcurses/fullname.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,34 +32,29 @@ */ #ifndef lint -static char sccsid[] = "@(#)fullname.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ - -# define reg register +static char sccsid[] = "@(#)fullname.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ /* + * fullname -- * This routine fills in "def" with the full name of the terminal. - * This is assumed to be the last name in the list of aliases. - * + * This is assumed to be the last name in the list of aliases. */ char * fullname(bp, def) -reg char *bp, *def; + register char *bp, *def; { + register char *cp; - reg char *cp; - - *def = 0; /* in case no name */ + *def = '\0'; /* In case no name. */ while (*bp && *bp != ':') { - cp = def; /* start of answer */ - while (*bp && *bp != ':' && *bp != '|') { - *cp++ = *bp++; /* copy name over */ - } - *cp = 0; /* zero end of name */ - if (*bp == '|') { - bp++; /* skip over '|' if that is case */ - } + cp = def; /* Start of answer. */ + while (*bp && *bp != ':' && *bp != '|') + *cp++ = *bp++; /* Copy name over. */ + *cp = '\0'; /* Zero end of name. */ + if (*bp == '|') + bp++; /* Skip over '|' if that is case. */ } - return(def); + return (def); } diff --git a/lib/libcurses/getch.c b/lib/libcurses/getch.c index d3e04d08f667..d260db11bc51 100644 --- a/lib/libcurses/getch.c +++ b/lib/libcurses/getch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,43 +32,46 @@ */ #ifndef lint -static char sccsid[] = "@(#)getch.c 5.6 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)getch.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine reads in a character from the window. - * + * wgetch -- + * Read in a character from the window. */ +int wgetch(win) -reg WINDOW *win; { - - reg bool weset = FALSE; - reg int inp; + register WINDOW *win; +{ + register int inp, weset; - if (!win->_scroll && (win->_flags&_FULLWIN) - && win->_curx == win->_maxx - 1 && win->_cury == win->_maxy - 1) - return ERR; -# ifdef DEBUG - fprintf(outf, "WGETCH: _echoit = %c, _rawmode = %c\n", _echoit ? 'T' : 'F', _rawmode ? 'T' : 'F'); -# endif - if (_echoit && !_rawmode) { + if (!(win->flags & __SCROLLOK) && (win->flags & __FULLWIN) + && win->curx == win->maxx - 1 && win->cury == win->maxy - 1) + return (ERR); +#ifdef DEBUG + __CTRACE("wgetch: __echoit = %d, __rawmode = %d\n", + __echoit, __rawmode); +#endif + if (__echoit && !__rawmode) { cbreak(); - weset++; - } + weset = 1; + } else + weset = 0; + inp = getchar(); if (inp != EOF) { -# ifdef DEBUG - fprintf(outf,"WGETCH got '%s'\n",unctrl(inp)); -# endif - if (_echoit) { - mvwaddch(curscr, win->_cury + win->_begy, - win->_curx + win->_begx, (unsigned char) inp); - waddch(win, (unsigned char) inp); +#ifdef DEBUG + __CTRACE("wgetch got '%s'\n", unctrl(inp)); +#endif + if (__echoit) { + mvwaddch(curscr, + win->cury + win->begy, win->curx + win->begx, inp); + waddch(win, inp); } } if (weset) nocbreak(); - return inp; + return (inp); } diff --git a/lib/libcurses/getstr.c b/lib/libcurses/getstr.c index ec3af26fe7ae..97305b807110 100644 --- a/lib/libcurses/getstr.c +++ b/lib/libcurses/getstr.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,24 +32,26 @@ */ #ifndef lint -static char sccsid[] = "@(#)getstr.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)getstr.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine gets a string starting at (_cury,_curx) - * + * wgetstr -- + * Get a string starting at (cury, curx). */ -wgetstr(win,str) -reg WINDOW *win; -reg char *str; { +int +wgetstr(win, str) + register WINDOW *win; + register char *str; +{ int c; while ((c = wgetch(win)) != ERR && c != EOF && c != '\n') *str++ = c; - *str = '\0'; + *str = '\0'; if (c == ERR) - return ERR; - return OK; + return (ERR); + return (OK); } diff --git a/lib/libcurses/id_subwins.c b/lib/libcurses/id_subwins.c index 9bbc3bc16a85..6dc715c2572f 100644 --- a/lib/libcurses/id_subwins.c +++ b/lib/libcurses/id_subwins.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,34 +32,34 @@ */ #ifndef lint -static char sccsid[] = "@(#)id_subwins.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)id_subwins.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * _id_subwins: - * Re-sync the pointers to _y for all the subwindows. - * + * __id_subwins -- + * Re-sync the pointers to lines for all the subwindows. */ -_id_subwins(orig) -register WINDOW *orig; +void +__id_subwins(orig) + register WINDOW *orig; { - register WINDOW *win; - register int realy; - register int y, oy, x; + register WINDOW *win; + register int oy, realy, y; - realy = orig->_begy + orig->_cury; - for (win = orig->_nextp; win != orig; win = win->_nextp) { + realy = orig->begy + orig->cury; + for (win = orig->nextp; win != orig; win = win->nextp) { /* - * If the window ends before our current position, - * don't need to do anything. + * If the window ends before our current position, don't need + * to do anything. */ - if (win->_begy + win->_maxy <= realy) + if (win->begy + win->maxy <= realy) continue; - oy = orig->_cury; - for (y = realy - win->_begy; y < win->_maxy; y++, oy++) - win->_y[y] = &orig->_y[oy][win->_ch_off]; + oy = orig->cury; + for (y = realy - win->begy; y < win->maxy; y++, oy++) + win->lines[y]->line = + &orig->lines[oy]->line[win->ch_off]; } } diff --git a/lib/libcurses/idlok.c b/lib/libcurses/idlok.c index 92566b20b35c..ef0a1e20d8ba 100644 --- a/lib/libcurses/idlok.c +++ b/lib/libcurses/idlok.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,23 +32,23 @@ */ #ifndef lint -static char sccsid[] = "@(#)idlok.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)idlok.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * idlok: - * Turn on and off using insert/deleteln sequences for the given - * window. - * + * idlok -- + * Turn on and off using insert/deleteln sequences for the + * given window. */ +void idlok(win, bf) -register WINDOW *win; -bool bf; + WINDOW *win; + int bf; { if (bf) - win->_flags |= _IDLINE; + win->flags |= __IDLINE; else - win->_flags &= ~_IDLINE; + win->flags &= ~__IDLINE; } diff --git a/lib/libcurses/initscr.c b/lib/libcurses/initscr.c index 5dd97e8b2255..8ed0f9f769a1 100644 --- a/lib/libcurses/initscr.c +++ b/lib/libcurses/initscr.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,62 +32,63 @@ */ #ifndef lint -static char sccsid[] = "@(#)initscr.c 5.6 (Berkeley) 3/3/91"; -#endif /* not lint */ +static char sccsid[] = "@(#)initscr.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" -# include <signal.h> - -extern char *getenv(); +#include <curses.h> +#include <signal.h> +#include <stdlib.h> /* - * This routine initializes the current and standard screen. - * + * initscr -- + * Initialize the current and standard screen. */ WINDOW * -initscr() { +initscr() +{ + register char *sp; - reg char *sp; - void tstp(); +#ifdef DEBUG + __CTRACE("initscr\n"); +#endif + __echoit = 1; + __pfast = __rawmode = __noqch = 0; -# ifdef DEBUG - fprintf(outf, "INITSCR()\n"); -# endif - if (My_term) - setterm(Def_term); - else { - gettmode(); - if ((sp = getenv("TERM")) == NULL) - sp = Def_term; - setterm(sp); -# ifdef DEBUG - fprintf(outf, "INITSCR: term = %s\n", sp); -# endif - } - _puts(TI); - _puts(VS); -# ifdef SIGTSTP - signal(SIGTSTP, tstp); -# endif - if (curscr != NULL) { -# ifdef DEBUG - fprintf(outf, "INITSCR: curscr = 0%o\n", curscr); -# endif + if (gettmode() == ERR) + return (NULL); + + /* + * If My_term is set, or can't find a terminal in the environment, + * use Def_term. + */ + if (My_term || (sp = getenv("TERM")) == NULL) + sp = Def_term; + if (setterm(sp) == ERR) + return (NULL); + + /* Need either homing or cursor motion for refreshes */ + if (!HO && !CM) + return (NULL); + + if (curscr != NULL) delwin(curscr); - } -# ifdef DEBUG - fprintf(outf, "LINES = %d, COLS = %d\n", LINES, COLS); -# endif if ((curscr = newwin(LINES, COLS, 0, 0)) == ERR) - return ERR; - clearok(curscr, TRUE); - curscr->_flags &= ~_FULLLINE; - if (stdscr != NULL) { -# ifdef DEBUG - fprintf(outf, "INITSCR: stdscr = 0%o\n", stdscr); -# endif + return (NULL); + clearok(curscr, 1); + + if (stdscr != NULL) delwin(stdscr); + if ((stdscr = newwin(LINES, COLS, 0, 0)) == ERR) { + delwin(curscr); + return (NULL); } - stdscr = newwin(LINES, COLS, 0, 0); - return stdscr; + + __set_stophandler(); + +#ifdef DEBUG + __CTRACE("initscr: LINES = %d, COLS = %d\n", LINES, COLS); +#endif + __startwin(); + + return (stdscr); } diff --git a/lib/libcurses/insch.c b/lib/libcurses/insch.c index 5ec1c9a7d861..e9b389ba1ea7 100644 --- a/lib/libcurses/insch.c +++ b/lib/libcurses/insch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,37 +32,41 @@ */ #ifndef lint -static char sccsid[] = "@(#)insch.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)insch.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <string.h> /* - * This routine performs an insert-char on the line, leaving - * (_cury,_curx) unchanged. - * + * winsch -- + * Do an insert-char on the line, leaving (cury, curx) unchanged. */ -winsch(win, c) -reg WINDOW *win; -char c; { +int +winsch(register WINDOW *win, char ch) +{ - reg chtype *temp1, *temp2; - reg chtype *end; + register __LDATA *end, *temp1, *temp2; - end = &win->_y[win->_cury][win->_curx]; - temp1 = &win->_y[win->_cury][win->_maxx - 1]; + end = &win->lines[win->cury]->line[win->curx]; + temp1 = &win->lines[win->cury]->line[win->maxx - 1]; temp2 = temp1 - 1; - while (temp1 > end) - *temp1-- = *temp2--; - *temp1 = (unsigned char) c; - touchline(win, win->_cury, win->_curx, win->_maxx - 1); - if (win->_cury == LINES - 1 && win->_y[LINES-1][COLS-1] != ' ') - if (win->_scroll) { + while (temp1 > end) { + (void)memcpy(temp1, temp2, sizeof(__LDATA)); + temp1--, temp2--; + } + temp1->ch = ch; + temp1->attr &= ~__STANDOUT; + __touchline(win, win->cury, win->curx, win->maxx - 1, 0); + if (win->cury == LINES - 1 && + (win->lines[LINES - 1]->line[COLS - 1].ch != ' ' || + win->lines[LINES -1]->line[COLS - 1].attr != 0)) + if (win->flags & __SCROLLOK) { wrefresh(win); scroll(win); - win->_cury--; - } - else - return ERR; - return OK; + win->cury--; + + } else + return (ERR); + return (OK); } diff --git a/lib/libcurses/insertln.c b/lib/libcurses/insertln.c index 09b8b4353035..9a9e321c72be 100644 --- a/lib/libcurses/insertln.c +++ b/lib/libcurses/insertln.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,43 +32,50 @@ */ #ifndef lint -static char sccsid[] = "@(#)insertln.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)insertln.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> +#include <string.h> /* - * This routine performs an insert-line on the window, leaving - * (_cury,_curx) unchanged. - * + * winsertln -- + * Do an insert-line on the window, leaving (cury, curx) unchanged. */ +int winsertln(win) -reg WINDOW *win; { + register WINDOW *win; +{ - reg chtype *temp; - reg int y; - reg chtype *end; - reg int x; + register int y, i; + register __LINE *temp; -#ifdef DEBUG - fprintf(outf, "INSERTLN(%0.2o)\n", win); +#ifdef DEBUG + __CTRACE("insertln: (%0.2o)\n", win); #endif - if (win->_orig == NULL) - temp = win->_y[win->_maxy - 1]; - for (y = win->_maxy - 1; y > win->_cury; --y) { - if (win->_orig == NULL) - win->_y[y] = win->_y[y - 1]; + if (win->orig == NULL) + temp = win->lines[win->maxy - 1]; + for (y = win->maxy - 1; y > (int) win->cury; --y) { + win->lines[y]->flags &= ~__ISPASTEOL; + win->lines[y - 1]->flags &= ~__ISPASTEOL; + if (win->orig == NULL) + win->lines[y] = win->lines[y - 1]; else - bcopy(win->_y[y - 1], win->_y[y], win->_maxx * sizeof(chtype)); - touchline(win, y, 0, win->_maxx - 1); + (void)memcpy(win->lines[y]->line, + win->lines[y - 1]->line, + win->maxx * __LDATASIZE); + __touchline(win, y, 0, win->maxx - 1, 0); } - if (win->_orig == NULL) - win->_y[y] = temp; + if (win->orig == NULL) + win->lines[y] = temp; else - temp = win->_y[y]; - for (end = &temp[win->_maxx]; temp < end; ) - *temp++ = ' '; - touchline(win, y, 0, win->_maxx - 1); - if (win->_orig == NULL) - _id_subwins(win); + temp = win->lines[y]; + for(i = 0; i < win->maxx; i++) { + temp->line[i].ch = ' '; + temp->line[i].attr = 0; + } + __touchline(win, y, 0, win->maxx - 1, 0); + if (win->orig == NULL) + __id_subwins(win); + return (OK); } diff --git a/lib/libcurses/longname.c b/lib/libcurses/longname.c index 94364b4a1be3..fd54630f161d 100644 --- a/lib/libcurses/longname.c +++ b/lib/libcurses/longname.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,29 +32,25 @@ */ #ifndef lint -static char sccsid[] = "@(#)longname.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ - -# define reg register +static char sccsid[] = "@(#)longname.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ /* - * This routine fills in "def" with the long name of the terminal. - * + * longname -- + * Fill in "def" with the long name of the terminal. */ char * longname(bp, def) -reg char *bp, *def; { - - reg char *cp; + register char *bp, *def; +{ + register char *cp; while (*bp && *bp != ':' && *bp != '|') bp++; if (*bp == '|') { - bp++; - cp = def; - while (*bp && *bp != ':' && *bp != '|') + for (cp = def, ++bp; *bp && *bp != ':' && *bp != '|';) *cp++ = *bp++; - *cp = 0; + *cp = '\0'; } - return def; + return (def); } diff --git a/lib/libcurses/move.c b/lib/libcurses/move.c index 78c104b31bc9..60a377b273fa 100644 --- a/lib/libcurses/move.c +++ b/lib/libcurses/move.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,27 +32,31 @@ */ #ifndef lint -static char sccsid[] = "@(#)move.c 5.5 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine moves the cursor to the given point - * + * wmove -- + * Moves the cursor to the given point. */ +int wmove(win, y, x) -reg WINDOW *win; -reg int y, x; { + register WINDOW *win; + register int y, x; +{ -# ifdef DEBUG - fprintf(outf, "MOVE to (%d, %d)\n", y, x); -# endif +#ifdef DEBUG + __CTRACE("wmove: (%d, %d)\n", y, x); +#endif if (x < 0 || y < 0) - return ERR; - if (x >= win->_maxx || y >= win->_maxy) - return ERR; - win->_curx = x; - win->_cury = y; - return OK; + return (ERR); + if (x >= win->maxx || y >= win->maxy) + return (ERR); + win->curx = x; + win->lines[win->cury]->flags &= ~__ISPASTEOL; + win->cury = y; + win->lines[y]->flags &= ~__ISPASTEOL; + return (OK); } diff --git a/lib/libcurses/mvscanw.c b/lib/libcurses/mvscanw.c deleted file mode 100644 index 544cbaa32d11..000000000000 --- a/lib/libcurses/mvscanw.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 1981 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)mvscanw.c 5.5 (Berkeley) 4/15/91"; -#endif /* not lint */ - -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "curses.ext" - -/* - * implement the mvscanw commands. Due to the variable number of - * arguments, they cannot be macros. Another sigh.... - */ - -#if __STDC__ -mvscanw(reg int y, reg int x, const char *fmt, ...) -#else -mvscanw(y, x, fmt, va_alist) - reg int y, x; - char *fmt; - va_dcl -#endif -{ - va_list ap; - int ret; - - if (move(y, x) != OK) - return ERR; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = _sscans(stdscr, fmt, ap); - va_end(ap); - return ret; -} - -#if __STDC__ -mvwscanw(reg WINDOW *win, reg int y, reg int x, const char *fmt, ...) -#else -mvwscanw(win, y, x, fmt, va_alist) - reg WINDOW *win; - reg int y, x; - char *fmt; - va_dcl -#endif -{ - va_list ap; - int ret; - - if (move(y, x) != OK) - return ERR; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = _sscans(win, fmt, ap); - va_end(ap); - return ret; -} diff --git a/lib/libcurses/mvwin.c b/lib/libcurses/mvwin.c index 69af8a9c4976..5699295769c3 100644 --- a/lib/libcurses/mvwin.c +++ b/lib/libcurses/mvwin.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,47 +32,46 @@ */ #ifndef lint -static char sccsid[] = "@(#)mvwin.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)mvwin.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * relocate the starting position of a window - * + * mvwin -- + * Relocate the starting position of a window. */ - +int mvwin(win, by, bx) -reg WINDOW *win; -reg int by, bx; { + register WINDOW *win; + register int by, bx; +{ + register WINDOW *orig; + register int dy, dx; - register WINDOW *orig; - register int dy, dx; - - if (by + win->_maxy > LINES || bx + win->_maxx > COLS) - return ERR; - dy = by - win->_begy; - dx = bx - win->_begx; - orig = win->_orig; + if (by + win->maxy > LINES || bx + win->maxx > COLS) + return (ERR); + dy = by - win->begy; + dx = bx - win->begx; + orig = win->orig; if (orig == NULL) { orig = win; do { - win->_begy += dy; - win->_begx += dx; - _swflags_(win); - win = win->_nextp; + win->begy += dy; + win->begx += dx; + __swflags(win); + win = win->nextp; } while (win != orig); + } else { + if (by < orig->begy || win->maxy + dy > orig->maxy) + return (ERR); + if (bx < orig->begx || win->maxx + dx > orig->maxx) + return (ERR); + win->begy = by; + win->begx = bx; + __swflags(win); + __set_subwin(orig, win); } - else { - if (by < orig->_begy || win->_maxy + dy > orig->_maxy) - return ERR; - if (bx < orig->_begx || win->_maxx + dx > orig->_maxx) - return ERR; - win->_begy = by; - win->_begx = bx; - _swflags_(win); - _set_subwin_(orig, win); - } - touchwin(win); - return OK; + __touchwin(win); + return (OK); } diff --git a/lib/libcurses/newwin.c b/lib/libcurses/newwin.c index dfa7e75e63bf..d0c75257773c 100644 --- a/lib/libcurses/newwin.c +++ b/lib/libcurses/newwin.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,204 +32,217 @@ */ #ifndef lint -static char sccsid[] = "@(#)newwin.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)newwin.c 8.1 (Berkeley) 7/20/93"; +#endif /* not lint */ -/* - * allocate space for and set up defaults for a new window - * - */ - -# include "curses.ext" - -char *malloc(); +#include <curses.h> +#include <stdlib.h> -# define SMALLOC (short *) malloc +#undef nl /* Don't need it here, and it interferes. */ -static WINDOW *makenew(); +static WINDOW *__makenew __P((int, int, int, int, int)); -# undef nl /* don't need it here, and it interferes */ +void __set_subwin __P((WINDOW *, WINDOW *)); +/* + * newwin -- + * Allocate space for and set up defaults for a new window. + */ WINDOW * -newwin(num_lines, num_cols, begy, begx) -int num_lines, num_cols, begy, begx; +newwin(nl, nc, by, bx) + register int nl, nc, by, bx; { - reg WINDOW *win; - reg chtype *sp; - reg int i, by, bx, nl, nc; - reg int j; - - by = begy; - bx = begx; - nl = num_lines; - nc = num_cols; + register WINDOW *win; + register __LINE *lp; + register int i, j; + register __LDATA *sp; if (nl == 0) nl = LINES - by; if (nc == 0) nc = COLS - bx; - if ((win = makenew(nl, nc, by, bx)) == NULL) - return ERR; - if ((win->_firstch = SMALLOC(nl * sizeof win->_firstch[0])) == NULL) { - free(win->_y); - free(win); - return NULL; - } - if ((win->_lastch = SMALLOC(nl * sizeof win->_lastch[0])) == NULL) { - free(win->_y); - free(win->_firstch); - free(win); - return NULL; - } - win->_nextp = win; + + if ((win = __makenew(nl, nc, by, bx, 0)) == NULL) + return (NULL); + + win->nextp = win; + win->ch_off = 0; + win->orig = NULL; + +#ifdef DEBUG + __CTRACE("newwin: win->ch_off = %d\n", win->ch_off); +#endif + for (i = 0; i < nl; i++) { - win->_firstch[i] = _NOCHANGE; - win->_lastch[i] = _NOCHANGE; - } - for (i = 0; i < nl; i++) - if ((win->_y[i] = (chtype *) malloc(nc * sizeof(chtype))) == NULL) { - for (j = 0; j < i; j++) - free(win->_y[j]); - free(win->_firstch); - free(win->_lastch); - free(win->_y); - free(win); - return ERR; + lp = win->lines[i]; + lp->flags = 0; + for (sp = lp->line, j = 0; j < nc; j++, sp++) { + sp->ch = ' '; + sp->attr = 0; } - else - for (sp = win->_y[i]; sp < win->_y[i] + nc; ) - *sp++ = ' '; - win->_ch_off = 0; -# ifdef DEBUG - fprintf(outf, "NEWWIN: win->_ch_off = %d\n", win->_ch_off); -# endif - return win; + lp->hash = __hash((char *) lp->line, nc * __LDATASIZE); + } + return (win); } WINDOW * -subwin(orig, num_lines, num_cols, begy, begx) -reg WINDOW *orig; -int num_lines, num_cols, begy, begx; +subwin(orig, nl, nc, by, bx) + register WINDOW *orig; + register int by, bx, nl, nc; { - reg int i; - reg WINDOW *win; - reg int by, bx, nl, nc; - - by = begy; - bx = begx; - nl = num_lines; - nc = num_cols; - - /* - * make sure window fits inside the original one - */ -# ifdef DEBUG - fprintf(outf, "SUBWIN(%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx); -# endif - if (by < orig->_begy || bx < orig->_begx - || by + nl > orig->_maxy + orig->_begy - || bx + nc > orig->_maxx + orig->_begx) - return ERR; + int i; + __LINE *lp; + register WINDOW *win; + + /* Make sure window fits inside the original one. */ +#ifdef DEBUG + __CTRACE("subwin: (%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx); +#endif + if (by < orig->begy || bx < orig->begx + || by + nl > orig->maxy + orig->begy + || bx + nc > orig->maxx + orig->begx) + return (NULL); if (nl == 0) - nl = orig->_maxy + orig->_begy - by; + nl = orig->maxy + orig->begy - by; if (nc == 0) - nc = orig->_maxx + orig->_begx - bx; - if ((win = makenew(nl, nc, by, bx)) == NULL) - return ERR; - win->_nextp = orig->_nextp; - orig->_nextp = win; - win->_orig = orig; - _set_subwin_(orig, win); - return win; + nc = orig->maxx + orig->begx - bx; + if ((win = __makenew(nl, nc, by, bx, 1)) == NULL) + return (NULL); + win->nextp = orig->nextp; + orig->nextp = win; + win->orig = orig; + + /* Initialize flags here so that refresh can also use __set_subwin. */ + for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) + lp->flags = 0; + __set_subwin(orig, win); + return (win); } /* - * this code is shared with mvwin() + * This code is shared with mvwin(). */ -_set_subwin_(orig, win) -register WINDOW *orig, *win; +void +__set_subwin(orig, win) + register WINDOW *orig, *win; { - register int i, j, k; - - j = win->_begy - orig->_begy; - k = win->_begx - orig->_begx; - win->_ch_off = k; -# ifdef DEBUG - fprintf(outf, "_SET_SUBWIN_: win->_ch_off = %d\n", win->_ch_off); -# endif - win->_firstch = &orig->_firstch[j]; - win->_lastch = &orig->_lastch[j]; - for (i = 0; i < win->_maxy; i++, j++) - win->_y[i] = &orig->_y[j][k]; + int i; + __LINE *lp, *olp; + + win->ch_off = win->begx - orig->begx; + /* Point line pointers to line space. */ + for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) { + win->lines[i] = lp; + olp = orig->lines[i + win->begy]; + lp->line = &olp->line[win->begx]; + lp->firstchp = &olp->firstch; + lp->lastchp = &olp->lastch; + lp->hash = __hash((char *) lp->line, win->maxx * __LDATASIZE); + } +#ifdef DEBUG + __CTRACE("__set_subwin: win->ch_off = %d\n", win->ch_off); +#endif } /* - * This routine sets up a window buffer and returns a pointer to it. + * __makenew -- + * Set up a window buffer and returns a pointer to it. */ static WINDOW * -makenew(num_lines, num_cols, begy, begx) -int num_lines, num_cols, begy, begx; { - - reg int i; - reg WINDOW *win; - reg int by, bx, nl, nc; - - by = begy; - bx = begx; - nl = num_lines; - nc = num_cols; - -# ifdef DEBUG - fprintf(outf, "MAKENEW(%d, %d, %d, %d)\n", nl, nc, by, bx); -# endif - if ((win = (WINDOW *) malloc(sizeof *win)) == NULL) - return NULL; -# ifdef DEBUG - fprintf(outf, "MAKENEW: nl = %d\n", nl); -# endif - if ((win->_y = (chtype **) malloc(nl * sizeof(chtype *))) == NULL) { +__makenew(nl, nc, by, bx, sub) + register int by, bx, nl, nc; + int sub; +{ + register WINDOW *win; + register __LINE *lp; + int i; + + +#ifdef DEBUG + __CTRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx); +#endif + if ((win = malloc(sizeof(*win))) == NULL) + return (NULL); +#ifdef DEBUG + __CTRACE("makenew: nl = %d\n", nl); +#endif + + /* + * Set up line pointer array and line space. + */ + if ((win->lines = malloc (nl * sizeof(__LINE *))) == NULL) { free(win); return NULL; } -# ifdef DEBUG - fprintf(outf, "MAKENEW: nc = %d\n", nc); -# endif - win->_cury = win->_curx = 0; - win->_clear = FALSE; - win->_maxy = nl; - win->_maxx = nc; - win->_begy = by; - win->_begx = bx; - win->_flags = 0; - win->_scroll = win->_leave = FALSE; - _swflags_(win); -# ifdef DEBUG - fprintf(outf, "MAKENEW: win->_clear = %d\n", win->_clear); - fprintf(outf, "MAKENEW: win->_leave = %d\n", win->_leave); - fprintf(outf, "MAKENEW: win->_scroll = %d\n", win->_scroll); - fprintf(outf, "MAKENEW: win->_flags = %0.2o\n", win->_flags); - fprintf(outf, "MAKENEW: win->_maxy = %d\n", win->_maxy); - fprintf(outf, "MAKENEW: win->_maxx = %d\n", win->_maxx); - fprintf(outf, "MAKENEW: win->_begy = %d\n", win->_begy); - fprintf(outf, "MAKENEW: win->_begx = %d\n", win->_begx); -# endif - return win; + if ((win->lspace = malloc (nl * sizeof(__LINE))) == NULL) { + free (win); + free (win->lines); + return NULL; + } + + /* Don't allocate window and line space if it's a subwindow */ + if (!sub) { + /* + * Allocate window space in one chunk. + */ + if ((win->wspace = + malloc(nc * nl * sizeof(__LDATA))) == NULL) { + free(win->lines); + free(win->lspace); + free(win); + return NULL; + } + + /* + * Point line pointers to line space, and lines themselves into + * window space. + */ + for (lp = win->lspace, i = 0; i < nl; i++, lp++) { + win->lines[i] = lp; + lp->line = &win->wspace[i * nc]; + lp->firstchp = &lp->firstch; + lp->lastchp = &lp->lastch; + lp->firstch = 0; + lp->lastch = 0; + } + } +#ifdef DEBUG + __CTRACE("makenew: nc = %d\n", nc); +#endif + win->cury = win->curx = 0; + win->maxy = nl; + win->maxx = nc; + + win->begy = by; + win->begx = bx; + win->flags = 0; + __swflags(win); +#ifdef DEBUG + __CTRACE("makenew: win->flags = %0.2o\n", win->flags); + __CTRACE("makenew: win->maxy = %d\n", win->maxy); + __CTRACE("makenew: win->maxx = %d\n", win->maxx); + __CTRACE("makenew: win->begy = %d\n", win->begy); + __CTRACE("makenew: win->begx = %d\n", win->begx); +#endif + return (win); } -_swflags_(win) -register WINDOW *win; +void +__swflags(win) + register WINDOW *win; { - win->_flags &= ~(_ENDLINE|_FULLLINE|_FULLWIN|_SCROLLWIN); - if (win->_begx + win->_maxx == COLS) { - win->_flags |= _ENDLINE; - if (win->_begx == 0) { - if (AL && DL) - win->_flags |= _FULLLINE; - if (win->_maxy == LINES && win->_begy == 0) - win->_flags |= _FULLWIN; + win->flags &= + ~(__ENDLINE | __FULLLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK); + if (win->begx + win->maxx == COLS) { + win->flags |= __ENDLINE; + if (win->begx == 0) { + if (!__noqch) + win->flags |= __FULLLINE; + if (win->maxy == LINES && win->begy == 0) + win->flags |= __FULLWIN; } - if (win->_begy + win->_maxy == LINES) - win->_flags |= _SCROLLWIN; + if (win->begy + win->maxy == LINES) + win->flags |= __SCROLLWIN; } } diff --git a/lib/libcurses/overlay.c b/lib/libcurses/overlay.c index d272c7ba6daf..1f50b6d1c72a 100644 --- a/lib/libcurses/overlay.c +++ b/lib/libcurses/overlay.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,46 +32,49 @@ */ #ifndef lint -static char sccsid[] = "@(#)overlay.c 5.6 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)overlay.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" - -# define min(a,b) (a < b ? a : b) -# define max(a,b) (a > b ? a : b) +#include <curses.h> /* - * This routine writes win1 on win2 non-destructively. - * + * overlay -- + * Writes win1 on win2 non-destructively. */ +int overlay(win1, win2) -reg WINDOW *win1, *win2; { + register WINDOW *win1, *win2; +{ - reg chtype *sp, *end; - reg int x, y, endy, endx, starty, startx; - reg int y1,y2; + register int x, y, y1, y2, endy, endx, starty, startx; + register __LDATA *sp, *end; -# ifdef DEBUG - fprintf(outf, "OVERLAY(%0.2o, %0.2o);\n", win1, win2); -# endif - starty = max(win1->_begy, win2->_begy); - startx = max(win1->_begx, win2->_begx); - endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begx); - endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx); -# ifdef DEBUG - fprintf(outf, "OVERLAY:from (%d,%d) to (%d,%d)\n", starty, startx, endy, endx); -# endif +#ifdef DEBUG + __CTRACE("overlay: (%0.2o, %0.2o);\n", win1, win2); +#endif + starty = max(win1->begy, win2->begy); + startx = max(win1->begx, win2->begx); + endy = min(win1->maxy + win1->begy, win2->maxy + win2->begx); + endx = min(win1->maxx + win1->begx, win2->maxx + win2->begx); +#ifdef DEBUG + __CTRACE("overlay: from (%d,%d) to (%d,%d)\n", + starty, startx, endy, endx); +#endif if (starty >= endy || startx >= endx) - return; - y1 = starty - win1->_begy; - y2 = starty - win2->_begy; + return (OK); + y1 = starty - win1->begy; + y2 = starty - win2->begy; for (y = starty; y < endy; y++, y1++, y2++) { - end = &win1->_y[y1][endx - win1->_begx]; - x = startx - win2->_begx; - for (sp = &win1->_y[y1][startx - win1->_begx]; sp < end; sp++) { - if (*sp != ' ') - mvwaddch(win2, y2, x, *sp); + end = &win1->lines[y1]->line[endx - win1->begx]; + x = startx - win2->begx; + for (sp = &win1->lines[y1]->line[startx - win1->begx]; + sp < end; sp++) { + if (sp->ch != ' ') { + wmove(win2, y2, x); + __waddch(win2, sp); + } x++; } } + return (OK); } diff --git a/lib/libcurses/overwrite.c b/lib/libcurses/overwrite.c index 655f923ab26a..0924fa7e9318 100644 --- a/lib/libcurses/overwrite.c +++ b/lib/libcurses/overwrite.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,40 +32,43 @@ */ #ifndef lint -static char sccsid[] = "@(#)overwrite.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)overwrite.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" -# include <ctype.h> - -# define min(a,b) (a < b ? a : b) -# define max(a,b) (a > b ? a : b) +#include <curses.h> +#include <string.h> /* - * This routine writes win1 on win2 destructively. - * + * overwrite -- + * Writes win1 on win2 destructively. */ +int overwrite(win1, win2) -reg WINDOW *win1, *win2; { - - reg int x, y, endy, endx, starty, startx; + register WINDOW *win1, *win2; +{ + register int x, y, endy, endx, starty, startx; -# ifdef DEBUG - fprintf(outf, "OVERWRITE(%0.2o, %0.2o);\n", win1, win2); -# endif - starty = max(win1->_begy, win2->_begy); - startx = max(win1->_begx, win2->_begx); - endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begx); - endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx); +#ifdef DEBUG + __CTRACE("overwrite: (%0.2o, %0.2o);\n", win1, win2); +#endif + starty = max(win1->begy, win2->begy); + startx = max(win1->begx, win2->begx); + endy = min(win1->maxy + win1->begy, win2->maxy + win2->begx); + endx = min(win1->maxx + win1->begx, win2->maxx + win2->begx); if (starty >= endy || startx >= endx) - return; -# ifdef DEBUG - fprintf(outf, "OVERWRITE:from (%d,%d) to (%d,%d)\n", starty, startx, endy, endx); -# endif + return (OK); +#ifdef DEBUG + __CTRACE("overwrite: from (%d, %d) to (%d, %d)\n", + starty, startx, endy, endx); +#endif x = endx - startx; for (y = starty; y < endy; y++) { - bcopy(&win1->_y[y - win1->_begy][startx - win1->_begx], - &win2->_y[y - win2->_begy][startx - win2->_begx], x * sizeof(chtype)); - touchline(win2, y, startx - win2->_begx, endx - win2->_begx); + (void)memcpy( + &win2->lines[y - win2->begy]->line[startx - win2->begx], + &win1->lines[y - win1->begy]->line[startx - win1->begx], + x * __LDATASIZE); + __touchline(win2, y, startx - win2->begx, endx - win2->begx, + 0); } + return (OK); } diff --git a/lib/libcurses/printw.c b/lib/libcurses/printw.c index 4568c5f4b875..bc34ce621b20 100644 --- a/lib/libcurses/printw.c +++ b/lib/libcurses/printw.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,8 +32,16 @@ */ #ifndef lint -static char sccsid[] = "@(#)printw.c 5.8 (Berkeley) 4/15/91"; -#endif /* not lint */ +static char sccsid[] = "@(#)printw.c 8.2 (Berkeley) 10/5/93"; +#endif /* not lint */ + +#include <curses.h> + +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif /* * printw and friends. @@ -42,17 +50,14 @@ static char sccsid[] = "@(#)printw.c 5.8 (Berkeley) 4/15/91"; * is not in effect. */ -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "curses.ext" +static int __winwrite __P((void *, const char *, int)); /* - * This routine implements a printf on the standard screen. + * printw -- + * Printf on the standard screen. */ -#if __STDC__ +int +#ifdef __STDC__ printw(const char *fmt, ...) #else printw(fmt, va_alist) @@ -60,24 +65,26 @@ printw(fmt, va_alist) va_dcl #endif { - va_list ap; - int ret; + va_list ap; + int ret; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif - ret = _sprintw(stdscr, fmt, ap); + ret = vwprintw(stdscr, fmt, ap); va_end(ap); return (ret); } /* - * This routine implements a printf on the given window. + * wprintw -- + * Printf on the given window. */ -#if __STDC__ -wprintw(WINDOW *win, const char *fmt, ...) +int +#ifdef __STDC__ +wprintw(WINDOW * win, const char *fmt, ...) #else wprintw(win, fmt, va_alist) WINDOW *win; @@ -85,56 +92,109 @@ wprintw(win, fmt, va_alist) va_dcl #endif { - va_list ap; - int ret; + va_list ap; + int ret; + +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = vwprintw(win, fmt, ap); + va_end(ap); + return (ret); +} + +/* + * mvprintw, mvwprintw -- + * Implement the mvprintw commands. Due to the variable number of + * arguments, they cannot be macros. Sigh.... + */ +int +#ifdef __STDC__ +mvprintw(register int y, register int x, const char *fmt, ...) +#else +mvprintw(y, x, fmt, va_alist) + register int y, x; + char *fmt; + va_dcl +#endif +{ + va_list ap; + int ret; + +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (move(y, x) != OK) + return (ERR); + ret = vwprintw(stdscr, fmt, ap); + va_end(ap); + return (ret); +} + +int +#ifdef __STDC__ +mvwprintw(register WINDOW * win, register int y, register int x, + const char *fmt, ...) +#else +mvwprintw(win, y, x, fmt, va_alist) + register WINDOW *win; + register int y, x; + char *fmt; + va_dcl +#endif +{ + va_list ap; + int ret; #ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif - ret = _sprintw(win, fmt, ap); + if (wmove(win, y, x) != OK) + return (ERR); + + ret = vwprintw(win, fmt, ap); va_end(ap); return (ret); } /* - * Internal write-buffer-to-window function. + * Internal write-buffer-to-window function. */ static int -_winwrite(cookie, buf, n) +__winwrite(cookie, buf, n) void *cookie; - register char *buf; + register const char *buf; int n; { - register WINDOW *win = (WINDOW *)cookie; - register int c = n; + register WINDOW *win; + register int c; - while (--c >= 0) { - if (waddch(win, (unsigned char) *buf++) == ERR) + for (c = n, win = cookie; --c >= 0;) + if (waddch(win, *buf++) == ERR) return (-1); - } - return n; + return (n); } /* + * vwprintw -- * This routine actually executes the printf and adds it to the window. - * It must not be declared static as it is used in mvprintw.c. - * THIS SHOULD BE RENAMED vwprintw AND EXPORTED */ -_sprintw(win, fmt, ap) +int +vwprintw(win, fmt, ap) WINDOW *win; -#if __STDC__ const char *fmt; -#else - char *fmt; -#endif - va_list ap; + va_list ap; { FILE *f; - if ((f = fwopen((void *)win, _winwrite)) == NULL) - return ERR; - (void) vfprintf(f, fmt, ap); - return fclose(f) ? ERR : OK; + if ((f = funopen(win, NULL, __winwrite, NULL, NULL)) == NULL) + return (ERR); + (void)vfprintf(f, fmt, ap); + return (fclose(f) ? ERR : OK); } diff --git a/lib/libcurses/putchar.c b/lib/libcurses/putchar.c index 886d1a94a399..4d90d93f1241 100644 --- a/lib/libcurses/putchar.c +++ b/lib/libcurses/putchar.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,17 +32,18 @@ */ #ifndef lint -static char sccsid[] = "@(#)putchar.c 5.4 (Berkeley) 6/1/90"; -#endif /* not lint */ +static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ -# include "curses.ext" +#include <curses.h> -char -_putchar(c) -reg char c; { +void +_putchar(ch) + int ch; +{ - putchar(c); #ifdef DEBUG - fprintf(outf, "_PUTCHAR(%s)\n", unctrl(c)); + __CTRACE("_putchar: %s\n", unctrl(ch)); #endif + (void)putchar(ch); } diff --git a/lib/libcurses/refresh.c b/lib/libcurses/refresh.c index 62673d2f8797..1a371fe45b2a 100644 --- a/lib/libcurses/refresh.c +++ b/lib/libcurses/refresh.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,308 +32,728 @@ */ #ifndef lint -static char sccsid[] = "@(#)refresh.c 5.5 (Berkeley) 3/3/91"; +static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 7/20/93"; #endif /* not lint */ -/* - * make the current screen look like "win" over the area coverd by - * win. - */ - -# include "curses.ext" - -# ifdef DEBUG -# define STATIC -# else -# define STATIC static -# endif +#include <curses.h> +#include <string.h> -STATIC short ly, lx; +static int curwin; +static short ly, lx; -STATIC bool curwin; - -WINDOW *_win = NULL; - -STATIC int domvcur(), makech(); +static void domvcur __P((int, int, int, int)); +static int makech __P((WINDOW *, int)); +static void quickch __P((WINDOW *)); +static void scrolln __P((int, int, int, int, int)); +/* + * wrefresh -- + * Make the current screen look like "win" over the area coverd by + * win. + */ +int wrefresh(win) -reg WINDOW *win; + register WINDOW *win; { - reg short wy; - reg int retval; - reg WINDOW *orig; - - /* - * make sure were in visual state - */ - if (_endwin) { - _puts(VS); - _puts(TI); - _endwin = FALSE; - } - - /* - * initialize loop parameters - */ - - ly = curscr->_cury; - lx = curscr->_curx; + register __LINE *wlp; + register int retval; + register short wy; + int dnum; + + /* Initialize loop parameters. */ + ly = curscr->cury; + lx = curscr->curx; wy = 0; - _win = win; curwin = (win == curscr); - if (win->_clear || curscr->_clear || curwin) { - if ((win->_flags & _FULLWIN) || curscr->_clear) { - _puts(CL); + if (!curwin) + for (wy = 0; wy < win->maxy; wy++) { + wlp = win->lines[wy]; + if (wlp->flags & __ISDIRTY) + wlp->hash = + __hash((char *) wlp->line, win->maxx * __LDATASIZE); + } + + if (win->flags & __CLEAROK || curscr->flags & __CLEAROK || curwin) { + if ((win->flags & __FULLWIN) || curscr->flags & __CLEAROK) { + tputs(CL, 0, __cputchar); ly = 0; lx = 0; if (!curwin) { - curscr->_clear = FALSE; - curscr->_cury = 0; - curscr->_curx = 0; + curscr->flags &= ~__CLEAROK; + curscr->cury = 0; + curscr->curx = 0; werase(curscr); } - touchwin(win); + __touchwin(win); } - win->_clear = FALSE; + win->flags &= ~__CLEAROK; } if (!CA) { - if (win->_curx != 0) - _putchar('\n'); + if (win->curx != 0) + putchar('\n'); if (!curwin) werase(curscr); } -# ifdef DEBUG - fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin); - fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n"); -# endif - for (wy = 0; wy < win->_maxy; wy++) { -# ifdef DEBUG - fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy], - win->_lastch[wy]); -# endif - if (win->_firstch[wy] != _NOCHANGE) +#ifdef DEBUG + __CTRACE("wrefresh: (%0.2o): curwin = %d\n", win, curwin); + __CTRACE("wrefresh: \tfirstch\tlastch\n"); +#endif + +#ifndef NOQCH + if ((win->flags & __FULLLINE) && !curwin) { + /* + * Invoke quickch() only if more than a quarter of the lines + * in the window are dirty. + */ + for (wy = 0, dnum = 0; wy < win->maxy; wy++) + if (win->lines[wy]->flags & (__ISDIRTY | __FORCEPAINT)) + dnum++; + /* __noqch already checked in __FULLLINE */ + if (dnum > (int) win->maxy / 4) + quickch(win); + } +#endif + +#ifdef DEBUG +{ int i, j; + __CTRACE("#####################################\n"); + for (i = 0; i < curscr->maxy; i++) { + __CTRACE("C: %d:", i); + __CTRACE(" 0x%x \n", curscr->lines[i]->hash); + for (j = 0; j < curscr->maxx; j++) + __CTRACE("%c", + curscr->lines[i]->line[j].ch); + __CTRACE("\n"); + for (j = 0; j < curscr->maxx; j++) + __CTRACE("%x", + curscr->lines[i]->line[j].attr); + __CTRACE("\n"); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); + __CTRACE(" 0x%x \n", win->lines[i - win->begy]->hash); + __CTRACE(" 0x%x ", win->lines[i - win->begy]->flags); + for (j = 0; j < win->maxx; j++) + __CTRACE("%c", + win->lines[i - win->begy]->line[j].ch); + __CTRACE("\n"); + for (j = 0; j < win->maxx; j++) + __CTRACE("%x", + win->lines[i - win->begy]->line[j].attr); + __CTRACE("\n"); + } +} +#endif /* DEBUG */ + + for (wy = 0; wy < win->maxy; wy++) { +#ifdef DEBUG + __CTRACE("%d\t%d\t%d\n", + wy, *win->lines[wy]->firstchp, *win->lines[wy]->lastchp); +#endif + if (!curwin) + curscr->lines[win->begy + wy]->hash = win->lines[wy]->hash; + if (win->lines[wy]->flags & (__ISDIRTY | __FORCEPAINT)) { if (makech(win, wy) == ERR) - return ERR; + return (ERR); else { - if (win->_firstch[wy] >= win->_ch_off) - win->_firstch[wy] = win->_maxx + - win->_ch_off; - if (win->_lastch[wy] < win->_maxx + - win->_ch_off) - win->_lastch[wy] = win->_ch_off; - if (win->_lastch[wy] < win->_firstch[wy]) - win->_firstch[wy] = _NOCHANGE; + if (*win->lines[wy]->firstchp >= win->ch_off) + *win->lines[wy]->firstchp = win->maxx + + win->ch_off; + if (*win->lines[wy]->lastchp < win->maxx + + win->ch_off) + *win->lines[wy]->lastchp = win->ch_off; + if (*win->lines[wy]->lastchp < + *win->lines[wy]->firstchp) { +#ifdef DEBUG + __CTRACE("wrefresh: line %d notdirty \n", wy); +#endif + win->lines[wy]->flags &= ~__ISDIRTY; + } } -# ifdef DEBUG - fprintf(outf, "\t%d\t%d\n", win->_firstch[wy], - win->_lastch[wy]); -# endif + + } +#ifdef DEBUG + __CTRACE("\t%d\t%d\n", *win->lines[wy]->firstchp, + *win->lines[wy]->lastchp); +#endif } + +#ifdef DEBUG + __CTRACE("refresh: ly=%d, lx=%d\n", ly, lx); +#endif if (win == curscr) - domvcur(ly, lx, win->_cury, win->_curx); + domvcur(ly, lx, win->cury, win->curx); else { - if (win->_leave) { - curscr->_cury = ly; - curscr->_curx = lx; - ly -= win->_begy; - lx -= win->_begx; - if (ly >= 0 && ly < win->_maxy && lx >= 0 && - lx < win->_maxx) { - win->_cury = ly; - win->_curx = lx; - } - else - win->_cury = win->_curx = 0; - } - else { - domvcur(ly, lx, win->_cury + win->_begy, - win->_curx + win->_begx); - curscr->_cury = win->_cury + win->_begy; - curscr->_curx = win->_curx + win->_begx; + if (win->flags & __LEAVEOK) { + curscr->cury = ly; + curscr->curx = lx; + ly -= win->begy; + lx -= win->begx; + if (ly >= 0 && ly < win->maxy && lx >= 0 && + lx < win->maxx) { + win->cury = ly; + win->curx = lx; + } else + win->cury = win->curx = 0; + } else { + domvcur(ly, lx, win->cury + win->begy, + win->curx + win->begx); + curscr->cury = win->cury + win->begy; + curscr->curx = win->curx + win->begx; } } retval = OK; -ret: - _win = NULL; - fflush(stdout); - return retval; + + (void)fflush(stdout); + return (retval); } /* - * make a change on the screen + * makech -- + * Make a change on the screen. */ -STATIC +static int makech(win, wy) -reg WINDOW *win; -short wy; + register WINDOW *win; + int wy; { - reg chtype *nsp, *csp, *ce; - reg short wx, lch, y; - reg int nlsp, clsp; /* last space in lines */ - char *ce_tcap; - static chtype blank[] = {' ','\0'}; - - wx = win->_firstch[wy] - win->_ch_off; - if (wx >= win->_maxx) - return OK; - else if (wx < 0) + static __LDATA blank = {' ', 0}; + register int nlsp, clsp; /* Last space in lines. */ + register int wx, lch, y; + register __LDATA *nsp, *csp, *cp, *cep; + u_int force; + char *ce; + + /* Is the cursor still on the end of the last line? */ + if (wy > 0 && win->lines[wy - 1]->flags & __ISPASTEOL) { + domvcur(ly, lx, ly + 1, 0); + ly++; + lx = 0; + } + wx = *win->lines[wy]->firstchp - win->ch_off; + if (wx < 0) wx = 0; - lch = win->_lastch[wy] - win->_ch_off; + else if (wx >= win->maxx) + return (OK); + lch = *win->lines[wy]->lastchp - win->ch_off; if (lch < 0) - return OK; - else if (lch >= win->_maxx) - lch = win->_maxx - 1;; - y = wy + win->_begy; + return (OK); + else if (lch >= (int) win->maxx) + lch = win->maxx - 1; + y = wy + win->begy; if (curwin) - csp = blank; + csp = ␣ else - csp = &curscr->_y[wy + win->_begy][wx + win->_begx]; + csp = &curscr->lines[wy + win->begy]->line[wx + win->begx]; - nsp = &win->_y[wy][wx]; + nsp = &win->lines[wy]->line[wx]; + force = win->lines[wy]->flags & __FORCEPAINT; + win->lines[wy]->flags &= ~__FORCEPAINT; if (CE && !curwin) { - for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--) - if (ce <= win->_y[wy]) + for (cp = &win->lines[wy]->line[win->maxx - 1]; + cp->ch == ' ' && cp->attr == 0; cp--) + if (cp <= win->lines[wy]->line) break; - nlsp = ce - win->_y[wy]; + nlsp = cp - win->lines[wy]->line; } - if (!curwin) - ce_tcap = CE; + ce = CE; else - ce_tcap = NULL; + ce = NULL; + if (force) { + if (CM) + tputs(tgoto(CM, lx, ly), 0, __cputchar); + else { + tputs(HO, 0, __cputchar); + __mvcur(0, 0, ly, lx, 1); + } + } while (wx <= lch) { - if (*nsp != *csp) { - domvcur(ly, lx, y, wx + win->_begx); -# ifdef DEBUG - fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx); -# endif - ly = y; - lx = wx + win->_begx; - while (*nsp != *csp && wx <= lch) { - if (ce_tcap != NULL && wx >= nlsp && *nsp == ' ') { - /* - * check for clear to end-of-line - */ - ce = &curscr->_y[ly][COLS - 1]; - while (*ce == ' ') - if (ce-- <= csp) - break; - clsp = ce - curscr->_y[ly] - win->_begx; -# ifdef DEBUG - fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp); -# endif - if (clsp - nlsp >= strlen(CE) - && clsp < win->_maxx) { -# ifdef DEBUG - fprintf(outf, "MAKECH: using CE\n"); -# endif - _puts(CE); - lx = wx + win->_begx; - while (wx++ <= clsp) - *csp++ = ' '; - return OK; - } - ce_tcap = NULL; - } - /* - * enter/exit standout mode as appropriate - */ - if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) { - if (*nsp & _STANDOUT) { - _puts(SO); - curscr->_flags |= _STANDOUT; - } - else { - _puts(SE); - curscr->_flags &= ~_STANDOUT; - } - } - wx++; - if (wx >= win->_maxx && wy == win->_maxy - 1) - if (win->_scroll) { - if ((curscr->_flags&_STANDOUT) && - (win->_flags & _ENDLINE)) - if (!MS) { - _puts(SE); - curscr->_flags &= ~_STANDOUT; - } + if (!force && memcmp(nsp, csp, sizeof(__LDATA)) == 0) { + if (wx <= lch) { + while (wx <= lch && + memcmp(nsp, csp, sizeof(__LDATA)) == 0) { + nsp++; if (!curwin) - _putchar((*csp = *nsp)); - else - _putchar(*nsp); - if (win->_flags&_FULLWIN && !curwin) - scroll(curscr); - ly = win->_begy+win->_cury; - lx = win->_begx+win->_curx; - return OK; - } - else if (win->_flags&_SCROLLWIN) { - lx = --wx; - return ERR; + csp++; + ++wx; + } + continue; + } + break; + } + domvcur(ly, lx, y, wx + win->begx); + +#ifdef DEBUG + __CTRACE("makech: 1: wx = %d, ly= %d, lx = %d, newy = %d, newx = %d, force =%d\n", + wx, ly, lx, y, wx + win->begx, force); +#endif + ly = y; + lx = wx + win->begx; + while ((force || memcmp(nsp, csp, sizeof(__LDATA)) != 0) + && wx <= lch) { + + if (ce != NULL && win->maxx + win->begx == + curscr->maxx && wx >= nlsp && nsp->ch == ' ') { + /* Check for clear to end-of-line. */ + cep = &curscr->lines[win->begy + wy]->line[win->begx + win->maxx - 1]; + while (cep->ch == ' ' && cep->attr == 0) + if (cep-- <= csp) + break; + clsp = cep - curscr->lines[win->begy + wy]->line - + win->begx; +#ifdef DEBUG + __CTRACE("makech: clsp = %d, nlsp = %d\n", clsp, nlsp); +#endif + if ((clsp - nlsp >= strlen(CE) + && clsp < win->maxx) || + wy == win->maxy - 1) { +#ifdef DEBUG + __CTRACE("makech: using CE\n"); +#endif + tputs(CE, 0, __cputchar); + lx = wx + win->begx; + while (wx++ <= clsp) { + csp->ch = ' '; + csp->attr = 0; + csp++; } - if (!curwin) - _putchar((*csp++ = *nsp)); - else - _putchar(*nsp); -# ifdef FULLDEBUG - fprintf(outf, - "MAKECH:putchar(%c)\n", *nsp); -# endif - if (UC && (*nsp & _STANDOUT)) { - _putchar('\b'); - _puts(UC); + return (OK); } - nsp++; + ce = NULL; } -# ifdef DEBUG - fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx); -# endif - if (lx == wx + win->_begx) /* if no change */ - break; - lx = wx + win->_begx; - if (lx >= COLS && AM) { - lx = 0; - ly++; - /* - * xn glitch: chomps a newline after auto-wrap. - * we just feed it now and forget about it. - */ - if (XN) { - _putchar('\n'); - _putchar('\r'); + + /* Enter/exit standout mode as appropriate. */ + if (SO && (nsp->attr & __STANDOUT) != + (curscr->flags & __WSTANDOUT)) { + if (nsp->attr & __STANDOUT) { + tputs(SO, 0, __cputchar); + curscr->flags |= __WSTANDOUT; + } else { + tputs(SE, 0, __cputchar); + curscr->flags &= ~__WSTANDOUT; } } - } - else if (wx <= lch) - while (*nsp == *csp && wx <= lch) { - nsp++; - if (!curwin) + + wx++; + if (wx >= win->maxx && wy == win->maxy - 1 && !curwin) + if (win->flags & __SCROLLOK) { + if (curscr->flags & __WSTANDOUT + && win->flags & __ENDLINE) + if (!MS) { + tputs(SE, 0, + __cputchar); + curscr->flags &= + ~__WSTANDOUT; + } + if (!(win->flags & __SCROLLWIN)) { + if (!curwin) { + csp->attr = nsp->attr; + putchar(csp->ch = nsp->ch); + } else + putchar(nsp->ch); + } + if (wx + win->begx < curscr->maxx) { + domvcur(ly, wx + win->begx, + win->begy + win->maxy - 1, + win->begx + win->maxx - 1); + } + ly = win->begy + win->maxy - 1; + lx = win->begx + win->maxx - 1; + return (OK); + } + if (wx < win->maxx || wy < win->maxy - 1 || + !(win->flags & __SCROLLWIN)) { + if (!curwin) { + csp->attr = nsp->attr; + putchar(csp->ch = nsp->ch); csp++; - ++wx; + } else + putchar(nsp->ch); } - else +#ifdef DEBUG + __CTRACE("makech: putchar(%c)\n", nsp->ch & 0177); +#endif + if (UC && (nsp->attr & __STANDOUT)) { + putchar('\b'); + tputs(UC, 0, __cputchar); + } + nsp++; +#ifdef DEBUG + __CTRACE("makech: 2: wx = %d, lx = %d\n", wx, lx); +#endif + } + if (lx == wx + win->begx) /* If no change. */ break; -# ifdef DEBUG - fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx); -# endif + lx = wx + win->begx; + if (lx >= COLS && AM) + lx = COLS - 1; + else if (wx >= win->maxx) { + domvcur(ly, lx, ly, win->maxx + win->begx - 1); + lx = win->maxx + win->begx - 1; + } + +#ifdef DEBUG + __CTRACE("makech: 3: wx = %d, lx = %d\n", wx, lx); +#endif } - return OK; + return (OK); } /* - * perform a mvcur, leaving standout mode if necessary + * domvcur -- + * Do a mvcur, leaving standout mode if necessary. */ -STATIC +static void domvcur(oy, ox, ny, nx) -int oy, ox, ny, nx; { + int oy, ox, ny, nx; +{ + if (curscr->flags & __WSTANDOUT && !MS) { + tputs(SE, 0, __cputchar); + curscr->flags &= ~__WSTANDOUT; + } + + __mvcur(oy, ox, ny, nx, 1); +} + +/* + * Quickch() attempts to detect a pattern in the change of the window + * in order to optimize the change, e.g., scroll n lines as opposed to + * repainting the screen line by line. + */ + +static void +quickch(win) + WINDOW *win; +{ +#define THRESH (int) win->maxy / 4 + + register __LINE *clp, *tmp1, *tmp2; + register int bsize, curs, curw, starts, startw, i, j; + int n, target, cur_period, bot, top, sc_region; + __LDATA buf[1024]; + u_int blank_hash; + + /* + * Find how many lines from the top of the screen are unchanged. + */ + for (top = win->begy; top < win->begy + win->maxy; top++) + if (win->lines[top - win->begy]->flags & __FORCEPAINT || + win->lines[top - win->begy]->hash != curscr->lines[top]->hash + || memcmp(win->lines[top - win->begy]->line, + curscr->lines[top]->line, + win->maxx * __LDATASIZE) != 0) + break; + else + win->lines[top - win->begy]->flags &= ~__ISDIRTY; + /* + * Find how many lines from bottom of screen are unchanged. + */ + for (bot = win->begy + win->maxy - 1; bot >= (int) win->begy; bot--) { + if (win->lines[bot - win->begy]->flags & __FORCEPAINT || + win->lines[bot - win->begy]->hash != curscr->lines[bot]->hash + || memcmp(win->lines[bot - win->begy]->line, + curscr->lines[bot]->line, + win->maxx * __LDATASIZE) != 0) + break; + else + win->lines[bot - win->begy]->flags &= ~__ISDIRTY; + } + +#ifdef NO_JERKINESS + /* + * If we have a bottom unchanged region return. Scrolling the + * bottom region up and then back down causes a screen jitter. + * This will increase the number of characters sent to the screen + * but it looks better. + */ + if (bot < (int) win->begy + win->maxy - 1) + return; +#endif /* NO_JERKINESS */ + + /* + * Search for the largest block of text not changed. + * Invariants of the loop: + * - Startw is the index of the beginning of the examined block in win. + * - Starts is the index of the beginning of the examined block in + * curscr. + * - Curw is the index of one past the end of the exmined block in win. + * - Curs is the index of one past the end of the exmined block in + * curscr. + * - bsize is the current size of the examined block. + */ + for (bsize = bot - top; bsize >= THRESH; bsize--) { + for (startw = top; startw <= bot - bsize; startw++) + for (starts = top; starts <= bot - bsize; + starts++) { + for (curw = startw, curs = starts; + curs < starts + bsize; curw++, curs++) + if (win->lines[curw - win->begy]->flags & + __FORCEPAINT || + (win->lines[curw - win->begy]->hash != + curscr->lines[curs]->hash || + memcmp(win->lines[curw - win->begy]->line, + curscr->lines[curs]->line, + win->maxx * __LDATASIZE) != 0)) + break; + if (curs == starts + bsize) + goto done; + } + } + done: + /* Did not find anything */ + if (bsize < THRESH) + return; + +#ifdef DEBUG + __CTRACE("quickch:bsize=%d,starts=%d,startw=%d,curw=%d,curs=%d,top=%d,bot=%d\n", + bsize, starts, startw, curw, curs, top, bot); +#endif + + /* + * Make sure that there is no overlap between the bottom and top + * regions and the middle scrolled block. + */ + if (bot < curs) + bot = curs - 1; + if (top > starts) + top = starts; - if (curscr->_flags & _STANDOUT && !MS) { - _puts(SE); - curscr->_flags &= ~_STANDOUT; + n = startw - starts; + +#ifdef DEBUG + __CTRACE("#####################################\n"); + for (i = 0; i < curscr->maxy; i++) { + __CTRACE("C: %d:", i); + __CTRACE(" 0x%x \n", curscr->lines[i]->hash); + for (j = 0; j < curscr->maxx; j++) + __CTRACE("%c", + curscr->lines[i]->line[j].ch); + __CTRACE("\n"); + for (j = 0; j < curscr->maxx; j++) + __CTRACE("%x", + curscr->lines[i]->line[j].attr); + __CTRACE("\n"); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); + __CTRACE(" 0x%x \n", win->lines[i - win->begy]->hash); + __CTRACE(" 0x%x ", win->lines[i - win->begy]->flags); + for (j = 0; j < win->maxx; j++) + __CTRACE("%c", + win->lines[i - win->begy]->line[j].ch); + __CTRACE("\n"); + for (j = 0; j < win->maxx; j++) + __CTRACE("%x", + win->lines[i - win->begy]->line[j].attr); + __CTRACE("\n"); + } +#endif + + /* So we don't have to call __hash() each time */ + for (i = 0; i < win->maxx; i++) { + buf[i].ch = ' '; + buf[i].attr = 0; + } + blank_hash = __hash((char *) buf, win->maxx * __LDATASIZE); + + /* + * Perform the rotation to maintain the consistency of curscr. + * This is hairy since we are doing an *in place* rotation. + * Invariants of the loop: + * - I is the index of the current line. + * - Target is the index of the target of line i. + * - Tmp1 points to current line (i). + * - Tmp2 and points to target line (target); + * - Cur_period is the index of the end of the current period. + * (see below). + * + * There are 2 major issues here that make this rotation non-trivial: + * 1. Scrolling in a scrolling region bounded by the top + * and bottom regions determined (whose size is sc_region). + * 2. As a result of the use of the mod function, there may be a + * period introduced, i.e., 2 maps to 4, 4 to 6, n-2 to 0, and + * 0 to 2, which then causes all odd lines not to be rotated. + * To remedy this, an index of the end ( = beginning) of the + * current 'period' is kept, cur_period, and when it is reached, + * the next period is started from cur_period + 1 which is + * guaranteed not to have been reached since that would mean that + * all records would have been reached. (think about it...). + * + * Lines in the rotation can have 3 attributes which are marked on the + * line so that curscr is consistent with the visual screen. + * 1. Not dirty -- lines inside the scrolled block, top region or + * bottom region. + * 2. Blank lines -- lines in the differential of the scrolling + * region adjacent to top and bot regions + * depending on scrolling direction. + * 3. Dirty line -- all other lines are marked dirty. + */ + sc_region = bot - top + 1; + i = top; + tmp1 = curscr->lines[top]; + cur_period = top; + for (j = top; j <= bot; j++) { + target = (i - top + n + sc_region) % sc_region + top; + tmp2 = curscr->lines[target]; + curscr->lines[target] = tmp1; + /* Mark block as clean and blank out scrolled lines. */ + clp = curscr->lines[target]; +#ifdef DEBUG + __CTRACE("quickch: n=%d startw=%d curw=%d i = %d target=%d ", + n, startw, curw, i, target); +#endif + if ((target >= startw && target < curw) || target < top + || target > bot) { +#ifdef DEBUG + __CTRACE("-- notdirty"); +#endif + win->lines[target - win->begy]->flags &= ~__ISDIRTY; + } else if ((n > 0 && target >= top && target < top + n) || + (n < 0 && target <= bot && target > bot + n)) { + if (clp->hash != blank_hash || memcmp(clp->line, + buf, win->maxx * __LDATASIZE) !=0) { + (void)memcpy(clp->line, buf, + win->maxx * __LDATASIZE); +#ifdef DEBUG + __CTRACE("-- blanked out: dirty"); +#endif + clp->hash = blank_hash; + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); + } else { + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); +#ifdef DEBUG + __CTRACE(" -- blank line already: dirty"); +#endif + } + } else { +#ifdef DEBUG + __CTRACE(" -- dirty"); +#endif + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); + } +#ifdef DEBUG + __CTRACE("\n"); +#endif + if (target == cur_period) { + i = target + 1; + tmp1 = curscr->lines[i]; + cur_period = i; + } else { + tmp1 = tmp2; + i = target; + } + } +#ifdef DEBUG + __CTRACE("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + for (i = 0; i < curscr->maxy; i++) { + __CTRACE("C: %d:", i); + for (j = 0; j < curscr->maxx; j++) + __CTRACE("%c", + curscr->lines[i]->line[j].ch); + __CTRACE("\n"); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); + for (j = 0; j < win->maxx; j++) + __CTRACE("%c", + win->lines[i - win->begy]->line[j].ch); + __CTRACE("\n"); + } +#endif + if (n != 0) { + WINDOW *wp; + scrolln(starts, startw, curs, bot, top); + /* + * Need to repoint any subwindow lines to the rotated + * line structured. + */ + for (wp = win->nextp; wp != win; wp = wp->nextp) + __set_subwin(win, wp); + } +} + +/* + * Scrolln performs the scroll by n lines, where n is starts - startw. + */ +static void +scrolln(starts, startw, curs, bot, top) + int starts, startw, curs, bot, top; +{ + int i, oy, ox, n; + + oy = curscr->cury; + ox = curscr->curx; + n = starts - startw; + + if (!__usecs) { /* Use insert/delete line */ + if (n > 0) { + __mvcur(oy, ox, top, 0, 1); + /* Scroll up the block */ + if (DL && (!dl || n > 1)) + tputs(__tscroll(DL, n), 0, __cputchar); + else + for(i = 0; i < n; i++) + tputs(dl, 0, __cputchar); + + /* + * Push down the bottom region. + */ + __mvcur(top, 0, bot - n + 1, 0, 1); + if (AL && (!al || n > 1)) + tputs(__tscroll(AL, n), 0, __cputchar); + else + for(i = 0; i < n; i++) + tputs(al, 0, __cputchar); + __mvcur(bot - n + 1, 0, oy, ox, 1); + } else { + /* Preserve the bottom lines */ + __mvcur(oy, ox, bot + n + 1, 0, 1); /* n < 0 */ + if (DL && (!dl || -n > 1)) + tputs(__tscroll(DL, -n), 0, __cputchar); + else + for(i = n; i < 0; i++) + tputs(dl, 0, __cputchar); + __mvcur(bot + n + 1, 0, top, 0, 1); + + /* Scroll the block down */ + if (AL && (!al || -n > 1)) + tputs(__tscroll(AL, -n), 0, __cputchar); + else + for(i = n; i < 0; i++) + tputs(al, 0, __cputchar); + __mvcur(top, 0, oy, ox, 1); + } + } else { /* Use change scroll region */ + if (bot != curscr->maxy - 1 || top != 0) + __set_scroll_region(top, bot); + if (n > 0) { + __mvcur(oy, ox, bot, 0, 1); + /* Scroll up the block */ + if (SF && n > 1) + tputs(__tscroll(SF, n), 0, __cputchar); + else + for(i = 0; i < n; i++) + if (NL && __pfast) + tputs(NL, 0, __cputchar); + else + putchar('\n'); + __mvcur(bot, 0, oy, ox, 1); + } else { + __mvcur(oy, ox, top, 0, 1); + /* Scroll the block down */ + if (SR && (!sr || -n > 1)) + tputs(__tscroll(SR, -n), 0, __cputchar); + else + for(i = n; i < 0; i++) + tputs(sr, 0, __cputchar); + __mvcur(top, 0, oy, ox, 1); + } + if (bot != curscr->maxy - 1 || top != 0) + __set_scroll_region(0, curscr->maxy - 1); } - mvcur(oy, ox, ny, nx); } diff --git a/lib/libcurses/scanw.c b/lib/libcurses/scanw.c index 470b9bd47371..ddd1ba9278d5 100644 --- a/lib/libcurses/scanw.c +++ b/lib/libcurses/scanw.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,25 +32,27 @@ */ #ifndef lint -static char sccsid[] = "@(#)scanw.c 5.7 (Berkeley) 4/15/91"; -#endif /* not lint */ +static char sccsid[] = "@(#)scanw.c 8.2 (Berkeley) 10/5/93"; +#endif /* not lint */ /* - * scanw and friends - * + * scanw and friends. */ -#if __STDC__ +#include <curses.h> + +#ifdef __STDC__ #include <stdarg.h> #else #include <varargs.h> #endif -#include "curses.ext" /* - * This routine implements a scanf on the standard screen. + * scanw -- + * Implement a scanf on the standard screen. */ -#if __STDC__ +int +#ifdef __STDC__ scanw(const char *fmt, ...) #else scanw(fmt, va_alist) @@ -61,20 +63,22 @@ scanw(fmt, va_alist) va_list ap; int ret; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif - ret = _sscans(stdscr, fmt, ap); + ret = vwscanw(stdscr, fmt, ap); va_end(ap); - return ret; + return (ret); } /* - * This routine implements a scanf on the given window. + * wscanw -- + * Implements a scanf on the given window. */ -#if __STDC__ +int +#ifdef __STDC__ wscanw(WINDOW *win, const char *fmt, ...) #else wscanw(win, fmt, va_alist) @@ -86,30 +90,86 @@ wscanw(win, fmt, va_alist) va_list ap; int ret; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif - ret = _sscans(win, fmt, ap); + ret = vwscanw(win, fmt, ap); va_end(ap); - return ret; + return (ret); } /* - * This routine actually executes the scanf from the window. - * THIS SHOULD BE RENAMED vwscanw AND EXPORTED + * mvscanw, mvwscanw -- + * Implement the mvscanw commands. Due to the variable number of + * arguments, they cannot be macros. Another sigh.... */ -_sscans(win, fmt, ap) - WINDOW *win; -#if __STDC__ - const char *fmt; +int +#ifdef __STDC__ +mvscanw(register int y, register int x, const char *fmt,...) +#else +mvscanw(y, x, fmt, va_alist) + register int y, x; + char *fmt; + va_dcl +#endif +{ + va_list ap; + int ret; + + if (move(y, x) != OK) + return (ERR); +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = vwscanw(stdscr, fmt, ap); + va_end(ap); + return (ret); +} + +int +#ifdef __STDC__ +mvwscanw(register WINDOW * win, register int y, register int x, + const char *fmt, ...) #else +mvwscanw(win, y, x, fmt, va_alist) + register WINDOW *win; + register int y, x; char *fmt; + va_dcl #endif +{ + va_list ap; + int ret; + + if (move(y, x) != OK) + return (ERR); +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = vwscanw(win, fmt, ap); + va_end(ap); + return (ret); +} + +/* + * vwscanw -- + * This routine actually executes the scanf from the window. + */ +int +vwscanw(win, fmt, ap) + WINDOW *win; + const char *fmt; va_list ap; { - char buf[100]; - return wgetstr(win, buf) == OK ? vsscanf(buf, fmt, ap) : ERR; + char buf[1024]; + + return (wgetstr(win, buf) == OK ? + vsscanf(buf, fmt, ap) : ERR); } diff --git a/lib/libcurses/scroll.c b/lib/libcurses/scroll.c index 25cf822cba84..1b03eccab9d1 100644 --- a/lib/libcurses/scroll.c +++ b/lib/libcurses/scroll.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,26 +32,27 @@ */ #ifndef lint -static char sccsid[] = "@(#)scroll.c 5.4 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)scroll.c 8.2 (Berkeley) 1/9/94"; #endif /* not lint */ -# include "curses.ext" +#include <curses.h> /* - * This routine scrolls the window up a line. - * + * scroll -- + * Scroll the window up a line. */ +int scroll(win) -register WINDOW *win; + register WINDOW *win; { - register int oy, ox; + register int oy, ox; -# ifdef DEBUG - fprintf(outf, "SCROLL(%0.2o)\n", win); -# endif +#ifdef DEBUG + __CTRACE("scroll: (%0.2o)\n", win); +#endif - if (!win->_scroll) - return ERR; + if (!(win->flags & __SCROLLOK)) + return (ERR); getyx(win, oy, ox); wmove(win, 0, 0); @@ -59,11 +60,12 @@ register WINDOW *win; wmove(win, oy, ox); if (win == curscr) { - _putchar('\n'); + putchar('\n'); if (!NONL) - win->_curx = 0; -# ifdef DEBUG - fprintf(outf, "SCROLL: win == curscr\n"); -# endif + win->curx = 0; +#ifdef DEBUG + __CTRACE("scroll: win == curscr\n"); +#endif } + return (OK); } diff --git a/lib/libcurses/setterm.c b/lib/libcurses/setterm.c new file mode 100644 index 000000000000..35e4e55b26d6 --- /dev/null +++ b/lib/libcurses/setterm.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)setterm.c 8.3 (Berkeley) 1/2/94"; +#endif /* not lint */ + +#include <sys/ioctl.h> + +#include <curses.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void zap __P((void)); + +static char *sflags[] = { + /* am bs da eo hc in mi ms */ + &AM, &BS, &DA, &EO, &HC, &IN, &MI, &MS, + /* nc ns os ul xb xn xt xs xx */ + &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS, &XX + }; + +static char *_PC, + **sstrs[] = { + /* AL bc bt cd ce cl cm cr cs */ + &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS, + /* dc DL dm do ed ei k0 k1 k2 */ + &DC, &DL, &DM, &DO, &ED, &EI, &K0, &K1, &K2, + /* k3 k4 k5 k6 k7 k8 k9 ho ic */ + &K3, &K4, &K5, &K6, &K7, &K8, &K9, &HO, &IC, + /* im ip kd ke kh kl kr ks ku */ + &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, + /* ll ma nd nl pc rc sc se SF */ + &LL, &MA, &ND, &NL, &_PC, &RC, &SC, &SE, &SF, + /* so SR ta te ti uc ue up us */ + &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US, + /* vb vs ve al dl sf sr AL */ + &VB, &VS, &VE, &al, &dl, &sf, &sr, &AL_PARM, + /* DL UP DO LE */ + &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, + /* RI */ + &RIGHT_PARM, + }; + +static char *aoftspace; /* Address of _tspace for relocation */ +static char tspace[2048]; /* Space for capability strings */ + +char *ttytype; + +int +setterm(type) + register char *type; +{ + static char genbuf[1024]; + static char __ttytype[1024]; + register int unknown; + struct winsize win; + char *p; + +#ifdef DEBUG + __CTRACE("setterm: (\"%s\")\nLINES = %d, COLS = %d\n", + type, LINES, COLS); +#endif + if (type[0] == '\0') + type = "xx"; + unknown = 0; + if (tgetent(genbuf, type) != 1) { + unknown++; + strcpy(genbuf, "xx|dumb:"); + } +#ifdef DEBUG + __CTRACE("setterm: tty = %s\n", type); +#endif + + /* Try TIOCGWINSZ, and, if it fails, the termcap entry. */ + if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1 && + win.ws_row != 0 && win.ws_col != 0) { + LINES = win.ws_row; + COLS = win.ws_col; + } else { + LINES = tgetnum("li"); + COLS = tgetnum("co"); + } + + /* POSIX 1003.2 requires that the environment override. */ + if ((p = getenv("LINES")) != NULL) + LINES = strtol(p, NULL, 10); + if ((p = getenv("COLUMNS")) != NULL) + COLS = strtol(p, NULL, 10); + + /* + * Want cols > 4, otherwise things will fail. + */ + if (COLS <= 4) + return (ERR); + +#ifdef DEBUG + __CTRACE("setterm: LINES = %d, COLS = %d\n", LINES, COLS); +#endif + aoftspace = tspace; + zap(); /* Get terminal description. */ + + /* If we can't tab, we can't backtab, either. */ + if (!GT) + BT = NULL; + + /* + * Test for cursor motion capbility. + * + * XXX + * This is truly stupid -- tgoto returns "OOPS" if it can't + * do cursor motions. + */ + if (tgoto(CM, 0, 0)[0] == 'O') { + CA = 0; + CM = 0; + } else + CA = 1; + + PC = _PC ? _PC[0] : 0; + aoftspace = tspace; + ttytype = longname(genbuf, __ttytype); + + if (!NS && SC && RC && CS && (sr || SR)) + __usecs = 1; + + if ((!AL && !al || !DL && !dl) && !__usecs) + __noqch = 1; + + return (unknown ? ERR : OK); +} + +/* + * zap -- + * Gets all the terminal flags from the termcap database. + */ +static void +zap() +{ + register char *namp, ***sp; + register char **fp; + char tmp[3]; +#ifdef DEBUG + register char *cp; +#endif + tmp[2] = '\0'; + + namp = "ambsdaeohcinmimsncnsosulxbxnxtxsxx"; + fp = sflags; + do { + *tmp = *namp; + *(tmp + 1) = *(namp + 1); + *(*fp++) = tgetflag(tmp); +#ifdef DEBUG + __CTRACE("2.2s = %s\n", namp, *fp[-1] ? "TRUE" : "FALSE"); +#endif + namp += 2; + + } while (*namp); + namp = "ALbcbtcdceclcmcrcsdcDLdmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullmandnlpcrcscseSFsoSRtatetiucueupusvbvsvealdlsfsrALDLUPDOLERI"; + sp = sstrs; + do { + *tmp = *namp; + *(tmp + 1) = *(namp + 1); + *(*sp++) = tgetstr(tmp, &aoftspace); +#ifdef DEBUG + __CTRACE("2.2s = %s", namp, *sp[-1] == NULL ? "NULL\n" : "\""); + if (*sp[-1] != NULL) { + for (cp = *sp[-1]; *cp; cp++) + __CTRACE("%s", unctrl(*cp)); + __CTRACE("\"\n"); + } +#endif + namp += 2; + } while (*namp); + if (XS) + SO = SE = NULL; + else { + if (tgetnum("sg") > 0) + SO = NULL; + if (tgetnum("ug") > 0) + US = NULL; + if (!SO && US) { + SO = US; + SE = UE; + } + } +} + +/* + * getcap -- + * Return a capability from termcap. + */ +char * +getcap(name) + char *name; +{ + return (tgetstr(name, &aoftspace)); +} diff --git a/lib/libcurses/standout.c b/lib/libcurses/standout.c index 9cdaee6b1074..14a983da6185 100644 --- a/lib/libcurses/standout.c +++ b/lib/libcurses/standout.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,40 +32,37 @@ */ #ifndef lint -static char sccsid[] = "@(#)standout.c 5.4 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)standout.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint */ -/* - * routines dealing with entering and exiting standout mode - * - */ - -# include "curses.ext" +#include <curses.h> /* - * enter standout mode + * wstandout + * Enter standout mode. */ -char * +int wstandout(win) -reg WINDOW *win; + register WINDOW *win; { if (!SO && !UC) - return FALSE; + return (0); - win->_flags |= _STANDOUT; - return (SO ? SO : UC); + win->flags |= __WSTANDOUT; + return (1); } /* - * exit standout mode + * wstandend -- + * Exit standout mode. */ -char * +int wstandend(win) -reg WINDOW *win; + register WINDOW *win; { if (!SO && !UC) - return FALSE; + return (0); - win->_flags &= ~_STANDOUT; - return (SE ? SE : UC); + win->flags &= ~__WSTANDOUT; + return (1); } diff --git a/lib/libcurses/toucholap.c b/lib/libcurses/toucholap.c index 4404755a731c..8924ebe24798 100644 --- a/lib/libcurses/toucholap.c +++ b/lib/libcurses/toucholap.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,42 +32,46 @@ */ #ifndef lint -static char sccsid[] = "@(#)toucholap.c 5.4 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)toucholap.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint */ -# include "curses.ext" - -# define min(a,b) (a < b ? a : b) -# define max(a,b) (a > b ? a : b) +#include <curses.h> /* + * touchoverlap -- * Touch, on win2, the part that overlaps with win1. - * */ +int touchoverlap(win1, win2) -reg WINDOW *win1, *win2; { + register WINDOW *win1, *win2; +{ + register int y, endy, endx, starty, startx; - reg int x, y, endy, endx, starty, startx; - -# ifdef DEBUG - fprintf(outf, "TOUCHOVERLAP(%0.2o, %0.2o);\n", win1, win2); -# endif - starty = max(win1->_begy, win2->_begy); - startx = max(win1->_begx, win2->_begx); - endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begx); - endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx); -# ifdef DEBUG - fprintf(outf, "TOUCHOVERLAP:from (%d,%d) to (%d,%d)\n", starty, startx, endy, endx); - fprintf(outf, "TOUCHOVERLAP:win1 (%d,%d) to (%d,%d)\n", win1->_begy, win1->_begx, win1->_begy + win1->_maxy, win1->_begx + win1->_maxx); - fprintf(outf, "TOUCHOVERLAP:win2 (%d,%d) to (%d,%d)\n", win2->_begy, win2->_begx, win2->_begy + win2->_maxy, win2->_begx + win2->_maxx); -# endif +#ifdef DEBUG + __CTRACE("touchoverlap: (%0.2o, %0.2o);\n", win1, win2); +#endif + starty = max(win1->begy, win2->begy); + startx = max(win1->begx, win2->begx); + endy = min(win1->maxy + win1->begy, win2->maxy + win2->begx); + endx = min(win1->maxx + win1->begx, win2->maxx + win2->begx); +#ifdef DEBUG + __CTRACE("touchoverlap: from (%d,%d) to (%d,%d)\n", + starty, startx, endy, endx); + __CTRACE("touchoverlap: win1 (%d,%d) to (%d,%d)\n", + win1->begy, win1->begx, win1->begy + win1->maxy, + win1->begx + win1->maxx); + __CTRACE("touchoverlap: win2 (%d,%d) to (%d,%d)\n", + win2->begy, win2->begx, win2->begy + win2->maxy, + win2->begx + win2->maxx); +#endif if (starty >= endy || startx >= endx) - return; - starty -= win2->_begy; - startx -= win2->_begx; - endy -= win2->_begy; - endx -= win2->_begx; - endx--; - for (y = starty; y < endy; y++) - touchline(win2, y, startx, endx); + return (OK); + starty -= win2->begy; + startx -= win2->begx; + endy -= win2->begy; + endx -= win2->begx; + for (--endx, y = starty; y < endy; y++) + __touchline(win2, y, startx, endx, 0); + return (OK); } + diff --git a/lib/libcurses/touchwin.c b/lib/libcurses/touchwin.c index 13d433138956..68fa78588922 100644 --- a/lib/libcurses/touchwin.c +++ b/lib/libcurses/touchwin.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,52 +32,90 @@ */ #ifndef lint -static char sccsid[] = "@(#)touchwin.c 5.4 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)touchwin.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint */ -# include "curses.ext" +#include <curses.h> + /* - * make it look like the whole window has been changed. - * + * touchline -- + * Touch a given line. */ +int +touchline(win, y, sx, ex) + WINDOW *win; + register int y, sx, ex; +{ + return (__touchline(win, y, sx, ex, 1)); +} + + +/* + * touchwin -- + * Make it look like the whole window has been changed. + */ +int touchwin(win) -register WINDOW *win; + register WINDOW *win; { - register int y, maxy; + register int y, maxy; -# ifdef DEBUG - fprintf(outf, "TOUCHWIN(%0.2o)\n", win); -# endif - maxy = win->_maxy; +#ifdef DEBUG + __CTRACE("touchwin: (%0.2o)\n", win); +#endif + maxy = win->maxy; for (y = 0; y < maxy; y++) - touchline(win, y, 0, win->_maxx - 1); + __touchline(win, y, 0, win->maxx - 1, 1); + return (OK); } -/* - * touch a given line - */ -touchline(win, y, sx, ex) -register WINDOW *win; -register int y, sx, ex; + +int +__touchwin(win) + register WINDOW *win; { -# ifdef DEBUG - fprintf(outf, "TOUCHLINE(%0.2o, %d, %d, %d)\n", win, y, sx, ex); - fprintf(outf, "TOUCHLINE:first = %d, last = %d\n", win->_firstch[y], win->_lastch[y]); -# endif - sx += win->_ch_off; - ex += win->_ch_off; - if (win->_firstch[y] == _NOCHANGE) { - win->_firstch[y] = sx; - win->_lastch[y] = ex; - } - else { - if (win->_firstch[y] > sx) - win->_firstch[y] = sx; - if (win->_lastch[y] < ex) - win->_lastch[y] = ex; + register int y, maxy; + +#ifdef DEBUG + __CTRACE("touchwin: (%0.2o)\n", win); +#endif + maxy = win->maxy; + for (y = 0; y < maxy; y++) + __touchline(win, y, 0, win->maxx - 1, 0); + return (OK); +} + +int +__touchline(win, y, sx, ex, force) + register WINDOW *win; + register int y, sx, ex; + int force; +{ +#ifdef DEBUG + __CTRACE("touchline: (%0.2o, %d, %d, %d, %d)\n", win, y, sx, ex, force); + __CTRACE("touchline: first = %d, last = %d\n", + *win->lines[y]->firstchp, *win->lines[y]->lastchp); +#endif + if (force) + win->lines[y]->flags |= __FORCEPAINT; + sx += win->ch_off; + ex += win->ch_off; + if (!(win->lines[y]->flags & __ISDIRTY)) { + win->lines[y]->flags |= __ISDIRTY; + *win->lines[y]->firstchp = sx; + *win->lines[y]->lastchp = ex; + } else { + if (*win->lines[y]->firstchp > sx) + *win->lines[y]->firstchp = sx; + if (*win->lines[y]->lastchp < ex) + *win->lines[y]->lastchp = ex; } -# ifdef DEBUG - fprintf(outf, "TOUCHLINE:first = %d, last = %d\n", win->_firstch[y], win->_lastch[y]); -# endif +#ifdef DEBUG + __CTRACE("touchline: first = %d, last = %d\n", + *win->lines[y]->firstchp, *win->lines[y]->lastchp); +#endif + return (OK); } + + diff --git a/lib/libcurses/tscroll.c b/lib/libcurses/tscroll.c new file mode 100644 index 000000000000..92faeaf399ea --- /dev/null +++ b/lib/libcurses/tscroll.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)tscroll.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include <curses.h> + +#define MAXRETURNSIZE 64 + +/* + * Routine to perform scrolling. Derived from tgoto.c in tercamp(3) library. + * Cap is a string containing printf type escapes to allow + * scrolling. + * The following escapes are defined for substituting n: + * + * %d as in printf + * %2 like %2d + * %3 like %3d + * %. gives %c hacking special case characters + * %+x like %c but adding x first + * + * The codes below affect the state but don't use up a value. + * + * %>xy if value > x add y + * %i increments n + * %% gives % + * %B BCD (2 decimal digits encoded in one byte) + * %D Delta Data (backwards bcd) + * + * all other characters are ``self-inserting''. + */ +char * +__tscroll(cap, n) + const char *cap; + int n; +{ + static char result[MAXRETURNSIZE]; + register char *dp; + register int c; + char *cp; + + if (cap == NULL) { +toohard: + /* + * ``We don't do that under BOZO's big top'' + */ + return ("OOPS"); + } + + cp = (char *) cap; + dp = result; + while (c = *cp++) { + if (c != '%') { + *dp++ = c; + continue; + } + switch (c = *cp++) { + case 'n': + n ^= 0140; + continue; + case 'd': + if (n < 10) + goto one; + if (n < 100) + goto two; + /* fall into... */ + case '3': + *dp++ = (n / 100) | '0'; + n %= 100; + /* fall into... */ + case '2': +two: + *dp++ = n / 10 | '0'; +one: + *dp++ = n % 10 | '0'; + continue; + case '>': + if (n > *cp++) + n += *cp++; + else + cp++; + continue; + case '+': + n += *cp++; + /* fall into... */ + case '.': + *dp++ = n; + continue; + case 'i': + n++; + continue; + case '%': + *dp++ = c; + continue; + + case 'B': + n = (n / 10 << 4) + n % 10; + continue; + case 'D': + n = n - 2 * (n % 16); + continue; + default: + goto toohard; + } + } + *dp = '\0'; + return (result); +} diff --git a/lib/libcurses/tstp.c b/lib/libcurses/tstp.c index 4c5f1a6ebbd6..daac9174d745 100644 --- a/lib/libcurses/tstp.c +++ b/lib/libcurses/tstp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,42 +32,97 @@ */ #ifndef lint -static char sccsid[] = "@(#)tstp.c 5.6 (Berkeley) 3/3/91"; +static char sccsid[] = "@(#)tstp.c 8.2 (Berkeley) 1/2/94"; #endif /* not lint */ -# include <signal.h> +#include <curses.h> +#include <errno.h> +#include <signal.h> +#include <termios.h> +#include <unistd.h> -# include "curses.ext" /* - * handle stop and start signals - * - * @(#)tstp.c 5.6 (Berkeley) 3/3/91 + * stop_signal_handler -- + * Handle stop signals. */ void -tstp() { - -# ifdef SIGTSTP - - SGTTY tty; - int omask; -# ifdef DEBUG - if (outf) - fflush(outf); -# endif - tty = _tty; - mvcur(0, COLS - 1, LINES - 1, 0); +__stop_signal_handler(signo) + int signo; +{ + struct termios save; + sigset_t oset, set; + + /* Get the current terminal state (which the user may have changed). */ + if (tcgetattr(STDIN_FILENO, &save)) + return; + + /* + * Block window change and timer signals. The latter is because + * applications use timers to decide when to repaint the screen. + */ + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGALRM); + (void)sigaddset(&set, SIGWINCH); + (void)sigprocmask(SIG_BLOCK, &set, &oset); + + /* + * End the window, which also resets the terminal state to the + * original modes. + */ endwin(); - fflush(stdout); - /* reset signal handler so kill below stops us */ - signal(SIGTSTP, SIG_DFL); -#define mask(s) (1 << ((s)-1)) - omask = sigsetmask(sigblock(0) &~ mask(SIGTSTP)); - kill(0, SIGTSTP); - sigblock(mask(SIGTSTP)); - signal(SIGTSTP, tstp); - _tty = tty; - ioctl(_tty_ch, TIOCSETP, &_tty); + + /* Unblock SIGTSTP. */ + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGTSTP); + (void)sigprocmask(SIG_UNBLOCK, &set, NULL); + + /* Stop ourselves. */ + __restore_stophandler(); + (void)kill(0, SIGTSTP); + + /* Time passes ... */ + + /* Reset the curses SIGTSTP signal handler. */ + __set_stophandler(); + + /* save the new "default" terminal state */ + (void)tcgetattr(STDIN_FILENO, &__orig_termios); + + /* Reset the terminal state to the mode just before we stopped. */ + (void)tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, &save); + + /* Restart the screen. */ + __startwin(); + + /* Repaint the screen. */ wrefresh(curscr); -# endif SIGTSTP + + /* Reset the signals. */ + (void)sigprocmask(SIG_SETMASK, &oset, NULL); } + +static void (*otstpfn)() = SIG_DFL; + +/* + * Set the TSTP handler. + */ +void +__set_stophandler() +{ + otstpfn = signal(SIGTSTP, __stop_signal_handler); +} + +/* + * Restore the TSTP handler. + */ +void +__restore_stophandler() +{ + (void)signal(SIGTSTP, otstpfn); +} + +/* For compatibility */ + +void tstp() { __stop_signal_handler(SIGTSTP); } diff --git a/lib/libcurses/tty.c b/lib/libcurses/tty.c new file mode 100644 index 000000000000..d0345bfba993 --- /dev/null +++ b/lib/libcurses/tty.c @@ -0,0 +1,277 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)tty.c 8.2 (Berkeley) 1/2/94"; +#endif /* not lint */ + +#include <sys/ioctl.h> + +#include <curses.h> +#include <termios.h> +#include <unistd.h> + +/* + * In general, curses should leave tty hardware settings alone (speed, parity, + * word size). This is most easily done in BSD by using TCSASOFT on all + * tcsetattr calls. On other systems, it would be better to get and restore + * those attributes at each change, or at least when stopped and restarted. + * See also the comments in getterm(). + */ +#ifdef TCSASOFT +int __tcaction = 1; /* Ignore hardware settings. */ +#else +int __tcaction = 0; +#endif + +struct termios __orig_termios, __baset; +static struct termios cbreakt, rawt, *curt; +static int useraw; + +#ifndef OXTABS +#ifdef XTABS /* SMI uses XTABS. */ +#define OXTABS XTABS +#else +#define OXTABS 0 +#endif +#endif + +/* + * gettmode -- + * Do terminal type initialization. + */ +int +gettmode() +{ + useraw = 0; + + if (tcgetattr(STDIN_FILENO, &__orig_termios)) + return (ERR); + + __baset = __orig_termios; + __baset.c_oflag &= ~OXTABS; + + GT = 0; /* historical. was used before we wired OXTABS off */ + NONL = (__baset.c_oflag & ONLCR) == 0; + + /* + * XXX + * System V and SMI systems overload VMIN and VTIME, such that + * VMIN is the same as the VEOF element, and VTIME is the same + * as the VEOL element. This means that, if VEOF was ^D, the + * default VMIN is 4. Majorly stupid. + */ + cbreakt = __baset; + cbreakt.c_lflag &= ~ICANON; + cbreakt.c_cc[VMIN] = 1; + cbreakt.c_cc[VTIME] = 0; + + rawt = cbreakt; + rawt.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON); + rawt.c_oflag &= ~OPOST; + rawt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + + /* + * In general, curses should leave hardware-related settings alone. + * This includes parity and word size. Older versions set the tty + * to 8 bits, no parity in raw(), but this is considered to be an + * artifact of the old tty interface. If it's desired to change + * parity and word size, the TCSASOFT bit has to be removed from the + * calls that switch to/from "raw" mode. + */ + if (!__tcaction) { + rawt.c_iflag &= ~ISTRIP; + rawt.c_cflag &= ~(CSIZE|PARENB); + rawt.c_cflag |= CS8; + } + + curt = &__baset; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); +} + +int +raw() +{ + useraw = __pfast = __rawmode = 1; + curt = &rawt; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +noraw() +{ + useraw = __pfast = __rawmode = 0; + curt = &__baset; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +cbreak() +{ + + __rawmode = 1; + curt = useraw ? &rawt : &cbreakt; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +nocbreak() +{ + + __rawmode = 0; + curt = useraw ? &rawt : &__baset; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +echo() +{ + rawt.c_lflag |= ECHO; + cbreakt.c_lflag |= ECHO; + __baset.c_lflag |= ECHO; + + __echoit = 1; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +noecho() +{ + rawt.c_lflag &= ~ECHO; + cbreakt.c_lflag &= ~ECHO; + __baset.c_lflag &= ~ECHO; + + __echoit = 0; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +nl() +{ + rawt.c_iflag |= ICRNL; + rawt.c_oflag |= ONLCR; + cbreakt.c_iflag |= ICRNL; + cbreakt.c_oflag |= ONLCR; + __baset.c_iflag |= ICRNL; + __baset.c_oflag |= ONLCR; + + __pfast = __rawmode; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +int +nonl() +{ + rawt.c_iflag &= ~ICRNL; + rawt.c_oflag &= ~ONLCR; + cbreakt.c_iflag &= ~ICRNL; + cbreakt.c_oflag &= ~ONLCR; + __baset.c_iflag &= ~ICRNL; + __baset.c_oflag &= ~ONLCR; + + __pfast = 1; + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, curt)); +} + +void +__set_scroll_region(top, bot) +int top, bot; +{ + tputs(SC, 0, __cputchar); + tputs(tgoto(CS, bot, top), 0, __cputchar); + tputs(RC, 0, __cputchar); +} + +void +__startwin() +{ + (void)fflush(stdout); + (void)setvbuf(stdout, NULL, _IOFBF, 0); + + tputs(TI, 0, __cputchar); + tputs(VS, 0, __cputchar); + if (curscr != NULL && __usecs) + __set_scroll_region(0, curscr->maxy - 1); +} + +int +endwin() +{ + __restore_stophandler(); + + if (curscr != NULL) { + if (curscr->flags & __WSTANDOUT) { + tputs(SE, 0, __cputchar); + curscr->flags &= ~__WSTANDOUT; + } + if (__usecs) + __set_scroll_region(0, curscr->maxy - 1); + __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0); + } + + (void)tputs(VE, 0, __cputchar); + (void)tputs(TE, 0, __cputchar); + (void)fflush(stdout); + (void)setvbuf(stdout, NULL, _IOLBF, 0); + + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios)); +} + +/* + * The following routines, savetty and resetty are completely useless and + * are left in only as stubs. If people actually use them they will almost + * certainly screw up the state of the world. + */ +static struct termios savedtty; +int +savetty() +{ + return (tcgetattr(STDIN_FILENO, &savedtty)); +} + +int +resetty() +{ + return (tcsetattr(STDIN_FILENO, __tcaction ? + TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty)); +} diff --git a/lib/libcurses/unctrl.c b/lib/libcurses/unctrl.c index fcd7a2f9a827..ff52230b2e9b 100644 --- a/lib/libcurses/unctrl.c +++ b/lib/libcurses/unctrl.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1981 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1981, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,24 +32,76 @@ */ #ifndef lint -static char sccsid[] = "@(#)unctrl.c 5.4 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)unctrl.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint */ -/* - * define unctrl codes for each character - * - */ +char *__unctrl[256] = { + "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", + "^H", "^I", "^J", "^K", "^L", "^M", "^N", "^O", + "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W", + "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_", + " ", "!", "\"", "#", "$", "%", "&", "'", + "(", ")", "*", "+", ",", "-", ".", "/", + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", ":", ";", "<", "=", ">", "?", + "@", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "[", "\\", "]", "^", "_", + "`", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", "^?", + + "0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87", + "0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f", + "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97", + "0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f", + "0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7", + "0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf", + "0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7", + "0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf", + "0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7", + "0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf", + "0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7", + "0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf", + "0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7", + "0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef", + "0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7", + "0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff", +}; -/* LINTLIBRARY */ -char *_unctrl[] = { /* unctrl codes for ttys */ - "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K", - "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W", - "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_", - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", - ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", - "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", - "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", - "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", - "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", - "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?" +char __unctrllen[256] = { + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, }; diff --git a/lib/libf2c/Makefile b/lib/libf2c/Makefile new file mode 100644 index 000000000000..cf7f6686a41d --- /dev/null +++ b/lib/libf2c/Makefile @@ -0,0 +1,37 @@ +.PATH: ${.CURDIR}/../libF77 ${.CURDIR}/../libI77 + +LIB=f2c +CFLAGS+= -DIEEE_drem -DSkip_f2c_Undefs -DNON_ANSI_RW_MODES + +MISC = Version.c main.c s_rnge.c abort_.c getarg_.c iargc_.c getenv_.c\ + signal_.c s_stop.c s_paus.c system_.c cabs.c\ + derf_.c derfc_.c erf_.c erfc_.c sig_die.c +POW = pow_ci.c pow_dd.c pow_di.c pow_hh.c pow_ii.c pow_ri.c pow_zi.c pow_zz.c +CX = c_abs.c c_cos.c c_div.c c_exp.c c_log.c c_sin.c c_sqrt.c +DCX = z_cos.c z_div.c z_exp.c z_log.c z_sin.c z_sqrt.c +REAL = r_abs.c r_acos.c r_asin.c r_atan.c r_atn2.c r_cnjg.c r_cos.c\ + r_cosh.c r_dim.c r_exp.c r_imag.c r_int.c\ + r_lg10.c r_log.c r_mod.c r_nint.c r_sign.c\ + r_sin.c r_sinh.c r_sqrt.c r_tan.c r_tanh.c +DBL = d_abs.c d_acos.c d_asin.c d_atan.c d_atn2.c\ + d_cnjg.c d_cos.c d_cosh.c d_dim.c d_exp.c\ + d_imag.c d_int.c d_lg10.c d_log.c d_mod.c\ + d_nint.c d_prod.c d_sign.c d_sin.c d_sinh.c\ + d_sqrt.c d_tan.c d_tanh.c +INT = i_abs.c i_dim.c i_dnnt.c i_indx.c i_len.c i_mod.c i_nint.c i_sign.c +HALF = h_abs.c h_dim.c h_dnnt.c h_indx.c h_len.c h_mod.c h_nint.c h_sign.c +CMP = l_ge.c l_gt.c l_le.c l_lt.c hl_ge.c hl_gt.c hl_le.c hl_lt.c +EFL = ef1asc_.c ef1cmc_.c +CHAR = s_cat.c s_cmp.c s_copy.c + +F77SRCS= $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ + $(HALF) $(CMP) $(EFL) $(CHAR) + +I77SRCS = Version.c backspace.c close.c dfe.c dolio.c due.c endfile.c err.c \ + fmt.c fmtlib.c iio.c ilnw.c inquire.c lread.c lwrite.c open.c \ + rdfmt.c rewind.c rsfe.c rsli.c rsne.c sfe.c sue.c typesize.c uio.c \ + util.c wref.c wrtfmt.c wsfe.c wsle.c wsne.c xwsne.c + +SRCS= ${F77SRCS} ${I77SRCS} + +.include <bsd.lib.mk> diff --git a/lib/libm/common_source/exp.3 b/lib/libm/common_source/exp.3 index e8ef437e8a5b..2ab8ec78416c 100644 --- a/lib/libm/common_source/exp.3 +++ b/lib/libm/common_source/exp.3 @@ -138,7 +138,7 @@ is exact until it is bigger than 2**56 on a .Tn IEEE 754. .Sh RETURN VALUES -These functions will return the approprate computation unless an error +These functions will return the appropriate computation unless an error occurs or an argument is out of range. The functions .Fn exp , diff --git a/lib/libm/common_source/j0.3 b/lib/libm/common_source/j0.3 index 8f02dfb83a57..49b74d1619f8 100644 --- a/lib/libm/common_source/j0.3 +++ b/lib/libm/common_source/j0.3 @@ -87,7 +87,7 @@ compute the linearly independent .Em order 1, respectively, for the -postive +positive .Em integer value .Fa x @@ -97,7 +97,7 @@ the function computes the .Em Bessel function of the second kind for the integer order .Fa n -for the postive +for the positive .Em integer value .Fa x diff --git a/lib/libm/common_source/pow.c b/lib/libm/common_source/pow.c index a10fcd7e71d2..fe665f023bc1 100644 --- a/lib/libm/common_source/pow.c +++ b/lib/libm/common_source/pow.c @@ -174,7 +174,7 @@ pow_P(x, y) double x, y; #endif { struct Double s, t, log__D(); - double exp__D(), huge = 1e300, tiny = 1e-300; + double exp__D(), tiny = 1e-300; if (x == zero) return ((y>zero)? x : one/x); @@ -184,7 +184,7 @@ pow_P(x, y) double x, y; if (x < 1) return(tiny*tiny); else if (_IEEE) - return (huge*huge); + return (HUGE_VAL*HUGE_VAL); else return (infnan(ERANGE)); diff --git a/lib/libpthread/COPYRIGHT b/lib/libpthread/COPYRIGHT new file mode 100644 index 000000000000..1fb4e43cf268 --- /dev/null +++ b/lib/libpthread/COPYRIGHT @@ -0,0 +1,31 @@ +Copyright (c) 1993 by Chris Provenzano and contributors, proven@mit.edu +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 Chris Provenzano, + the University of California, Berkeley, and contributors. +4. Neither the name of Chris Provenzano, the University, nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, 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. + diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile new file mode 100644 index 000000000000..85978519fe81 --- /dev/null +++ b/lib/libpthread/Makefile @@ -0,0 +1,22 @@ +# from: @(#)Makefile 5.2 (Berkeley) 3/5/91 + +LIB=pthread +NOPIC= no +CPPFLAGS+= -DPTHREAD_KERNEL -I. -I${.CURDIR}/include -I${.CURDIR}/arch/${MACHINE} +CFLAGS+= ${CPPFLAGS} + +.include "${.CURDIR}/arch/${MACHINE}/Makefile.inc" +.include "${.CURDIR}/pthreads/Makefile.inc" +.include "${.CURDIR}/stdio/Makefile.inc" + +all beforedepend: pthread + +CLEANFILES+=pthread + +pthread: + if [ ! -e pthread ]; then \ + ln -s ${.CURDIR}/include pthread; \ + fi + +.include <bsd.lib.mk> + diff --git a/lib/libpthread/README b/lib/libpthread/README new file mode 100644 index 000000000000..d4c92a98f680 --- /dev/null +++ b/lib/libpthread/README @@ -0,0 +1,88 @@ +This pthread package is/will be based on the POSIX1003.4a Draft 7 pthread +standard, and Frank Mullers paper on signal handelling presented +at the Winter 93 USENIX conference. + +It is currently being designed and written by me, Chris Provenzano. +All bug, comments, and questions can be sent me at proven@mit.edu. + +PLEASE, don't send questions, bugs or patches to any of the *BSD* mailing lists. + +Thanks goes to John Carr jfc@mit.edu for porting this to the IBM/RT, +and for his bug reports and fixes, Greg Hudson for the testing he's +done, and all the others. + +PORTING +One of the goals of this user space implementation of pthreads is that it +be portable. I have minimized the ammount of assembler code necessary, +but some is. + +If you want to port it to another platform here are a few basic hints. + +There are currently three files you'll have to creat for your +architecture, machdep.h, machdep.c and syscall.S. +The first two are necessary to get the context switch section of +the pthread package running, the third is for all the syscalls. + +To do an initial port, create an appropriate machdep.h, and machdep.c +and define PTHREAD_INITIAL_PORT in the Makefile + +Comment out references to the stdio package. + +INCLUDE FILES AND PORTING +To continue to make this package portable, some basic rules on includes +files must be followed. + +pthread.h should be included first (if it is to be included). +machdep.h should define size_t if the system doesn't define it already + +posix.h should be included last. This file is used to correct non +POSIX features, after everything else has been defined. + +INTERNAL LOCKING +To prevent deadlocks the following rules were used for locks. + +1. Local locks for mutex queues and other like things are only locked + by running threads, at NO time will a local lock be held by + a thread in a non running state. +2. Only threads that are in a run state can attempt to lock another thread, + this way, we can assume that the lock will be released shortly, and don't + have to unlock the local lock. +3. The only time a thread will have a pthread->lock and is not in a run + state is when it is in the reschedule routine. +4. The reschedule routine assumes all local locks have been released, + there is a lock on the currently running thread (pthread_run), + and that this thread is being rescheduled to a non running state. + It is safe to unlock the currently running threads lock after it + has been rescheduled. +5. The reschedule routine locks the kernel, sets the state of the currently + running thread, unlocks the currently running thread, calls the + context switch routines. +6 the kernel lock is used only ... + + +7. The order of locking is ... + +1 local locks +2 pthread->lock /* Assumes it will get it soon */ +3 pthread_run->lock /* Assumes it will get it soon, but must release 2 */ +4 kernel lock /* Currently assumes it will ALWAYS get it. */ + +8. The kernel lock will be changed to a spin lock for systems that +already support kernel threads, this way we can mutiplex threads onto +kernel threads. +9. There are points where the kernel is locked and it needs to get +either a local lock or a pthread lock, if at these points the code +fails to get the lock the kernel gives up and sets a flag which will +be checked at a later point. +10. Interrupts are dissabled while the kernel is locked, the interrupt +mask must be checked afterwards or cleared in some way, after interrputs +have been reenabled, this allows back to back interrupts, but should always +avoid missing one. + +------------------------------------------------------------------------------ +Copyright (c) 1993 Chris Provenzano. All rights reserved. +This product includes software developed by the Univeristy of California, +Berkeley and its contributors. + +For further licencing and distribution restrictions see the file COPYRIGHT +included in this directory. diff --git a/lib/libpthread/arch/i386/Makefile.inc b/lib/libpthread/arch/i386/Makefile.inc new file mode 100644 index 000000000000..5719f431fbbc --- /dev/null +++ b/lib/libpthread/arch/i386/Makefile.inc @@ -0,0 +1,5 @@ +# Machine dependent sources +.PATH: ${.CURDIR}/arch/${MACHINE} + +SRCS+= machdep.c syscall.S + diff --git a/lib/libpthread/arch/i386/machdep.c b/lib/libpthread/arch/i386/machdep.c new file mode 100644 index 000000000000..53da10559347 --- /dev/null +++ b/lib/libpthread/arch/i386/machdep.c @@ -0,0 +1,102 @@ +/* ==== machdep.c ============================================================ + * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu + * + * Description : Machine dependent functions for NetBSD on i386 + * + * 1.00 93/08/04 proven + * -Started coding this file. + */ + +#include "pthread.h" + +/* ========================================================================== + * machdep_save_state() + */ +int machdep_save_state(void) +{ + return(_setjmp(pthread_run->machdep_data.machdep_state)); +} + +/* ========================================================================== + * machdep_restore_state() + */ +void machdep_restore_state(void) +{ + _longjmp(pthread_run->machdep_data.machdep_state, 1); +} + +/* ========================================================================== + * machdep_set_thread_timer() + */ +void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread) +{ + if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) { + PANIC(); + } +} + +/* ========================================================================== + * machdep_unset_thread_timer() + */ +void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread) +{ + struct itimerval zeroval = { { 0, 0 }, { 0, 0} }; + + if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) { + PANIC(); + } +} + +/* ========================================================================== + * machdep_pthread_cleanup() + */ +void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread) +{ + return(machdep_pthread->machdep_stack); +} + +/* ========================================================================== + * machdep_pthread_start() + */ +void machdep_pthread_start(void) +{ + context_switch_done(); + sig_check_and_resume(); + + /* Run current threads start routine with argument */ + pthread_exit(pthread_run->machdep_data.start_routine + (pthread_run->machdep_data.start_argument)); + + /* should never reach here */ + PANIC(); +} + +/* ========================================================================== + * machdep_pthread_create() + */ +void machdep_pthread_create(struct machdep_pthread *machdep_pthread, + void *(* start_routine)(), void *start_argument, long stack_size, + void *stack_start, long nsec) +{ + machdep_pthread->machdep_stack = stack_start; + + machdep_pthread->start_routine = start_routine; + machdep_pthread->start_argument = start_argument; + + machdep_pthread->machdep_timer.it_value.tv_sec = 0; + machdep_pthread->machdep_timer.it_interval.tv_sec = 0; + machdep_pthread->machdep_timer.it_interval.tv_usec = 0; + machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000; + + _setjmp(machdep_pthread->machdep_state); + /* + * Set up new stact frame so that it looks like it + * returned from a longjmp() to the beginning of + * machdep_pthread_start(). + */ + machdep_pthread->machdep_state[0] = (int)machdep_pthread_start; + + /* Stack starts high and builds down. */ + machdep_pthread->machdep_state[2] = + (int)machdep_pthread->machdep_stack + stack_size; +} diff --git a/lib/libpthread/arch/i386/machdep.h b/lib/libpthread/arch/i386/machdep.h new file mode 100644 index 000000000000..10521b022355 --- /dev/null +++ b/lib/libpthread/arch/i386/machdep.h @@ -0,0 +1,58 @@ +/* ==== machdep.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + */ + + +/* + * The first machine dependent functions are the SEMAPHORES + * needing the test and set instruction. + */ +#define SEMAPHORE_CLEAR 0 +#define SEMAPHORE_SET 1 + +#define SEMAPHORE_TEST_AND_SET(lock) \ +({ \ +volatile long temp = SEMAPHORE_SET; \ + \ +__asm__("xchgl %0,(%2)" \ + :"=r" (temp) \ + :"0" (temp),"r" (lock)); \ +temp; \ +}) + +#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR + +/* + * Minimum stack size + */ +#define PTHREAD_STACK_MIN 1024 + diff --git a/lib/libpthread/arch/i386/syscall.S b/lib/libpthread/arch/i386/syscall.S new file mode 100644 index 000000000000..eba7cec297b3 --- /dev/null +++ b/lib/libpthread/arch/i386/syscall.S @@ -0,0 +1,168 @@ +/* ==== syscall.S ============================================================ + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993 Chris Provenzano, proven@mit.edu + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * + * Description : Machine dependent syscalls for i386/i486/i586 + * + * 1.00 93/08/26 proven + * -Started coding this file. + * + * 1.01 93/11/13 proven + * -The functions readv() and writev() added. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90" +#endif /* SYSLIBC_SCCS and not lint */ + +#include <sys/syscall.h> + +#define SYSCALL(x) \ + .globl _machdep_sys_/**/x; \ + \ +_machdep_sys_/**/x:; \ + \ + lea SYS_/**/x, %eax; \ + .byte 0x9a; .long 0; .word 7; \ + jb 1b; \ + ret; + +/* + * Initial asm stuff for all functions. + */ + .text + .align 2 + + +/* ========================================================================== + * error code for all syscalls. The error value is returned as the negative + * of the errno value. + */ + +1: + neg %eax + ret + +/* ========================================================================== + * machdep_sys_write() + */ +SYSCALL(write) + +/* ========================================================================== + * machdep_sys_read() + */ +SYSCALL(read) + +/* ========================================================================== + * machdep_sys_open() + */ +SYSCALL(open) + +/* ========================================================================== + * machdep_sys_close() + */ +SYSCALL(close) + +/* ========================================================================== + * machdep_sys_fcntl() + */ +SYSCALL(fcntl) + +/* ========================================================================== + * machdep_sys_lseek() + */ +SYSCALL(lseek) + +/* ========================================================================== + * Nonstandard calls used to make the system work + * + * ========================================================================== + * machdep_sys_select() + */ +SYSCALL(select) + +/* ========================================================================== + * Berkeley socket stuff + * + * ========================================================================== + * machdep_sys_socket() + */ +SYSCALL(socket) + +/* ========================================================================== + * machdep_sys_bind() + */ +SYSCALL(bind) + +/* ========================================================================== + * machdep_sys_connect() + */ +SYSCALL(connect) + +/* ========================================================================== + * machdep_sys_accept() + */ +SYSCALL(accept) + +/* ========================================================================== + * machdep_sys_listen() + */ +SYSCALL(listen) + +/* ========================================================================== + * machdep_sys_getsockopt() + */ +SYSCALL(getsockopt) + +/* ========================================================================== + * machdep_sys_readv() + */ +SYSCALL(readv) + +/* ========================================================================== + * machdep_sys_writev() + */ +SYSCALL(writev) + +/* ========================================================================== + * machdep_sys_getpeername() + */ +SYSCALL(getpeername) + +/* ========================================================================== + * machdep_sys_getsockname() + */ +SYSCALL(getsockname) + diff --git a/lib/libpthread/include/Makefile.inc b/lib/libpthread/include/Makefile.inc new file mode 100644 index 000000000000..8c1fe5140c3b --- /dev/null +++ b/lib/libpthread/include/Makefile.inc @@ -0,0 +1,30 @@ +# from: @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91 + +# Doing a make install builds /usr/include/pthread +# +# The ``rm -rf''s used below are safe because rm doesn't follow symbolic +# links. + + +FILES= cond.h engine.h fd.h fd_pipe.h kernel.h mutex.h posix.h \ + pthread.h pthread_attr.h queue.h stdio.h util.h + +# Machine dependent header file +MFILE= ${.CURDIR}/arch/${MACHINE}/machdep.h + +realinstall: + if [ ! -d ${DESTDIR}/usr/include/pthread ]; then \ + mkdir ${DESTDIR}/usr/include/pthread; \ + fi + @echo installing ${FILES} + @-for i in ${FILES}; do \ + cmp -s $$i ${DESTDIR}/usr/include/pthread/$$i || \ + install -c -m 644 $$i ${DESTDIR}/usr/include/$$i; \ + done + cmp -s ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h || \ + install -c -m 644 ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h + rm -rf ${DESTDIR}/usr/include/pthread.h + ln -s /usr/include/pthread/pthread.h ${DESTDIR}/usr/include/pthread.h + @chown -R ${BINOWN}:${BINGRP} ${DESTDIR}/usr/include/pthread + @chmod -R a-w ${DESTDIR}/usr/include/pthread + diff --git a/lib/libpthread/include/cond.h b/lib/libpthread/include/cond.h new file mode 100644 index 000000000000..82c064eac028 --- /dev/null +++ b/lib/libpthread/include/cond.h @@ -0,0 +1,89 @@ +/* ==== cond.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : mutex header. + * + * 1.00 93/10/30 proven + * -Started coding this file. + */ + +/* + * New cond structures + */ +enum pthread_cond_type { + COND_TYPE_FAST, + COND_TYPE_STATIC_FAST, + COND_TYPE_METERED, + COND_TYPE_DEBUG, /* Debug conds will have lots of options */ + COND_TYPE_MAX +}; + +typedef struct pthread_cond { + enum pthread_cond_type c_type; + struct pthread_queue c_queue; + semaphore c_lock; + void * c_data; + long c_flags; +} pthread_cond_t; + +typedef struct pthread_cond_attr { + enum pthread_cond_type c_type; + long c_flags; +} pthread_condattr_t; + +/* + * Flags for conds. + */ +#define COND_FLAGS_PRIVATE 0x01 +#define COND_FLAGS_INITED 0x02 +#define COND_FLAGS_BUSY 0x04 + +/* + * Static cond initialization values. + */ +#define PTHREAD_COND_INITIALIZER \ +{ COND_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \ + NULL, SEMAPHORE_CLEAR, COND_FLAGS_INITED } + +/* + * New functions + */ + +__BEGIN_DECLS + +int pthread_cond_init __P((pthread_cond_t *, pthread_condattr_t *)); +int pthread_cond_wait __P((pthread_cond_t *, pthread_mutex_t *)); +int pthread_cond_signal __P((pthread_cond_t *)); +int pthread_cond_broadcast __P((pthread_cond_t *)); +int pthread_cond_destroy __P((pthread_cond_t *)); + +__END_DECLS + diff --git a/lib/libpthread/include/engine.h b/lib/libpthread/include/engine.h new file mode 100644 index 000000000000..3539686755cb --- /dev/null +++ b/lib/libpthread/include/engine.h @@ -0,0 +1,86 @@ +/* ==== engine.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + */ + +#include <unistd.h> +#include <setjmp.h> +#include <sys/time.h> + +#if defined(PTHREAD_KERNEL) +#include "machdep.h" +#endif + +/* + * New types + */ +typedef long semaphore; + +#define SIGMAX 31 + +/* + * New Strutures + */ +struct machdep_pthread { + void *(*start_routine)(void *); + void *start_argument; + void *machdep_stack; + struct itimerval machdep_timer; + jmp_buf machdep_state; +}; + +/* + * Static machdep_pthread initialization values. + * For initial thread only. + */ +#define MACHDEP_PTHREAD_INIT \ +{ NULL, NULL, NULL, { { 0, 0 }, { 0, 0 } }, 0 } + +/* + * Some fd flag defines that are necessary to distinguish between posix + * behavior and bsd4.3 behavior. + */ +#define __FD_NONBLOCK O_NONBLOCK + +/* + * New functions + */ + +__BEGIN_DECLS + +#if defined(PTHREAD_KERNEL) + +int semaphore_text_and_set __P((semaphore *)); +int machdep_save_state __P((void)); + +#endif + +__END_DECLS diff --git a/lib/libpthread/include/fd.h b/lib/libpthread/include/fd.h new file mode 100644 index 000000000000..408f101e9aeb --- /dev/null +++ b/lib/libpthread/include/fd.h @@ -0,0 +1,104 @@ +/* ==== fd.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Basic fd header. + * + * 1.00 93/08/14 proven + * -Started coding this file. + * + * 1.01 93/11/13 proven + * -The functions readv() and writev() added + */ + +/* + * New pthread types. + */ +enum fd_type { + FD_NT, /* Not tested */ + FD_NIU, /* Known to be not in use */ + FD_HALF_DUPLEX, /* Files, and seeking devices */ + FD_FULL_DUPLEX /* pipes, sockets, drivers, ... */ +}; + + +#define FD_READ 0x1 +#define FD_WRITE 0x2 +#define FD_RDWR (FD_READ | FD_WRITE) + +struct fd_ops { + int (*write)(); + int (*read)(); + int (*close)(); + int (*fcntl)(); + int (*writev)(); + int (*readv)(); + int (*seek)(); +}; + +union fd_data { + void *ptr; + int i; +}; + +struct fd_table_entry { + struct pthread_queue r_queue; + struct pthread_queue w_queue; + struct pthread *r_owner; + struct pthread *w_owner; + semaphore lock; + struct fd_table_entry *next; + struct fd_ops *ops; + enum fd_type type; + int lockcount; /* Count for FILE locks */ + int count; + + /* data that needs to be passed to the type dependent fd */ + int flags; + union fd_data fd; +}; + +/* + * Important data structure + */ +extern struct fd_table_entry *fd_table[]; +extern int dtablesize; + +/* + * New functions + */ + +__BEGIN_DECLS + +#if defined(PTHREAD_KERNEL) + +#endif + +__END_DECLS diff --git a/lib/libpthread/include/fd_pipe.h b/lib/libpthread/include/fd_pipe.h new file mode 100644 index 000000000000..1ac1471d1a82 --- /dev/null +++ b/lib/libpthread/include/fd_pipe.h @@ -0,0 +1,52 @@ +/* ==== fd_pipe.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : The new fast ITC pipe header. + * + * 1.00 93/08/14 proven + * -Started coding this file. + */ + +struct __pipe { + semaphore lock; + char * buf; + int size; + int flags; + int count; + int offset; + struct pthread * wait; + char * wait_buf; + size_t wait_size; +}; + +#define RD_CLOSED 0x01 +#define WR_CLOSED 0x02 + diff --git a/lib/libpthread/include/kernel.h b/lib/libpthread/include/kernel.h new file mode 100644 index 000000000000..53e104e07e65 --- /dev/null +++ b/lib/libpthread/include/kernel.h @@ -0,0 +1,48 @@ +/* ==== kernel.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : mutex header. + * + * 1.00 93/07/22 proven + * -Started coding this file. + */ + +/* + * Defines only for the pthread user kernel. + */ +#if defined(PTHREAD_KERNEL) + +#define PANIC() abort() + +/* Time each rr thread gets */ +#define PTHREAD_RR_TIMEOUT 100000000 + +#endif diff --git a/lib/libpthread/include/mutex.h b/lib/libpthread/include/mutex.h new file mode 100644 index 000000000000..2afc727219d0 --- /dev/null +++ b/lib/libpthread/include/mutex.h @@ -0,0 +1,91 @@ +/* ==== mutex.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : mutex header. + * + * 1.00 93/07/20 proven + * -Started coding this file. + */ + +/* + * New mutex structures + */ +enum pthread_mutex_type { + MUTEX_TYPE_FAST, + MUTEX_TYPE_STATIC_FAST, + MUTEX_TYPE_RECURSIVE, + MUTEX_TYPE_METERED, + MUTEX_TYPE_DEBUG, /* Debug mutexes will have lots of options */ + MUTEX_TYPE_MAX +}; + +typedef struct pthread_mutex { + enum pthread_mutex_type m_type; + struct pthread_queue m_queue; + struct pthread *m_owner; + semaphore m_lock; + void *m_data; + long m_flags; +} pthread_mutex_t; + +typedef struct pthread_mutex_attr { + enum pthread_mutex_type m_type; + long m_flags; +} pthread_mutexattr_t; + +/* + * Flags for mutexes. + */ +#define MUTEX_FLAGS_PRIVATE 0x01 +#define MUTEX_FLAGS_INITED 0x02 +#define MUTEX_FLAGS_BUSY 0x04 + +/* + * Static mutex initialization values. + */ +#define PTHREAD_MUTEX_INITIALIZER \ +{ MUTEX_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \ + NULL, SEMAPHORE_CLEAR, NULL, MUTEX_FLAGS_INITED } + +/* + * New functions + */ + +__BEGIN_DECLS + +int pthread_mutex_init __P((pthread_mutex_t *, pthread_mutexattr_t *)); +int pthread_mutex_lock __P((pthread_mutex_t *)); +int pthread_mutex_unlock __P((pthread_mutex_t *)); +int pthread_mutex_trylock __P((pthread_mutex_t *)); +int pthread_mutex_destroy __P((pthread_mutex_t *)); + +__END_DECLS + diff --git a/lib/libpthread/include/posix.h b/lib/libpthread/include/posix.h new file mode 100644 index 000000000000..cc440bb9e7ef --- /dev/null +++ b/lib/libpthread/include/posix.h @@ -0,0 +1,19 @@ +/* ==== posix.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Convert an Ultrix-4.2 system to a more or less POSIX system. + * + * 1.00 93/07/20 proven + * -Started coding this file. + */ + +#ifndef _PTHREAD_POSIX_H_ +#define _PTHREAD_POSIX_H_ + +#include <sys/cdefs.h> + +/* Make sure we have size_t defined */ +#include <stdlib.h> +#include <stdarg.h> + +#endif diff --git a/lib/libpthread/include/pthread.h b/lib/libpthread/include/pthread.h new file mode 100644 index 000000000000..d8c8c9d1d1f2 --- /dev/null +++ b/lib/libpthread/include/pthread.h @@ -0,0 +1,146 @@ +/* ==== pthread.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Basic pthread header. + * + * 1.00 93/07/20 proven + * -Started coding this file. + */ + +#include <pthread/engine.h> +#include <pthread/kernel.h> +#include <pthread/queue.h> +#include <pthread/mutex.h> +#include <pthread/cond.h> +#include <pthread/fd.h> + +#include <pthread/util.h> +#include <errno.h> + +/* More includes */ +#include <pthread/pthread_once.h> + +/* More includes, that need size_t */ +#include <pthread/pthread_attr.h> + +enum pthread_state { + PS_RUNNING, + PS_MUTEX_WAIT, + PS_COND_WAIT, + PS_FDLR_WAIT, + PS_FDLW_WAIT, + PS_FDR_WAIT, + PS_FDW_WAIT, + PS_SLEEP_WAIT, + PS_JOIN, + PS_DEAD +}; + +#define PF_DETACHED 0x00000001 + +struct pthread { + struct machdep_pthread machdep_data; + enum pthread_state state; + pthread_attr_t attr; + + /* Other flags */ + int flags; + + /* Time until timeout */ + int time_sec; + int time_usec; + + /* Join queue for waiting threads */ + struct pthread_queue join_queue; + + /* Queue thread is waiting on, (mutexes, cond. etc.) */ + struct pthread_queue *queue; + + /* + * Thread implementations are just multiple queue type implemenations, + * Below are the various link lists currently necessary + * It is possible for a thread to be on multiple, or even all the + * queues at once, much care must be taken during queue manipulation. + * + * The pthread structure must be locked before you can even look at + * the link lists. + */ + + struct pthread *pll; /* ALL threads, in any state */ + /* struct pthread *rll; Current run queue, before resced */ + struct pthread *sll; /* For sleeping threads */ + struct pthread *next; /* Standard for mutexes, etc ... */ + /* struct pthread *fd_next; For kernel fd operations */ + + int fd; /* Used when thread waiting on fd */ + + semaphore lock; + void *ret; + int error; +}; + +typedef struct pthread* pthread_t; + +/* + * Globals + */ +extern struct pthread *pthread_run; +extern struct pthread *pthread_initial; +extern struct pthread *pthread_link_list; +extern pthread_attr_t pthread_default_attr; +extern struct pthread_queue pthread_current_queue; +extern struct fd_table_entry *fd_table[]; + +/* + * New functions + */ + +__BEGIN_DECLS + +void pthread_init __P((void)); +int pthread_create __P((pthread_t *, const pthread_attr_t *, + void * (*start_routine)(void *), void *)); +void pthread_exit __P((void *)); +pthread_t pthread_self __P((void)); +int pthread_equal __P((pthread_t, pthread_t)); +int pthread_join __P((pthread_t, void **)); +int pthread_detach __P((pthread_t)); + +#if defined(PTHREAD_KERNEL) + +void pthread_yield __P((void)); + +/* Not valid, but I can't spell so this will be caught at compile time */ +#define pthread_yeild(notvalid) + +#endif + +__END_DECLS diff --git a/lib/libpthread/include/pthread_attr.h b/lib/libpthread/include/pthread_attr.h new file mode 100644 index 000000000000..ba64d25f3255 --- /dev/null +++ b/lib/libpthread/include/pthread_attr.h @@ -0,0 +1,71 @@ +/* ==== pthread_attr.h ======================================================== + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Basic pthread attributes header. + * + * 1.00 93/11/03 proven + * -Started coding this file. + */ + +#define _POSIX_THREAD_ATTR_STACKSIZE + +#define PTHREAD_STACK_DEFAULT 65536 + +/* + * New pthread attribute types. + */ +enum pthread_sched_attr { + SCHED_RR, + SCHED_IO, + SCHED_FIFO, + SCHED_OTHER, +}; + +typedef struct pthread_attr { + enum pthread_sched_attr sched_attr; + void * stackaddr_attr; + size_t stacksize_attr; +} pthread_attr_t; + +/* + * New functions + */ + +__BEGIN_DECLS + +int pthread_attr_init __P((pthread_attr_t *)); +int pthread_attr_destroy __P((pthread_attr_t *)); +int pthread_attr_setstacksize __P((pthread_attr_t *, size_t)); +int pthread_attr_getstacksize __P((pthread_attr_t *, size_t *)); +int pthread_attr_setstackaddr __P((pthread_attr_t *, void *)); +int pthread_attr_getstackaddr __P((pthread_attr_t *, void **)); + +__END_DECLS diff --git a/lib/libpthread/include/pthread_once.h b/lib/libpthread/include/pthread_once.h new file mode 100644 index 000000000000..5967080ac0b3 --- /dev/null +++ b/lib/libpthread/include/pthread_once.h @@ -0,0 +1,51 @@ +/* ==== pthread_once.h ======================================================== + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : mutex header. + * + * 1.00 93/12/12 proven + * -Started coding this file. + */ + +/* New pthread_once structures */ +typedef int pthread_once_t; + +/* Static pthread_once_t initialization value. */ +#define PTHREAD_ONCE_INIT 0 + +/* New functions */ + +__BEGIN_DECLS + +int pthread_once __P((pthread_once_t *, void (*init_routine)(void))); + +__END_DECLS + diff --git a/lib/libpthread/include/queue.h b/lib/libpthread/include/queue.h new file mode 100644 index 000000000000..687df4907124 --- /dev/null +++ b/lib/libpthread/include/queue.h @@ -0,0 +1,65 @@ +/* ==== queue.h ============================================================ + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : mutex header. + * + * 1.00 93/07/20 proven + * -Started coding this file. + */ + +/* + * New queue structures + */ +struct pthread_queue { + struct pthread *q_next; + struct pthread *q_last; + void *q_data; +}; + +/* + * Static queue initialization values. + */ +#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL } + +/* + * New functions + * Should make pthread_queue_get a macro + */ + +__BEGIN_DECLS + +void pthread_queue_init __P((struct pthread_queue *)); +void pthread_queue_enq __P((struct pthread_queue *, struct pthread *)); +void pthread_queue_remove __P((struct pthread_queue *, struct pthread *)); +struct pthread *pthread_queue_get __P((struct pthread_queue *)); +struct pthread *pthread_queue_deq __P((struct pthread_queue *)); + +__END_DECLS diff --git a/lib/libpthread/include/stdio.h b/lib/libpthread/include/stdio.h new file mode 100644 index 000000000000..70a4265ae2ab --- /dev/null +++ b/lib/libpthread/include/stdio.h @@ -0,0 +1,353 @@ +/* ==== stdio.h ============================================================ + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu + * 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. + * + * from: @(#)stdio.h 5.17 (Berkeley) 6/3/91 + * $Id: stdio.h,v 1.1 1994/01/30 04:22:49 proven Exp $ + */ + +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include <pthread/posix.h> + +#ifndef NULL +#define NULL 0 +#endif + +typedef long fpos_t; /* Must match off_t <sys/types.h> */ + +#define _FSTDIO /* Define for new stdio with functions. */ + +/* + * NB: to fit things in six character monocase externals, the stdio + * code uses the prefix `__s' for stdio objects, typically followed + * by a three-character attempt at a mnemonic. + */ + +/* stdio buffers */ +struct __sbuf { + unsigned char *_base; + int _size; +}; + +/* + * stdio state variables. + * + * The following always hold: + * + * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), + * _lbfsize is -_bf._size, else _lbfsize is 0 + * if _flags&__SRD, _w is 0 + * if _flags&__SWR, _r is 0 + * + * This ensures that the getc and putc macros (or inline functions) never + * try to write or read from a file that is in `read' or `write' mode. + * (Moreover, they can, and do, automatically switch from read mode to + * write mode, and back, on "r+" and "w+" files.) + * + * _lbfsize is used only to make the inline line-buffered output stream + * code as compact as possible. + * + * _ub, _up, and _ur are used when ungetc() pushes back more characters + * than fit in the current _bf, or when ungetc() pushes back a character + * that does not match the previous one in _bf. When this happens, + * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff + * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. + */ +typedef struct __sFILE { + unsigned char *_p; /* current position in (some) buffer */ + int _r; /* read space left for getc() */ + int _w; /* write space left for putc() */ + short _flags; /* flags, below; this FILE is free if 0 */ + short _file; /* fileno, if Unix descriptor, else -1 */ + struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ + int _lbfsize; /* 0 or -_bf._size, for inline putc */ + + /* separate buffer for long sequences of ungetc() */ + struct __sbuf _ub; /* ungetc buffer */ + unsigned char *_up; /* saved _p when _p is doing ungetc data */ + int _ur; /* saved _r when _r is counting ungetc data */ + + /* tricks to meet minimum requirements even when malloc() fails */ + unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ + unsigned char _nbuf[1]; /* guarantee a getc() buffer */ + + /* separate buffer for fgetline() when line crosses buffer boundary */ + struct __sbuf _lb; /* buffer for fgetline() */ + + /* Unix stdio files get aligned to block boundaries on fseek() */ + int _blksize; /* stat.st_blksize (may be != _bf._size) */ + int _offset; /* current lseek offset */ +} FILE; + +__BEGIN_DECLS +extern FILE __sF[]; +__END_DECLS + +#define __SLBF 0x0001 /* line buffered */ +#define __SNBF 0x0002 /* unbuffered */ +#define __SRD 0x0004 /* OK to read */ +#define __SWR 0x0008 /* OK to write */ + /* RD and WR are never simultaneously asserted */ +#define __SRW 0x0010 /* open for reading & writing */ +#define __SEOF 0x0020 /* found EOF */ +#define __SERR 0x0040 /* found error */ +#define __SMBF 0x0080 /* _buf is from malloc */ +#define __SAPP 0x0100 /* fdopen()ed in append mode */ +#define __SSTR 0x0200 /* this is an sprintf/snprintf string */ +#define __SOPT 0x0400 /* do fseek() optimisation */ +#define __SNPT 0x0800 /* do not do fseek() optimisation */ +#define __SOFF 0x1000 /* set iff _offset is in fact correct */ +#define __SMOD 0x2000 /* true => fgetline modified _p text */ + +/* + * The following three definitions are for ANSI C, which took them + * from System V, which brilliantly took internal interface macros and + * made them official arguments to setvbuf(), without renaming them. + * Hence, these ugly _IOxxx names are *supposed* to appear in user code. + * + * Although numbered as their counterparts above, the implementation + * does not rely on this. + */ +#define _IOFBF 0 /* setvbuf should set fully buffered */ +#define _IOLBF 1 /* setvbuf should set line buffered */ +#define _IONBF 2 /* setvbuf should set unbuffered */ + +#define BUFSIZ 1024 /* size of buffer used by setbuf */ +#define EOF (-1) + +/* + * FOPEN_MAX is a minimum maximum, and should be the number of descriptors + * that the kernel can provide without allocation of a resource that can + * fail without the process sleeping. Do not use this for anything. + */ +#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */ +#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */ + +/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ +#ifndef _ANSI_SOURCE +#define P_tmpdir "/var/tmp/" +#endif +#define L_tmpnam 1024 /* XXX must be == PATH_MAX */ +#ifndef TMP_MAX +#define TMP_MAX 308915776 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + +#define stdin (&__sF[0]) +#define stdout (&__sF[1]) +#define stderr (&__sF[2]) + +/* + * Functions defined in ANSI C standard. + */ +__BEGIN_DECLS +void clearerr __P((FILE *)); +int fclose __P((FILE *)); +int feof __P((FILE *)); +int ferror __P((FILE *)); +int fflush __P((FILE *)); +int fgetc __P((FILE *)); +int fgetpos __P((FILE *, fpos_t *)); +char * fgets __P((char *, size_t, FILE *)); +FILE * fopen __P((const char *, const char *)); +int fprintf __P((FILE *, const char *, ...)); +int fputc __P((int, FILE *)); +int fputs __P((const char *, FILE *)); +size_t fread __P((void *, size_t, size_t, FILE *)); +FILE * freopen __P((const char *, const char *, FILE *)); +int fscanf __P((FILE *, const char *, ...)); +int fseek __P((FILE *, long, int)); +int fsetpos __P((FILE *, const fpos_t *)); +long ftell __P((const FILE *)); +size_t fwrite __P((const void *, size_t, size_t, FILE *)); +int getc __P((FILE *)); +int getchar __P((void)); +char * gets __P((char *)); + +#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) +extern int sys_nerr; /* perror(3) external variables */ +extern char *sys_errlist[]; +#endif + +void perror __P((const char *)); +int printf __P((const char *, ...)); +int putc __P((int, FILE *)); +int putchar __P((int)); +int puts __P((const char *)); +int remove __P((const char *)); +int rename __P((const char *, const char *)); +void rewind __P((FILE *)); +int scanf __P((const char *, ...)); +void setbuf __P((FILE *, char *)); +int setvbuf __P((FILE *, char *, int, size_t)); +int sprintf __P((char *, const char *, ...)); +int sscanf __P((const char *, const char *, ...)); +FILE *tmpfile __P((void)); +char *tmpnam __P((char *)); +int ungetc __P((int, FILE *)); +int vfprintf __P((FILE *, const char *, va_list)); +int vprintf __P((const char *, va_list)); +int vsprintf __P((char *, const char *, va_list)); +__END_DECLS + +/* + * Functions defined in POSIX 1003.1. + */ +#ifndef _ANSI_SOURCE +#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ +#define L_cuserid 9 /* size for cuserid(); UT_NAMESIZE + 1 */ + +__BEGIN_DECLS +char *ctermid __P((char *)); +char *cuserid __P((char *)); +FILE *fdopen __P((int, const char *)); +int fileno __P((FILE *)); +__END_DECLS +#endif /* not ANSI */ + +/* + * Routines that are purely local. + */ +#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE) +__BEGIN_DECLS +char *fgetline __P((FILE *, size_t *)); +int fpurge __P((FILE *)); +int getw __P((FILE *)); +int pclose __P((FILE *)); +FILE *popen __P((const char *, const char *)); +int putw __P((int, FILE *)); +void setbuffer __P((FILE *, char *, int)); +int setlinebuf __P((FILE *)); +char *tempnam __P((const char *, const char *)); +int snprintf __P((char *, size_t, const char *, ...)); +int vsnprintf __P((char *, size_t, const char *, va_list)); +int vscanf __P((const char *, va_list)); +int vsscanf __P((const char *, const char *, va_list)); +__END_DECLS + +/* + * This is a #define because the function is used internally and + * (unlike vfscanf) the name __svfscanf is guaranteed not to collide + * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined. + */ +#define vfscanf __svfscanf + +/* + * Stdio function-access interface. + */ +__BEGIN_DECLS +FILE *funopen __P((const void *, + int (*)(void *, char *, int), + int (*)(void *, const char *, int), + fpos_t (*)(void *, fpos_t, int), + int (*)(void *))); +__END_DECLS +#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) +#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) +#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ + +/* + * Functions internal to the implementation. + */ +__BEGIN_DECLS +int __srget __P((FILE *)); +int __svfscanf __P((FILE *, const char *, va_list)); +int __swbuf __P((int, FILE *)); +__END_DECLS + +/* + * The __sfoo macros are here so that we can + * define function versions in the C library. + */ +#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) +static __inline int __getc(FILE *_p) +{ + int ret; + flockfile(_p); + ret = __sgetc(_p); + funlockfile(_p); + return(ret); +} + +#define getc(fp) __gets(fp) +#define getchar() getc(stdin) +#define getc_unlocked(fp) __sgetc(fp) +#define getchar_unlocked() getc_unlocked(stdin) + +static __inline int __sputc(int _c, FILE *_p) +{ + if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) + return (*_p->_p++ = _c); + else + return (__swbuf(_c, _p)); +} + +static __inline int __putc(int _c, FILE *_p) +{ + int ret; + flockfile(_p); + ret = __sputc(_c, _p); + funlockfile(_p); + return(ret); +} + +#define putc(x, fp) __putc(x, fp); +#define putchar(x) putc(x, stdout) +#define putc_unlocked(x, fp) __sputc(x, fp) +#define putchar_unlocked(x) putc_unlocked(x, stdout) + +#define __sfeof(p) (((p)->_flags & __SEOF) != 0) +#define __sferror(p) (((p)->_flags & __SERR) != 0) +#define __sfileno(p) ((p)->_file) + +#define feof(p) __sfeof(p) +#define ferror(p) __sferror(p) + +#ifndef _ANSI_SOURCE +#define fileno(p) __sfileno(p) +#endif + +#endif diff --git a/lib/libpthread/include/util.h b/lib/libpthread/include/util.h new file mode 100644 index 000000000000..91d094c2856b --- /dev/null +++ b/lib/libpthread/include/util.h @@ -0,0 +1,87 @@ +/* ==== util.h ============================================================ + * Copyright (c) 1991, 1992, 1993 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Header file for generic utility functions. + * + * 91/08/31 proven - Added exchange. + * Exchange any two objects of any size in any table. + * + * 91/10/06 proven - Cleaned out all the old junk. + * + * 91/03/06 proven - Added getint. + */ + +#ifndef _PTHREAD_UTIL_H +#define _PTHREAD_UTIL_H + +#ifndef NULL +#define NULL 0 +#endif + +/* Stuff only pthread internals really uses */ +#if defined(PTHREAD_KERNEL) + +#undef FALSE +#undef TRUE + +typedef enum Boolean { + FALSE, + TRUE, +} Boolean; + +#define OK 0 +#define NUL '\0' +#define NOTOK -1 + +#if ! defined(min) +#define min(a,b) (((a)<(b))?(a):(b)) +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + +/* Alingn the size to the next multiple of 4 bytes */ +#define ALIGN4(size) ((size + 3) & ~3) +#define ALIGN8(size) ((size + 7) & ~7) + +#ifdef DEBUG +#define DEBUG0(s) printf(s) +#define DEBUG1(s,a) printf(s,a) +#define DEBUG2(s,a,b) printf(s,a,b) +#define DEBUG3(s,a,b,c) printf(s,a,b,c) +#else +#define DEBUG0(s) +#define DEBUG1(s) +#define DEBUG2(s) +#define DEBUG3(s) +#endif + +#endif + +#endif diff --git a/lib/libpthread/pthreads/Makefile.inc b/lib/libpthread/pthreads/Makefile.inc new file mode 100644 index 000000000000..29581c2264ac --- /dev/null +++ b/lib/libpthread/pthreads/Makefile.inc @@ -0,0 +1,13 @@ +# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 + +# pthread sources +.PATH: ${.CURDIR}/pthreads + +SRCS+= cond.c fd.c fd_kern.c fd_pipe.c file.c globals.c malloc.c mutex.c \ + pthread.c pthread_attr.c queue.c signal.c \ + pthread_join.c pthread_detach.c sleep.c + +MAN2+= + +MAN3+= + diff --git a/lib/libpthread/pthreads/cond.c b/lib/libpthread/pthreads/cond.c new file mode 100644 index 000000000000..84a90ba494c5 --- /dev/null +++ b/lib/libpthread/pthreads/cond.c @@ -0,0 +1,204 @@ +/* ==== cond.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Condition cariable functions. + * + * 1.00 93/10/28 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> + +/* ========================================================================== + * pthread_cond_init() + * + * In this implementation I don't need to allocate memory. + * ENOMEM, EAGAIN should never be returned. Arch that have + * weird constraints may need special coding. + */ +int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) +{ + /* Only check if attr specifies some mutex type other than fast */ + if ((cond_attr) && (cond_attr->c_type != COND_TYPE_FAST)) { + if (cond_attr->c_type >= COND_TYPE_MAX) { + return(EINVAL); + } + if (cond->c_flags & COND_FLAGS_INITED) { + return(EBUSY); + } + cond->c_type = cond_attr->c_type; + } else { + cond->c_type = COND_TYPE_FAST; + } + /* Set all other paramaters */ + pthread_queue_init(&cond->c_queue); + cond->c_flags |= COND_FLAGS_INITED; + cond->c_lock = SEMAPHORE_CLEAR; + return(OK); +} + +/* ========================================================================== + * pthread_cond_destroy() + */ +int pthread_cond_destroy(pthread_cond_t *cond) +{ + /* Only check if cond is of type other than fast */ + switch(cond->c_type) { + case COND_TYPE_FAST: + break; + case COND_TYPE_STATIC_FAST: + default: + return(EINVAL); + break; + } + + /* Cleanup cond, others might want to use it. */ + pthread_queue_init(&cond->c_queue); + cond->c_flags |= COND_FLAGS_INITED; + cond->c_lock = SEMAPHORE_CLEAR; + cond->c_flags = 0; + return(OK); +} + +/* ========================================================================== + * pthread_cond_wait() + */ +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + semaphore *lock, *plock; + int rval; + + lock = &(cond->c_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (cond->c_type) { + /* + * Fast condition variables do not check for any error conditions. + */ + case COND_TYPE_FAST: + case COND_TYPE_STATIC_FAST: + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_enq(&cond->c_queue, pthread_run); + pthread_mutex_unlock(mutex); + SEMAPHORE_RESET(lock); + + /* Reschedule will unlock pthread_run */ + reschedule(PS_COND_WAIT); + + return(pthread_mutex_lock(mutex)); + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} + +/* ========================================================================== + * pthread_cond_signal() + */ +int pthread_cond_signal(pthread_cond_t *cond) +{ + struct pthread *pthread; + semaphore *lock, *plock; + int rval; + + lock = &(cond->c_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (cond->c_type) { + case COND_TYPE_FAST: + case COND_TYPE_STATIC_FAST: + if (pthread = pthread_queue_get(&cond->c_queue)) { + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_deq(&cond->c_queue); + pthread->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } + rval = OK; + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} + +/* ========================================================================== + * pthread_cond_broadcast() + * + * Not much different then the above routine. + */ +int pthread_cond_broadcast(pthread_cond_t *cond) +{ + struct pthread *pthread; + semaphore *lock, *plock; + int rval; + + lock = &(cond->c_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (cond->c_type) { + case COND_TYPE_FAST: + case COND_TYPE_STATIC_FAST: + while (pthread = pthread_queue_get(&cond->c_queue)) { + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_deq(&cond->c_queue); + pthread->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } + rval = OK; + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} diff --git a/lib/libpthread/pthreads/fd.c b/lib/libpthread/pthreads/fd.c new file mode 100644 index 000000000000..20f1b0105859 --- /dev/null +++ b/lib/libpthread/pthreads/fd.c @@ -0,0 +1,558 @@ +/* ==== fd.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : All the syscalls dealing with fds. + * + * 1.00 93/08/14 proven + * -Started coding this file. + * + * 1.01 93/11/13 proven + * -The functions readv() and writev() added. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <stdarg.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread/posix.h> + +/* + * These first functions really should not be called by the user. + * + * I really should dynamically figure out what the table size is. + */ +int dtablesize = 64; +static struct fd_table_entry fd_entry[64]; + +/* ========================================================================== + * fd_init() + */ +void fd_init(void) +{ + int i; + + for (i = 0; i < dtablesize; i++) { + fd_table[i] = &fd_entry[i]; + + fd_table[i]->ops = NULL; + fd_table[i]->type = FD_NT; + fd_table[i]->fd.i = NOTOK; + fd_table[i]->flags = 0; + fd_table[i]->count = 0; + + pthread_queue_init(&(fd_table[i]->r_queue)); + pthread_queue_init(&(fd_table[i]->w_queue)); + + fd_table[i]->r_owner = NULL; + fd_table[i]->w_owner = NULL; + fd_table[i]->lock = SEMAPHORE_CLEAR; + fd_table[i]->next = NULL; + fd_table[i]->lockcount = 0; + } + + /* Currently only initialize first 3 fds. */ + fd_kern_init(0); + fd_kern_init(1); + fd_kern_init(2); + printf ("Warning: threaded process may have changed open file descriptors\n"); +} + +/* ========================================================================== + * fd_allocate() + */ +int fd_allocate() +{ + semaphore *lock; + int i; + + for (i = 0; i < dtablesize; i++) { + lock = &(fd_table[i]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + continue; + } + if (fd_table[i]->count || fd_table[i]->r_owner + || fd_table[i]->w_owner) { + SEMAPHORE_RESET(lock); + continue; + } + if (fd_table[i]->type == FD_NT) { + /* Test to see if the kernel version is in use */ + /* If so continue; */ + } + fd_table[i]->count++; + SEMAPHORE_RESET(lock); + return(i); + } + pthread_run->error = ENFILE; + return(NOTOK); +} + +/* ========================================================================== + * fd_free() + * + * Assumes fd is locked and owner by pthread_run + * Don't clear the queues, fd_unlock will do that. + */ +int fd_free(int fd) +{ + struct fd_table_entry *fd_valid; + int ret; + + if (ret = --fd_table[fd]->count) { + /* Separate pthread queue into two distinct queues. */ + fd_valid = fd_table[fd]; + fd_table[fd] = fd_table[fd]->next; + fd_valid->next = fd_table[fd]->next; + } + + fd_table[fd]->type = FD_NIU; + fd_table[fd]->fd.i = NOTOK; + fd_table[fd]->next = NULL; + fd_table[fd]->flags = 0; + fd_table[fd]->count = 0; + return(ret); +} + +/* ========================================================================== + * fd_basic_unlock() + * + * The real work of unlock without the locking of fd_table[fd].lock. + */ +void fd_basic_unlock(int fd, int lock_type) +{ + struct pthread *pthread; + semaphore *plock; + + if (fd_table[fd]->r_owner == pthread_run) { + if (pthread = pthread_queue_get(&fd_table[fd]->r_queue)) { + + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_deq(&fd_table[fd]->r_queue); + fd_table[fd]->r_owner = pthread; + pthread->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } else { + fd_table[fd]->r_owner = NULL; + } + } + + if (fd_table[fd]->w_owner == pthread_run) { + if (pthread = pthread_queue_get(&fd_table[fd]->w_queue)) { + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_deq(&fd_table[fd]->r_queue); + fd_table[fd]->w_owner = pthread; + pthread->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } else { + fd_table[fd]->w_owner = NULL; + } + } +} + +/* ========================================================================== + * fd_unlock() + * If there is a lock count then the function fileunlock will do + * the unlocking, just return. + */ +void fd_unlock(int fd, int lock_type) +{ + semaphore *lock; + + if (!(fd_table[fd]->lockcount)) { + lock = &(fd_table[fd]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + fd_basic_unlock(fd, lock_type); + SEMAPHORE_RESET(lock); + } +} + +/* ========================================================================== + * fd_basic_lock() + * + * The real work of lock without the locking of fd_table[fd].lock. + * Be sure to leave the lock the same way you found it. i.e. locked. + */ +int fd_basic_lock(unsigned int fd, int lock_type, semaphore * lock) +{ + semaphore *plock; + + /* If not in use return EBADF error */ + if (fd_table[fd]->type == FD_NIU) { + return(NOTOK); + } + + /* If not tested, test it and see if it is valid */ + if (fd_table[fd]->type == FD_NT) { + /* If not ok return EBADF error */ + if (fd_kern_init(fd) != OK) { + return(NOTOK); + } + } + if ((fd_table[fd]->type == FD_HALF_DUPLEX) || + (lock_type & FD_READ)) { + if (fd_table[fd]->r_owner) { + if (fd_table[fd]->r_owner != pthread_run) { + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_enq(&fd_table[fd]->r_queue, pthread_run); + SEMAPHORE_RESET(lock); + + /* Reschedule will unlock pthread_run */ + reschedule(PS_FDLR_WAIT); + + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + } else { + if (!fd_table[fd]->lockcount) { + PANIC(); + } + } + } + fd_table[fd]->r_owner = pthread_run; + } + if ((fd_table[fd]->type != FD_HALF_DUPLEX) && + (lock_type & FD_WRITE)) { + if (fd_table[fd]->w_owner) { + if (fd_table[fd]->w_owner != pthread_run) { + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_enq(&fd_table[fd]->w_queue, pthread_run); + SEMAPHORE_RESET(lock); + + /* Reschedule will unlock pthread_run */ + reschedule(PS_FDLW_WAIT); + + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + } + } + fd_table[fd]->w_owner = pthread_run; + } + if (!fd_table[fd]->count) { + fd_basic_unlock(fd, lock_type); + return(NOTOK); + } + return(OK); +} + +/* ========================================================================== + * fd_lock() + */ +int fd_lock(unsigned int fd, int lock_type) +{ + semaphore *lock; + int error; + + if (fd < dtablesize) { + lock = &(fd_table[fd]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + error = fd_basic_lock(fd, lock_type, lock); + SEMAPHORE_RESET(lock); + return(error); + } + return(NOTOK); +} + + +/* ========================================================================== + * ======================================================================= */ + +/* ========================================================================== + * read() + */ +ssize_t read(int fd, void *buf, size_t nbytes) +{ + int ret; + + if ((ret = fd_lock(fd, FD_READ)) == OK) { + ret = fd_table[fd]->ops->read(fd_table[fd]->fd, + fd_table[fd]->flags, buf, nbytes); + fd_unlock(fd, FD_READ); + } + return(ret); +} + +/* ========================================================================== + * readv() + */ +int readv(int fd, const struct iovec *iov, int iovcnt) +{ + int ret; + + if ((ret = fd_lock(fd, FD_READ)) == OK) { + ret = fd_table[fd]->ops->readv(fd_table[fd]->fd, + fd_table[fd]->flags, iov, iovcnt); + fd_unlock(fd, FD_READ); + } + return(ret); +} + +/* ========================================================================== + * write() + */ +ssize_t write(int fd, const void *buf, size_t nbytes) +{ + int ret; + + if ((ret = fd_lock(fd, FD_WRITE)) == OK) { + ret = fd_table[fd]->ops->write(fd_table[fd]->fd, + fd_table[fd]->flags, buf, nbytes); + fd_unlock(fd, FD_WRITE); + } + return(ret); +} + +/* ========================================================================== + * writev() + */ +int writev(int fd, const struct iovec *iov, int iovcnt) +{ + int ret; + + if ((ret = fd_lock(fd, FD_WRITE)) == OK) { + ret = fd_table[fd]->ops->writev(fd_table[fd]->fd, + fd_table[fd]->flags, iov, iovcnt); + fd_unlock(fd, FD_WRITE); + } + return(ret); +} + +/* ========================================================================== + * lseek() + */ +off_t lseek(int fd, off_t offset, int whence) +{ + int ret; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + ret = fd_table[fd]->ops->seek(fd_table[fd]->fd, + fd_table[fd]->flags, offset, whence); + fd_unlock(fd, FD_RDWR); + } + return(ret); +} + +/* ========================================================================== + * close() + * + * The whole close procedure is a bit odd and needs a bit of a rethink. + * For now close() locks the fd, calls fd_free() which checks to see if + * there are any other fd values poinging to the same real fd. If so + * It breaks the wait queue into two sections those that are waiting on fd + * and those waiting on other fd's. Those that are waiting on fd are connected + * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT + * RELEASED). close() then calls fd_unlock which give the fd to the next queued + * element which determins that the fd is closed and then calls fd_unlock etc... + */ +int close(int fd) +{ + union fd_data realfd; + int ret, flags; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + flags = fd_table[fd]->flags; + realfd = fd_table[fd]->fd; + if (fd_free(fd) == OK) { + ret = fd_table[fd]->ops->close(realfd, flags); + } + fd_unlock(fd, FD_RDWR); + } + return(ret); +} + +/* ========================================================================== + * fd_basic_dup() + * + * Might need to do more than just what's below. + */ +static inline void fd_basic_dup(int fd, int newfd) +{ + fd_table[newfd]->next = fd_table[fd]->next; + fd_table[fd]->next = fd_table[newfd]; + fd_table[fd]->count++; +} + +/* ========================================================================== + * dup2() + * + * Always lock the lower number fd first to avoid deadlocks. + * newfd must be locked by hand so it can be closed if it is open, + * or it won't be opened while dup is in progress. + */ +int dup2(fd, newfd) +{ + union fd_data realfd; + semaphore *lock; + int ret, flags; + + if (newfd < dtablesize) { + if (fd < newfd) { + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + /* Need to lock the newfd by hand */ + lock = &(fd_table[newfd]->lock); + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Is it inuse */ + if (fd_basic_lock(newfd, FD_RDWR, lock) == OK) { + /* free it and check close status */ + flags = fd_table[fd]->flags; + realfd = fd_table[fd]->fd; + if (fd_free(fd) == OK) { + ret = fd_table[fd]->ops->close(realfd, flags); + } else { + /* Lots of work to do */ + } + } + fd_basic_dup(fd, newfd); + } + fd_unlock(fd, FD_RDWR); + } else { + /* Need to lock the newfd by hand */ + lock = &(fd_table[newfd]->lock); + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + } + /* Is it inuse */ + if ((ret = fd_basic_lock(newfd, FD_RDWR, lock)) == OK) { + /* free it and check close status */ + flags = fd_table[fd]->flags; + realfd = fd_table[fd]->fd; + if (fd_free(fd) == OK) { + ret = fd_table[fd]->ops->close(realfd, flags); + } else { + /* Lots of work to do */ + } + + fd_basic_dup(fd, newfd); + fd_unlock(fd, FD_RDWR); + } + SEMAPHORE_RESET(lock); + } + } else { + ret = NOTOK; + } + return(ret); + +} + +/* ========================================================================== + * dup() + */ +int dup(int fd) +{ + int ret; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + ret = fd_allocate(); + fd_basic_dup(fd, ret); + fd_unlock(fd, FD_RDWR); + } + return(ret); +} + +/* ========================================================================== + * fcntl() + */ +int fcntl(int fd, int cmd, ...) +{ + int ret, realfd, flags; + struct flock *flock; + semaphore *plock; + va_list ap; + + flags = 0; + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + va_start(ap, cmd); + switch(cmd) { + case F_DUPFD: + ret = fd_allocate(); + fd_basic_dup(va_arg(ap, int), ret); + break; + case F_SETFD: + flags = va_arg(ap, int); + case F_GETFD: + ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, + fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK); + break; + case F_GETFL: + ret = fd_table[fd]->flags; + break; + case F_SETFL: + flags = va_arg(ap, int); + if ((ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, + fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK)) == OK) { + fd_table[fd]->flags = flags; + } + break; +/* case F_SETLKW: */ + /* + * Do the same as SETLK but if it fails with EACCES or EAGAIN + * block the thread and try again later, not implemented yet + */ +/* case F_SETLK: */ +/* case F_GETLK: + flock = va_arg(ap, struct flock*); + ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, + fd_table[fd]->flags, cmd, flock); + break; */ + default: + /* Might want to make va_arg use a union */ + ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd, + fd_table[fd]->flags, cmd, va_arg(ap, void*)); + break; + } + va_end(ap); + fd_unlock(fd, FD_RDWR); + } + return(ret); +} diff --git a/lib/libpthread/pthreads/fd_kern.c b/lib/libpthread/pthreads/fd_kern.c new file mode 100644 index 000000000000..41b638724fb9 --- /dev/null +++ b/lib/libpthread/pthreads/fd_kern.c @@ -0,0 +1,643 @@ +/* ==== fd_kern.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Deals with the valid kernel fds. + * + * 1.00 93/09/27 proven + * -Started coding this file. + * + * 1.01 93/11/13 proven + * -The functions readv() and writev() added. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/uio.h> +#include <stdarg.h> +#include <signal.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread/posix.h> + +/* ========================================================================== + * Variables used by both fd_kern_poll and fd_kern_wait + */ +static struct pthread *fd_wait_read, *fd_wait_write; +static fd_set fd_set_read, fd_set_write; + +/* ========================================================================== + * fd_kern_poll() + * + * Called only from context_switch(). The kernel must be locked. + * + * This function uses a linked list of waiting pthreads, NOT a queue. + */ +static semaphore fd_wait_lock = SEMAPHORE_CLEAR; + +void fd_kern_poll() +{ + struct timeval __fd_kern_poll_timeout = { 0, 0 }; + struct pthread **pthread; + semaphore *lock; + int count; + + /* If someone has the lock then they are in RUNNING state, just return */ + lock = &fd_wait_lock; + if (SEMAPHORE_TEST_AND_SET(lock)) { + return; + } + if (fd_wait_read || fd_wait_write) { + for (pthread = &fd_wait_read; *pthread; pthread = &((*pthread)->next)) { + FD_SET((*pthread)->fd, &fd_set_read); + } + for (pthread = &fd_wait_write; *pthread; pthread = &((*pthread)->next)) { + FD_SET((*pthread)->fd, &fd_set_write); + } + + if ((count = machdep_sys_select(dtablesize, &fd_set_read, + &fd_set_write, NULL, &__fd_kern_poll_timeout)) < OK) { + if (count == -EINTR) { + SEMAPHORE_RESET(lock); + return; + } + PANIC(); + } + + for (pthread = &fd_wait_read; count && *pthread; ) { + if (FD_ISSET((*pthread)->fd, &fd_set_read)) { + /* Get lock on thread */ + + (*pthread)->state = PS_RUNNING; + *pthread = (*pthread)->next; + count--; + continue; + } + pthread = &((*pthread)->next); + } + + for (pthread = &fd_wait_write; count && *pthread; ) { + if (FD_ISSET((*pthread)->fd, &fd_set_write)) { + semaphore *plock; + + /* Get lock on thread */ + plock = &(*pthread)->lock; + if (!(SEMAPHORE_TEST_AND_SET(plock))) { + /* Thread locked, skip it. */ + (*pthread)->state = PS_RUNNING; + *pthread = (*pthread)->next; + SEMAPHORE_RESET(plock); + } + count--; + continue; + } + pthread = &((*pthread)->next); + } + } + SEMAPHORE_RESET(lock); +} + +/* ========================================================================== + * fd_kern_wait() + * + * Called when there is no active thread to run. + */ +extern struct timeval __fd_kern_wait_timeout; + +void fd_kern_wait() +{ + struct pthread **pthread; + sigset_t sig_to_block; + int count; + + if (fd_wait_read || fd_wait_write) { + for (pthread = &fd_wait_read; *pthread; pthread = &((*pthread)->next)) { + FD_SET((*pthread)->fd, &fd_set_read); + } + for (pthread = &fd_wait_write; *pthread; pthread = &((*pthread)->next)) { + FD_SET((*pthread)->fd, &fd_set_write); + } + + /* Turn off interrupts for real while we set the timer. */ + + sigfillset(&sig_to_block); + sigprocmask(SIG_BLOCK, &sig_to_block, NULL); + + machdep_unset_thread_timer(); + __fd_kern_wait_timeout.tv_usec = 0; + __fd_kern_wait_timeout.tv_sec = 3600; + + sigprocmask(SIG_UNBLOCK, &sig_to_block, NULL); + + /* + * There is a small but finite chance that an interrupt will + * occure between the unblock and the select. Because of this + * sig_handler_real() sets the value of __fd_kern_wait_timeout + * to zero causing the select to do a poll instead of a wait. + */ + + while ((count = machdep_sys_select(dtablesize, &fd_set_read, + &fd_set_write, NULL, &__fd_kern_wait_timeout)) < OK) { + if (count == -EINTR) { + return; + } + PANIC(); + } + + for (pthread = &fd_wait_read; count && *pthread; ) { + if (FD_ISSET((*pthread)->fd, &fd_set_read)) { + /* Get lock on thread */ + + (*pthread)->state = PS_RUNNING; + *pthread = (*pthread)->next; + count--; + continue; + } + pthread = &((*pthread)->next); + } + + for (pthread = &fd_wait_write; count && *pthread; ) { + if (FD_ISSET((*pthread)->fd, &fd_set_write)) { + semaphore *plock; + + /* Get lock on thread */ + plock = &(*pthread)->lock; + if (!(SEMAPHORE_TEST_AND_SET(plock))) { + /* Thread locked, skip it. */ + (*pthread)->state = PS_RUNNING; + *pthread = (*pthread)->next; + SEMAPHORE_RESET(plock); + } + count--; + continue; + } + pthread = &((*pthread)->next); + } + } else { + /* No threads, waiting on I/O, do a sigsuspend */ + sig_handler_pause(); + } +} + +/* ========================================================================== + * Special Note: All operations return the errno as a negative of the errno + * listed in errno.h + * ======================================================================= */ + +/* ========================================================================== + * read() + */ +ssize_t __fd_kern_read(int fd, int flags, void *buf, size_t nbytes) +{ + semaphore *lock, *plock; + int ret; + + while ((ret = machdep_sys_read(fd, buf, nbytes)) < OK) { + if (ret == -EWOULDBLOCK) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDR_WAIT */ + pthread_run->next = fd_wait_read; + fd_wait_read = pthread_run; + pthread_run->fd = fd; + SEMAPHORE_RESET(lock); + reschedule(PS_FDR_WAIT); + } else { + pthread_run->error = -ret; + ret = NOTOK; + break; + } + } + return(ret); +} + +/* ========================================================================== + * readv() + */ +int __fd_kern_readv(int fd, int flags, struct iovec *iov, int iovcnt) +{ + semaphore *lock, *plock; + int ret; + + while ((ret = machdep_sys_readv(fd, iov, iovcnt)) < OK) { + if (ret == -EWOULDBLOCK) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDR_WAIT */ + pthread_run->next = fd_wait_read; + fd_wait_read = pthread_run; + pthread_run->fd = fd; + SEMAPHORE_RESET(lock); + reschedule(PS_FDR_WAIT); + } else { + pthread_run->error = -ret; + ret = NOTOK; + break; + } + } + return(ret); +} + +/* ========================================================================== + * write() + */ +ssize_t __fd_kern_write(int fd, int flags, const void *buf, size_t nbytes) +{ + semaphore *lock, *plock; + int ret; + + while ((ret = machdep_sys_write(fd, buf, nbytes)) < OK) { + if (pthread_run->error == -EWOULDBLOCK) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDW_WAIT */ + pthread_run->next = fd_wait_write; + fd_wait_write = pthread_run; + pthread_run->fd = fd; + SEMAPHORE_RESET(lock); + reschedule(PS_FDW_WAIT); + } else { + pthread_run->error = ret; + break; + } + } + return(ret); +} + +/* ========================================================================== + * writev() + */ +int __fd_kern_writev(int fd, int flags, struct iovec *iov, int iovcnt) +{ + semaphore *lock, *plock; + int ret; + + while ((ret = machdep_sys_writev(fd, iov, iovcnt)) < OK) { + if (pthread_run->error == -EWOULDBLOCK) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDW_WAIT */ + pthread_run->next = fd_wait_write; + fd_wait_write = pthread_run; + pthread_run->fd = fd; + SEMAPHORE_RESET(lock); + reschedule(PS_FDW_WAIT); + } else { + pthread_run->error = ret; + break; + } + } + return(ret); +} + +/* ========================================================================== + * For blocking version we really should set an interrupt + * fcntl() + */ +int __fd_kern_fcntl(int fd, int flags, int cmd, int arg) +{ + return(machdep_sys_fcntl(fd, cmd, arg)); +} + +/* ========================================================================== + * close() + */ +int __fd_kern_close(int fd, int flags) +{ + return(machdep_sys_close(fd)); +} + +/* ========================================================================== + * lseek() + */ +int __fd_kern_lseek(int fd, int flags, off_t offset, int whence) +{ + return(machdep_sys_lseek(fd, offset, whence)); +} + +/* + * File descriptor operations + */ +extern machdep_sys_close(); + +/* Normal file operations */ +static struct fd_ops __fd_kern_ops = { + __fd_kern_write, __fd_kern_read, __fd_kern_close, __fd_kern_fcntl, + __fd_kern_readv, __fd_kern_writev, __fd_kern_lseek +}; + +/* NFS file opperations */ + +/* FIFO file opperations */ + +/* Device operations */ + +/* ========================================================================== + * open() + * + * Because open could potentially block opening a file from a remote + * system, we want to make sure the call will timeout. We then try and open + * the file, and stat the file to determine what operations we should + * associate with the fd. + * + * This is not done yet + * + * A reqular file on the local system needs no special treatment. + */ +int open(const char *path, int flags, ...) +{ + int fd, mode, fd_kern; + struct stat stat_buf; + va_list ap; + + /* If pthread scheduling == FIFO set a virtual timer */ + if (flags & O_CREAT) { + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } else { + mode = 0; + } + + if (!((fd = fd_allocate()) < OK)) { + fd_table[fd]->flags = flags; + flags |= __FD_NONBLOCK; + + if (!((fd_kern = machdep_sys_open(path, flags, mode)) < OK)) { + + /* fstat the file to determine what type it is */ + if (fstat(fd_kern, &stat_buf)) { +printf("error %d stating new fd %d\n", errno, fd); + } + if (S_ISREG(stat_buf.st_mode)) { + fd_table[fd]->ops = &(__fd_kern_ops); + fd_table[fd]->type = FD_HALF_DUPLEX; + } else { + fd_table[fd]->ops = &(__fd_kern_ops); + fd_table[fd]->type = FD_FULL_DUPLEX; + } + fd_table[fd]->fd = fd_kern; + return(fd); + } + + pthread_run->error = - fd_kern; + fd_table[fd]->count = 0; + } + return(NOTOK); +} + +/* ========================================================================== + * fd_kern_init() + * + * Assume the entry is locked before routine is invoked + * + * This may change. The problem is setting the fd to nonblocking changes + * the parents fd too, which may not be the desired result. + */ +static fd_kern_init_called = 0; +void fd_kern_init(int fd) +{ + if ((fd_table[fd]->flags = machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) { + machdep_sys_fcntl(fd, F_SETFL, fd_table[fd]->flags | __FD_NONBLOCK); + fd_table[fd]->ops = &(__fd_kern_ops); + fd_table[fd]->type = FD_HALF_DUPLEX; + fd_table[fd]->fd = fd; + fd_table[fd]->count = 1; + + } +} + +/* ========================================================================== + * Here are the berkeley socket functions. These are not POSIX. + * ======================================================================= */ + +/* ========================================================================== + * socket() + */ +int socket(int af, int type, int protocol) +{ + int fd, fd_kern; + + if (!((fd = fd_allocate()) < OK)) { + + if (!((fd_kern = machdep_sys_socket(af, type, protocol)) < OK)) { + machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK); + + /* Should fstat the file to determine what type it is */ + fd_table[fd]->ops = & __fd_kern_ops; + fd_table[fd]->type = FD_FULL_DUPLEX; + fd_table[fd]->fd = fd_kern; + fd_table[fd]->flags = 0; + return(fd); + } + + pthread_run->error = - fd_kern; + fd_table[fd]->count = 0; + } + return(NOTOK); +} + +/* ========================================================================== + * bind() + */ +int bind(int fd, const struct sockaddr *name, int namelen) +{ + /* Not much to do in bind */ + semaphore *plock; + int ret; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + if ((ret = machdep_sys_bind(fd_table[fd]->fd, name, namelen)) < OK) { + pthread_run->error = - ret; + } + fd_unlock(fd, FD_RDWR); + } + return(ret); +} + +/* ========================================================================== + * connect() + */ +int connect(int fd, const struct sockaddr *name, int namelen) +{ + semaphore *lock, *plock; + struct sockaddr tmpname; + int ret, tmpnamelen; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + if ((ret = machdep_sys_connect(fd_table[fd]->fd, name, namelen)) < OK) { + if ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) || + (ret == -EALREADY)) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDW_WAIT */ + pthread_run->fd = fd_table[fd]->fd.i; + pthread_run->next = fd_wait_write; + fd_wait_write = pthread_run; + SEMAPHORE_RESET(lock); + reschedule(PS_FDW_WAIT); + + /* OK now lets see if it really worked */ + if (((ret = machdep_sys_getpeername(fd_table[fd]->fd, + &tmpname, &tmpnamelen)) < OK) && (ret == -ENOTCONN)) { + + /* Get the error, this function should not fail */ + machdep_sys_getsockopt(fd_table[fd]->fd, SOL_SOCKET, + SO_ERROR, &pthread_run->error, &tmpnamelen); + } + } else { + pthread_run->error = -ret; + } + } + fd_unlock(fd, FD_RDWR); + } + return(ret); +} + +/* ========================================================================== + * accept() + */ +int accept(int fd, struct sockaddr *name, int *namelen) +{ + semaphore *lock, *plock; + int ret, fd_kern; + + + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + while ((fd_kern = machdep_sys_accept(fd_table[fd]->fd, name, namelen)) < OK) { + if (fd_kern == -EWOULDBLOCK) { + /* Lock queue */ + lock = &fd_wait_lock; + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDR_WAIT */ + pthread_run->fd = fd_table[fd]->fd.i; + pthread_run->next = fd_wait_write; + pthread_run->next = fd_wait_read; + fd_wait_read = pthread_run; + SEMAPHORE_RESET(lock); + reschedule(PS_FDR_WAIT); + } else { + fd_unlock(fd, FD_RDWR); + return(fd_kern); + } + } + fd_unlock(fd, FD_RDWR); + + if (!((ret = fd_allocate()) < OK)) { + + /* This may be unnecessary */ + machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK); + + /* Should fstat the file to determine what type it is */ + fd_table[ret]->ops = & __fd_kern_ops; + fd_table[ret]->type = FD_FULL_DUPLEX; + fd_table[ret]->fd = fd_kern; + fd_table[ret]->flags = 0; + } + } + return(ret); +} + +/* ========================================================================== + * listen() + */ +int listen(int fd, int backlog) +{ + int ret; + + if ((ret = fd_lock(fd, FD_RDWR)) == OK) { + ret = machdep_sys_listen(fd_table[fd]->fd, backlog); + fd_unlock(fd, FD_RDWR); + } + return(ret); +} diff --git a/lib/libpthread/pthreads/fd_pipe.c b/lib/libpthread/pthreads/fd_pipe.c new file mode 100644 index 000000000000..f504c75526b9 --- /dev/null +++ b/lib/libpthread/pthreads/fd_pipe.c @@ -0,0 +1,264 @@ +/* ==== fd_pipe.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : The new fast ITC pipe routines. + * + * 1.00 93/08/14 proven + * -Started coding this file. + * + * 1.01 93/11/13 proven + * -The functions readv() and writev() added. + */ + +#include <pthread.h> +#include <pthread/fd_pipe.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread/posix.h> + +/* ========================================================================== + * The pipe lock is never unlocked until all pthreads waiting are done with it + * read() + */ +ssize_t __pipe_read(struct __pipe *fd, int flags, void *buf, size_t nbytes) +{ + semaphore *lock, *plock; + int ret = 0; + + if (flags & O_ACCMODE) { return(NOTOK); } + + lock = &(fd->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + /* If there is nothing to read, go to sleep */ + if (fd->count == 0) { + if (flags == WR_CLOSED) { + SEMAPHORE_RESET(lock); + return(0); + } /* Lock pthread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* queue pthread for a FDR_WAIT */ + pthread_run->next = NULL; + fd->wait = pthread_run; + SEMAPHORE_RESET(lock); + reschedule(PS_FDR_WAIT); + ret = fd->size; + } else { + ret = MIN(nbytes, fd->count); + memcpy(buf, fd->buf + fd->offset, ret); + if (!(fd->count -= ret)) { + fd->offset = 0; + } + + /* Should try to read more from the waiting writer */ + + if (fd->wait) { + plock = &(fd->wait->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + fd->wait->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } else { + SEMAPHORE_RESET(lock); + } + } + return(ret); +} + +/* ========================================================================== + * __pipe_write() + * + * First check to see if the read side is still open, then + * check to see if there is a thread in a read wait for this pipe, if so + * copy as much data as possible directly into the read waiting threads + * buffer. The write thread(whether or not there was a read thread) + * copies as much data as it can into the pipe buffer and it there + * is still data it goes to sleep. + */ +ssize_t __pipe_write(struct __pipe *fd, int flags, const void *buf, size_t nbytes) { + semaphore *lock, *plock; + int ret, count; + + if (!(flags & O_ACCMODE)) { return(NOTOK); } + + lock = &(fd->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + while (fd->flags != RD_CLOSED) { + if (fd->wait) { + /* Lock pthread */ + plock = &(fd->wait->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* Copy data directly into waiting pthreads buf */ + fd->wait_size = MIN(nbytes, fd->wait_size); + memcpy(fd->wait_buf, buf, fd->wait_size); + buf = (const char *)buf + fd->wait_size; + nbytes -= fd->wait_size; + ret = fd->wait_size; + + /* Wake up waiting pthread */ + fd->wait->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + fd->wait = NULL; + } + + if (count = MIN(nbytes, fd->size - (fd->offset + fd->count))) { + memcpy(fd->buf + (fd->offset + fd->count), buf, count); + buf = (const char *)buf + count; + nbytes -= count; + ret += count; + } + if (nbytes) { + /* Lock pthread */ + plock = &(fd->wait->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + fd->wait = pthread_run; + SEMAPHORE_RESET(lock); + reschedule(PS_FDW_WAIT); + } else { + return(ret); + } + } + return(NOTOK); +} + +/* ========================================================================== + * __pipe_close() + * + * The whole close procedure is a bit odd and needs a bit of a rethink. + * For now close() locks the fd, calls fd_free() which checks to see if + * there are any other fd values poinging to the same real fd. If so + * It breaks the wait queue into two sections those that are waiting on fd + * and those waiting on other fd's. Those that are waiting on fd are connected + * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT + * RELEASED). close() then calls fd_unlock which give the fd to the next queued + * element which determins that the fd is closed and then calls fd_unlock etc... + */ +int __pipe_close(struct __pipe *fd, int flags) +{ + semaphore *lock, *plock; + + lock = &(fd->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + if (!(fd->flags)) { + if (fd->wait) { + if (flags & O_ACCMODE) { + fd->flags |= WR_CLOSED; + /* Lock pthread */ + /* Write side closed, wake read side and return EOF */ + plock = &((fd->wait)->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + fd->count = 0; + + /* Wake up waiting pthread */ + fd->wait->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + fd->wait = NULL; + } else { + /* Should send a signal */ + fd->flags |= RD_CLOSED; + } + } + } else { + free(fd); + return(OK); + } + SEMAPHORE_RESET(lock); +} + +/* ========================================================================== + * For those function that aren't implemented yet + * __pipe_enosys() + */ +static int __pipe_enosys() +{ + pthread_run->error = ENOSYS; + return(NOTOK); +} + +/* + * File descriptor operations + */ +struct fd_ops fd_ops[] = { +{ NULL, NULL, }, /* Non operations */ +{ __pipe_write, __pipe_read, __pipe_close, __pipe_enosys, __pipe_enosys, + __pipe_enosys }, +}; + +/* ========================================================================== + * open() + */ +/* int __pipe_open(const char *path, int flags, ...) */ +int newpipe(int fd[2]) +{ + struct __pipe *fd_data; + + if ((!((fd[0] = fd_allocate()) < OK)) && (!((fd[1] = fd_allocate()) < OK))) { + fd_data = malloc(sizeof(struct __pipe)); + fd_data->buf = malloc(4096); + fd_data->size = 4096; + fd_data->count = 0; + fd_data->offset = 0; + + fd_data->wait = NULL; + fd_data->flags = 0; + + fd_table[fd[0]]->fd.ptr = fd_data; + fd_table[fd[0]]->flags = O_RDONLY; + fd_table[fd[1]]->fd.ptr = fd_data; + fd_table[fd[1]]->flags = O_WRONLY; + + return(OK); + } + return(NOTOK); +} + diff --git a/lib/libpthread/pthreads/file.c b/lib/libpthread/pthreads/file.c new file mode 100644 index 000000000000..d2cafc69b643 --- /dev/null +++ b/lib/libpthread/pthreads/file.c @@ -0,0 +1,113 @@ +/* ==== file.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : The locking functions for stdio. + * + * 1.00 93/09/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> + +/* ========================================================================== + * flockfile() + */ +void flockfile(FILE *fp) +{ + semaphore *lock; + int fd; + + fd = fileno(fp); + lock = &(fd_table[fd]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + if (fd_table[fd]->r_owner != pthread_run) { + /* This might fail but POSIX doesn't give a damn. */ + fd_basic_lock(fd, FD_RDWR, lock); + } + fd_table[fd]->lockcount++; + SEMAPHORE_RESET(lock); +} + +/* ========================================================================== + * ftrylockfile() + */ +int ftrylockfile(FILE *fp) +{ + semaphore *lock; + int fd; + + fd = fileno(fp); + lock = &(fd_table[fd]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + if (fd_table[fd]->r_owner != pthread_run) { + if (!(fd_table[fd]->r_owner && fd_table[fd]->w_owner)) { + fd_basic_lock(fd, FD_RDWR, lock); + fd = OK; + } else { + fd = NOTOK; + } + } else { + fd_table[fd]->lockcount++; + fd = OK; + } + SEMAPHORE_RESET(lock); + return(fd); +} + +/* ========================================================================== + * funlockfile() + */ +void funlockfile(FILE *fp) +{ + semaphore *lock; + int fd; + + fd = fileno(fp); + lock = &(fd_table[fd]->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + if (fd_table[fd]->r_owner == pthread_run) { + if (--fd_table[fd]->lockcount == 0) { + fd_basic_unlock(fd, FD_RDWR); + } + } + SEMAPHORE_RESET(lock); +} + diff --git a/lib/libpthread/pthreads/globals.c b/lib/libpthread/pthreads/globals.c new file mode 100644 index 000000000000..d5ed64d9ffaa --- /dev/null +++ b/lib/libpthread/pthreads/globals.c @@ -0,0 +1,63 @@ +/* ==== globals.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Global variables. + * + * 1.00 93/07/26 proven + * -Started coding this file. + */ + +#include <pthread.h> + +/* + * Initial thread, running thread, and top of link list + * of all threads. + */ +struct pthread *pthread_run; +struct pthread *pthread_initial; +struct pthread *pthread_link_list; + +/* + * default thread attributes + */ +pthread_attr_t pthread_default_attr = { SCHED_RR, NULL, PTHREAD_STACK_DEFAULT }; + +/* + * Queue for all threads elidgeable to run this scheduling round. + */ +struct pthread_queue pthread_current_queue = PTHREAD_QUEUE_INITIALIZER; + +/* + * File table information + */ +struct fd_table_entry *fd_table[64]; + + diff --git a/lib/libpthread/pthreads/malloc.c b/lib/libpthread/pthreads/malloc.c new file mode 100644 index 000000000000..c5947916a049 --- /dev/null +++ b/lib/libpthread/pthreads/malloc.c @@ -0,0 +1,357 @@ +/* ==== malloc.c ============================================================ + * Copyright (c) 1983 Regents of the University of California. + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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. + * + * Description : Malloc functions. + * 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. + * + * 0.00 82/02/21 Chris Kingsley kingsley@cit-20 + * + * 1.00 93/11/06 proven + * -Modified BSD libc malloc to be threadsafe. + * + */ + +#include <pthread.h> +#include <sys/types.h> +#include <string.h> +#include <pthread/posix.h> + +/* + * 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 */ +static semaphore malloc_lock = SEMAPHORE_CLEAR; + +#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 + +/* ========================================================================== + * morecore() + * + * Allocate more memory to the indicated bucket + */ +static inline void morecore(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); + } +} + +/* ========================================================================== + * malloc() + */ +void *malloc(size_t nbytes) +{ + union overhead *op; + unsigned int amt; + int bucket, n; + semaphore *lock; + + lock = &malloc_lock; + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + /* + * 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) { + SEMAPHORE_RESET(lock); + 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) { + SEMAPHORE_RESET(lock); + return (NULL); + } + } + /* remove from linked list */ + nextf[bucket] = op->ov_next; + op->ov_magic = MAGIC; + op->ov_index = bucket; +#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 + SEMAPHORE_RESET(lock); + return ((char *)(op + 1)); +} + +/* ========================================================================== + * free() + */ +void free(void *cp) +{ + union overhead *op; + semaphore *lock; + int size; + + lock = &malloc_lock; + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + if (cp == NULL) { + SEMAPHORE_RESET(lock); + 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) { + SEMAPHORE_RESET(lock); + 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; + + SEMAPHORE_RESET(lock); +} + +/* ========================================================================== + * realloc() + * + * Storage compaction is no longer supported, fix program and try again. + */ +void *realloc(void *cp, size_t nbytes) +{ + u_int onb; + int i; + semaphore *lock; + union overhead *op; + char *res; + + if (cp == NULL) + return (malloc(nbytes)); + op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); + + if (op->ov_magic == MAGIC) { + i = op->ov_index; + } else { + /* + * This will cause old programs using storage compaction feature of + * realloc to break in a pseudo resonable way that is easy to debug. + * Returning a malloced buffer without the copy may cause + * indeterministic behavior. + */ + return(NULL); + } + + lock = &malloc_lock; + while(SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + 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 (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 + SEMAPHORE_RESET(lock); + return(cp); + } + SEMAPHORE_RESET(lock); + + if ((res = malloc(nbytes)) == NULL) { + free(cp); + return (NULL); + } + + bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + free(cp); + + return (res); +} + diff --git a/lib/libpthread/pthreads/mutex.c b/lib/libpthread/pthreads/mutex.c new file mode 100644 index 000000000000..0f3e9abfca7a --- /dev/null +++ b/lib/libpthread/pthreads/mutex.c @@ -0,0 +1,223 @@ +/* ==== mutex.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Mutex functions. + * + * 1.00 93/07/19 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> + +/* + * Basic mutex functionality + + * This is the basic lock order + * queue + * pthread + * global + * + * semaphore functionality is defined in machdep.h + */ + +/* ========================================================================== + * pthread_mutex_init() + * + * In this implementation I don't need to allocate memory. + * ENOMEM, EAGAIN should never be returned. Arch that have + * weird constraints may need special coding. + */ +int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mutex_attr) +{ + /* Only check if attr specifies some mutex type other than fast */ + if ((mutex_attr) && (mutex_attr->m_type != MUTEX_TYPE_FAST)) { + if (mutex_attr->m_type >= MUTEX_TYPE_MAX) { + return(EINVAL); + } + if (mutex->m_flags & MUTEX_FLAGS_INITED) { + return(EBUSY); + } + mutex->m_type = mutex_attr->m_type; + } else { + mutex->m_type = MUTEX_TYPE_FAST; + } + /* Set all other paramaters */ + pthread_queue_init(&mutex->m_queue); + mutex->m_flags |= MUTEX_FLAGS_INITED; + mutex->m_lock = SEMAPHORE_CLEAR; + mutex->m_owner = NULL; + return(OK); +} + +/* ========================================================================== + * pthread_mutex_destroy() + */ +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + /* Only check if mutex is of type other than fast */ + switch(mutex->m_type) { + case MUTEX_TYPE_FAST: + break; + case MUTEX_TYPE_STATIC_FAST: + default: + return(EINVAL); + break; + } + + /* Cleanup mutex, others might want to use it. */ + pthread_queue_init(&mutex->m_queue); + mutex->m_flags |= MUTEX_FLAGS_INITED; + mutex->m_lock = SEMAPHORE_CLEAR; + mutex->m_owner = NULL; + mutex->m_flags = 0; + return(OK); +} + +/* ========================================================================== + * pthread_mutex_trylock() + */ +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + semaphore *lock; + int rval; + + lock = &(mutex->m_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (mutex->m_type) { + /* + * Fast mutexes do not check for any error conditions. + */ + case MUTEX_TYPE_FAST: + case MUTEX_TYPE_STATIC_FAST: + if (!mutex->m_owner) { + mutex->m_owner = pthread_run; + rval = OK; + } else { + rval = EBUSY; + } + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} + +/* ========================================================================== + * pthread_mutex_lock() + */ +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + semaphore *lock, *plock; + int rval; + + lock = &(mutex->m_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (mutex->m_type) { + /* + * Fast mutexes do not check for any error conditions. + */ + case MUTEX_TYPE_FAST: + case MUTEX_TYPE_STATIC_FAST: + if (mutex->m_owner) { + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + pthread_queue_enq(&mutex->m_queue, pthread_run); + SEMAPHORE_RESET(lock); + + /* Reschedule will unlock pthread_run */ + reschedule(PS_MUTEX_WAIT); + return(OK); + } + mutex->m_owner = pthread_run; + rval = OK; + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} + +/* ========================================================================== + * pthread_mutex_unlock() + */ +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + struct pthread *pthread; + semaphore *lock, *plock; + int rval; + + lock = &(mutex->m_lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + switch (mutex->m_type) { + /* + * Fast mutexes do not check for any error conditions. + */ + case MUTEX_TYPE_FAST: + case MUTEX_TYPE_STATIC_FAST: + if (pthread = pthread_queue_get(&mutex->m_queue)) { + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + mutex->m_owner = pthread; + + /* Reset pthread state */ + pthread_queue_deq(&mutex->m_queue); + pthread->state = PS_RUNNING; + SEMAPHORE_RESET(plock); + } else { + mutex->m_owner = NULL; + } + rval = OK; + break; + default: + rval = EINVAL; + break; + } + SEMAPHORE_RESET(lock); + return(rval); +} diff --git a/lib/libpthread/pthreads/pthread.c b/lib/libpthread/pthreads/pthread.c new file mode 100644 index 000000000000..6a039d2d67d9 --- /dev/null +++ b/lib/libpthread/pthreads/pthread.c @@ -0,0 +1,200 @@ +/* ==== pthread.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Pthread functions. + * + * 1.00 93/07/26 proven + * -Started coding this file. + */ + +#include "pthread.h" +#include <signal.h> +#include <errno.h> + +/* + * These first functions really should not be called by the user. + */ + +/* ========================================================================== + * pthread_init() + * + * This function should be called in crt0.o before main() is called. + * But on some systems It may not be possible to change crt0.o so currently + * I'm requiring this function to be called first thing after main. + * Actually I'm assuming it is, because I do no locking here. + */ +void pthread_init(void) +{ + struct machdep_pthread machdep_data = MACHDEP_PTHREAD_INIT; + + /* Initialize the first thread */ + if (pthread_initial = (pthread_t)malloc(sizeof(struct pthread))) { + memcpy(&(pthread_initial->machdep_data), &machdep_data, sizeof(machdep_data)); + pthread_initial->state = PS_RUNNING; + pthread_initial->queue = NULL; + pthread_initial->next = NULL; + pthread_initial->pll = NULL; + + pthread_initial->lock = SEMAPHORE_CLEAR; + pthread_initial->error = 0; + + pthread_link_list = pthread_initial; + pthread_run = pthread_initial; + + /* Initialize the signal handler. */ + sig_init(); + + /* Initialize the fd table. */ + fd_init(); + + return; + } + PANIC(); +} + +/* ========================================================================== + * pthread_yield() + */ +void pthread_yield() +{ + sig_handler_fake(SIGVTALRM); +} + +/* ======================================================================= */ +/* ========================================================================== + * pthread_self() + */ +pthread_t pthread_self() +{ + return(pthread_run); +} + +/* ========================================================================== + * pthread_equal() + */ +int pthread_equal(pthread_t t1, pthread_t t2) +{ + return(t1 == t2); +} + +/* ========================================================================== + * pthread_exit() + */ +void pthread_exit(void *status) +{ + semaphore *lock, *plock; + pthread_t pthread; + + lock = &pthread_run->lock; + if (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* Save return value */ + pthread_run->ret = status; + + /* First execute all cleanup handlers */ + + + /* + * Are there any threads joined to this one, + * if so wake them and let them detach this thread. + */ + if (pthread = pthread_queue_get(&(pthread_run->join_queue))) { + /* The current thread pthread_run can't be detached */ + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + (void)pthread_queue_deq(&(pthread_run->join_queue)); + pthread->state = PS_RUNNING; + + /* Thread will unlock itself in pthread_join() */ + } + + /* This thread will never run again */ + reschedule(PS_DEAD); + PANIC(); +} + +/* ========================================================================== + * pthread_create() + * + * After the new thread structure is allocated and set up, it is added to + * pthread_run_next_queue, which requires a sig_prevent(), + * sig_check_and_resume() + */ +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void * (*start_routine)(void *), void *arg) +{ + long nsec = 100000000; + void *stack; + + if ((*thread) = (pthread_t)malloc(sizeof(struct pthread))) { + + if (! attr) { attr = &pthread_default_attr; } + + /* Get a stack, if necessary */ + if ((stack = attr->stackaddr_attr) || + (stack = (void *)malloc(attr->stacksize_attr))) { + + machdep_pthread_create(&((*thread)->machdep_data), + start_routine, arg, 65536, stack, nsec); + + memcpy(&(*thread)->attr, attr, sizeof(pthread_attr_t)); + + (*thread)->queue = NULL; + (*thread)->next = NULL; + + (*thread)->lock = SEMAPHORE_CLEAR; + (*thread)->error = 0; + + sig_prevent(); + + /* Add to the link list of all threads. */ + (*thread)->pll = pthread_link_list; + pthread_link_list = (*thread); + + (*thread)->state = PS_RUNNING; + sig_check_and_resume(); + + return(OK); + } + free((*thread)); + } + return(ENOMEM); +} + +/* ========================================================================== + * pthread_cancel() + * + * This routine will also require a sig_prevent/sig_check_and_resume() + */ diff --git a/lib/libpthread/pthreads/pthread_attr.c b/lib/libpthread/pthreads/pthread_attr.c new file mode 100644 index 000000000000..639b240e63d0 --- /dev/null +++ b/lib/libpthread/pthreads/pthread_attr.c @@ -0,0 +1,96 @@ +/* ==== pthread_attr.c ======================================================= + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Pthread attribute functions. + * + * 1.00 93/11/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> + +/* Currently we do no locking, should we just to be safe? CAP */ +/* ========================================================================== + * pthread_attr_init() + */ +int pthread_attr_init(pthread_attr_t *attr) +{ + memcpy(attr, &pthread_default_attr, sizeof(pthread_attr_t)); + return(OK); +} + +/* ========================================================================== + * pthread_attr_destroy() + */ +int pthread_attr_destroy(pthread_attr_t *attr) +{ + return(OK); +} + +/* ========================================================================== + * pthread_attr_getstacksize() + */ +int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize) +{ + *stacksize = attr->stacksize_attr; + return(OK); +} + +/* ========================================================================== + * pthread_attr_setstacksize() + */ +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) +{ + if (stacksize >= PTHREAD_STACK_MIN) { + attr->stacksize_attr = stacksize; + return(OK); + } + return(EINVAL); +} + +/* ========================================================================== + * pthread_attr_getstackaddr() + */ +int pthread_attr_getstackaddr(pthread_attr_t *attr, void ** stackaddr) +{ + *stackaddr = attr->stackaddr_attr; + return(OK); +} + +/* ========================================================================== + * pthread_attr_setstackaddr() + */ +int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr) +{ + attr->stackaddr_attr = stackaddr; + return(OK); +} diff --git a/lib/libpthread/pthreads/pthread_detach.c b/lib/libpthread/pthreads/pthread_detach.c new file mode 100644 index 000000000000..d996bf092dc3 --- /dev/null +++ b/lib/libpthread/pthreads/pthread_detach.c @@ -0,0 +1,86 @@ +/* ==== pthread_detach.c ======================================================= + * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : pthread_join function. + * + * 1.00 94/01/15 proven + * -Started coding this file. + */ + +#include <pthread.h> + +/* ========================================================================== + * pthread_detach() + */ +int pthread_detach(pthread_t pthread) +{ + semaphore *plock; + int ret; + + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* Check that thread isn't detached already */ + if (!(pthread->flags & PF_DETACHED)) { + + pthread->flags |= PF_DETACHED; + + /* Wakeup first threads waiting on a join */ + { + struct pthread * next_thread; + semaphore * next_lock; + + if (next_thread = pthread_queue_get(&(pthread->join_queue))) { + next_lock = &(next_thread->lock); + while (SEMAPHORE_TEST_AND_SET(next_lock)) { + pthread_yield(); + } + pthread_queue_deq(&(pthread->join_queue)); + next_thread->state = PS_RUNNING; + /* + * Thread will wake up in pthread_join(), see the thread + * it was joined to already detached and unlock itself + * and pthread + */ + } else { + SEMAPHORE_RESET(plock); + } + } + ret = OK; + + } else { + SEMAPHORE_RESET(plock); + ret = ESRCH; + } + return(ret); +} diff --git a/lib/libpthread/pthreads/pthread_join.c b/lib/libpthread/pthreads/pthread_join.c new file mode 100644 index 000000000000..773098618972 --- /dev/null +++ b/lib/libpthread/pthreads/pthread_join.c @@ -0,0 +1,109 @@ +/* ==== pthread_join.c ======================================================= + * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : pthread_join function. + * + * 1.00 94/01/15 proven + * -Started coding this file. + */ + +#include <pthread.h> + +/* ========================================================================== + * pthread_join() + */ +int pthread_join(pthread_t pthread, void **thread_return) +{ + semaphore *lock, *plock; + int ret; + + + plock = &(pthread->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* Check that thread isn't detached already */ + if (pthread->flags & PF_DETACHED) { + SEMAPHORE_RESET(plock); + return(ESRCH); + } + + lock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* If OK then queue current thread. */ + pthread_queue(&(pthread->join_queue), pthread_run); + + SEMAPHORE_RESET(plock); + reschedule(PS_JOIN); + + /* + * At this point the thread is locked from the pthread_exit + * and so are we, so no extra locking is required, but be sure + * to unlock at least ourself. + */ + if (!(pthread->flags & PF_DETACHED)) { + if (thread_return) { + *thread_return = pthread->ret; + } + pthread->flags |= PF_DETACHED; + ret = OK; + } else { + ret = ESRCH; + } + + /* Cant do a cleanup until queue is cleared */ + { + struct pthread * next_thread; + semaphore * next_lock; + + if (next_thread = pthread_queue_get(&(pthread->join_queue))) { + next_lock = &(next_thread->lock); + while (SEMAPHORE_TEST_AND_SET(next_lock)) { + pthread_yield(); + } + pthread_queue_deq(&(pthread->join_queue)); + next_thread->state = PS_RUNNING; + /* + * Thread will wake up in pthread_join(), see the thread + * it was joined to already detached and unlock itself + */ + } else { + SEMAPHORE_RESET(lock); + } + } + + SEMAPHORE_RESET(plock); + return(ret); +} diff --git a/lib/libpthread/pthreads/pthread_once.c b/lib/libpthread/pthreads/pthread_once.c new file mode 100644 index 000000000000..fe791440eda3 --- /dev/null +++ b/lib/libpthread/pthreads/pthread_once.c @@ -0,0 +1,57 @@ +/* ==== pthread_once.c ======================================================= + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : pthread_once function. + * + * 1.00 93/12/12 proven + * -Started coding this file. + */ + +#include <pthread.h> + +/* ========================================================================== + * pthread_once() + */ +static pthread_mutex_t __pthread_once_mutex = PTHREAD_MUTEX_INITIALIZER; + +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + /* Check first for speed */ + if (*once_control == PTHREAD_ONCE_INIT) { + pthread_mutex_lock(&__pthread_once_mutex); + if (*once_control == PTHREAD_ONCE_INIT) { + init_routine(); + (*once_control)++; + } + pthread_mutex_unlock(&__pthread_once_mutex); + } + return(OK); +} diff --git a/lib/libpthread/pthreads/queue.c b/lib/libpthread/pthreads/queue.c new file mode 100644 index 000000000000..7e5ff372d2f7 --- /dev/null +++ b/lib/libpthread/pthreads/queue.c @@ -0,0 +1,119 @@ +/* ==== queue.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Queue functions. + * + * 1.00 93/07/15 proven + * -Started coding this file. + */ + +#include <pthread.h> + +/* + * All routines in this file assume that the queue has been appropriatly + * locked. + */ + +/* ========================================================================== + * pthread_queue_init() + */ +void pthread_queue_init(struct pthread_queue *queue) +{ + queue->q_next = NULL; + queue->q_last = NULL; + queue->q_data = NULL; +} + +/* ========================================================================== + * pthread_queue_enq() + */ +void pthread_queue_enq(struct pthread_queue *queue, struct pthread *thread) +{ + if (queue->q_last) { + queue->q_last->next = thread; + } else { + queue->q_next = thread; + } + queue->q_last = thread; + thread->queue = queue; + thread->next = NULL; + +} + +/* ========================================================================== + * pthread_queue_get() + */ +struct pthread *pthread_queue_get(struct pthread_queue *queue) +{ + return(queue->q_next); +} + +/* ========================================================================== + * pthread_queue_deq() + */ +struct pthread *pthread_queue_deq(struct pthread_queue *queue) +{ + struct pthread *thread = NULL; + + if (queue->q_next) { + thread = queue->q_next; + if (!(queue->q_next = queue->q_next->next)) { + queue->q_last = NULL; + } + thread->queue = NULL; + thread->next = NULL; + } + return(thread); +} + +/* ========================================================================== + * pthread_queue_remove() + */ +void pthread_queue_remove(struct pthread_queue *queue, struct pthread *thread) +{ + struct pthread **current = &(queue->q_next); + struct pthread *prev = NULL; + + while (*current) { + if (*current == thread) { + if ((*current)->next) { + *current = (*current)->next; + } else { + queue->q_last = prev; + *current = NULL; + } + } + prev = *current; + current = &((*current)->next); + } + thread->queue = NULL; + thread->next = NULL; +} diff --git a/lib/libpthread/pthreads/signal.c b/lib/libpthread/pthreads/signal.c new file mode 100644 index 000000000000..b181b84dac14 --- /dev/null +++ b/lib/libpthread/pthreads/signal.c @@ -0,0 +1,426 @@ +/* ==== signal.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Queue functions. + * + * 1.00 93/07/21 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <signal.h> + +/* + * Time which select in fd_kern_wait() will sleep. + * If there are no threads to run we sleep for an hour or until + * we get an interrupt or an fd thats awakens. To make sure we + * don't miss an interrupt this variable gets reset too zero in + * sig_handler_real(). + */ +struct timeval __fd_kern_wait_timeout = { 0, 0 }; + +/* + * Global for user-kernel lock, and blocked signals + */ +static volatile sigset_t sig_to_tryagain; +static volatile sigset_t sig_to_process; +static volatile int kernel_lock = 0; +static volatile int sig_count = 0; + +static void sig_handler(int signal); +static void set_thread_timer(); +void sig_prevent(void); +void sig_resume(void); + +/* ========================================================================== + * context_switch() + * + * This routine saves the current state of the running thread gets + * the next thread to run and restores it's state. To allow different + * processors to work with this routine, I allow the machdep_restore_state() + * to either return or have it return from machdep_save_state with a value + * other than 0, this is for implementations which use setjmp/longjmp. + */ +static void context_switch() +{ + struct pthread **current, *next, *last; + semaphore *lock; + int count; + + /* save state of current thread */ + if (machdep_save_state()) { + return; + } + + last = pthread_run; + if (pthread_run = pthread_queue_deq(&pthread_current_queue)) { + /* restore state of new current thread */ + machdep_restore_state(); + return; + } + + /* Poll all the kernel fds */ + fd_kern_poll(); + +context_switch_reschedule:; + /* + * Go through the reschedule list once, this is the only place + * that goes through the queue without using the queue routines. + * + * But first delete the current queue. + */ + pthread_queue_init(&pthread_current_queue); + current = &(pthread_link_list); + count = 0; + + while (*current) { + switch((*current)->state) { + case PS_RUNNING: + pthread_queue_enq(&pthread_current_queue, *current); + current = &((*current)->pll); + count++; + break; + case PS_DEAD: + /* Cleanup thread, unless we're using the stack */ + if (((*current)->flags & PF_DETACHED) && (*current != last)) { + next = (*current)->pll; + lock = &((*current)->lock); + if (SEMAPHORE_TEST_AND_SET(lock)) { + /* Couldn't cleanup this time, try again later */ + current = &((*current)->pll); + } else { + if (!((*current)->attr.stackaddr_attr)) { + free (machdep_pthread_cleanup(&((*current)->machdep_data))); + } + free (*current); + *current = next; + } + } else { + current = &((*current)->pll); + } + break; + default: + /* Should be on a different queue. Ignore. */ + current = &((*current)->pll); + count++; + break; + } + } + + /* Are there any threads to run */ + if (pthread_run = pthread_queue_deq(&pthread_current_queue)) { + /* restore state of new current thread */ + machdep_restore_state(); + return; + } + + /* Are there any threads at all */ + if (count) { + /* + * Do a wait, timeout is set to a hour unless we get an interrupt + * before the select in wich case it polls and returns. + */ + fd_kern_wait(); + + /* Check for interrupts, but ignore SIGVTALR */ + sigdelset(&sig_to_process, SIGVTALRM); + + if (sig_to_process) { + /* Process interrupts */ + sig_handler(0); + } + + goto context_switch_reschedule; + + } + exit(0); +} + +/* ========================================================================== + * sig_handler_pause() + * + * Wait until a signal is sent to the process. + */ +void sig_handler_pause() +{ + sigset_t sig_to_block, sig_to_pause; + + sigfillset(&sig_to_block); + sigemptyset(&sig_to_pause); + sigprocmask(SIG_BLOCK, &sig_to_block, NULL); + if (!sig_to_process) { + sigsuspend(&sig_to_pause); + } + sigprocmask(SIG_UNBLOCK, &sig_to_block, NULL); +} + +/* ========================================================================== + * context_switch_done() + * + * This routine does all the things that are necessary after a context_switch() + * calls the machdep_restore_state(). DO NOT put this in the context_switch() + * routine because sometimes the machdep_restore_state() doesn't return + * to context_switch() but instead ends up in machdep_thread_start() or + * some such routine, which will need to call this routine and + * sig_check_and_resume(). + */ +void context_switch_done() +{ + sigdelset(&sig_to_process, SIGVTALRM); + set_thread_timer(); +} + +/* ========================================================================== + * set_thread_timer() + * + * Assums kernel is locked. + */ +static void set_thread_timer() +{ + static int last_sched_attr = SCHED_RR; + + switch (pthread_run->attr.sched_attr) { + case SCHED_RR: + machdep_set_thread_timer(&(pthread_run->machdep_data)); + break; + case SCHED_FIFO: + if (last_sched_attr != SCHED_FIFO) { + machdep_unset_thread_timer(); + } + break; + case SCHED_IO: + if ((last_sched_attr != SCHED_IO) && (!sig_count)) { + machdep_set_thread_timer(&(pthread_run->machdep_data)); + } + break; + default: + machdep_set_thread_timer(&(pthread_run->machdep_data)); + break; + } + last_sched_attr = pthread_run->attr.sched_attr; +} + +/* ========================================================================== + * sig_handler() + * + * Assumes the kernel is locked. + */ +static void sig_handler(int sig) +{ + + /* + * First check for old signals, do one pass through and don't + * check any twice. + */ + if (sig_to_tryagain) { + if (sigismember(&sig_to_tryagain, SIGALRM)) { + switch (sleep_wakeup()) { + case 1: + /* Do the default action, no threads were sleeping */ + case OK: + /* Woke up a sleeping thread */ + sigdelset(&sig_to_tryagain, SIGALRM); + break; + case NOTOK: + /* Couldn't get appropriate locks, try again later */ + break; + } + } else { + PANIC(); + } + } + + /* + * NOW, process signal that just came in, plus any pending on the + * signal mask. All of these must be resolved. + */ + +sig_handler_top:; + + switch(sig) { + case 0: + break; + case SIGVTALRM: + if (sig_count) { + sigset_t sigall; + + sig_count = 0; + + /* Unblock all signals */ + sigemptyset(&sigall); + sigprocmask(SIG_SETMASK, &sigall, NULL); + } + context_switch(); + context_switch_done(); + break; + case SIGALRM: + sigdelset(&sig_to_process, SIGALRM); + switch (sleep_wakeup()) { + case 1: + /* Do the default action, no threads were sleeping */ + case OK: + /* Woke up a sleeping thread */ + break; + case NOTOK: + /* Couldn't get appropriate locks, try again later */ + sigaddset(&sig_to_tryagain, SIGALRM); + break; + } + break; + default: + PANIC(); + } + + /* Determine if there are any other signals */ + if (sig_to_process) { + for (sig = 1; sig <= SIGMAX; sig++) { + if (sigismember(&sig_to_process, sig)) { + + /* goto sig_handler_top */ + goto sig_handler_top; + } + } + } +} + +/* ========================================================================== + * sig_handler_real() + * + * On a multi-processor this would need to use the test and set instruction + * otherwise the following will work. + */ +void sig_handler_real(int sig) +{ + if (kernel_lock) { + __fd_kern_wait_timeout.tv_sec = 0; + sigaddset(&sig_to_process, sig); + return; + } + sig_prevent(); + sig_count++; + sig_handler(sig); + sig_resume(); +} + +/* ========================================================================== + * sig_handler_fake() + */ +void sig_handler_fake(int sig) +{ + if (kernel_lock) { + /* Currently this should be impossible */ + PANIC(); + } + sig_prevent(); + sig_handler(sig); + sig_resume(); +} + +/* ========================================================================== + * reschedule() + * + * This routine assumes that the caller is the current pthread, pthread_run + * and that it has a lock on itself and that it wants to reschedule itself. + */ +void reschedule(enum pthread_state state) +{ + semaphore *plock; + + if (kernel_lock) { + /* Currently this should be impossible */ + PANIC(); + } + sig_prevent(); + pthread_run->state = state; + SEMAPHORE_RESET((plock = &(pthread_run->lock))); + sig_handler(SIGVTALRM); + sig_resume(); +} + +/* ========================================================================== + * sig_prevent() + */ +void sig_prevent(void) +{ + kernel_lock++; +} + +/* ========================================================================== + * sig_resume() + */ +void sig_resume() +{ + kernel_lock--; +} + +/* ========================================================================== + * sig_check_and_resume() + */ +void sig_check_and_resume() +{ + /* Some routine name that is yet to be determined. */ + + /* Only bother if we are truely unlocking the kernel */ + while (!(--kernel_lock)) { + + /* Assume sigset_t is not a struct or union */ + if (sig_to_process) { + kernel_lock++; + sig_handler(0); + } else { + break; + } + } +} + +/* ========================================================================== + * sig_init() + * + * SIGVTALRM (NOT POSIX) needed for thread timeslice timeouts. + * Since it's not POSIX I will replace it with a + * virtual timer for threads. + * SIGALRM (IS POSIX) so some special handling will be + * necessary to fake SIGALRM signals + */ +void sig_init(void) +{ + int sig_to_init[] = { SIGVTALRM, SIGALRM, 0 }; + int i; + + /* Initialize only the necessary signals */ + + for (i = 0; sig_to_init[i]; i++) { + if (signal(sig_to_init[i], sig_handler_real)) { + PANIC(); + } + } +} + diff --git a/lib/libpthread/pthreads/sleep.c b/lib/libpthread/pthreads/sleep.c new file mode 100644 index 000000000000..30b5d24d7e38 --- /dev/null +++ b/lib/libpthread/pthreads/sleep.c @@ -0,0 +1,227 @@ +/* ==== sleep.c ============================================================ + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * Description : Condition cariable functions. + * + * 1.00 93/12/28 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <unistd.h> + +struct pthread * pthread_sleep = NULL; +semaphore sleep_semaphore = SEMAPHORE_CLEAR; + + +#include <sys/time.h> +#include <stdio.h> + +/* ========================================================================== + * machdep_start_timer() + */ +int machdep_start_timer(struct itimerval *start_time_val) +{ + setitimer(ITIMER_REAL, start_time_val, NULL); + return(OK); +} + +/* ========================================================================== + * machdep_stop_timer() + */ +struct itimerval stop_time_val = { { 0, 0 }, { 0, 0 } }; +int machdep_stop_timer(struct itimerval * current) +{ + setitimer(ITIMER_REAL, &stop_time_val, current); + return(OK); +} + +/* ========================================================================== + * machdep_sub_timer() + * + * formula is: new -= current; + */ +static inline void machdep_sub_timer(struct itimerval * new, + struct itimerval * current) +{ + new->it_value.tv_usec -= current->it_value.tv_usec; + if (new->it_value.tv_usec < 0) { + new->it_value.tv_usec += 1000000; + new->it_value.tv_sec--; + } + new->it_value.tv_sec -= current->it_value.tv_sec; +} + + +/* ========================================================================== + * sleep_wakeup() + * + * This routine is called by the interrupt handler. It cannot call + * pthread_yield() thenrfore it returns NOTOK to inform the handler + * that it will have to be called at a later time. + */ +int sleep_wakeup() +{ + struct pthread *pthread_sleep_next; + struct itimerval current_time; + semaphore *lock, *plock; + + /* Lock sleep queue */ + lock = &(sleep_semaphore); + if (SEMAPHORE_TEST_AND_SET(lock)) { + return(NOTOK); + } + if (pthread_sleep) { + + plock = &(pthread_sleep->lock); + if (SEMAPHORE_TEST_AND_SET(plock)) { + SEMAPHORE_RESET(lock); + return(NOTOK); + } + + /* return remaining time */ + machdep_stop_timer(¤t_time); + pthread_sleep->time_sec = current_time.it_value.tv_sec; + pthread_sleep->time_usec = current_time.it_value.tv_usec; + + if (pthread_sleep_next = pthread_sleep->sll) { + pthread_sleep_next->time_usec += current_time.it_value.tv_usec; + current_time.it_value.tv_usec = pthread_sleep_next->time_usec; + pthread_sleep_next->time_sec += current_time.it_value.tv_sec; + current_time.it_value.tv_sec = pthread_sleep_next->time_sec; + machdep_start_timer(¤t_time); + } + + /* Clean up removed thread and start it runnng again. */ + pthread_sleep->state = PS_RUNNING; + pthread_sleep->sll = NULL; + SEMAPHORE_RESET(plock); + + /* Set top of queue to next queue item */ + pthread_sleep = pthread_sleep_next; + } + SEMAPHORE_RESET(lock); + return(OK); +} + +/* ========================================================================== + * sleep() + */ +unsigned int sleep(unsigned int seconds) +{ + struct pthread *pthread_sleep_current, *pthread_sleep_prev; + struct itimerval current_time, new_time; + semaphore *lock, *plock; + + if (seconds) { + /* Lock current thread */ + plock = &(pthread_run->lock); + while (SEMAPHORE_TEST_AND_SET(plock)) { + pthread_yield(); + } + + /* Set new_time timer value */ + new_time.it_value.tv_usec = 0; + new_time.it_value.tv_sec = seconds; + + /* Lock sleep queue */ + lock = &(sleep_semaphore); + while (SEMAPHORE_TEST_AND_SET(lock)) { + pthread_yield(); + } + + /* any threads? */ + if (pthread_sleep_current = pthread_sleep) { + + machdep_stop_timer(¤t_time); + + /* Is remaining time left <= new thread time */ + if (current_time.it_value.tv_sec < new_time.it_value.tv_sec) { + machdep_sub_timer(&new_time, ¤t_time); + machdep_start_timer(¤t_time); + + while (pthread_sleep_current->sll) { + pthread_sleep_prev = pthread_sleep_current; + pthread_sleep_current = pthread_sleep_current->sll; + current_time.it_value.tv_sec = pthread_sleep_current->time_sec; + + if ((current_time.it_value.tv_sec > new_time.it_value.tv_sec) || + ((current_time.it_value.tv_sec == new_time.it_value.tv_sec) && + (current_time.it_value.tv_usec > new_time.it_value.tv_usec))) { + pthread_run->time_usec = new_time.it_value.tv_usec; + pthread_run->time_sec = new_time.it_value.tv_sec; + machdep_sub_timer(¤t_time, &new_time); + pthread_run->sll = pthread_sleep_current; + pthread_sleep_prev->sll = pthread_run; + + /* Unlock sleep mutex */ + SEMAPHORE_RESET(lock); + + /* Reschedule thread */ + reschedule(PS_SLEEP_WAIT); + + return(pthread_run->time_sec); + } + machdep_sub_timer(&new_time, ¤t_time); + + } + + /* No more threads in queue, attach pthread_run to end of list */ + pthread_sleep_current->sll = pthread_run; + pthread_run->sll = NULL; + + } else { + /* Start timer and enqueue thread */ + machdep_start_timer(&new_time); + current_time.it_value.tv_sec -= new_time.it_value.tv_sec; + pthread_run->sll = pthread_sleep_current; + pthread_sleep = pthread_run; + } + } else { + /* Start timer and enqueue thread */ + machdep_start_timer(&new_time); + pthread_sleep = pthread_run; + pthread_run->sll = NULL; + } + + pthread_run->time_usec = new_time.it_value.tv_usec; + pthread_run->time_sec = new_time.it_value.tv_sec; + + /* Unlock sleep mutex */ + SEMAPHORE_RESET(lock); + + /* Reschedule thread */ + reschedule(PS_SLEEP_WAIT); + + } + return(pthread_run->time_sec); +} + diff --git a/lib/libpthread/stdio/Makefile.inc b/lib/libpthread/stdio/Makefile.inc new file mode 100644 index 000000000000..44d1a0e200a6 --- /dev/null +++ b/lib/libpthread/stdio/Makefile.inc @@ -0,0 +1,18 @@ +# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91 +# $Id: Makefile.inc,v 1.1 1994/01/30 04:24:29 proven Exp $ + +# Thread safe stdio sources +.PATH: ${.CURDIR}/stdio + +SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \ + fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \ + fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \ + fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \ + getc.c getchar.c gets.c getw.c makebuf.c perror.c printf.c putc.c \ + putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \ + setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c sscanf.c \ + stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vfprintf.c \ + vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \ + wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \ + getchar_unlocked.c strerror.c wbuf.c + diff --git a/lib/libpthread/stdio/README b/lib/libpthread/stdio/README new file mode 100644 index 000000000000..d8d7dd779f63 --- /dev/null +++ b/lib/libpthread/stdio/README @@ -0,0 +1,37 @@ +This is a threadsafe stdio based on the BSD stdio written by Chris Torek. + +INCLUDE FILES AND PORTING +To continue to make this package portable, some basic rules on includes +files must be followed. + +pthread.h should be included first (if it is to be included). +stdio.h should be included. + +INTERNAL LOCKING +1. All functions that can be called by the user must have __flockfile at the + begining and a __funlockfile at the end. __Flockfile is a counting mutex, + The thread that owns the lock can call __flockfile as many times as + it wants, but must call an equal number of __funlockfile before the + lock will be released. +2. All functions starting with __ shouldn't need addtional locking. +3. Anything that writes the variable __sglue should lock __sfp_mutex, + check __sfp_state, and do a condion wait if it is set. +4. Anything that checks fp->_flag for valididity should also lock + __sfp_mutex. +5. Anything that reads the variable __sglue should lock __sfp_mutex, increment + __sfp_state, and then unlock the mutex. At function return it should + lock the mutex again decrement __sfp_state and check if zero. If so + do a cond_signal, and unlock the mutex. +6. The functions fopen, fdopen, and freopen are the only functions that + will change a fp->_file +7. fdopen and fopen both allocate the next fp by locking __sfp_mutex + checking fp->_flags and then setting it if free. +8. freopen tries to preserve fp->_file. It sets __sfp_mutex, then it + tries to lock fp->_file and close it. +9. __sinit is done with a pthread_once routine. + +Copyright (c) 1993 Chris Provenzano. All rights reserved. + +This product includes software developed by the Univeristy of California, +Berkeley and its contributors. + diff --git a/lib/libpthread/stdio/clrerr.c b/lib/libpthread/stdio/clrerr.c new file mode 100644 index 000000000000..a7c83e45b4a6 --- /dev/null +++ b/lib/libpthread/stdio/clrerr.c @@ -0,0 +1,50 @@ +/*- + * 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 = "from: @(#)clrerr.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: clrerr.c,v 1.1 1994/01/30 04:24:31 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +void clearerr(FILE *fp) +{ + flockfile(fp); + fp->_flags &= ~(__SERR|__SEOF); + funlockfile(fp); +} diff --git a/lib/libpthread/stdio/fclose.c b/lib/libpthread/stdio/fclose.c new file mode 100644 index 000000000000..c48b5d53e726 --- /dev/null +++ b/lib/libpthread/stdio/fclose.c @@ -0,0 +1,71 @@ +/*- + * 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 = "from: @(#)fclose.c 5.2 (Berkeley) 2/1/91";*/ +static char *rcsid = "$Id: fclose.c,v 1.1 1994/01/30 04:24:32 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +/* Do not reset the fd */ +fclose(fp) + register FILE *fp; +{ + register int r; + + if (fp->_flags) { + flockfile(fp); + r = fp->_flags & __SWR ? __sflush(fp) : 0; + if (__sclose(fp) < 0) + r = EOF; + if (fp->_flags & __SMBF) + free((char *)fp->_bf._base); + if (HASUB(fp)) + FREEUB(fp); + if (HASLB(fp)) + FREELB(fp); + fp->_flags = 0; /* release this FILE for reuse, DO THIS LAST */ + funlockfile(fp); + return(r); + } + errno = EBADF; + return(EOF); +} diff --git a/lib/libpthread/stdio/fdopen.c b/lib/libpthread/stdio/fdopen.c new file mode 100644 index 000000000000..b2231a29e402 --- /dev/null +++ b/lib/libpthread/stdio/fdopen.c @@ -0,0 +1,92 @@ +/*- + * 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 = "from: @(#)fdopen.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fdopen.c,v 1.1 1994/01/30 04:24:33 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include "local.h" + +extern pthread_mutex_t __sfp_mutex; +extern pthread_cond_t __sfp_cond; +extern int __sfp_state; + +FILE *fdopen(int fd, const char *mode) +{ + register FILE *fp; + int flags, oflags, fdflags, tmp; + + if ((flags = __sflags(mode, &oflags)) == 0) + return (NULL); + + /* Make sure the mode the user wants is a subset of the actual mode. */ + if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) + return (NULL); + tmp = fdflags & O_ACCMODE; + if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { + errno = EINVAL; + return (NULL); + } + + pthread_once(&__sdidinit, __sinit); + pthread_mutex_lock(&__sfp_mutex); + while (__sfp_state) { + pthread_cond_wait(&__sfp_cond, &__sfp_mutex); + } + + if (fp = __sfp()) { + fp->_flags = flags; + + /* + * If opened for appending, but underlying descriptor does not have + * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to + * end before each write. + */ + if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) + fp->_flags |= __SAPP; + fp->_file = fd; + + } + pthread_mutex_unlock(&__sfp_mutex); + return (fp); +} diff --git a/lib/libpthread/stdio/feof.c b/lib/libpthread/stdio/feof.c new file mode 100644 index 000000000000..befe1fda81eb --- /dev/null +++ b/lib/libpthread/stdio/feof.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)feof.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: feof.c,v 1.1 1994/01/30 04:24:35 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro feof. + */ +#undef feof + +feof(fp) + FILE *fp; +{ + return (__sfeof(fp)); +} diff --git a/lib/libpthread/stdio/ferror.c b/lib/libpthread/stdio/ferror.c new file mode 100644 index 000000000000..82cf9dda5499 --- /dev/null +++ b/lib/libpthread/stdio/ferror.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)ferror.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: ferror.c,v 1.1 1994/01/30 04:24:36 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro ferror. + */ +#undef ferror + +ferror(fp) + FILE *fp; +{ + return (__sferror(fp)); +} diff --git a/lib/libpthread/stdio/fflush.c b/lib/libpthread/stdio/fflush.c new file mode 100644 index 000000000000..b7f66c3b4a13 --- /dev/null +++ b/lib/libpthread/stdio/fflush.c @@ -0,0 +1,97 @@ +/*- + * 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 = "from: @(#)fflush.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fflush.c,v 1.1 1994/01/30 04:24:37 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/errno.h> +#include <stdio.h> +#include "local.h" + +/* Flush a single file, or (if fp is NULL) all files. */ +fflush(fp) + register FILE *fp; +{ + int retval; + + if (fp == NULL) + return (__swalk_sflush); + flockfile(fp); + + if ((fp->_flags & (__SWR | __SRW)) == 0) { + errno = EBADF; + retval = EOF; + } else { + retval = __sflush(fp); + } + funlockfile(fp); + return(retval); +} + +__sflush(fp) + register FILE *fp; +{ + register unsigned char *p; + register int n, t; + + t = fp->_flags; + if ((t & __SWR) == 0) + return (0); + + if ((p = fp->_bf._base) == NULL) + return (0); + + n = fp->_p - p; /* write this much */ + + /* + * Set these immediately to avoid problems with longjmp and to allow + * exchange buffering (via setvbuf) in user write function. + */ + fp->_p = p; + fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + + for (; n > 0; n -= t, p += t) { + t = __swrite(fp, (char *)p, n); + if (t <= 0) { + fp->_flags |= __SERR; + return (EOF); + } + } + return (0); +} diff --git a/lib/libpthread/stdio/fgetc.c b/lib/libpthread/stdio/fgetc.c new file mode 100644 index 000000000000..9dbd24fda800 --- /dev/null +++ b/lib/libpthread/stdio/fgetc.c @@ -0,0 +1,51 @@ +/*- + * 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 = "from: @(#)fgetc.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fgetc.c,v 1.1 1994/01/30 04:24:38 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +fgetc(fp) + FILE *fp; +{ + flockfile(fp); + return (__sgetc(fp)); + funlockfile(fp); +} diff --git a/lib/libpthread/stdio/fgetline.c b/lib/libpthread/stdio/fgetline.c new file mode 100644 index 000000000000..28f7e7242019 --- /dev/null +++ b/lib/libpthread/stdio/fgetline.c @@ -0,0 +1,169 @@ +/*- + * 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 = "from: @(#)fgetline.c 5.2 (Berkeley) 5/4/91";*/ +static char *rcsid = "$Id: fgetline.c,v 1.1 1994/01/30 04:24:39 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "local.h" + +/* + * Expand the line buffer. Return -1 on error. + * The `new size' does not account for a terminating '\0', + * so we add 1 here. + */ +__slbexpand(fp, newsize) + FILE *fp; + size_t newsize; +{ + void *p; + + if (fp->_lb._size >= ++newsize) + return (0); + if ((p = realloc(fp->_lb._base, newsize)) == NULL) + return (-1); + fp->_lb._base = p; + fp->_lb._size = newsize; + return (0); +} + +/* + * Get an input line. The returned pointer often (but not always) + * points into a stdio buffer. Fgetline smashes the newline (if any) + * in the stdio buffer; callers must not use it on streams that + * have `magic' setvbuf() games happening. + */ +char * +fgetline(fp, lenp) + register FILE *fp; + size_t *lenp; +{ + register unsigned char *p; + register size_t len; + size_t off; + + flockfile(fp); + + /* make sure there is input */ + if (fp->_r <= 0 && __srefill(fp)) { + if (lenp != NULL) + *lenp = 0; + funlockfile(fp); + return (NULL); + } + + /* look for a newline in the input */ + if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) { + register char *ret; + + /* + * Found one. Flag buffer as modified to keep + * fseek from `optimising' a backward seek, since + * the newline is about to be trashed. (We should + * be able to get away with doing this only if + * p is not pointing into an ungetc buffer, since + * fseek discards ungetc data, but this is the + * usual case anyway.) + */ + ret = (char *)fp->_p; + len = p - fp->_p; + fp->_flags |= __SMOD; + *p = 0; + fp->_r -= len + 1; + fp->_p = p + 1; + if (lenp != NULL) + *lenp = len; + funlockfile(fp); + return (ret); + } + + /* + * We have to copy the current buffered data to the line buffer. + * + * OPTIMISTIC is length that we (optimistically) + * expect will accomodate the `rest' of the string, + * on each trip through the loop below. + */ +#define OPTIMISTIC 80 + + for (len = fp->_r, off = 0;; len += fp->_r) { + register size_t diff; + + /* + * Make sure there is room for more bytes. + * Copy data from file buffer to line buffer, + * refill file and look for newline. The + * loop stops only when we find a newline. + */ + if (__slbexpand(fp, len + OPTIMISTIC)) + goto error; + (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off), + len - off); + off = len; + if (__srefill(fp)) + break; /* EOF or error: return partial line */ + if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL) + continue; + + /* got it: finish up the line (like code above) */ + fp->_flags |= __SMOD; /* soon */ + diff = p - fp->_p; + len += diff; + if (__slbexpand(fp, len)) + goto error; + (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off), diff); + fp->_r -= diff + 1; + fp->_p = p + 1; + break; + } + if (lenp != NULL) + *lenp = len; + fp->_lb._base[len] = 0; + + funlockfile(fp); + return ((char *)fp->_lb._base); + +error: + if (lenp != NULL) + *lenp = 0; /* ??? */ + funlockfile(fp); + return (NULL); /* ??? */ +} diff --git a/lib/libpthread/stdio/fgetpos.c b/lib/libpthread/stdio/fgetpos.c new file mode 100644 index 000000000000..5170ce3ddcdf --- /dev/null +++ b/lib/libpthread/stdio/fgetpos.c @@ -0,0 +1,50 @@ +/*- + * 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 = "from: @(#)fgetpos.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fgetpos.c,v 1.1 1994/01/30 04:24:40 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +/* Don't bother locking, ftell does it */ +fgetpos(fp, pos) + FILE *fp; + fpos_t *pos; +{ + return ((*pos = ftell(fp)) == (fpos_t)-1); +} diff --git a/lib/libpthread/stdio/fgets.c b/lib/libpthread/stdio/fgets.c new file mode 100644 index 000000000000..338c03ced5b7 --- /dev/null +++ b/lib/libpthread/stdio/fgets.c @@ -0,0 +1,108 @@ +/*- + * 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 = "from: @(#)fgets.c 5.4 (Berkeley) 5/4/91";*/ +static char *rcsid = "$Id: fgets.c,v 1.1 1994/01/30 04:24:41 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <string.h> + +/* + * Read at most n-1 characters from the given file. + * Stop when a newline has been read, or the count runs out. + * Return first argument, or NULL if no characters were read. + */ +char * +fgets(buf, n, fp) + char *buf; + register size_t n; + register FILE *fp; +{ + register size_t len; + register char *s; + register unsigned char *p, *t; + + if (n < 2) /* sanity check */ + return (NULL); + + flockfile(fp); + s = buf; + n--; /* leave space for NUL */ + do { + /* + * If the buffer is empty, refill it. + */ + if ((len = fp->_r) <= 0) { + if (__srefill(fp)) { + /* EOF/error: stop with partial or no line */ + if (s == buf) + buf = NULL; + break; + } + len = fp->_r; + } + p = fp->_p; + + /* + * Scan through at most n bytes of the current buffer, + * looking for '\n'. If found, copy up to and including + * newline, and stop. Otherwise, copy entire chunk + * and loop. + */ + if (len > n) + len = n; + t = memchr((void *)p, '\n', len); + if (t != NULL) { + len = ++t - p; + fp->_r -= len; + fp->_p = t; + (void) bcopy((void *)p, (void *)s, len); + s += len; + break; + } + fp->_r -= len; + fp->_p += len; + (void) bcopy((void *)p, (void *)s, len); + s += len; + } while ((n -= len) != 0); + + *s = 0; + funlockfile(fp); + return (buf); +} diff --git a/lib/libpthread/stdio/fileno.c b/lib/libpthread/stdio/fileno.c new file mode 100644 index 000000000000..11ff61f30542 --- /dev/null +++ b/lib/libpthread/stdio/fileno.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)fileno.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fileno.c,v 1.1 1994/01/30 04:24:41 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro fileno. + */ +#undef fileno + +fileno(fp) + FILE *fp; +{ + return (__sfileno(fp)); +} diff --git a/lib/libpthread/stdio/findfp.c b/lib/libpthread/stdio/findfp.c new file mode 100644 index 000000000000..96a078d6883b --- /dev/null +++ b/lib/libpthread/stdio/findfp.c @@ -0,0 +1,151 @@ +/*- + * 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 = "from: @(#)findfp.c 5.10 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: findfp.c,v 1.1 1994/01/30 04:24:42 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <posix.h> +#include "local.h" +#include "glue.h" + + +#define NSTATIC 20 /* stdin + stdout + stderr + the usual */ +#define NDYNAMIC 10 /* add ten more whenever necessary */ + +#define std(flags, file) \ + {0,0,0,flags,file,{0},0 } +/* p r w flags file _bf z */ + +static FILE usual[NSTATIC - 3]; /* the usual */ +static struct glue uglue = { 0, NSTATIC - 3, usual }; + +FILE __sF[3] = { + std(__SRD, 0), /* stdin */ + std(__SWR, 1), /* stdout */ + std(__SWR|__SNBF, 2) /* stderr */ +}; +struct glue __sglue = { &uglue, 3, __sF }; + +pthread_mutex_t __sfp_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t __sfp_cond = PTHREAD_COND_INITIALIZER; +pthread_once_t __sdidinit = PTHREAD_ONCE_INIT; +/* + * __sfp_state = 0, when free, > 0 when in _fwalk + * This allows multiple readers in _fwalk, but only one writer __sfp, + * or freopen() at a time. + */ +int __sfp_state = 0; + +static struct glue *moreglue(register int n) +{ + register struct glue *g; + register FILE *p; + static FILE empty; + + g = (struct glue *)malloc(sizeof(*g) + n * sizeof(FILE)); + if (g == NULL) + return (NULL); + p = (FILE *)(g + 1); + g->next = NULL; + g->niobs = n; + g->iobs = p; + while (--n >= 0) + *p++ = empty; + return (g); +} + +/* + * Find a free FILE for fopen et al. + */ +FILE *__sfp() +{ + register FILE *fp; + register int n; + register struct glue *g; + + for (g = &__sglue;; g = g->next) { + for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) + if (fp->_flags == 0) { + fp->_flags = 1; /* reserve this slot; caller sets real flags */ + fp->_p = NULL; /* no current pointer */ + fp->_w = 0; /* nothing to read or write */ + fp->_r = 0; + fp->_bf._base = NULL; /* no buffer */ + fp->_bf._size = 0; + fp->_lbfsize = 0; /* not line buffered */ + fp->_file = -1; /* no file */ + fp->_ub._base = NULL; /* no ungetc buffer */ + fp->_ub._size = 0; + fp->_lb._base = NULL; /* no line buffer */ + fp->_lb._size = 0; + goto __sfp_done; + } + if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL) { + fp = NULL; + break; + } + } +__sfp_done:; + return (fp); +} + +/* + * exit() calls _cleanup() through *__cleanup, set whenever we + * open or buffer a file. This chicanery is done so that programs + * that do not use stdio need not link it all in. + * + * The name `_cleanup' is, alas, fairly well known outside stdio. + */ +void _cleanup() +{ + (void) __swalk_sflush; +} + +/* + * __sinit() is called whenever stdio's internal variables must be set up. + */ +void __sinit() +{ + /* make sure we clean up on exit */ + __cleanup = _cleanup; + __sdidinit = 1; +} diff --git a/lib/libpthread/stdio/flags.c b/lib/libpthread/stdio/flags.c new file mode 100644 index 000000000000..4dc04c126ca2 --- /dev/null +++ b/lib/libpthread/stdio/flags.c @@ -0,0 +1,90 @@ +/*- + * 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 = "from: @(#)flags.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: flags.c,v 1.1 1994/01/30 04:24:44 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <stdio.h> +#include <errno.h> + +/* + * Return the (stdio) flags for a given mode. Store the flags + * to be passed to an open() syscall through *optr. + * Return 0 on error. + */ +__sflags(mode, optr) + register char *mode; + int *optr; +{ + register int ret, m, o; + + switch (*mode++) { + + case 'r': /* open for reading */ + ret = __SRD; + m = O_RDONLY; + o = 0; + break; + + case 'w': /* open for writing */ + ret = __SWR; + m = O_WRONLY; + o = O_CREAT | O_TRUNC; + break; + + case 'a': /* open for appending */ + ret = __SWR; + m = O_WRONLY; + o = O_CREAT | O_APPEND; + break; + + default: /* illegal mode */ + errno = EINVAL; + return (0); + } + + /* [rwa]\+ or [rwa]b\+ means read and write */ + if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) { + ret = __SRW; + m = O_RDWR; + } + *optr = m | o; + return (ret); +} diff --git a/lib/libpthread/stdio/floatio.h b/lib/libpthread/stdio/floatio.h new file mode 100644 index 000000000000..e55222027cdb --- /dev/null +++ b/lib/libpthread/stdio/floatio.h @@ -0,0 +1,47 @@ +/*- + * 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. + * + * from: @(#)floatio.h 5.1 (Berkeley) 1/20/91 + * $Id: floatio.h,v 1.1 1994/01/30 04:24:47 proven Exp $ + */ + +/* + * Floating point scanf/printf (input/output) definitions. + */ + +/* 11-bit exponent (VAX G floating point) is 308 decimal digits */ +#define MAXEXP 308 +/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ +#define MAXFRACT 39 diff --git a/lib/libpthread/stdio/fopen.c b/lib/libpthread/stdio/fopen.c new file mode 100644 index 000000000000..aa50aaabefa2 --- /dev/null +++ b/lib/libpthread/stdio/fopen.c @@ -0,0 +1,89 @@ +/*- + * 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 = "from: @(#)fopen.c 5.5 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: fopen.c,v 1.1 1994/01/30 04:24:49 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> +#include "local.h" + +extern pthread_mutex_t __sfp_mutex; +extern pthread_cond_t __sfp_cond; +extern int __sfp_state; + +FILE *fopen(const char *file, const char *mode) +{ + register FILE *fp; + register int f; + int flags, oflags; + + if ((flags = __sflags(mode, &oflags)) == 0) + return (NULL); + if ((f = open(file, oflags, 0666)) < 0) { + return (NULL); + } + + pthread_once(&__sdidinit, __sinit); + pthread_mutex_lock(&__sfp_mutex); + while (__sfp_state) { + pthread_cond_wait(&__sfp_cond, &__sfp_mutex); + } + + if (fp = __sfp()) { + fp->_file = f; + fp->_flags = flags; + + /* + * When opening in append mode, even though we use O_APPEND, + * we need to seek to the end so that ftell() gets the right + * answer. If the user then alters the seek pointer, or + * the file extends, this will fail, but there is not much + * we can do about this. (We could set __SAPP and check in + * fseek and ftell.) + */ + if (oflags & O_APPEND) + (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); + } + pthread_mutex_unlock(&__sfp_mutex); + return (fp); +} diff --git a/lib/libpthread/stdio/fprintf.c b/lib/libpthread/stdio/fprintf.c new file mode 100644 index 000000000000..3e8be7857245 --- /dev/null +++ b/lib/libpthread/stdio/fprintf.c @@ -0,0 +1,70 @@ +/*- + * 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 = "from: @(#)fprintf.c 5.6 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fprintf.c,v 1.1 1994/01/30 04:24:50 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#if __STDC__ +fprintf(FILE *fp, const char *fmt, ...) +#else +fprintf(fp, fmt, va_alist) + FILE *fp; + char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = vfprintf(fp, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/lib/libpthread/stdio/fpurge.c b/lib/libpthread/stdio/fpurge.c new file mode 100644 index 000000000000..5666d6933517 --- /dev/null +++ b/lib/libpthread/stdio/fpurge.c @@ -0,0 +1,72 @@ +/*- + * 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 = "from: @(#)fpurge.c 5.2 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fpurge.c,v 1.1 1994/01/30 04:24:51 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +/* + * fpurge: like fflush, but without writing anything: leave the + * given FILE's buffer empty. + */ +int +fpurge(fp) + register FILE *fp; +{ + int ret; + + flockfile(fp); + if (fp->_flags) { + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + ret = 0; + } else { + errno = EBADF; + ret = EOF; + } + funlockfile(fp); + return (ret); +} diff --git a/lib/libpthread/stdio/fputc.c b/lib/libpthread/stdio/fputc.c new file mode 100644 index 000000000000..5a71c8a047d4 --- /dev/null +++ b/lib/libpthread/stdio/fputc.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)fputc.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fputc.c,v 1.1 1994/01/30 04:24:52 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +fputc(c, fp) + int c; + register FILE *fp; +{ + int ret; + flockfile(fp); + ret = __sputc(c, fp); + funlockfile(fp); + return(ret); +} diff --git a/lib/libpthread/stdio/fputs.c b/lib/libpthread/stdio/fputs.c new file mode 100644 index 000000000000..73a590a6b720 --- /dev/null +++ b/lib/libpthread/stdio/fputs.c @@ -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 = "from: @(#)fputs.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fputs.c,v 1.1 1994/01/30 04:24:53 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include "fvwrite.h" + +/* + * Write the given string to the given file. + */ +fputs(s, fp) + const char *s; + FILE *fp; +{ + struct __suio uio; + struct __siov iov; + int ret; + + iov.iov_base = (void *)s; + iov.iov_len = uio.uio_resid = strlen(s); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + flockfile(fp); + ret = __sfvwrite(fp, &uio); + funlockfile(fp); + return(ret); +} diff --git a/lib/libpthread/stdio/fread.c b/lib/libpthread/stdio/fread.c new file mode 100644 index 000000000000..8d4998768dc8 --- /dev/null +++ b/lib/libpthread/stdio/fread.c @@ -0,0 +1,83 @@ +/*- + * 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 = "from: @(#)fread.c 5.4 (Berkeley) 5/4/91";*/ +static char *rcsid = "$Id: fread.c,v 1.1 1994/01/30 04:24:54 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <string.h> + +size_t +fread(buf, size, count, fp) + void *buf; + size_t size, count; + register FILE *fp; +{ + register size_t resid; + register char *p; + register int r; + size_t total; + + if ((resid = count * size) == 0) + return (count); + + flockfile(fp); + if (fp->_r < 0) + fp->_r = 0; + total = resid; + p = buf; + while (resid > (r = fp->_r)) { + (void) bcopy((void *)fp->_p, (void *)p, (size_t)r); + fp->_p += r; + /* fp->_r = 0 ... done in __srefill */ + p += r; + resid -= r; + if (__srefill(fp)) { + /* no more input: return partial result */ + count = (total - resid) / size; + goto done_fread; + } + } + (void) bcopy((void *)fp->_p, (void *)p, resid); + fp->_r -= resid; + fp->_p += resid; +done_fread:; + funlockfile(fp); + return (count); +} diff --git a/lib/libpthread/stdio/freopen.c b/lib/libpthread/stdio/freopen.c new file mode 100644 index 000000000000..a8a26e875ff4 --- /dev/null +++ b/lib/libpthread/stdio/freopen.c @@ -0,0 +1,146 @@ +/*- + * 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 = "from: @(#)freopen.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: freopen.c,v 1.1 1994/01/30 04:24:55 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +extern pthread_mutex_t __sfp_mutex; +extern pthread_cond_t __sfp_cond; +extern int __sfp_state; + +/* + * Re-direct an existing, open (probably) file to some other file. + * ANSI is written such that the original file gets closed if at + * all possible, no matter what. + */ +FILE * +freopen(file, mode, fp) + const char *file, *mode; + register FILE *fp; +{ + int f, flags, oflags; + FILE *ret; + + if ((flags = __sflags(mode, &oflags)) == 0) { + (void) fclose(fp); + return (NULL); + } + + pthread_once(&__sdidinit, __sinit); + + /* + * There are actually programs that depend on being able to "freopen" + * descriptors that weren't originally open. Keep this from breaking. + * Remember whether the stream was open to begin with, and which file + * descriptor (if any) was associated with it. If it was attached to + * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin) + * should work. This is unnecessary if it was not a Unix file. + */ + /* while lock __sfp_mutex, to block out fopen, and other freopen calls */ + while (pthread_mutex_lock(&__sfp_mutex) == OK) { + if (ftrylockfile(fp) == OK) { + if (fp->_flags) { + /* flush the stream; ANSI doesn't require this. */ + if (fp->_flags & __SWR) + (void) __sflush(fp); + __sclose(fp); + /* + * Finish closing fp. We cannot keep fp->_base: + * it may be the wrong size. This loses the effect + * of any setbuffer calls, but stdio has always done + * this before. + * NOTE: We do this even if __ftrylockfilr failed with + * an error to avoid memory leaks. + */ + if (fp->_flags & __SMBF) + free((char *)fp->_bf._base); + fp->_w = 0; + fp->_r = 0; + fp->_p = NULL; + fp->_bf._base = NULL; + fp->_bf._size = 0; + fp->_lbfsize = 0; + if (HASUB(fp)) + FREEUB(fp); + fp->_ub._size = 0; + if (HASLB(fp)) + FREELB(fp); + fp->_lb._size = 0; + } + /* Get a new descriptor to refer to the new file. */ + if ((f = open(file, oflags, 0666)) < OK) + ret = NULL; + /* + * If reopening something that was open before on a real file, try + * to maintain the descriptor. Various C library routines (perror) + * assume stderr is always fd STDERR_FILENO, even if being freopen'd. + */ + /* Testing f == fp->_file may no longer be necessary */ + if (fp->_file >= 0 && f != fp->_file) { + if (dup2(f, fp->_file) >= OK) { + (void)close(f); + f = fp->_file; + } + } + fp->_flags = flags; + fp->_file = f; + ret = fp; + break; + } else { + /* unlock __sfp_mutex, and try again later */ + pthread_mutex_unlock(&__sfp_mutex); + pthread_yield(); + continue; + } + pthread_mutex_unlock(&__sfp_mutex); + funlockfile(fp); + return(ret); + } + (void)fclose(fp); + return(NULL); +} diff --git a/lib/libpthread/stdio/fscanf.c b/lib/libpthread/stdio/fscanf.c new file mode 100644 index 000000000000..f1b492863b11 --- /dev/null +++ b/lib/libpthread/stdio/fscanf.c @@ -0,0 +1,72 @@ +/*- + * 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 = "from: @(#)fscanf.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: fscanf.c,v 1.1 1994/01/30 04:24:56 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#if __STDC__ +fscanf(FILE *fp, char const *fmt, ...) { + int r; + va_list ap; + + va_start(ap, fmt); +#else +fscanf(fp, fmt, va_alist) + FILE *fp; + char *fmt; + va_dcl +{ + int r; + va_list ap; + + va_start(ap); +#endif + flockfile(fp); + r = __svfscanf(fp, fmt, ap); + funlockfile(fp); + va_end(ap); + return(r); +} diff --git a/lib/libpthread/stdio/fseek.c b/lib/libpthread/stdio/fseek.c new file mode 100644 index 000000000000..90cf15544b22 --- /dev/null +++ b/lib/libpthread/stdio/fseek.c @@ -0,0 +1,246 @@ +/*- + * 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 = "from: @(#)fseek.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fseek.c,v 1.1 1994/01/30 04:24:57 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include "local.h" + +#define POS_ERR (-(fpos_t)1) + +/* + * Seek the given file to the given offset. + * `Whence' must be one of the three SEEK_* macros. + */ +fseek(fp, offset, whence) + register FILE *fp; + long offset; + int whence; +{ +#if __STDC__ + register fpos_t (*seekfn)(void *, fpos_t, int); +#else + register fpos_t (*seekfn)(); +#endif + fpos_t target, curoff; + size_t n; + struct stat st; + int havepos; + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + flockfile(fp); + + /* + * Change any SEEK_CUR to SEEK_SET, and check `whence' argument. + * After this, whence is either SEEK_SET or SEEK_END. + */ + switch (whence) { + case SEEK_CUR: + /* + * In order to seek relative to the current stream offset, + * we have to first find the current stream offset a la + * ftell (see ftell for details). + */ + if (fp->_flags & __SOFF) + curoff = fp->_offset; + else { + curoff = __sseek(fp, (fpos_t)0, SEEK_CUR); + if (curoff == -1L) + funlockfile(fp); + return (EOF); + } + if (fp->_flags & __SRD) { + curoff -= fp->_r; + if (HASUB(fp)) + curoff -= fp->_ur; + } else if (fp->_flags & __SWR && fp->_p != NULL) + curoff += fp->_p - fp->_bf._base; + + offset += curoff; + whence = SEEK_SET; + havepos = 1; + break; + + case SEEK_SET: + case SEEK_END: + curoff = 0; /* XXX just to keep gcc quiet */ + havepos = 0; + break; + + default: + errno = EINVAL; + funlockfile(fp); + return (EOF); + } + + /* + * Can only optimise if: + * reading (and not reading-and-writing); + * not unbuffered; and + * this is a `regular' Unix file (and hence seekfn==__sseek). + * We must check __NBF first, because it is possible to have __NBF + * and __SOPT both set. + */ + if (fp->_bf._base == NULL) + __smakebuf(fp); + if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT)) + goto dumb; + if ((fp->_flags & __SOPT) == 0) { + if (fp->_file < 0 || fstat(fp->_file, &st) || + (st.st_mode & S_IFMT) != S_IFREG) { + fp->_flags |= __SNPT; + goto dumb; + } + fp->_blksize = st.st_blksize; + fp->_flags |= __SOPT; + } + + /* + * We are reading; we can try to optimise. + * Figure out where we are going and where we are now. + */ + if (whence == SEEK_SET) + target = offset; + else { + if (fstat(fp->_file, &st)) + goto dumb; + target = st.st_size + offset; + } + + if (!havepos) { + if (fp->_flags & __SOFF) + curoff = fp->_offset; + else { + curoff = __sseek(fp, 0L, SEEK_CUR); + if (curoff == POS_ERR) + goto dumb; + } + curoff -= fp->_r; + if (HASUB(fp)) + curoff -= fp->_ur; + } + + /* + * Compute the number of bytes in the input buffer (pretending + * that any ungetc() input has been discarded). Adjust current + * offset backwards by this count so that it represents the + * file offset for the first byte in the current input buffer. + */ + if (HASUB(fp)) { + n = fp->_up - fp->_bf._base; + curoff -= n; + n += fp->_ur; + } else { + n = fp->_p - fp->_bf._base; + curoff -= n; + n += fp->_r; + } + + /* + * If the target offset is within the current buffer, + * simply adjust the pointers, clear EOF, undo ungetc(), + * and return. (If the buffer was modified, we have to + * skip this; see fgetline.c.) + */ + if ((fp->_flags & __SMOD) == 0 && + target >= curoff && target < curoff + n) { + register int o = target - curoff; + + fp->_p = fp->_bf._base + o; + fp->_r = n - o; + if (HASUB(fp)) + FREEUB(fp); + fp->_flags &= ~__SEOF; + funlockfile(fp); + return (0); + } + + /* + * The place we want to get to is not within the current buffer, + * but we can still be kind to the kernel copyout mechanism. + * By aligning the file offset to a block boundary, we can let + * the kernel use the VM hardware to map pages instead of + * copying bytes laboriously. Using a block boundary also + * ensures that we only read one block, rather than two. + */ + curoff = target & ~(fp->_blksize - 1); + if (__sseek(fp, 0L, SEEK_CUR) != POS_ERR) { + fp->_r = 0; + fp->_p = fp->_bf._base; + if (HASUB(fp)) + FREEUB(fp); + fp->_flags &= ~__SEOF; + n = target - curoff; + if (n) { + if (__srefill(fp) || fp->_r < n) + goto dumb; + fp->_p += n; + fp->_r -= n; + } + funlockfile(fp); + return (0); + } + + /* + * We get here if we cannot optimise the seek ... just + * do it. Allow the seek function to change fp->_bf._base. + */ +dumb: + if (__sflush(fp) || __sseek(fp, offset, whence) == POS_ERR) { + funlockfile(fp); + return (EOF); + } + /* success: clear EOF indicator and discard ungetc() data */ + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + /* fp->_w = 0; */ /* unnecessary (I think...) */ + fp->_flags &= ~__SEOF; + funlockfile(fp); + return (0); +} diff --git a/lib/libpthread/stdio/fsetpos.c b/lib/libpthread/stdio/fsetpos.c new file mode 100644 index 000000000000..2c90f5c02c02 --- /dev/null +++ b/lib/libpthread/stdio/fsetpos.c @@ -0,0 +1,53 @@ +/*- + * 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 = "from: @(#)fsetpos.c 5.2 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: fsetpos.c,v 1.1 1994/01/30 04:24:59 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +/* + * fsetpos: like fseek. + * Don't bother locking, fseek does it. + */ +fsetpos(iop, pos) + FILE *iop; + const fpos_t *pos; +{ + return (fseek(iop, (long)*pos, SEEK_SET)); +} diff --git a/lib/libpthread/stdio/ftell.c b/lib/libpthread/stdio/ftell.c new file mode 100644 index 000000000000..d19e5825ad50 --- /dev/null +++ b/lib/libpthread/stdio/ftell.c @@ -0,0 +1,89 @@ +/*- + * 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 = "from: @(#)ftell.c 5.4 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: ftell.c,v 1.1 1994/01/30 04:25:01 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include "local.h" + +/* + * ftell: return current offset. + */ +long +ftell(fp) + register const FILE *fp; +{ + register fpos_t pos; + + flockfile(fp); + + /* + * Find offset of underlying I/O object, then + * adjust for buffered bytes. + */ + if (fp->_flags & __SOFF) + pos = fp->_offset; + else { + pos = lseek(fp, (fpos_t)0, SEEK_CUR); + } + + if (pos != -1L) { + if (fp->_flags & __SRD) { + /* + * Reading. Any unread characters (including + * those from ungetc) cause the position to be + * smaller than that in the underlying object. + */ + pos -= fp->_r; + if (HASUB(fp)) + pos -= fp->_ur; + } else if (fp->_flags & __SWR && fp->_p != NULL) { + /* + * Writing. Any buffered characters cause the + * position to be greater than that in the + * underlying object. + */ + pos += fp->_p - fp->_bf._base; + } + } + funlockfile(fp); + return (pos); +} diff --git a/lib/libpthread/stdio/funopen.c b/lib/libpthread/stdio/funopen.c new file mode 100644 index 000000000000..6e3676fdb086 --- /dev/null +++ b/lib/libpthread/stdio/funopen.c @@ -0,0 +1,100 @@ +/*- + * 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 = "from: @(#)funopen.c 5.2 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: funopen.c,v 1.1 1994/01/30 04:25:01 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include "local.h" + +FILE * +funopen(cookie, readfn, writefn, seekfn, closefn) + const void *cookie; + int (*readfn)(), (*writefn)(); +#if __STDC__ + fpos_t (*seekfn)(void *cookie, fpos_t off, int whence); +#else + fpos_t (*seekfn)(); +#endif + int (*closefn)(); +{ + struct fd_ops *fd_ops; + char *flags; + FILE *fp; + int fd; + + if (readfn == NULL) { + if (writefn == NULL) { /* illegal */ + errno = EINVAL; + return (NULL); + } else + flags = "w"; /* write only */ + } else { + if (writefn == NULL) + flags = "r"; /* read only */ + else + flags = "r+"; /* read-write */ + } + + if (fd_ops = (struct fd_ops*)malloc(sizeof(struct fd_ops))) { + if ((!(fd = fd_allocate())) < OK) { + + /* Set functions */ + fd_ops->seek = seekfn; + fd_ops->read = readfn; + fd_ops->write = writefn; + fd_ops->close = closefn; + + /* Alloc space for funtion pointer table */ + fd_table[fd]->type = FD_HALF_DUPLEX; + fd_table[fd]->ops = fd_ops; + + /* Save the cookie, it's important */ + fd_table[fd]->fd.ptr = cookie; + + if (fp = fdopen(fd, flags)) + return(fp); + + fd_free(fd); + } + free(fd_ops); + } + return(NULL); +} diff --git a/lib/libpthread/stdio/fvwrite.c b/lib/libpthread/stdio/fvwrite.c new file mode 100644 index 000000000000..3820f4f614ae --- /dev/null +++ b/lib/libpthread/stdio/fvwrite.c @@ -0,0 +1,188 @@ +/*- + * 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 = "from: @(#)fvwrite.c 5.3 (Berkeley) 5/4/91";*/ +static char *rcsid = "$Id: fvwrite.c,v 1.1 1994/01/30 04:25:03 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include "local.h" +#include "fvwrite.h" + +/* + * Write some memory regions. Return zero on success, EOF on error. + * + * This routine is large and unsightly, but most of the ugliness due + * to the three different kinds of output buffering is handled here. + */ +__sfvwrite(fp, uio) + register FILE *fp; + register struct __suio *uio; +{ + register size_t len; + register char *p; + register struct __siov *iov; + register int w, s; + char *nl; + int nlknown, nldist; + + if ((len = uio->uio_resid) == 0) + return (0); + /* make sure we can write */ + if (cantwrite(fp)) + return (EOF); + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define COPY(n) (void) bcopy((void *)p, (void *)fp->_p, (size_t)(n)); + + iov = uio->uio_iov; + p = iov->iov_base; + len = iov->iov_len; + iov++; +#define GETIOV(extra_work) \ + while (len == 0) { \ + extra_work; \ + p = iov->iov_base; \ + len = iov->iov_len; \ + iov++; \ + } + if (fp->_flags & __SNBF) { + /* + * Unbuffered: write up to BUFSIZ bytes at a time. + */ + do { + GETIOV(;); + w = __swrite(fp, p, MIN(len, BUFSIZ)); + if (w <= 0) + goto err; + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } else if ((fp->_flags & __SLBF) == 0) { + /* + * Fully buffered: fill partially full buffer, if any, + * and then flush. If there is no partial buffer, write + * one _bf._size byte chunk directly (without copying). + * + * String output is a special case: write as many bytes + * as fit, but pretend we wrote everything. This makes + * snprintf() return the number of bytes needed, rather + * than the number used, and avoids its write function + * (so that the write function can be invalid). + */ + do { + GETIOV(;); + w = fp->_w; + if (fp->_flags & __SSTR) { + if (len < w) + w = len; + COPY(w); /* copy MIN(fp->_w,len), */ + fp->_w -= w; + fp->_p += w; + w = len; /* but pretend copied all */ + } else if (fp->_p > fp->_bf._base && len > w) { + /* fill and flush */ + COPY(w); + /* fp->_w -= w; */ /* unneeded */ + fp->_p += w; + if (fflush(fp)) + goto err; + } else if (len >= (w = fp->_bf._size)) { + if ((w = __swrite(fp, p, w)) <= 0) + goto err; + } else { + /* fill and done */ + w = len; + COPY(w); + fp->_w -= w; + fp->_p += w; + } + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } else { + /* + * Line buffered: like fully buffered, but we + * must check for newlines. Compute the distance + * to the first newline (including the newline), + * or `infinity' if there is none, then pretend + * that the amount to write is MIN(len,nldist). + */ + nlknown = 0; + nldist = 0; /* XXX just to keep gcc happy */ + do { + GETIOV(nlknown = 0); + if (!nlknown) { + nl = memchr((void *)p, '\n', len); + nldist = nl ? nl + 1 - p : len + 1; + nlknown = 1; + } + s = MIN(len, nldist); + w = fp->_w + fp->_bf._size; + if (fp->_p > fp->_bf._base && s > w) { + COPY(w); + /* fp->_w -= w; */ + fp->_p += w; + if (fflush(fp)) + goto err; + } else if (s >= (w = fp->_bf._size)) { + if ((w = __swrite(fp, p, w)) <= 0) + goto err; + } else { + w = s; + COPY(w); + fp->_w -= w; + fp->_p += w; + } + if ((nldist -= w) == 0) { + /* copied the newline: flush and forget */ + if (fflush(fp)) + goto err; + nlknown = 0; + } + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } + return (0); + +err: + fp->_flags |= __SERR; + return (EOF); +} diff --git a/lib/libpthread/stdio/fvwrite.h b/lib/libpthread/stdio/fvwrite.h new file mode 100644 index 000000000000..e84163e04328 --- /dev/null +++ b/lib/libpthread/stdio/fvwrite.h @@ -0,0 +1,54 @@ +/*- + * 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. + * + * from: @(#)fvwrite.h 5.1 (Berkeley) 1/20/91 + * $Id: fvwrite.h,v 1.1 1994/01/30 04:25:05 proven Exp $ + */ + +/* + * I/O descriptors for __sfvwrite(). + */ +struct __siov { + void *iov_base; + size_t iov_len; +}; + +struct __suio { + struct __siov *uio_iov; + int uio_iovcnt; + int uio_resid; +}; + +extern int __sfvwrite __P(( FILE *, struct __suio *)); diff --git a/lib/libpthread/stdio/fwalk.c b/lib/libpthread/stdio/fwalk.c new file mode 100644 index 000000000000..3129f305cfc4 --- /dev/null +++ b/lib/libpthread/stdio/fwalk.c @@ -0,0 +1,131 @@ +/*- + * 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 = "from: @(#)fwalk.c 5.2 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fwalk.c,v 1.1 1994/01/30 04:25:06 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include "local.h" +#include "glue.h" + +extern pthread_mutex_t __sfp_mutex; +extern pthread_cond_t __sfp_cond; +extern int __sfp_state; + +/* + * fwalk now can only be used for flushing the buffers. + * This is all it was originally used for. + * The function has also become much more complicated. + * The first time through we flush everything we can. + * If this fails to flush everything because we couldn't get a lock + * we wait on the locksfor the second pass. Why this works ... + * + * This function must allow for multiple threads to flush everything. + * This function cannot flush buffers locked by another thread. + * So we flush everything we can the first pass. This includes all + * buffers locked by this thread, and wait on buffers that are locked. + * Eventually other threads willl unlock there buffers or flush them themselves + * at which point this thread will notice that it's empty or be able to + * flush the buffer. This is fine so long as no other thread tries to flush + * all buffers. Here is the possible deadlock condition, but since this thread + * has flushed all buffers it can, there are NO buffers locked by this thread + * that need flushing so any other thread flushing won't block waiting on this + * thread thereby eliminating the deadlock condition. + */ + +int __swalk_sflush() +{ + register FILE *fp, *savefp; + register int n, ret, saven; + register struct glue *g, *saveg; + + /* Only allow other threads to read __sglue */ + pthread_mutex_lock(&__sfp_mutex); + __sfp_state++; + pthread_mutex_unlock(&__sfp_mutex); + + ret = 0; + saven = 0; + saveg = NULL; + savefp = NULL; + for (g = &__sglue; g != NULL; g = g->next) { + for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) { + if (fp->_flags != 0) { + /* Is there anything to flush? */ + if (fp->_bf._base && (fp->_bf._base - fp->_p)) { + if (ftrylockfile(fp)) { /* Can we flush it */ + if (!saven) { /* No, save first fp we can't flush */ + saven; + saveg = g; + savefp = fp; + continue; + } + ret |= __sflush(fp); + } + } + } + } + } + if (savefp) { + for (g = saveg; g != NULL; g = g->next) { + for (fp = savefp, n = saven + 1; --n >= 0; fp++) { + if (fp->_flags != 0) { + /* Anything to flush */ + while (fp->_bf._base && (fp->_bf._base - fp->_p)) { + if (ftrylockfile(fp)) { /* Can we flush it */ + pthread_yield(); + continue; + } + ret |= __sflush(fp); + } + } + } + } + } + + /* If no other readers wakeup a thread waiting to do __sfp */ + pthread_mutex_lock(&__sfp_mutex); + if (! (--__sfp_state)) { + pthread_cond_signal(&__sfp_cond); + } + pthread_mutex_unlock(&__sfp_mutex); + return (ret); +} + diff --git a/lib/libpthread/stdio/fwrite.c b/lib/libpthread/stdio/fwrite.c new file mode 100644 index 000000000000..daeb7ae6d54d --- /dev/null +++ b/lib/libpthread/stdio/fwrite.c @@ -0,0 +1,77 @@ +/*- + * 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 = "from: @(#)fwrite.c 5.5 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: fwrite.c,v 1.1 1994/01/30 04:25:07 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include "local.h" +#include "fvwrite.h" + +/* + * Write `count' objects (each size `size') from memory to the given file. + * Return the number of whole objects written. + */ +size_t +fwrite(buf, size, count, fp) + const void *buf; + size_t size, count; + FILE *fp; +{ + struct __suio uio; + struct __siov iov; + size_t n; + + iov.iov_base = (void *)buf; + uio.uio_resid = iov.iov_len = n = count * size; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + + flockfile(fp); + + /* + * The usual case is success (__sfvwrite returns 0); + * skip the divide if this happens, since divides are + * generally slow and since this occurs whenever size==0. + */ + if (__sfvwrite(fp, &uio) == 0) + count = (n - uio.uio_resid) / size; + funlockfile(fp); + return(count); +} diff --git a/lib/libpthread/stdio/getc.c b/lib/libpthread/stdio/getc.c new file mode 100644 index 000000000000..257b776c360e --- /dev/null +++ b/lib/libpthread/stdio/getc.c @@ -0,0 +1,57 @@ +/*- + * 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 = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: getc.c,v 1.1 1994/01/30 04:25:07 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +/* + * A subroutine version of the macro getc. + */ +#undef getc + +getc(fp) + register FILE *fp; +{ + int ret; + flockfile(fp); + ret = __sgetc(fp); + funlockfile(fp); + return(ret); +} diff --git a/lib/libpthread/stdio/getc_unlocked.c b/lib/libpthread/stdio/getc_unlocked.c new file mode 100644 index 000000000000..98a0f0eb5b1e --- /dev/null +++ b/lib/libpthread/stdio/getc_unlocked.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: getc_unlocked.c,v 1.1 1994/01/30 04:25:08 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro getc. + */ +#undef getc_unlocked + +getc_unlocked(fp) + register FILE *fp; +{ + return (__sgetc(fp)); +} diff --git a/lib/libpthread/stdio/getchar.c b/lib/libpthread/stdio/getchar.c new file mode 100644 index 000000000000..8d8499543d25 --- /dev/null +++ b/lib/libpthread/stdio/getchar.c @@ -0,0 +1,57 @@ +/*- + * 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 = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: getchar.c,v 1.1 1994/01/30 04:25:09 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * A subroutine version of the macro getchar. + */ +#include <pthread.h> +#include <stdio.h> + +#undef getchar + +getchar() +{ + int ret; + flockfile(stdin); + ret = getc(stdin); + funlockfile(stdin); + return(ret); +} diff --git a/lib/libpthread/stdio/getchar_unlocked.c b/lib/libpthread/stdio/getchar_unlocked.c new file mode 100644 index 000000000000..1cc6abd58db8 --- /dev/null +++ b/lib/libpthread/stdio/getchar_unlocked.c @@ -0,0 +1,53 @@ +/*- + * 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 = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: getchar_unlocked.c,v 1.1 1994/01/30 04:25:10 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * A subroutine version of the macro getchar. + */ +#include <pthread.h> +#include <stdio.h> + +#undef getchar_unlocked + +getchar_unlocked() +{ + return (getc(stdin)); +} diff --git a/lib/libpthread/stdio/gets.c b/lib/libpthread/stdio/gets.c new file mode 100644 index 000000000000..4012c60ee237 --- /dev/null +++ b/lib/libpthread/stdio/gets.c @@ -0,0 +1,69 @@ +/*- + * 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 = "from: @(#)gets.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: gets.c,v 1.1 1994/01/30 04:25:11 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <unistd.h> +#include <stdio.h> + +char * +gets(buf) + char *buf; +{ + register int c; + register char *s; + static int warned; + static char w[] = + "warning: this program uses gets(), which is unsafe.\r\n"; + + if (!warned) { + (void) write(STDERR_FILENO, w, sizeof(w) - 1); + warned = 1; + } + for (s = buf; (c = getchar()) != '\n';) + if (c == EOF) + if (s == buf) + return (NULL); + else + break; + else + *s++ = c; + *s = 0; + return (buf); +} diff --git a/lib/libpthread/stdio/getw.c b/lib/libpthread/stdio/getw.c new file mode 100644 index 000000000000..3968c068b488 --- /dev/null +++ b/lib/libpthread/stdio/getw.c @@ -0,0 +1,50 @@ +/*- + * 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 = "from: @(#)getw.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: getw.c,v 1.1 1994/01/30 04:25:12 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +getw(fp) + FILE *fp; +{ + int x; + + return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF); +} diff --git a/lib/libpthread/stdio/glue.h b/lib/libpthread/stdio/glue.h new file mode 100644 index 000000000000..04a9eec80de7 --- /dev/null +++ b/lib/libpthread/stdio/glue.h @@ -0,0 +1,48 @@ +/*- + * 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. + * + * from: @(#)glue.h 5.1 (Berkeley) 1/20/91 + * $Id: glue.h,v 1.1 1994/01/30 04:25:13 proven Exp $ + */ + +/* + * The first few FILEs are statically allocated; others are dynamically + * allocated and linked in via this glue structure. + */ +struct glue { + struct glue *next; + int niobs; + FILE *iobs; +} __sglue; diff --git a/lib/libpthread/stdio/local.h b/lib/libpthread/stdio/local.h new file mode 100644 index 000000000000..a5915975bf3d --- /dev/null +++ b/lib/libpthread/stdio/local.h @@ -0,0 +1,88 @@ +/*- + * 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. + * + * from: @(#)local.h 5.3 (Berkeley) 5/6/93 + * $Id: local.h,v 1.1 1994/01/30 04:25:14 proven Exp $ + */ + +/* + * Information local to this implementation of stdio, + * in particular, macros and private variables. + */ + +FILE *__sfp __P((void)); +int __sflush __P((FILE *)); +int __srefill __P((FILE *)); +int __swrite __P((FILE *, const char *, int)); +int __sread __P((FILE *, char *, int)); +fpos_t __sseek __P((FILE *, fpos_t, int)); +int __sclose __P((FILE *)); +void __sinit __P((void)); +void _cleanup __P((void)); +void (*__cleanup) __P((void)); +void __smakebuf __P((FILE *)); +int __swhatbuf __P((FILE *, size_t *, int *)); +int __swalk_sflush __P(()); +int __swsetup __P((FILE *)); +int __sflags __P((const char *, int *)); + +extern int __sdidinit; + +/* + * Return true iff the given FILE cannot be written now. + */ +#define cantwrite(fp) \ + ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ + __swsetup(fp)) + +/* + * Test whether the given stdio file has an active ungetc buffer; + * release such a buffer, without restoring ordinary unread data. + */ +#define HASUB(fp) ((fp)->_ub._base != NULL) +#define FREEUB(fp) { \ + if ((fp)->_ub._base != (fp)->_ubuf) \ + free((char *)(fp)->_ub._base); \ + (fp)->_ub._base = NULL; \ +} + +/* + * test for an fgetline() buffer. + */ +#define HASLB(fp) ((fp)->_lb._base != NULL) +#define FREELB(fp) { \ + free((char *)(fp)->_lb._base); \ + (fp)->_lb._base = NULL; \ +} diff --git a/lib/libpthread/stdio/makebuf.c b/lib/libpthread/stdio/makebuf.c new file mode 100644 index 000000000000..0c9434917e57 --- /dev/null +++ b/lib/libpthread/stdio/makebuf.c @@ -0,0 +1,119 @@ +/*- + * 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 = "from: @(#)makebuf.c 5.3 (Berkeley) 5/6/93";*/ +static char *rcsid = "$Id: makebuf.c,v 1.1 1994/01/30 04:25:14 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the fstat() that finds the buffer size. + */ +void +__smakebuf(fp) + register FILE *fp; +{ + register void *p; + register int flags; + size_t size; + int couldbetty; + + if (fp->_flags & __SNBF) { + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + flags = __swhatbuf(fp, &size, &couldbetty); + if ((p = malloc(size)) == NULL) { + fp->_flags |= __SNBF; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + return; + } + __cleanup = _cleanup; + flags |= __SMBF; + fp->_bf._base = fp->_p = p; + fp->_bf._size = size; + if (couldbetty && isatty(fp->_file)) + flags |= __SLBF; + fp->_flags |= flags; +} + +/* + * Internal routine to determine `proper' buffering for a file. + */ +int +__swhatbuf(fp, bufsize, couldbetty) + register FILE *fp; + size_t *bufsize; + int *couldbetty; +{ + struct stat st; + + if (fp->_file < 0 || fstat(fp->_file, &st) < 0) { + *couldbetty = 0; + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* could be a tty iff it is a character device */ + *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR; + if (st.st_blksize <= 0) { + *bufsize = BUFSIZ; + return (__SNPT); + } + + /* + * Optimise fseek() only if it is a regular file. (The test for + * __sseek is mainly paranoia.) It is safe to set _blksize + * unconditionally; it will only be used if __SOPT is also set. + */ + *bufsize = st.st_blksize; + fp->_blksize = st.st_blksize; + return ((st.st_mode & S_IFMT) == S_IFREG ? __SOPT : __SNPT); +} diff --git a/lib/libc/db/PORT/clib/mktemp.c b/lib/libpthread/stdio/mktemp.c index 6cedd6a6be43..5e45153c3205 100644 --- a/lib/libc/db/PORT/clib/mktemp.c +++ b/lib/libpthread/stdio/mktemp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. + * 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 @@ -32,7 +32,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; +/*static char *sccsid = "from: @(#)mktemp.c 5.10 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: mktemp.c,v 1.1 1994/01/30 04:25:15 proven Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -40,7 +41,6 @@ static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #include <fcntl.h> #include <errno.h> #include <stdio.h> -#include <ctype.h> static int _gettemp(); diff --git a/lib/libpthread/stdio/perror.c b/lib/libpthread/stdio/perror.c new file mode 100644 index 000000000000..c4cb0154da2e --- /dev/null +++ b/lib/libpthread/stdio/perror.c @@ -0,0 +1,67 @@ +/* + * 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[] = "@(#)perror.c 5.11 (Berkeley) 2/24/91"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +void +perror(s) + const char *s; +{ + register struct iovec *v; + struct iovec iov[4]; + + v = iov; + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = strerror(errno); + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + (void)writev(STDERR_FILENO, iov, (v - iov) + 1); +} diff --git a/lib/libpthread/stdio/perror.c.old b/lib/libpthread/stdio/perror.c.old new file mode 100644 index 000000000000..19ebba595739 --- /dev/null +++ b/lib/libpthread/stdio/perror.c.old @@ -0,0 +1,77 @@ +/* + * 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 = "from: @(#)perror.c 5.11 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: perror.c.old,v 1.1 1994/01/30 04:25:17 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +/* + * Since perror() is not allowed to change the contents of strerror()'s + * static buffer, both functions supply their own buffers to the + * internal function __strerror(). + */ + +extern char *__strerror __P((int , char *)); + +void +perror(s) + const char *s; +{ + register struct iovec *v; + struct iovec iov[4]; + static char buf[40]; + + v = iov; + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = __strerror(errno, buf); + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + (void)writev(STDERR_FILENO, iov, (v - iov) + 1); +} diff --git a/lib/libpthread/stdio/printf.c b/lib/libpthread/stdio/printf.c new file mode 100644 index 000000000000..96deb03b4f9e --- /dev/null +++ b/lib/libpthread/stdio/printf.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)printf.c 5.6 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: printf.c,v 1.1 1994/01/30 04:25:19 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +printf(char const *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(stdout, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/lib/libpthread/stdio/putc.c b/lib/libpthread/stdio/putc.c new file mode 100644 index 000000000000..6edd0b1f50e4 --- /dev/null +++ b/lib/libpthread/stdio/putc.c @@ -0,0 +1,59 @@ +/*- + * 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 = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: putc.c,v 1.1 1994/01/30 04:25:20 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro putc. + */ +#undef putc + +putc(c, fp) + int c; + register FILE *fp; +{ + int ret; + flockfile(fp); + ret = __sputc(c, fp); + funlockfile(fp); + return(ret); +} diff --git a/lib/libpthread/stdio/putc_unlocked.c b/lib/libpthread/stdio/putc_unlocked.c new file mode 100644 index 000000000000..bf88208c3c96 --- /dev/null +++ b/lib/libpthread/stdio/putc_unlocked.c @@ -0,0 +1,55 @@ +/*- + * 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 = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: putc_unlocked.c,v 1.1 1994/01/30 04:25:22 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +/* + * A subroutine version of the macro putc. + */ +#undef putc_unlocked + +putc_unlocked(c, fp) + int c; + register FILE *fp; +{ + return (__sputc(c, fp)); +} diff --git a/lib/libpthread/stdio/putchar.c b/lib/libpthread/stdio/putchar.c new file mode 100644 index 000000000000..e8dc068fcbb6 --- /dev/null +++ b/lib/libpthread/stdio/putchar.c @@ -0,0 +1,59 @@ +/*- + * 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 = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: putchar.c,v 1.1 1994/01/30 04:25:26 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +#undef putchar + +/* + * A subroutine version of the macro putchar + */ +putchar(c) + int c; +{ + register FILE *so = stdout; + int ret; + + flockfile(so); + ret = __sputc(c, so); + funlockfile(so); + return(ret); +} diff --git a/lib/libpthread/stdio/putchar_unlocked.c b/lib/libpthread/stdio/putchar_unlocked.c new file mode 100644 index 000000000000..15e35433e8d7 --- /dev/null +++ b/lib/libpthread/stdio/putchar_unlocked.c @@ -0,0 +1,55 @@ +/*- + * 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 = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: putchar_unlocked.c,v 1.1 1994/01/30 04:25:27 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +#undef putchar_unlocked +/* + * A subroutine version of the macro putchar + */ +putchar_unlocked(c) + int c; +{ + register FILE *so = stdout; + + return (__sputc(c, so)); +} diff --git a/lib/libpthread/stdio/puts.c b/lib/libpthread/stdio/puts.c new file mode 100644 index 000000000000..9c38a1880c6d --- /dev/null +++ b/lib/libpthread/stdio/puts.c @@ -0,0 +1,70 @@ +/*- + * 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 = "from: @(#)puts.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: puts.c,v 1.1 1994/01/30 04:25:28 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include "fvwrite.h" + +/* + * Write the given string to stdout, appending a newline. + */ +puts(s) + char const *s; +{ + size_t c = strlen(s); + struct __suio uio; + struct __siov iov[2]; + int r; + + iov[0].iov_base = (void *)s; + iov[0].iov_len = c; + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + uio.uio_resid = c + 1; + uio.uio_iov = &iov[0]; + uio.uio_iovcnt = 2; + + flockfile(stdout); + r = (__sfvwrite(stdout, &uio) ? EOF : '\n'); + funlockfile(stdout); + return(r); +} diff --git a/lib/libpthread/stdio/putw.c b/lib/libpthread/stdio/putw.c new file mode 100644 index 000000000000..a334acd4ed12 --- /dev/null +++ b/lib/libpthread/stdio/putw.c @@ -0,0 +1,63 @@ +/*- + * 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 = "from: @(#)putw.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: putw.c,v 1.1 1994/01/30 04:25:30 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include "fvwrite.h" + +putw(w, fp) + int w; + FILE *fp; +{ + struct __suio uio; + struct __siov iov; + int r; + + iov.iov_base = &w; + iov.iov_len = uio.uio_resid = sizeof(w); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + + flockfile(fp); + r = (__sfvwrite(fp, &uio)); + funlockfile(fp); + return(r); +} diff --git a/lib/libpthread/stdio/refill.c b/lib/libpthread/stdio/refill.c new file mode 100644 index 000000000000..635fd357582b --- /dev/null +++ b/lib/libpthread/stdio/refill.c @@ -0,0 +1,183 @@ +/*- + * 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 = "from: @(#)refill.c 5.3 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: refill.c,v 1.1 1994/01/30 04:25:31 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" +#include "glue.h" + +extern pthread_mutex_t __sfp_mutex; +extern pthread_cond_t __sfp_cond; +extern struct glue __sglue; +extern int __sfp_state; + +/* This function is very similar to __swalk_sflush */ +static void __swalk_lflush() +{ + register FILE *fp, *savefp; + register int n, saven; + register struct glue *g, *saveg; + + /* Only allow other threads to read __sglue */ + pthread_mutex_lock(&__sfp_mutex); + __sfp_state++; + pthread_mutex_unlock(&__sfp_mutex); + + saven = 0; + saveg = NULL; + savefp = NULL; + for (g = &__sglue; g != NULL; g = g->next) { + for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) { + if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) { + /* Is there anything to flush? */ + if (fp->_bf._base && (fp->_bf._base - fp->_p)) { + if (ftrylockfile(fp)) { /* Can we flush it */ + if (!saven) { /* No, save first fp we can't flush */ + saven; + saveg = g; + savefp = fp; + continue; + } + (void) __sflush(fp); + } + } + } + } + } + if (savefp) { + for (g = saveg; g != NULL; g = g->next) { + for (fp = savefp, n = saven + 1; --n >= 0; fp++) { + if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) { + /* Anything to flush */ + while (fp->_bf._base && (fp->_bf._base - fp->_p)) { + if (ftrylockfile(fp)) { /* Can we flush it */ + pthread_yield(); + continue; + } + (void) __sflush(fp); + } + } + } + } + } + + /* If no other readers wakeup a thread waiting to do __sfp */ + pthread_mutex_lock(&__sfp_mutex); + if (! (--__sfp_state)) { + pthread_cond_signal(&__sfp_cond); + } + pthread_mutex_unlock(&__sfp_mutex); +} + +/* + * Refill a stdio buffer. + * Return EOF on eof or error, 0 otherwise. + */ +__srefill(fp) + register FILE *fp; +{ + + /* make sure stdio is set up */ + pthread_once(&__sdidinit, __sinit); + + fp->_r = 0; /* largely a convenience for callers */ + + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & __SEOF) + return (EOF); + + /* if not already reading, have to be reading and writing */ + if ((fp->_flags & __SRD) == 0) { + if ((fp->_flags & __SRW) == 0) { + errno = EBADF; + return (EOF); + } + /* switch to reading */ + if (fp->_flags & __SWR) { + if (__sflush(fp)) + return (EOF); + fp->_flags &= ~__SWR; + fp->_w = 0; + fp->_lbfsize = 0; + } + fp->_flags |= __SRD; + } else { + /* + * We were reading. If there is an ungetc buffer, + * we must have been reading from that. Drop it, + * restoring the previous buffer (if any). If there + * is anything in that buffer, return. + */ + if (HASUB(fp)) { + FREEUB(fp); + if ((fp->_r = fp->_ur) != 0) { + fp->_p = fp->_up; + return (0); + } + } + } + + if (fp->_bf._base == NULL) + __smakebuf(fp); + + /* + * Before reading from a line buffered or unbuffered file, + * flush all line buffered output files, per the ANSI C + * standard. + */ + if (fp->_flags & (__SLBF|__SNBF)) + __swalk_lflush(); + fp->_p = fp->_bf._base; + fp->_r = __sread(fp, (char *)fp->_p, fp->_bf._size); + fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ + if (fp->_r <= 0) { + if (fp->_r == 0) + fp->_flags |= __SEOF; + else { + fp->_r = 0; + fp->_flags |= __SERR; + } + return (EOF); + } + return (0); +} diff --git a/lib/libpthread/stdio/remove.c b/lib/libpthread/stdio/remove.c new file mode 100644 index 000000000000..20585b1eadea --- /dev/null +++ b/lib/libpthread/stdio/remove.c @@ -0,0 +1,48 @@ +/*- + * 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 = "from: @(#)remove.c 5.3 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: remove.c,v 1.1 1994/01/30 04:25:33 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <unistd.h> + +remove(file) + const char *file; +{ + return (unlink(file)); +} diff --git a/lib/libpthread/stdio/rewind.c b/lib/libpthread/stdio/rewind.c new file mode 100644 index 000000000000..34970f0d36f7 --- /dev/null +++ b/lib/libpthread/stdio/rewind.c @@ -0,0 +1,54 @@ +/*- + * 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 = "from: @(#)rewind.c 5.6 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: rewind.c,v 1.1 1994/01/30 04:25:34 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <errno.h> +#include <stdio.h> + +void +rewind(fp) + register FILE *fp; +{ + flockfile(fp); + (void) fseek(fp, 0L, SEEK_SET); + fp->_flags &= ~(__SERR|__SEOF); /* clearerr */ + funlockfile(fp); + errno = 0; /* not required, but seems reasonable */ +} diff --git a/lib/libpthread/stdio/rget.c b/lib/libpthread/stdio/rget.c new file mode 100644 index 000000000000..f2c3dbbd0453 --- /dev/null +++ b/lib/libpthread/stdio/rget.c @@ -0,0 +1,57 @@ +/*- + * 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 = "from: @(#)rget.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: rget.c,v 1.1 1994/01/30 04:25:37 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +/* + * Handle getc() when the buffer ran out: + * Refill, then return the first character + * in the newly-filled buffer. + */ +__srget(fp) + register FILE *fp; +{ + if (__srefill(fp) == 0) { + fp->_r--; + return (*fp->_p++); + } + return (EOF); +} diff --git a/lib/libpthread/stdio/scanf.c b/lib/libpthread/stdio/scanf.c new file mode 100644 index 000000000000..d0062ccf339a --- /dev/null +++ b/lib/libpthread/stdio/scanf.c @@ -0,0 +1,71 @@ +/*- + * 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 = "from: @(#)scanf.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: scanf.c,v 1.1 1994/01/30 04:25:38 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#if __STDC__ +scanf(char const *fmt, ...) +#else +scanf(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + flockfile(stdin); + ret = __svfscanf(stdin, fmt, ap); + flockfile(stdin); + va_end(ap); + return (ret); +} diff --git a/lib/libpthread/stdio/setbuf.c b/lib/libpthread/stdio/setbuf.c new file mode 100644 index 000000000000..154177275519 --- /dev/null +++ b/lib/libpthread/stdio/setbuf.c @@ -0,0 +1,51 @@ +/*- + * 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 = "from: @(#)setbuf.c 5.3 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: setbuf.c,v 1.1 1994/01/30 04:25:39 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include "local.h" + +void +setbuf(fp, buf) + FILE *fp; + char *buf; +{ + (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} diff --git a/lib/libpthread/stdio/setbuffer.c b/lib/libpthread/stdio/setbuffer.c new file mode 100644 index 000000000000..e091f2c96122 --- /dev/null +++ b/lib/libpthread/stdio/setbuffer.c @@ -0,0 +1,63 @@ +/*- + * 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 = "from: @(#)setbuffer.c 5.5 (Berkeley) 3/18/91";*/ +static char *rcsid = "$Id: setbuffer.c,v 1.1 1994/01/30 04:25:40 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +void +setbuffer(fp, buf, size) + register FILE *fp; + char *buf; + int size; +{ + + (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size); +} + +/* + * set line buffering + */ +setlinebuf(fp) + FILE *fp; +{ + + (void) setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0); + return (0); /* ??? */ +} diff --git a/lib/libpthread/stdio/setvbuf.c b/lib/libpthread/stdio/setvbuf.c new file mode 100644 index 000000000000..0a4bedfde236 --- /dev/null +++ b/lib/libpthread/stdio/setvbuf.c @@ -0,0 +1,153 @@ +/*- + * 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 = "from: @(#)setvbuf.c 5.5 (Berkeley) 5/6/93";*/ +static char *rcsid = "$Id: setvbuf.c,v 1.1 1994/01/30 04:25:41 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +/* + * Set one of the three kinds of buffering, optionally including + * a buffer. + */ +setvbuf(fp, buf, mode, size) + register FILE *fp; + char *buf; + register int mode; + register size_t size; +{ + register int ret, flags; + size_t iosize; + int ttyflag; + + /* + * Verify arguments. The `int' limit on `size' is due to this + * particular implementation. Note, buf and size are ignored + * when setting _IONBF. + */ + if (mode != _IONBF) + if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) + return (EOF); + + flockfile(fp); + /* + * Write current buffer, if any. Discard unread input, cancel + * line buffering, and free old buffer if malloc()ed. + */ + ret = 0; + (void)__sflush(fp); + fp->_r = fp->_lbfsize = 0; + flags = fp->_flags; + if (flags & __SMBF) + free((void *)fp->_bf._base); + flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT); + + /* If setting unbuffered mode, skip all the hard work. */ + if (mode == _IONBF) + goto nbf; + + /* + * Find optimal I/O size for seek optimization. This also returns + * a `tty flag' to suggest that we check isatty(fd), but we do not + * care since our caller told us how to buffer. + */ + flags |= __swhatbuf(fp, &iosize, &ttyflag); + if (size == 0) { + buf = NULL; /* force local allocation */ + size = iosize; + } + + /* Allocate buffer if needed. */ + if (buf == NULL) { + if ((buf = malloc(size)) == NULL) { + /* + * Unable to honor user's request. We will return + * failure, but try again with file system size. + */ + ret = EOF; + if (size != iosize) { + size = iosize; + buf = malloc(size); + } + } + if (buf == NULL) { + /* No luck; switch to unbuffered I/O. */ +nbf: + fp->_flags = flags | __SNBF; + fp->_w = 0; + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + funlockfile(fp); + return (ret); + } + flags |= __SMBF; + } + + /* + * Kill any seek optimization if the buffer is not the + * right size. + * + * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? + */ + if (size != iosize) + flags |= __SNPT; + + /* + * Fix up the FILE fields, and set __cleanup for output flush on + * exit (since we are buffered in some way). If in r/w mode, go + * to the intermediate state, so that everyone has to call + * __srefill or __swsetup on the first operation -- it is more + * trouble than it is worth to set things up correctly here. + */ + if (mode == _IOLBF) + flags |= __SLBF; + if (flags & __SRW) + flags &= ~(__SRD | __SWR); + fp->_w = 0; + fp->_flags = flags; + fp->_bf._base = fp->_p = (unsigned char *)buf; + fp->_bf._size = size; + fp->_lbfsize = 0; + __cleanup = _cleanup; + + funlockfile(fp); + return (ret); +} diff --git a/lib/libpthread/stdio/snprintf.c b/lib/libpthread/stdio/snprintf.c new file mode 100644 index 000000000000..42b2707bcf57 --- /dev/null +++ b/lib/libpthread/stdio/snprintf.c @@ -0,0 +1,77 @@ +/*- + * 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 = "from: @(#)snprintf.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: snprintf.c,v 1.1 1994/01/30 04:25:42 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#if __STDC__ +snprintf(char *str, size_t n, char const *fmt, ...) +#else +snprintf(str, n, fmt, va_alist) + char *str; + size_t n; + char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + if ((int)n < 1) + return (EOF); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = n - 1; + ret = vfprintf(&f, fmt, ap); + *f._p = 0; + va_end(ap); + return (ret); +} diff --git a/lib/libpthread/stdio/sprintf.c b/lib/libpthread/stdio/sprintf.c new file mode 100644 index 000000000000..9fc34c2d2d04 --- /dev/null +++ b/lib/libpthread/stdio/sprintf.c @@ -0,0 +1,76 @@ +/*- + * 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 = "from: @(#)sprintf.c 5.7 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: sprintf.c,v 1.1 1994/01/30 04:25:43 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include <limits.h> +#include "local.h" + +#if __STDC__ +sprintf(char *str, char const *fmt, ...) +#else +sprintf(str, fmt, va_alist) + char *str; + char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = INT_MAX; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = vfprintf(&f, fmt, ap); + va_end(ap); + *f._p = 0; + return (ret); +} diff --git a/lib/libpthread/stdio/sscanf.c b/lib/libpthread/stdio/sscanf.c new file mode 100644 index 000000000000..14587ae8876a --- /dev/null +++ b/lib/libpthread/stdio/sscanf.c @@ -0,0 +1,78 @@ +/*- + * 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 = "from: @(#)sscanf.c 5.1 (Berkeley) 1/20/91";*/ +static char *rcsid = "$Id: sscanf.c,v 1.1 1994/01/30 04:25:44 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <string.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include "local.h" + +#if __STDC__ +sscanf(const char *str, char const *fmt, ...) +#else +sscanf(str, fmt, va_alist) + const char *str; + char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SRD; + f._file = -1; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._r = strlen(str); + f._ub._base = NULL; + f._lb._base = NULL; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + ret = __svfscanf(&f, fmt, ap); + va_end(ap); + return (ret); +} diff --git a/lib/libpthread/stdio/stdio.c b/lib/libpthread/stdio/stdio.c new file mode 100644 index 000000000000..41f2d2519edc --- /dev/null +++ b/lib/libpthread/stdio/stdio.c @@ -0,0 +1,92 @@ +/*- + * 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 = "from: @(#)stdio.c 5.3 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: stdio.c,v 1.1 1994/01/30 04:25:45 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include "local.h" + +/* + * Small standard I/O/seek/close functions. + * These maintain the `known seek offset' for seek optimisation. + */ +int __sread(FILE *fp, char *buf, int n) +{ + register int ret; + + /* if the read succeeded, update the current offset */ + if ((ret = fd_table[fp->_file]->ops->read(fd_table[fp->_file]->fd, + fd_table[fp->_file]->flags, buf, n)) >= 0) { + fp->_offset += ret; + } else { + fp->_flags &= ~__SOFF; /* paranoia */ + } + return (ret); +} + +int __swrite(FILE *fp, const char *buf, int n) +{ + if (fp->_flags & __SAPP) + (void) lseek(fp->_file, (off_t)0, SEEK_END); + fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */ + return(fd_table[fp->_file]->ops->write(fd_table[fp->_file]->fd, + fd_table[fp->_file]->flags, buf, n)); +} + +fpos_t __sseek(FILE *fp, fpos_t offset, int whence) +{ + register off_t ret; + + ret = lseek(fp->_file, (off_t)offset, whence); + if (ret == -1L) + fp->_flags &= ~__SOFF; + else { + fp->_flags |= __SOFF; + fp->_offset = ret; + } + return (ret); +} + +int __sclose(FILE *fp) +{ + return (close(fp->_file)); +} diff --git a/lib/libpthread/stdio/strerror.c b/lib/libpthread/stdio/strerror.c new file mode 100644 index 000000000000..5aea7e7a4fc4 --- /dev/null +++ b/lib/libpthread/stdio/strerror.c @@ -0,0 +1,67 @@ +/* + * 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[] = "@(#)strerror.c 5.6 (Berkeley) 5/4/91"; +#endif /* LIBC_SCCS and not lint */ + +#include <string.h> + +char * +strerror(num) + int num; +{ + extern int sys_nerr; + extern char *sys_errlist[]; +#define UPREFIX "Unknown error: " + static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ + register unsigned int errnum; + register char *p, *t; + char tmp[40]; + + errnum = num; /* convert to unsigned */ + if (errnum < sys_nerr) + return(sys_errlist[errnum]); + + /* Do this by hand, so we don't include stdio(3). */ + t = tmp; + do { + *t++ = "0123456789"[errnum % 10]; + } while (errnum /= 10); + for (p = ebuf + sizeof(UPREFIX) - 1;;) { + *p++ = *--t; + if (t <= tmp) + break; + } + return(ebuf); +} diff --git a/lib/libpthread/stdio/tempnam.c b/lib/libpthread/stdio/tempnam.c new file mode 100644 index 000000000000..cffdd392aed3 --- /dev/null +++ b/lib/libpthread/stdio/tempnam.c @@ -0,0 +1,87 @@ +/* + * 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 = "from: @(#)tempnam.c 5.1 (Berkeley) 2/22/91";*/ +static char *rcsid = "$Id: tempnam.c,v 1.1 1994/01/30 04:25:47 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <paths.h> + +char * +tempnam(dir, pfx) + const char *dir, *pfx; +{ + int sverrno; + char *f, *name; + + if (!(name = malloc(MAXPATHLEN))) + return(NULL); + + if (!pfx) + pfx = "tmp."; + + if (f = getenv("TMPDIR")) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if (f = mktemp(name)) + return(f); + } + + if (f = (char *)dir) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if (f = mktemp(name)) + return(f); + } + + f = P_tmpdir; + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if (f = mktemp(name)) + return(f); + + f = _PATH_TMP; + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if (f = mktemp(name)) + return(f); + + sverrno = errno; + free(name); + errno = sverrno; + return(NULL); +} diff --git a/lib/libpthread/stdio/tmpfile.c b/lib/libpthread/stdio/tmpfile.c new file mode 100644 index 000000000000..0a5e877711d6 --- /dev/null +++ b/lib/libpthread/stdio/tmpfile.c @@ -0,0 +1,80 @@ +/*- + * 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 = "from: @(#)tmpfile.c 5.4 (Berkeley) 5/27/91";*/ +static char *rcsid = "$Id: tmpfile.c,v 1.1 1994/01/30 04:25:48 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <paths.h> + +FILE * +tmpfile() +{ + sigset_t set, oset; + FILE *fp; + int fd, sverrno; +#define TRAILER "tmp.XXXXXX" + char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)]; + + bcopy(_PATH_TMP, buf, sizeof(_PATH_TMP) - 1); + bcopy(TRAILER, buf + sizeof(_PATH_TMP) - 1, sizeof(TRAILER)); + + sigfillset(&set); + (void)sigprocmask(SIG_BLOCK, &set, &oset); + + fd = mkstemp(buf); + if (fd != -1) + (void)unlink(buf); + + (void)sigprocmask(SIG_SETMASK, &oset, NULL); + + if (fd == -1) + return (NULL); + + if (!(fp = fdopen(fd, "w+"))) { + sverrno = errno; + (void)close(fd); + errno = sverrno; + return (NULL); + } + return (fp); +} diff --git a/lib/libpthread/stdio/tmpnam.c b/lib/libpthread/stdio/tmpnam.c new file mode 100644 index 000000000000..c64c75475e77 --- /dev/null +++ b/lib/libpthread/stdio/tmpnam.c @@ -0,0 +1,55 @@ +/*- + * 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 = "from: @(#)tmpnam.c 5.3 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: tmpnam.c,v 1.1 1994/01/30 04:25:49 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <unistd.h> +#include <stdio.h> + +char * +tmpnam(s) + char *s; +{ + static char buf[L_tmpnam]; + + if (s == NULL) + s = buf; + (void)snprintf(s, L_tmpnam, "%stmp.XXXXXX", P_tmpdir); + return(mktemp(s)); +} diff --git a/lib/libpthread/stdio/ungetc.c b/lib/libpthread/stdio/ungetc.c new file mode 100644 index 000000000000..edf5a9aa9e5f --- /dev/null +++ b/lib/libpthread/stdio/ungetc.c @@ -0,0 +1,154 @@ +/*- + * 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 = "from: @(#)ungetc.c 5.6 (Berkeley) 5/4/91";*/ +static char *rcsid = "$Id: ungetc.c,v 1.1 1994/01/30 04:25:50 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "local.h" + +/* + * Expand the ungetc buffer `in place'. That is, adjust fp->_p when + * the buffer moves, so that it points the same distance from the end, + * and move the bytes in the buffer around as necessary so that they + * are all at the end (stack-style). + */ +static +__submore(fp) + register FILE *fp; +{ + register int i; + register unsigned char *p; + + if (fp->_ub._base == fp->_ubuf) { + /* + * Get a new buffer (rather than expanding the old one). + */ + if ((p = malloc((size_t)BUFSIZ)) == NULL) + return (EOF); + fp->_ub._base = p; + fp->_ub._size = BUFSIZ; + p += BUFSIZ - sizeof(fp->_ubuf); + for (i = sizeof(fp->_ubuf); --i >= 0;) + p[i] = fp->_ubuf[i]; + fp->_p = p; + return (0); + } + i = fp->_ub._size; + p = realloc(fp->_ub._base, i << 1); + if (p == NULL) + return (EOF); + (void) bcopy((void *)p, (void *)(p + i), (size_t)i); + fp->_p = p + i; + fp->_ub._base = p; + fp->_ub._size = i << 1; + return (0); +} + +ungetc(c, fp) + int c; + register FILE *fp; +{ + if (c == EOF) + return (EOF); + pthread_once(&__sdidinit, __sinit); + + flockfile(fp); + if ((fp->_flags & __SRD) == 0) { + /* + * Not already reading: no good unless reading-and-writing. + * Otherwise, flush any current write stuff. + */ + if ((fp->_flags & __SRW) == 0) + c = EOF; + goto ungetc_end; + if (fp->_flags & __SWR) { + if (__sflush(fp)) + c = EOF; + goto ungetc_end; + fp->_flags &= ~__SWR; + fp->_w = 0; + fp->_lbfsize = 0; + } + fp->_flags |= __SRD; + } + c = (unsigned char)c; + + /* + * If we are in the middle of ungetc'ing, just continue. + * This may require expanding the current ungetc buffer. + */ + if (HASUB(fp)) { + if (fp->_r >= fp->_ub._size && __submore(fp)) + return (EOF); + *--fp->_p = c; + fp->_r++; + goto ungetc_end; + } + + /* + * If we can handle this by simply backing up, do so, + * but never replace the original character. + * (This makes sscanf() work when scanning `const' data.) + */ + if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && + fp->_p[-1] == c) { + fp->_p--; + fp->_r++; + goto ungetc_end; + } + + /* + * Create an ungetc buffer. + * Initially, we will use the `reserve' buffer. + */ + fp->_ur = fp->_r; + fp->_up = fp->_p; + fp->_ub._base = fp->_ubuf; + fp->_ub._size = sizeof(fp->_ubuf); + fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; + fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; + fp->_r = 1; + +ungetc_end:; + funlockfile(fp); + return (c); +} diff --git a/lib/libpthread/stdio/vfprintf.c b/lib/libpthread/stdio/vfprintf.c new file mode 100644 index 000000000000..8b3d29e74e30 --- /dev/null +++ b/lib/libpthread/stdio/vfprintf.c @@ -0,0 +1,774 @@ +/*- + * 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 = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ +static char *rcsid = "$Id: vfprintf.c,v 1.1 1994/01/30 04:25:51 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Actual printf innards. + * + * This code is large and complicated... + */ + +#include <pthread.h> +#include <sys/types.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "local.h" +#include "fvwrite.h" + +/* Define FLOATING_POINT to get floating point. */ +#define FLOATING_POINT + +/* + * Flush out all the vectors defined by the given uio, + * then reset it so that it can be reused. + */ +static int +__sprint(fp, uio) + register FILE* fp; + register struct __suio *uio; +{ + register int err; + + if (uio->uio_resid == 0) { + uio->uio_iovcnt = 0; + return (0); + } + err = __sfvwrite(fp, uio); + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return (err); +} + +/* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids + * worries about ungetc buffers and so forth. + */ +static int +__sbprintf(fp, fmt, ap) + FILE *fp; + const char *fmt; + va_list ap; +{ + unsigned char buf[BUFSIZ]; + FILE fake; + int ret; + + /* copy the important variables */ + fake._flags = fp->_flags & ~__SNBF; + fake._file = fp->_file; + + /* set up the buffer */ + fake._bf._base = fake._p = buf; + fake._bf._size = fake._w = sizeof(buf); + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ + ret = vfprintf(&fake, fmt, ap); + if (ret >= 0 && fflush(&fake)) + ret = EOF; + if (fake._flags & __SERR) + fp->_flags |= __SERR; + return (ret); +} + + +#ifdef FLOATING_POINT +#include <locale.h> +#include <math.h> +#include "floatio.h" + +#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ +#define DEFPREC 6 + +static char *cvt __P((double, int, int, char *, int *, int, int *)); +static int exponent __P((char *, int, int)); + +#else /* no FLOATING_POINT */ + +#define BUF 40 + +#endif /* FLOATING_POINT */ + + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_digit(c) ((c) - '0') +#define is_digit(c) ((unsigned)to_digit(c) <= 9) +#define to_char(n) ((n) + '0') + +/* + * Flags used during conversion. + */ +#define ALT 0x001 /* alternate form */ +#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ +#define LADJUST 0x004 /* left adjustment */ +#define LONGDBL 0x008 /* long double; unimplemented */ +#define LONGINT 0x010 /* long integer */ +#define QUADINT 0x020 /* quad integer */ +#define SHORTINT 0x040 /* short integer */ +#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ +#define FPT 0x100 /* Floating point number */ +int +vfprintf(fp, fmt0, ap) + FILE *fp; + const char *fmt0; + va_list ap; +{ + register char *fmt; /* format string */ + register int ch; /* character from fmt */ + register int n; /* handy integer (short term usage) */ + register char *cp; /* handy char pointer (short term usage) */ + register struct __siov *iovp;/* for PRINT macro */ + register int flags; /* flags as above */ + int ret; /* return value accumulator */ + int width; /* width from format (%8d), or 0 */ + int prec; /* precision from format (%.3d), or -1 */ + char sign; /* sign prefix (' ', '+', '-', or \0) */ +#ifdef FLOATING_POINT + char softsign; /* temporary negative sign for floats */ + double _double; /* double precision arguments %[eEfgG] */ + int expt; /* integer value of exponent */ + int expsize; /* character count for expstr */ + int ndig; /* actual number of digits returned by cvt */ + char expstr[7]; /* buffer for exponent string */ +#endif + +#ifdef __GNUC__ /* gcc has builtin quad type (long long) SOS */ +#define quad_t long long +#define u_quad_t unsigned long long +#endif + + u_quad_t _uquad; /* integer arguments %[diouxX] */ + enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ + int dprec; /* a copy of prec if [diouxX], 0 otherwise */ + int fieldsz; /* field size expanded by sign, etc */ + int realsz; /* field size expanded by dprec */ + int size; /* size of converted field or string */ + char *xdigs; /* digits for [xX] conversion */ +#define NIOV 8 + struct __suio uio; /* output information: summary */ + struct __siov iov[NIOV];/* ... and individual io vectors */ + char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ + char ox[2]; /* space for 0x hex-prefix */ + + /* + * Choose PADSIZE to trade efficiency vs. size. If larger printf + * fields occur frequently, increase PADSIZE and make the initialisers + * below longer. + */ +#define PADSIZE 16 /* pad chunk size */ + static char blanks[PADSIZE] = + {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; + static char zeroes[PADSIZE] = + {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + + /* + * BEWARE, these `goto error' on error, and PAD uses `n'. + */ +#define PRINT(ptr, len) { \ + iovp->iov_base = (ptr); \ + iovp->iov_len = (len); \ + uio.uio_resid += (len); \ + iovp++; \ + if (++uio.uio_iovcnt >= NIOV) { \ + if (__sprint(fp, &uio)) \ + goto error; \ + iovp = iov; \ + } \ +} +#define PAD(howmany, with) { \ + if ((n = (howmany)) > 0) { \ + while (n > PADSIZE) { \ + PRINT(with, PADSIZE); \ + n -= PADSIZE; \ + } \ + PRINT(with, n); \ + } \ +} +#define FLUSH() { \ + if (uio.uio_resid && __sprint(fp, &uio)) \ + goto error; \ + uio.uio_iovcnt = 0; \ + iovp = iov; \ +} + + /* + * To extend shorts properly, we need both signed and unsigned + * argument extraction methods. + */ +#define SARG() \ + (flags&QUADINT ? va_arg(ap, quad_t) : \ + flags&LONGINT ? va_arg(ap, long) : \ + flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ + (long)va_arg(ap, int)) +#define UARG() \ + (flags&QUADINT ? va_arg(ap, u_quad_t) : \ + flags&LONGINT ? va_arg(ap, u_long) : \ + flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ + (u_long)va_arg(ap, u_int)) + + flockfile(fp); + + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ + if (cantwrite(fp)) + return (EOF); + + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) { + ret = (__sbprintf(fp, fmt0, ap)); + funlockfile(fp); + return(ret); + } + + fmt = (char *)fmt0; + uio.uio_iov = iovp = iov; + uio.uio_resid = 0; + uio.uio_iovcnt = 0; + ret = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) + /* void */; + if ((n = fmt - cp) != 0) { + PRINT(cp, n); + ret += n; + } + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + dprec = 0; + width = 0; + prec = -1; + sign = '\0'; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + /* + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (!sign) + sign = ' '; + goto rflag; + case '#': + flags |= ALT; + goto rflag; + case '*': + /* + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + if ((width = va_arg(ap, int)) >= 0) + goto rflag; + width = -width; + /* FALLTHROUGH */ + case '-': + flags |= LADJUST; + goto rflag; + case '+': + sign = '+'; + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + n = va_arg(ap, int); + prec = n < 0 ? -1 : n; + goto rflag; + } + n = 0; + while (is_digit(ch)) { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } + prec = n < 0 ? -1 : n; + goto reswitch; + case '0': + /* + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flags |= ZEROPAD; + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + width = n; + goto reswitch; +#ifdef FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + flags |= SHORTINT; + goto rflag; + case 'l': + flags |= LONGINT; + goto rflag; + case 'q': + flags |= QUADINT; + goto rflag; + case 'c': + *(cp = buf) = va_arg(ap, int); + size = 1; + sign = '\0'; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + _uquad = SARG(); + if ((quad_t)_uquad < 0) { + _uquad = -_uquad; + sign = '-'; + } + base = DEC; + goto number; +#ifdef FLOATING_POINT + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (prec == -1) { + prec = DEFPREC; + } else if ((ch == 'g' || ch == 'G') && prec == 0) { + prec = 1; + } + + if (flags & LONGDBL) { + _double = (double) va_arg(ap, long double); + } else { + _double = va_arg(ap, double); + } + + /* do this before tricky precision changes */ + if (isinf(_double)) { + if (_double < 0) + sign = '-'; + cp = "Inf"; + size = 3; + break; + } + if (isnan(_double)) { + cp = "NaN"; + size = 3; + break; + } + + flags |= FPT; + cp = cvt(_double, prec, flags, &softsign, + &expt, ch, &ndig); + if (ch == 'g' || ch == 'G') { + if (expt <= -4 || expt > prec) + ch = (ch == 'g') ? 'e' : 'E'; + else + ch = 'g'; + } + if (ch <= 'e') { /* 'e' or 'E' fmt */ + --expt; + expsize = exponent(expstr, expt, ch); + size = expsize + ndig; + if (ndig > 1 || flags & ALT) + ++size; + } else if (ch == 'f') { /* f fmt */ + if (expt > 0) { + size = expt; + if (prec || flags & ALT) + size += prec + 1; + } else /* "0.X" */ + size = prec + 2; + } else if (expt >= ndig) { /* fixed g fmt */ + size = expt; + if (flags & ALT) + ++size; + } else + size = ndig + (expt > 0 ? + 1 : 2 - expt); + + if (softsign) + sign = '-'; + break; +#endif /* FLOATING_POINT */ + case 'n': + if (flags & QUADINT) + *va_arg(ap, quad_t *) = ret; + else if (flags & LONGINT) + *va_arg(ap, long *) = ret; + else if (flags & SHORTINT) + *va_arg(ap, short *) = ret; + else + *va_arg(ap, int *) = ret; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + _uquad = UARG(); + base = OCT; + goto nosign; + case 'p': + /* + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ + /* NOSTRICT */ + _uquad = (u_quad_t)va_arg(ap, void *); + base = HEX; + xdigs = "0123456789abcdef"; + flags |= HEXPREFIX; + ch = 'x'; + goto nosign; + case 's': + if ((cp = va_arg(ap, char *)) == NULL) + cp = "(null)"; + if (prec >= 0) { + /* + * can't use strlen; can only look for the + * NUL in the first `prec' characters, and + * strlen() will go further. + */ + char *p = memchr(cp, 0, prec); + + if (p != NULL) { + size = p - cp; + if (size > prec) + size = prec; + } else + size = prec; + } else + size = strlen(cp); + sign = '\0'; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + _uquad = UARG(); + base = DEC; + goto nosign; + case 'X': + xdigs = "0123456789ABCDEF"; + goto hex; + case 'x': + xdigs = "0123456789abcdef"; +hex: _uquad = UARG(); + base = HEX; + /* leading 0x/X only if non-zero */ + if (flags & ALT && _uquad != 0) + flags |= HEXPREFIX; + + /* unsigned conversions */ +nosign: sign = '\0'; + /* + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ +number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + /* + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + */ + cp = buf + BUF; + if (_uquad != 0 || prec != 0) { + /* + * Unsigned mod is hard, and unsigned mod + * by a constant is easier than that by + * a variable; hence this switch. + */ + switch (base) { + case OCT: + do { + *--cp = to_char(_uquad & 7); + _uquad >>= 3; + } while (_uquad); + /* handle octal leading 0 */ + if (flags & ALT && *cp != '0') + *--cp = '0'; + break; + + case DEC: + /* many numbers are 1 digit */ + while (_uquad >= 10) { + *--cp = to_char(_uquad % 10); + _uquad /= 10; + } + *--cp = to_char(_uquad); + break; + + case HEX: + do { + *--cp = xdigs[_uquad & 15]; + _uquad >>= 4; + } while (_uquad); + break; + + default: + cp = "bug in vfprintf: bad base"; + size = strlen(cp); + goto skipsize; + } + } + size = buf + BUF - cp; + skipsize: + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + /* pretend it was %c with argument ch */ + cp = buf; + *cp = ch; + size = 1; + sign = '\0'; + break; + } + + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be + * padded out to `width' places. If flags&ZEROPAD, it should + * first be prefixed by any sign or other prefix; otherwise, + * it should be blank padded before the prefix is emitted. + * After any left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print the + * string proper, then emit zeroes required by any leftover + * floating precision; finally, if LADJUST, pad with blanks. + * + * Compute actual size, so we know how much to pad. + * fieldsz excludes decimal prec; realsz includes it. + */ + fieldsz = size; + if (sign) + fieldsz++; + else if (flags & HEXPREFIX) + fieldsz += 2; + realsz = dprec > fieldsz ? dprec : fieldsz; + + /* right-adjusting blank padding */ + if ((flags & (LADJUST|ZEROPAD)) == 0) + PAD(width - realsz, blanks); + + /* prefix */ + if (sign) { + PRINT(&sign, 1); + } else if (flags & HEXPREFIX) { + ox[0] = '0'; + ox[1] = ch; + PRINT(ox, 2); + } + + /* right-adjusting zero padding */ + if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) + PAD(width - realsz, zeroes); + + /* leading zeroes from decimal precision */ + PAD(dprec - fieldsz, zeroes); + + /* the string or number proper */ +#ifdef FLOATING_POINT + if ((flags & FPT) == 0) { + PRINT(cp, size); + } else { /* glue together f_p fragments */ + if (ch >= 'f') { /* 'f' or 'g' */ + if (_double == 0) { + /* kludge for __dtoa irregularity */ + if (expt >= ndig && (flags & ALT) == 0) { + PRINT("0", 1); + } else { + PRINT("0.", 2); + PAD(ndig - 1, zeroes); + } + } else if (expt <= 0) { + PRINT("0.", 2); + PAD(-expt, zeroes); + PRINT(cp, ndig); + } else if (expt >= ndig) { + PRINT(cp, ndig); + PAD(expt - ndig, zeroes); + if (flags & ALT) + PRINT(".", 1); + } else { + PRINT(cp, expt); + cp += expt; + PRINT(".", 1); + PRINT(cp, ndig-expt); + } + } else { /* 'e' or 'E' */ + if (ndig > 1 || flags & ALT) { + ox[0] = *cp++; + ox[1] = '.'; + PRINT(ox, 2); + if (_double || flags & ALT == 0) { + PRINT(cp, ndig-1); + } else /* 0.[0..] */ + /* __dtoa irregularity */ + PAD(ndig - 1, zeroes); + } else /* XeYYY */ + PRINT(cp, 1); + PRINT(expstr, expsize); + } + } +#else + PRINT(cp, size); +#endif + /* left-adjusting padding (always blank) */ + if (flags & LADJUST) + PAD(width - realsz, blanks); + + /* finally, adjust ret */ + ret += width > realsz ? width : realsz; + + FLUSH(); /* copy out the I/O vectors */ + } +done: + FLUSH(); +error: + if (__sferror(fp)) + ret = EOF; + funlockfile(fp); + return (ret); +} + +#ifdef FLOATING_POINT + +extern char *__dtoa __P((double, int, int, int *, int *, char **)); + +static char * +cvt(value, ndigits, flags, sign, decpt, ch, length) + double value; + int ndigits, flags, *decpt, ch, *length; + char *sign; +{ + int mode, dsgn; + char *digits, *bp, *rve; + + if (ch == 'f') { + mode = 3; /* ndigits after the decimal point */ + } else { + /* To obtain ndigits after the decimal point for the 'e' + * and 'E' formats, round to ndigits + 1 significant + * figures. + */ + if (ch == 'e' || ch == 'E') { + ndigits++; + } + mode = 2; /* ndigits significant digits */ + } + + if (value < 0) { + value = -value; + *sign = '-'; + } else + *sign = '\000'; + digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); + if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ + bp = digits + ndigits; + if (ch == 'f') { + if (*digits == '0' && value) + *decpt = -ndigits + 1; + bp += *decpt; + } + if (value == 0) /* kludge for __dtoa irregularity */ + rve = bp; + while (rve < bp) + *rve++ = '0'; + } + *length = rve - digits; + return (digits); +} + +static int +exponent(p0, exp, fmtch) + char *p0; + int exp, fmtch; +{ + register char *p, *t; + char expbuf[MAXEXP]; + + p = p0; + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAXEXP; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAXEXP; *p++ = *t++); + } + else { + *p++ = '0'; + *p++ = to_char(exp); + } + return (p - p0); +} +#endif /* FLOATING_POINT */ diff --git a/lib/libpthread/stdio/vfscanf.c b/lib/libpthread/stdio/vfscanf.c new file mode 100644 index 000000000000..bebfd63e75af --- /dev/null +++ b/lib/libpthread/stdio/vfscanf.c @@ -0,0 +1,749 @@ +/*- + * 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 = "from: @(#)vfscanf.c 5.7 (Berkeley) 12/14/92";*/ +static char *rcsid = "$Id: vfscanf.c,v 1.1 1994/01/30 04:25:53 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include "local.h" + +#define FLOATING_POINT + +#include "floatio.h" +#define BUF 513 /* Maximum length of numeric string. */ + +/* + * Flags used during conversion. + */ +#define LONG 0x01 /* l: long or double */ +#define LONGDBL 0x02 /* L: long double; unimplemented */ +#define SHORT 0x04 /* h: short */ +#define SUPPRESS 0x08 /* suppress assignment */ +#define POINTER 0x10 /* weird %p pointer (`fake hex') */ +#define NOSKIP 0x20 /* do not skip blanks */ + +/* + * The following are used in numeric conversions only: + * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; + * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. + */ +#define SIGNOK 0x40 /* +/- is (still) legal */ +#define NDIGITS 0x80 /* no digits detected */ + +#define DPTOK 0x100 /* (float) decimal point is still legal */ +#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ + +#define PFXOK 0x100 /* 0x prefix is (still) legal */ +#define NZDIGITS 0x200 /* no zero digits detected */ + +/* + * Conversion types. + */ +#define CT_CHAR 0 /* %c conversion */ +#define CT_CCL 1 /* %[...] conversion */ +#define CT_STRING 2 /* %s conversion */ +#define CT_INT 3 /* integer, i.e., strtol or strtoul */ +#define CT_FLOAT 4 /* floating, i.e., strtod */ + +#define u_char unsigned char +#define u_long unsigned long + +static u_char *__sccl(); + +/* + * vfscanf + */ +__svfscanf(fp, fmt0, ap) + register FILE *fp; + char const *fmt0; + va_list ap; +{ + register u_char *fmt = (u_char *)fmt0; + register int c; /* character from format, or conversion */ + register size_t width; /* field width, or 0 */ + register char *p; /* points into all kinds of strings */ + register int n; /* handy integer */ + register int flags; /* flags as defined above */ + register char *p0; /* saves original value of p when necessary */ + int nassigned; /* number of fields assigned */ + int nread; /* number of characters consumed from fp */ + int base; /* base argument to strtol/strtoul */ + u_long (*ccfn)(); /* conversion function (strtol/strtoul) */ + char ccltab[256]; /* character class table for %[...] */ + char buf[BUF]; /* buffer for numeric conversions */ + + /* `basefix' is used to avoid `if' tests in the integer scanner */ + static short basefix[17] = + { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + nassigned = 0; + nread = 0; + base = 0; /* XXX just to keep gcc happy */ + ccfn = NULL; /* XXX just to keep gcc happy */ + for (;;) { + c = *fmt++; + if (c == 0) + return (nassigned); + if (isspace(c)) { + for (;;) { + if (fp->_r <= 0 && __srefill(fp)) + return (nassigned); + if (!isspace(*fp->_p)) + break; + nread++, fp->_r--, fp->_p++; + } + continue; + } + if (c != '%') + goto literal; + width = 0; + flags = 0; + /* + * switch on the format. continue if done; + * break once format type is derived. + */ +again: c = *fmt++; + switch (c) { + case '%': +literal: + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + if (*fp->_p != c) + goto match_failure; + fp->_r--, fp->_p++; + nread++; + continue; + + case '*': + flags |= SUPPRESS; + goto again; + case 'l': + flags |= LONG; + goto again; + case 'L': + flags |= LONGDBL; + goto again; + case 'h': + flags |= SHORT; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + width = width * 10 + c - '0'; + goto again; + + /* + * Conversions. + * Those marked `compat' are for 4.[123]BSD compatibility. + * + * (According to ANSI, E and X formats are supposed + * to the same as e and x. Sorry about that.) + */ + case 'D': /* compat */ + flags |= LONG; + /* FALLTHROUGH */ + case 'd': + c = CT_INT; + ccfn = (u_long (*)())strtol; + base = 10; + break; + + case 'i': + c = CT_INT; + ccfn = (u_long (*)())strtol; + base = 0; + break; + + case 'O': /* compat */ + flags |= LONG; + /* FALLTHROUGH */ + case 'o': + c = CT_INT; + ccfn = strtoul; + base = 8; + break; + + case 'u': + c = CT_INT; + ccfn = strtoul; + base = 10; + break; + + case 'X': /* compat XXX */ + flags |= LONG; + /* FALLTHROUGH */ + case 'x': + flags |= PFXOK; /* enable 0x prefixing */ + c = CT_INT; + ccfn = strtoul; + base = 16; + break; + +#ifdef FLOATING_POINT + case 'E': /* compat XXX */ + case 'F': /* compat */ + flags |= LONG; + /* FALLTHROUGH */ + case 'e': case 'f': case 'g': + c = CT_FLOAT; + break; +#endif + + case 's': + c = CT_STRING; + break; + + case '[': + fmt = __sccl(ccltab, fmt); + flags |= NOSKIP; + c = CT_CCL; + break; + + case 'c': + flags |= NOSKIP; + c = CT_CHAR; + break; + + case 'p': /* pointer format is like hex */ + flags |= POINTER | PFXOK; + c = CT_INT; + ccfn = strtoul; + base = 16; + break; + + case 'n': + if (flags & SUPPRESS) /* ??? */ + continue; + if (flags & SHORT) + *va_arg(ap, short *) = nread; + else if (flags & LONG) + *va_arg(ap, long *) = nread; + else + *va_arg(ap, int *) = nread; + continue; + + /* + * Disgusting backwards compatibility hacks. XXX + */ + case '\0': /* compat */ + return (EOF); + + default: /* compat */ + if (isupper(c)) + flags |= LONG; + c = CT_INT; + ccfn = (u_long (*)())strtol; + base = 10; + break; + } + + /* + * We have a conversion that requires input. + */ + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + + /* + * Consume leading white space, except for formats + * that suppress this. + */ + if ((flags & NOSKIP) == 0) { + while (isspace(*fp->_p)) { + nread++; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + goto input_failure; + } + /* + * Note that there is at least one character in + * the buffer, so conversions that do not set NOSKIP + * ca no longer result in an input failure. + */ + } + + /* + * Do the conversion. + */ + switch (c) { + + case CT_CHAR: + /* scan arbitrary characters (sets NOSKIP) */ + if (width == 0) + width = 1; + if (flags & SUPPRESS) { + size_t sum = 0; + for (;;) { + if ((n = fp->_r) < width) { + sum += n; + width -= n; + fp->_p += n; + if (__srefill(fp)) { + if (sum == 0) + goto input_failure; + break; + } + } else { + sum += width; + fp->_r -= width; + fp->_p += width; + break; + } + } + nread += sum; + } else { + size_t r = fread((void *)va_arg(ap, char *), 1, + width, fp); + + if (r == 0) + goto input_failure; + nread += r; + nassigned++; + } + break; + + case CT_CCL: + /* scan a (nonempty) character class (sets NOSKIP) */ + if (width == 0) + width = ~0; /* `infinity' */ + /* take only those things in the class */ + if (flags & SUPPRESS) { + n = 0; + while (ccltab[*fp->_p]) { + n++, fp->_r--, fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) { + if (n == 0) + goto input_failure; + break; + } + } + if (n == 0) + goto match_failure; + } else { + p0 = p = va_arg(ap, char *); + while (ccltab[*fp->_p]) { + fp->_r--; + *p++ = *fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) { + if (p == p0) + goto input_failure; + break; + } + } + n = p - p0; + if (n == 0) + goto match_failure; + *p = 0; + nassigned++; + } + nread += n; + break; + + case CT_STRING: + /* like CCL, but zero-length string OK, & no NOSKIP */ + if (width == 0) + width = ~0; + if (flags & SUPPRESS) { + n = 0; + while (!isspace(*fp->_p)) { + n++, fp->_r--, fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) + break; + } + nread += n; + } else { + p0 = p = va_arg(ap, char *); + while (!isspace(*fp->_p)) { + fp->_r--; + *p++ = *fp->_p++; + if (--width == 0) + break; + if (fp->_r <= 0 && __srefill(fp)) + break; + } + *p = 0; + nread += p - p0; + nassigned++; + } + continue; + + case CT_INT: + /* scan an integer as if by strtol/strtoul */ +#ifdef hardway + if (width == 0 || width > sizeof(buf) - 1) + width = sizeof(buf) - 1; +#else + /* size_t is unsigned, hence this optimisation */ + if (--width > sizeof(buf) - 2) + width = sizeof(buf) - 2; + width++; +#endif + flags |= SIGNOK | NDIGITS | NZDIGITS; + for (p = buf; width; width--) { + c = *fp->_p; + /* + * Switch on the character; `goto ok' + * if we accept it as a part of number. + */ + switch (c) { + + /* + * The digit 0 is always legal, but is + * special. For %i conversions, if no + * digits (zero or nonzero) have been + * scanned (only signs), we will have + * base==0. In that case, we should set + * it to 8 and enable 0x prefixing. + * Also, if we have not scanned zero digits + * before this, do not turn off prefixing + * (someone else will turn it off if we + * have scanned any nonzero digits). + */ + case '0': + if (base == 0) { + base = 8; + flags |= PFXOK; + } + if (flags & NZDIGITS) + flags &= ~(SIGNOK|NZDIGITS|NDIGITS); + else + flags &= ~(SIGNOK|PFXOK|NDIGITS); + goto ok; + + /* 1 through 7 always legal */ + case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + base = basefix[base]; + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* digits 8 and 9 ok iff decimal or hex */ + case '8': case '9': + base = basefix[base]; + if (base <= 8) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* letters ok iff hex */ + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + /* no need to fix base here */ + if (base <= 10) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* sign ok only as first character */ + case '+': case '-': + if (flags & SIGNOK) { + flags &= ~SIGNOK; + goto ok; + } + break; + + /* x ok iff flag still set & 2nd char */ + case 'x': case 'X': + if (flags & PFXOK && p == buf + 1) { + base = 16; /* if %i */ + flags &= ~PFXOK; + goto ok; + } + break; + } + + /* + * If we got here, c is not a legal character + * for a number. Stop accumulating digits. + */ + break; + ok: + /* + * c is legal: store it and look at the next. + */ + *p++ = c; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + break; /* EOF */ + } + /* + * If we had only a sign, it is no good; push + * back the sign. If the number ends in `x', + * it was [sign] '0' 'x', so push back the x + * and treat it as [sign] '0'. + */ + if (flags & NDIGITS) { + if (p > buf) + (void) ungetc(*(u_char *)--p, fp); + goto match_failure; + } + c = ((u_char *)p)[-1]; + if (c == 'x' || c == 'X') { + --p; + (void) ungetc(c, fp); + } + if ((flags & SUPPRESS) == 0) { + u_long res; + + *p = 0; + res = (*ccfn)(buf, (char **)NULL, base); + if (flags & POINTER) + *va_arg(ap, void **) = (void *)res; + else if (flags & SHORT) + *va_arg(ap, short *) = res; + else if (flags & LONG) + *va_arg(ap, long *) = res; + else + *va_arg(ap, int *) = res; + nassigned++; + } + nread += p - buf; + break; + +#ifdef FLOATING_POINT + case CT_FLOAT: + /* scan a floating point number as if by strtod */ +#ifdef hardway + if (width == 0 || width > sizeof(buf) - 1) + width = sizeof(buf) - 1; +#else + /* size_t is unsigned, hence this optimisation */ + if (--width > sizeof(buf) - 2) + width = sizeof(buf) - 2; + width++; +#endif + flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; + for (p = buf; width; width--) { + c = *fp->_p; + /* + * This code mimicks the integer conversion + * code, but is much simpler. + */ + switch (c) { + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + flags &= ~(SIGNOK | NDIGITS); + goto fok; + + case '+': case '-': + if (flags & SIGNOK) { + flags &= ~SIGNOK; + goto fok; + } + break; + case '.': + if (flags & DPTOK) { + flags &= ~(SIGNOK | DPTOK); + goto fok; + } + break; + case 'e': case 'E': + /* no exponent without some digits */ + if ((flags&(NDIGITS|EXPOK)) == EXPOK) { + flags = + (flags & ~(EXPOK|DPTOK)) | + SIGNOK | NDIGITS; + goto fok; + } + break; + } + break; + fok: + *p++ = c; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill(fp)) + break; /* EOF */ + } + /* + * If no digits, might be missing exponent digits + * (just give back the exponent) or might be missing + * regular digits, but had sign and/or decimal point. + */ + if (flags & NDIGITS) { + if (flags & EXPOK) { + /* no digits at all */ + while (p > buf) + ungetc(*(u_char *)--p, fp); + goto match_failure; + } + /* just a bad exponent (e and maybe sign) */ + c = *(u_char *)--p; + if (c != 'e' && c != 'E') { + (void) ungetc(c, fp);/* sign */ + c = *(u_char *)--p; + } + (void) ungetc(c, fp); + } + if ((flags & SUPPRESS) == 0) { + double res; + + *p = 0; + res = strtod(buf, (char **) NULL); + if (flags & LONG) + *va_arg(ap, double *) = res; + else + *va_arg(ap, float *) = res; + nassigned++; + } + nread += p - buf; + break; +#endif /* FLOATING_POINT */ + } + } +input_failure: + return (nassigned ? nassigned : -1); +match_failure: + return (nassigned); +} + +/* + * Fill in the given table from the scanset at the given format + * (just after `['). Return a pointer to the character past the + * closing `]'. The table has a 1 wherever characters should be + * considered part of the scanset. + */ +static u_char * +__sccl(tab, fmt) + register char *tab; + register u_char *fmt; +{ + register int c, n, v; + + /* first `clear' the whole table */ + c = *fmt++; /* first char hat => negated scanset */ + if (c == '^') { + v = 1; /* default => accept */ + c = *fmt++; /* get new first char */ + } else + v = 0; /* default => reject */ + /* should probably use memset here */ + for (n = 0; n < 256; n++) + tab[n] = v; + if (c == 0) + return (fmt - 1);/* format ended before closing ] */ + + /* + * Now set the entries corresponding to the actual scanset + * to the opposite of the above. + * + * The first character may be ']' (or '-') without being special; + * the last character may be '-'. + */ + v = 1 - v; + for (;;) { + tab[c] = v; /* take character c */ +doswitch: + n = *fmt++; /* and examine the next */ + switch (n) { + + case 0: /* format ended too soon */ + return (fmt - 1); + + case '-': + /* + * A scanset of the form + * [01+-] + * is defined as `the digit 0, the digit 1, + * the character +, the character -', but + * the effect of a scanset such as + * [a-zA-Z0-9] + * is implementation defined. The V7 Unix + * scanf treats `a-z' as `the letters a through + * z', but treats `a-a' as `the letter a, the + * character -, and the letter a'. + * + * For compatibility, the `-' is not considerd + * to define a range if the character following + * it is either a close bracket (required by ANSI) + * or is not numerically greater than the character + * we just stored in the table (c). + */ + n = *fmt; + if (n == ']' || n < c) { + c = '-'; + break; /* resume the for(;;) */ + } + fmt++; + do { /* fill in the range */ + tab[++c] = v; + } while (c < n); +#if 1 /* XXX another disgusting compatibility hack */ + /* + * Alas, the V7 Unix scanf also treats formats + * such as [a-c-e] as `the letters a through e'. + * This too is permitted by the standard.... + */ + goto doswitch; +#else + c = *fmt++; + if (c == 0) + return (fmt - 1); + if (c == ']') + return (fmt); +#endif + break; + + case ']': /* end of scanset */ + return (fmt); + + default: /* just another character */ + c = n; + break; + } + } + /* NOTREACHED */ +} diff --git a/lib/libpthread/stdio/vprintf.c b/lib/libpthread/stdio/vprintf.c new file mode 100644 index 000000000000..ba0881b28cde --- /dev/null +++ b/lib/libpthread/stdio/vprintf.c @@ -0,0 +1,49 @@ +/*- + * 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 = "from: @(#)vprintf.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: vprintf.c,v 1.1 1994/01/30 04:25:53 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +vprintf(fmt, ap) + char const *fmt; + va_list ap; +{ + return (vfprintf(stdout, fmt, ap)); +} diff --git a/lib/libpthread/stdio/vscanf.c b/lib/libpthread/stdio/vscanf.c new file mode 100644 index 000000000000..6ffeee421358 --- /dev/null +++ b/lib/libpthread/stdio/vscanf.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Donn Seeley at UUNET Technologies, Inc. + * + * 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 = "from: @(#)vscanf.c 5.1 (Berkeley) 4/15/91";*/ +static char *rcsid = "$Id: vscanf.c,v 1.1 1994/01/30 04:25:55 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +vscanf(fmt, ap) + const char *fmt; + va_list ap; +{ + int r; + flockfile(stdin); + r = __svfscanf(stdin, fmt, ap); + funlockfile(stdin); + return(r); +} diff --git a/lib/libpthread/stdio/vsnprintf.c b/lib/libpthread/stdio/vsnprintf.c new file mode 100644 index 000000000000..f9504d15d602 --- /dev/null +++ b/lib/libpthread/stdio/vsnprintf.c @@ -0,0 +1,61 @@ +/*- + * 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 = "from: @(#)vsnprintf.c 5.2 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: vsnprintf.c,v 1.1 1994/01/30 04:25:56 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + const char *fmt; + va_list ap; +{ + int ret; + FILE f; + + if ((int)n < 1) + return (EOF); + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = n - 1; + ret = vfprintf(&f, fmt, ap); + *f._p = 0; + return (ret); +} diff --git a/lib/libpthread/stdio/vsprintf.c b/lib/libpthread/stdio/vsprintf.c new file mode 100644 index 000000000000..135ba3e22d18 --- /dev/null +++ b/lib/libpthread/stdio/vsprintf.c @@ -0,0 +1,59 @@ +/*- + * 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 = "from: @(#)vsprintf.c 5.5 (Berkeley) 2/5/91";*/ +static char *rcsid = "$Id: vsprintf.c,v 1.1 1994/01/30 04:25:57 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <limits.h> + +vsprintf(str, fmt, ap) + char *str; + const char *fmt; + va_list ap; +{ + int ret; + FILE f; + + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = INT_MAX; + ret = vfprintf(&f, fmt, ap); + *f._p = 0; + return (ret); +} diff --git a/lib/libpthread/stdio/vsscanf.c b/lib/libpthread/stdio/vsscanf.c new file mode 100644 index 000000000000..1b29143d27fa --- /dev/null +++ b/lib/libpthread/stdio/vsscanf.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Donn Seeley at UUNET Technologies, Inc. + * + * 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 = "from: @(#)vsscanf.c 5.1 (Berkeley) 4/15/91";*/ +static char *rcsid = "$Id: vsscanf.c,v 1.1 1994/01/30 04:25:57 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <string.h> + +vsscanf(str, fmt, ap) + const char *str; + const char *fmt; + va_list ap; +{ + int ret; + FILE f; + + f._flags = __SRD; + f._file = -1; /* This will do the right thing */ + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._r = strlen(str); + f._ub._base = NULL; + f._lb._base = NULL; + return (__svfscanf(&f, fmt, ap)); +} diff --git a/lib/libpthread/stdio/wbuf.c b/lib/libpthread/stdio/wbuf.c new file mode 100644 index 000000000000..63d8f9e3648c --- /dev/null +++ b/lib/libpthread/stdio/wbuf.c @@ -0,0 +1,88 @@ +/*- + * 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[] = "@(#)wbuf.c 5.6 (Berkeley) 1/20/91"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include "local.h" + +/* + * Write the given character into the (probably full) buffer for + * the given file. Flush the buffer out if it is or becomes full, + * or if c=='\n' and the file is line buffered. + */ +__swbuf(c, fp) + register int c; + register FILE *fp; +{ + register int n; + + /* + * In case we cannot write, or longjmp takes us out early, + * make sure _w is 0 (if fully- or un-buffered) or -_bf._size + * (if line buffered) so that we will get called again. + * If we did not do this, a sufficient number of putc() + * calls might wrap _w from negative to positive. + */ + fp->_w = fp->_lbfsize; + if (cantwrite(fp)) + return (EOF); + c = (unsigned char)c; + + /* + * If it is completely full, flush it out. Then, in any case, + * stuff c into the buffer. If this causes the buffer to fill + * completely, or if c is '\n' and the file is line buffered, + * flush it (perhaps a second time). The second flush will always + * happen on unbuffered streams, where _bf._size==1; fflush() + * guarantees that putc() will always call wbuf() by setting _w + * to 0, so we need not do anything else. + */ + n = fp->_p - fp->_bf._base; + if (n >= fp->_bf._size) { + if (fflush(fp)) + return (EOF); + n = 0; + } + fp->_w--; + *fp->_p++ = c; + if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) + if (fflush(fp)) + return (EOF); + return (c); +} diff --git a/lib/libpthread/stdio/wsetup.c b/lib/libpthread/stdio/wsetup.c new file mode 100644 index 000000000000..3aeb64b13a8b --- /dev/null +++ b/lib/libpthread/stdio/wsetup.c @@ -0,0 +1,92 @@ +/*- + * 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 = "from: @(#)wsetup.c 5.2 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id: wsetup.c,v 1.1 1994/01/30 04:25:59 proven Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include "local.h" + +/* + * Various output routines call wsetup to be sure it is safe to write, + * because either _flags does not include __SWR, or _buf is NULL. + * _wsetup returns 0 if OK to write, nonzero otherwise. + */ +__swsetup(fp) + register FILE *fp; +{ + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + /* + * If we are not writing, we had better be reading and writing. + */ + if ((fp->_flags & __SWR) == 0) { + if ((fp->_flags & __SRW) == 0) + return (EOF); + if (fp->_flags & __SRD) { + /* clobber any ungetc data */ + if (HASUB(fp)) + FREEUB(fp); + fp->_flags &= ~(__SRD|__SEOF); + fp->_r = 0; + fp->_p = fp->_bf._base; + } + fp->_flags |= __SWR; + } + + /* + * Make a buffer if necessary, then set _w. + */ + if (fp->_bf._base == NULL) + __smakebuf(fp); + if (fp->_flags & __SLBF) { + /* + * It is line buffered, so make _lbfsize be -_bufsize + * for the putc() macro. We will change _lbfsize back + * to 0 whenever we turn off __SWR. + */ + fp->_w = 0; + fp->_lbfsize = -fp->_bf._size; + } else + fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size; + return (0); +} diff --git a/lib/librpc/Makefile b/lib/librpc/Makefile deleted file mode 100644 index 00a53b76642b..000000000000 --- a/lib/librpc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIR= man rpc - -.include <bsd.subdir.mk> diff --git a/lib/librpc/man/Makefile b/lib/librpc/man/Makefile deleted file mode 100644 index 54b215477895..000000000000 --- a/lib/librpc/man/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIR=man1 man3 man5 man8 - -.include <bsd.subdir.mk> diff --git a/lib/librpc/man/man1/Makefile b/lib/librpc/man/man1/Makefile deleted file mode 100644 index 5f09977a8ae0..000000000000 --- a/lib/librpc/man/man1/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MAN1= rpcgen.1 rstat.1 - -.include <bsd.prog.mk> diff --git a/lib/librpc/man/man1/rpcgen.1 b/lib/librpc/man/man1/rpcgen.1 deleted file mode 100644 index c5a2128e279b..000000000000 --- a/lib/librpc/man/man1/rpcgen.1 +++ /dev/null @@ -1,175 +0,0 @@ -.\" @(#)rpcgen.1 2.2 88/08/02 4.0 RPCSRC -.TH RPCGEN 1 "18 January 1988" -.SH NAME -rpcgen \- an RPC protocol compiler -.SH SYNOPSIS -.BI rpcgen " infile" -.br -.B rpcgen -.BR \-c \|| \|\-h \|| \|\-l \||\fB\|\-m -[ -.BI \-o " outfile" -] -[ -.I infile -] -.br -.B rpcgen \-s -.I transport -[ -.BI \-o " outfile" -] -[ -.I infile -] -.br -.SH DESCRIPTION -.IX "compilers" rpcgen "" "\fLrpcgen\fR \(em generate RPC protocols, C header files" -.IX rpcgen "" "\fLrpcgen\fR \(em generate RPC protocol, C header files, and server skeleton" -.IX RPC "generate protocols \(em \fLrpcgen\fR" -.B rpcgen -is a tool that generates C -code to implement an -.SM RPC -protocol. The input to -.B rpcgen -is a language similar to C -known as -.SM RPC -Language (Remote Procedure Call Language). Information -about the syntax of -.SM RPC -Language is available in the -.RI ` rpcgen ' " Programming Guide." -.LP -.B rpcgen -is normally used as in the first synopsis where it takes an input file -and generates four output files. If the -.I infile -is named -.BR proto.x , -then -.B rpcgen -will generate a header file in -.BR proto.h , -.SM XDR -routines in -.BR proto_xdr.c , -server-side stubs in -.BR proto_svc.c , -and client-side stubs in -.BR proto_clnt.c . -.LP -The other synopses shown above are used when one does not want to -generate all the output files, but only a particular one. Their -usage is described in the -.SM USAGE -section below. -.LP -The C-preprocessor, -.BR cpp (1), -is run on all input files before they are actually -interpreted by -.BR rpcgen , -so all the -.B cpp -directives are legal within an -.B rpcgen -input file. For each type of output file, -.B rpcgen -defines a special -.B cpp -symbol for use by the -.B rpcgen -programmer: -.PP -.PD 0 -.TP 12 -.SM RPC_HDR -defined when compiling into header files -.TP -.SM RPC_XDR -defined when compiling into -.SM XDR -routines -.TP -.SM RPC_SVC -defined when compiling into server-side stubs -.TP -.SM RPC_CLNT -defined when compiling into client-side stubs -.PD -.LP -In addition, -.B rpcgen -does a little preprocessing of its own. -Any line beginning with -.RB ` % ' -is passed directly into the output file, uninterpreted by -.BR rpcgen . -.LP -You can customize some of your -.SM XDR -routines by leaving those data -types undefined. For every data type that is undefined, -.B rpcgen -will assume that there exists a routine with the name -.B xdr_ -prepended to the name of the undefined type. -.SH OPTIONS -.TP -.B \-c -Compile into -.SM XDR -routines. -.TP -.B \-h -Compile into -.B C -data-definitions (a header file) -.TP -.B \-l -Compile into client-side stubs. -.TP -.B \-m -Compile into server-side stubs, but do not generate a \(lqmain\(rq routine. -This option is useful for doing callback-routines and for people who -need to write their own \(lqmain\(rq routine to do initialization. -.TP -.BI \-o " outfile" -Specify the name of the output file. -If none is specified, standard output is used -.RB ( \-c , -.BR \-h , -.B \-l -and -.B \-s -modes only). -.TP -.BI \-s " transport" -Compile into server-side stubs, using the the given transport. The -supported transports -are -.B udp -and -.BR tcp . -This option may be invoked more than once -so as to compile a server that serves multiple transports. -.br -.ne 5 -.SH "SEE ALSO" -.BR cpp (1) -.LP -.RI ` rpcgen ' " Programming Guide." -.br -.ne 4 -.SH BUGS -.LP -Nesting is not supported. -As a work-around, structures can be declared at -top-level, and their name used inside other structures in order to achieve -the same effect. -.LP -Name clashes can occur when using program definitions, since the apparent -scoping does not really apply. Most of these can be avoided by giving -unique names for programs, versions, procedures and types. diff --git a/lib/librpc/man/man3/Makefile b/lib/librpc/man/man3/Makefile deleted file mode 100644 index 85ab536e06ea..000000000000 --- a/lib/librpc/man/man3/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MAN3= bindresvport.3n getrpcent.3n getrpcport.3r rpc.3n xdr.3n - -.include <bsd.prog.mk> diff --git a/lib/librpc/man/man5/Makefile b/lib/librpc/man/man5/Makefile deleted file mode 100644 index 5d07719edcae..000000000000 --- a/lib/librpc/man/man5/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MAN5= rpc.5 - -.include <bsd.prog.mk> diff --git a/lib/librpc/man/man8/Makefile b/lib/librpc/man/man8/Makefile deleted file mode 100644 index bb0dacbd9370..000000000000 --- a/lib/librpc/man/man8/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MAN8= portmap.8c rpcinfo.8c rstat_svc.8c - -.include <bsd.prog.mk> diff --git a/lib/librpc/man/man8/portmap.8c b/lib/librpc/man/man8/portmap.8c deleted file mode 100644 index 862bd0518460..000000000000 --- a/lib/librpc/man/man8/portmap.8c +++ /dev/null @@ -1,53 +0,0 @@ -.\" @(#)portmap.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 88/03/14 SMI -.TH PORTMAP 8C "9 September 1987" -.SH NAME -portmap \- DARPA port to RPC program number mapper -.SH SYNOPSIS -.B /usr/etc/rpc.portmap -.SH DESCRIPTION -.IX "portmap command" "" "\fLportmap\fP \(em DARPA to RPC mapper" -.IX DARPA "to RPC mapper \(em \fLportmap\fP" -.B portmap -is a server that converts -.SM RPC -program numbers into -.SM DARPA -protocol port numbers. -It must be running in order to make -.SM RPC -calls. -.LP -When an -.SM RPC -server is started, it will tell -.B portmap -what port number it is listening to, and what -.SM RPC -program numbers it is prepared to serve. -When a client wishes to make an -.SM RPC -call to a given program number, -it will first contact -.B portmap -on the server machine to determine -the port number where -.SM RPC -packets should be sent. -.LP -Normally, standard -.SM RPC -servers are started by -.BR inetd (8C), -so -.B portmap -must be started before -.B inetd -is invoked. -.SH "SEE ALSO" -.BR inetd.conf (5), -.BR rpcinfo (8), -.BR inetd (8) -.SH BUGS -If -.B portmap -crashes, all servers must be restarted. diff --git a/lib/librpc/man/man8/rpcinfo.8c b/lib/librpc/man/man8/rpcinfo.8c deleted file mode 100644 index 2d0de97fd39e..000000000000 --- a/lib/librpc/man/man8/rpcinfo.8c +++ /dev/null @@ -1,183 +0,0 @@ -.\" @(#)rpcinfo.8c 2.2 88/08/03 4.0 RPCSRC; from 1.24 88/02/25 SMI -.TH RPCINFO 8C "17 December 1987" -.SH NAME -rpcinfo \- report RPC information -.SH SYNOPSIS -.B "rpcinfo \-p" -[ -.I host -] -.LP -.B "rpcinfo" -[ -.B \-n -.I portnum -] -.B \-u -.I host -.I program -[ -.I version -] -.LP -.B "rpcinfo" -[ -.B \-n -.I portnum -] -.B \-t -.I host -.I program -[ -.I version -] -.LP -.B "rpcinfo \-b" -.I program -.I version -.LP -.B "rpcinfo \-d" -.I program -.I version -.SH DESCRIPTION -.B rpcinfo -makes an -.SM RPC -call to an -.SM RPC -server and reports what it finds. -.SH OPTIONS -.TP -.B \-p -Probe the portmapper on -.IR host , -and print a list of all registered -.SM RPC -programs. If -.I host -is not specified, it defaults to the value returned by -.BR hostname (1). -.TP -.B \-u -Make an -.SM RPC -call to procedure 0 of -.I program -on the specified -.I host -using -.SM UDP\s0, -and report whether a response was received. -.TP -.B \-t -Make an -.SM RPC -call to procedure 0 of -.I program -on the specified -.I host -using -.SM TCP\s0, -and report whether a response was received. -.TP -.B \-n -Use -.I portnum -as the port number for the -.I \-t -and -.I \-u -options instead of the port number given by the portmapper. -.TP -.B \-b -Make an -.SM RPC -broadcast to procedure 0 of the specified -.I program -and -.I version -using -.SM UDP -and report all hosts that respond. -.TP -.B \-d -Delete registration for the -.SM RPC -service of the specified -.I program -and -.IR version . -This option can be exercised only by the super-user. -.LP -The -.I program -argument can be either a name or a number. -.LP -If a -.I version -is specified, -.B rpcinfo -attempts to call that version of the specified -.IR program . -Otherwise, -.B rpcinfo -attempts to find all the registered version -numbers for the specified -.I program -by calling version 0 (which is presumed not -to exist; if it does exist, -.B rpcinfo -attempts to obtain this information by calling -an extremely high version -number instead) and attempts to call each registered version. -Note: the version number is required for -.B \-b -and -.B \-d -options. -.SH EXAMPLES -To show all of the -.SM RPC -services registered on the local machine use: -.IP -.B example% rpcinfo -p -.LP -To show all of the -.SM RPC -services registered on the machine named -.B klaxon -use: -.IP -.B example% rpcinfo -p klaxon -.LP -To show all machines on the local net that are running the Yellow Pages -service use: -.IP -.B "example% rpcinfo -b ypserv 'version' | uniq" -.LP -where 'version' is the current Yellow Pages version obtained from the -results of the -.B \-p -switch above. -.LP -To delete the registration for version 1 of the -.B walld -service use: -.IP -.B example% rpcinfo -d walld 1 -.SH "SEE ALSO" -.BR rpc (5), -.BR portmap (8C) -.LP -.I "\s-1RPC\s0 Programming Guide" -.SH BUGS -In releases prior to Sun\s-1OS\s0 -3.0, the Network File System (\s-1NFS\s0) did not -register itself with the -portmapper; -.B rpcinfo -cannot be used to make -.SM RPC -calls to the -.SM NFS -server on hosts running such releases. diff --git a/lib/librpcsvc/Makefile b/lib/librpcsvc/Makefile index 7f2f28c9997f..6591ee97e2d3 100644 --- a/lib/librpcsvc/Makefile +++ b/lib/librpcsvc/Makefile @@ -1,5 +1,5 @@ # from: @(#)Makefile 5.10 (Berkeley) 6/24/90 -# $Id: Makefile,v 1.1 1993/09/14 17:48:18 jtc Exp $ +# $Id: Makefile,v 1.6 1994/02/07 09:07:48 rgrimes Exp $ .PATH: ${.CURDIR}/../../include/rpcsvc /usr/src/include/rpcsvc diff --git a/lib/libtelnet/Makefile b/lib/libtelnet/Makefile index e28bc48a7471..1a3f17852e60 100644 --- a/lib/libtelnet/Makefile +++ b/lib/libtelnet/Makefile @@ -1,7 +1,7 @@ # @(#)Makefile 5.4 (Berkeley) 5/7/91 LIB= telnet -SRCS= genget.c getent.c gettytab.c misc.c +SRCS= genget.c gettytab.c misc.c .PATH: ${.CURDIR}/../../libexec/getty .include <bsd.lib.mk> diff --git a/lib/libterm/Makefile b/lib/libterm/Makefile index 4c7b0ba012c1..c0ee1c1c90d7 100644 --- a/lib/libterm/Makefile +++ b/lib/libterm/Makefile @@ -1,12 +1,5 @@ -# @(#)Makefile 5.10 (Berkeley) 6/1/90 -# -# PATCHES MAGIC LEVEL PATCH THAT GOT US HERE -# -------------------- ----- ---------------------- -# CURRENT PATCH LEVEL: 1 00138 -# -------------------- ----- ---------------------- -# -# 11 Apr 93 Rodney W. Grimes Added conditional for profiled -# library LINKS +# from: @(#)Makefile 5.10 (Berkeley) 6/1/90 +# $Id: Makefile,v 1.6 1994/02/05 13:19:00 rgrimes Exp $ LIB= termcap CFLAGS+=-DCM_N -DCM_GT -DCM_B -DCM_D @@ -22,3 +15,11 @@ LINKS+= ${LIBDIR}/libtermcap_p.a ${LIBDIR}/libtermlib_p.a .endif .include <bsd.lib.mk> + +# This must be after the .include, otherwise we do not pick up +# the SHLIB_{MAJOR,MINOR}! +# +.if !defined(NOPIC) && defined(SHLIB_MAJOR) && defined(SHLIB_MINOR) +LINKS+= ${LIBDIR}/libtermcap.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \ + ${LIBDIR}/libtermlib.so.${SHLIB_MAJOR}.${SHLIB_MINOR} +.endif diff --git a/lib/libterm/termcap.3 b/lib/libterm/termcap.3 index e708fce378ec..f11507db942d 100644 --- a/lib/libterm/termcap.3 +++ b/lib/libterm/termcap.3 @@ -51,7 +51,7 @@ .Fn tgetnum "char *id" .Fn tgetflag "char *id" .Ft char * -.Fn tgetstr "char *id" "char *area" +.Fn tgetstr "char *id" "char **area" .Ft char * .Fn tgoto "char *cm" destcol destline .Fn tputs "register char *cp" "int affcnt" "int (*outc)()" diff --git a/lib/libterm/termcap.c b/lib/libterm/termcap.c index 36638a6786a3..8ea65665ccce 100644 --- a/lib/libterm/termcap.c +++ b/lib/libterm/termcap.c @@ -62,9 +62,9 @@ static int hopcount; /* detect infinite loops in termcap, init 0 */ static char pathbuf[PBUFSIZ]; /* holds raw path of filenames */ static char *pathvec[PVECSIZ]; /* to point to names in pathbuf */ static char **pvec; /* holds usable tail of path vector */ -char *tskip(); +static char *tskip(); +static char *tdecode(); char *tgetstr(); -char *tdecode(); char *getenv(); /* diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index 8f30077d9dd4..50113aef1ebe 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -1,12 +1,18 @@ -# @(#)Makefile 5.10 (Berkeley) 5/6/91 +# from: @(#)Makefile 5.10 (Berkeley) 5/6/91 +# $Id: Makefile,v 1.10 1994/02/23 09:56:37 rgrimes Exp $ LIB= util # kvm.c needs -I/sys CFLAGS+=-DLIBC_SCCS -I/sys SRCS= daemon.c getloadavg.c kvm.c login.c login_tty.c logout.c logwtmp.c \ - pty.c pwcache.c -MAN3= getloadavg.3 pwcache.3 + pty.c pwcache.c config.c osname.c +MAN3= getloadavg.3 pwcache.3 config_open.3 daemon.3 osname.3 -MLINKS+=pwcache.3 user_from_uid.3 pwcache.3 group_from_gid.3 +MLINKS+=pwcache.3 user_from_uid.3 \ + pwcache.3 group_from_gid.3 \ + config_open.3 config_close.3 \ + config_open.3 config_next.3 \ + config_open.3 config_skip.3 \ + osname.3 osnamever.3 .include <bsd.lib.mk> diff --git a/lib/libutil/config.c b/lib/libutil/config.c new file mode 100644 index 000000000000..1f3ece26a115 --- /dev/null +++ b/lib/libutil/config.c @@ -0,0 +1,202 @@ +/* + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: config.c,v 1.1 1994/01/14 12:24:39 jkh Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * This file contains four procedures to read config-files with. + * + * char * config_open(const char *filename,int contlines) + * Will open the named file, and read it into a private malloced area, + * and close the file again. If contlines are non-zero + * continuation-lines will be allowed. In case of trouble, the name + * of the system-call causing the trouble will be returned. On success + * NULL is returned. + * + * void config_close() + * This will free the internal malloced area. + * + * char * config_next() + * This will return a pointer to the next entry in the area. NULL is + * returned at "end of file". If continuation-lines are used, the '\n' + * will be converted to ' '. The return value is '\0' terminated, and + * can be modified, but the contents must be copied somewhere else. + * + * char * config_skip(char **p) + * This will pick out the next word from the string. The return-value + * points to the word found, and *p is advanced past the word. NULL is + * returned at "end of string". + * + * The point about this is, that many programs have an n*100 bytes config-file + * and some N*1000 bytes of source to read it. Doing pointer-aerobics on + * files that small is waste of time, and bashing around with getchar/ungetc + * isn't much better. These routines implement a simple algorithm and syntax. + * + * 1. Lines starting in '#' are comments. + * 2. An entry starts with the first '!isspace()' character found. + * 3. If continuation-lines are enabled, an entry ends before the first + * empty line or before the first line not starting in an 'isspace()' + * character, whichever comes first. + * 4. Otherwise, an entry ends at the first '\n'. + * + * For config_skip goes that it considers a word as a contiguous string of + * !isspace() characters. + * + * There is an #ifdef'ed main() at the end, which is provided for test and + * illustration of use. + * + * 11jan1994 Poul-Henning Kamp phk@login.dkuug.dk + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <string.h> + +static char * file_buf; +static char * ptr; +static int clines; + +char * +config_open(const char *filename, int contlines) +{ + int fd; + struct stat st; + + clines = contlines; + if((fd = open(filename,O_RDONLY)) < 0) + return "open"; + if(fstat(fd,&st) < 0) { + close(fd); + return "fstat"; + } + if(file_buf) + free(file_buf); + file_buf = malloc(st.st_size+1); + if(!file_buf) { + close(fd); + return "malloc"; + } + if(st.st_size != read(fd,file_buf,st.st_size)) { + free(file_buf); + file_buf = (char*)0; + close(fd); + return "read"; + } + close(fd); + file_buf[st.st_size] = '\0'; + ptr = file_buf; + return 0; +} + +void +config_close(void) +{ + if(file_buf) + free(file_buf); + ptr = file_buf = 0; +} + +/* + * Get next entry. An entry starts in column 0, and not with a '#', + * following lines are joined, if they start with white-space. + */ +char * +config_next(void) +{ + char *p,*q; + + /* We might be done already ! */ + if(!ptr || !*ptr) + return 0; + + /* Skip comments and blank lines */ + while(*ptr) { + if(*ptr == '#') { + ptr = strchr(ptr,'\n'); + if(!ptr) + return 0; + ptr++; + continue; + } + for(q=ptr;*q != '\n' && isspace(*q);q++) ; + if(*q != '\n') + break; + ptr = q+1; + } + + if(!*ptr) + return 0; + + p = ptr; + while(1) { + ptr = strchr(ptr,'\n'); + if(!ptr) /* last line ? */ + return p; + if(clines && isspace(ptr[1])) { + for(q=ptr+1;*q != '\n' && isspace(*q);q++) ; + if(*q != '\n') { + *ptr++ = ' '; + continue; + } + } + *ptr++ = '\0'; + return p; + } +} + +/* + * return next word + */ + +char * +config_skip(char **p) +{ + char *q,*r; + + if(!*p || !**p) + return 0; + for(q = *p;isspace(*q);q++) ; + if(!*q) + return 0; + for(r=q;*r && !isspace(*r);r++) ; + if(*r) + *r++ = '\0'; + *p = r; + return q; +} diff --git a/lib/libutil/config_open.3 b/lib/libutil/config_open.3 new file mode 100644 index 000000000000..b8a5936a4699 --- /dev/null +++ b/lib/libutil/config_open.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1994 Christoph M. Robitschko +.\" 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 Christoph M. Robitschko +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software withough specific prior written permission +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: config_open.3,v 1.2 1994/02/23 09:56:39 rgrimes Exp $ +.\" +.Dd January 28, 1994 +.Dt config_open 3 +.Os FreeBSD +.Sh NAME +.Nm config_open , +.Nm config_close , +.Nm config_next , +.Nm config_skip +.Nd read config files +.Sh SYNOPSIS +.Ft char * +.Fn config_open "const char *filename" "int contlines" +.Ft void +.Fn config_close +.Ft char * +.Fn config_next +.Ft char * +.Fn config_skip "char **string" +.Sh DESCRIPTION +These functions are used to read config files with the following syntax: +.Bl -bullet -compact +.It +Lines starting in +.Sq # +are comments. +.It +An entry starts with the first +.Sq !isspace() +character found. +.It +If continuation-lines are enabled, an entry ends before the first +empty line or before the first line not starting in an +.Sq isspace() +character, whichever comes first. +.It +Otherwise, an entry ends at the first +.Sq Li \en +.Li . +.El +.Pp +.Fn config_open +will open the specified +.Fa filename +and read it into a private malloced area, and close the file again. If +.Fa contlines +is non-zero, continuation lines will be allowed. +In case of trouble, the name of the system-call causing the trouble will +be returned. If successful, +.Fn config_open +returns NULL. +.Pp +.Fn config_close +will free the malloced area. +.Pp +.Fn config_next +returns the next entry in the area. NULL is returned to indicate End-of-file. +The returned string is null-terminated, and +.Sq \en +characters (if continuation lines are enabled) are converted to +space characters. +.Pp +.Fn config_skip +returns the next word from the string +.Fa *string +.Li . +.Fa *string +will be advanced to point to the next word. +NULL is returned to indicate the end of the string. +.Sh FILES +.Pa /usr/lib/libutil.a +The name of the library these functions are part of. +.Sh AUTHOR +Poul-Henning Kamp <phk@login.dkuug.dk> diff --git a/lib/libutil/daemon.3 b/lib/libutil/daemon.3 new file mode 100644 index 000000000000..b9ddbd9e4d8c --- /dev/null +++ b/lib/libutil/daemon.3 @@ -0,0 +1,61 @@ +.\" Copyright (c) 1994 Christoph M. Robitschko +.\" 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 Christoph M. Robitschko +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software withough specific prior written permission +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: daemon.3,v 1.2 1994/02/23 09:56:40 rgrimes Exp $ +.\" +.Dd January 28, 1994 +.Dt daemon 3 +.Os FreeBSD +.Sh NAME +.Nm daemon +.Nd become a daemon process +.Sh SYNOPSIS +.Ft int +.Fn daemon "int nochdir" "int noclose" +.Sh DESCRIPTION +The +.Fn daemon +function makes the calling process into a daemon process: it forks and +continues as the child process (while the parent exits with a 0 exit value) , +creates a new session, disassociates itself from the controlling terminal, +closes stdin, stdout and stderr (unless +.Fa noclose +is nonzero) and changes the working directory to the root directory (unless +.Fa nochdir +is nonzero). +.Sh RETURN VALUES +.Fn daemon +returns -1 if the fork failed, or 0 otherwise. +.Sh SEE ALSO +.Xr fork 2 , +.Xr exit 2 , +.Xr setsid 2 , +.Xr chdir 2 +.Sh FILES +.Pa /usr/lib/libutil.a +The name of the library these functions are part of. diff --git a/lib/libutil/daemon.c b/lib/libutil/daemon.c index f4e663c8de26..ad5ca3e2c167 100644 --- a/lib/libutil/daemon.c +++ b/lib/libutil/daemon.c @@ -29,6 +29,9 @@ * 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. + * + * from: "@(#)daemon.c 5.3 (Berkeley) 12/28/90 + * $Id: daemon.c,v 1.3 1994/02/23 09:56:41 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) @@ -62,4 +65,5 @@ daemon(nochdir, noclose) (void) close(devnull); } } + return 0; } diff --git a/lib/libutil/getloadavg.3 b/lib/libutil/getloadavg.3 index 6864ec773cec..f9d32836e96a 100644 --- a/lib/libutil/getloadavg.3 +++ b/lib/libutil/getloadavg.3 @@ -29,7 +29,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)getloadavg.3 6.3 (Berkeley) 4/19/91 +.\" from: @(#)getloadavg.3 6.3 (Berkeley) 4/19/91 +.\" $Id: getloadavg.3,v 1.2 1994/02/23 09:56:43 rgrimes Exp $ .\" .Dd April 19, 1991 .Dt GETLOADAVG 3 diff --git a/lib/libutil/getloadavg.c b/lib/libutil/getloadavg.c index 8f6fb0bcaa86..9f0fb915c3ec 100644 --- a/lib/libutil/getloadavg.c +++ b/lib/libutil/getloadavg.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: getloadavg.c,v 1.2 1994/02/23 09:56:44 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/kvm.c b/lib/libutil/kvm.c index 96121cbb454a..2c5de35dd0b8 100644 --- a/lib/libutil/kvm.c +++ b/lib/libutil/kvm.c @@ -30,27 +30,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE - * -------------------- ----- ---------------------- - * CURRENT PATCH LEVEL: 3 00136 - * -------------------- ----- ---------------------- - * - * 08 Sep 92 Greenman & Kranenburg Change vaddr calc, move bogus #endif - * 05 Aug 92 David Greenman Fix kernel namelist db create/use - * 08 Aug 93 Paul Kranenburg Fix for command line args from ps and w + * $Id: kvm.c,v 1.8 1994/02/23 09:56:45 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #endif /* LIBC_SCCS and not lint */ -/* - * Updated for 386BSD 0.1 by David Greenman (davidg%implode@percy.rain.com) - * and Paul Kranenburg (pk@cs.few.eur.nl) - * 20-Aug-1992 - * And again by same on 04-Aug-1993 - */ - +#define DEBUG 0 #include <sys/param.h> #include <sys/user.h> @@ -58,6 +45,8 @@ static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #include <sys/ioctl.h> #include <sys/kinfo.h> #include <sys/tty.h> +#include <sys/file.h> +#include <sys/types.h> #include <machine/vmparam.h> #include <fcntl.h> #include <nlist.h> @@ -67,26 +56,14 @@ static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #include <paths.h> #include <stdio.h> #include <string.h> +#include <sys/mman.h> -#ifdef SPPWAIT -#define NEWVM -#endif - -#ifdef NEWVM #define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */ #define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */ #include <vm/vm.h> /* ??? kinfo_proc currently includes this*/ #include <vm/vm_page.h> #include <vm/swap_pager.h> #include <sys/kinfo_proc.h> -#ifdef hp300 -#include <hp300/hp300/pte.h> -#endif -#else /* NEWVM */ -#include <machine/pte.h> -#include <sys/vmmac.h> -#include <sys/text.h> -#endif /* NEWVM */ /* * files @@ -113,20 +90,13 @@ static union { char upages[UPAGES][NBPG]; } user; -#ifdef NEWVM struct swapblk { long offset; /* offset in swap device */ long size; /* remaining size of block in swap device */ }; -#endif /* * random other stuff */ -#ifndef NEWVM -static struct pte *Usrptmap, *usrpt; -static struct pte *Sysmap; -static int Syssize; -#endif static int dmmin, dmmax; static int pcbpf; static int argaddr0; /* XXX */ @@ -134,22 +104,11 @@ static int argaddr1; static int swaddr; static int nswap; static char *tmp; -#if defined(hp300) -static int lowram; -static struct ste *Sysseg; -#endif -#if defined(i386) static struct pde *PTD; -#endif #define basename(cp) ((tmp=rindex((cp), '/')) ? tmp+1 : (cp)) #define MAXSYMSIZE 256 -#if defined(hp300) -#define pftoc(f) ((f) - lowram) -#define iskva(v) (1) -#endif - #ifndef pftoc #define pftoc(f) (f) #endif @@ -174,41 +133,36 @@ static struct nlist nl[] = { #define X_VM_PAGE_HASH_MASK 6 { "_page_shift" }, #define X_PAGE_SHIFT 7 + { "_kstack" }, +#define X_KSTACK 8 + { "_kernel_object" }, +#define X_KERNEL_OBJECT 9 + { "_btext",}, +#define X_KERNEL_BTEXT 10 /* * everything here and down, only if a dead kernel */ { "_Sysmap" }, -#define X_SYSMAP 8 +#define X_SYSMAP 11 #define X_DEADKERNEL X_SYSMAP { "_Syssize" }, -#define X_SYSSIZE 9 +#define X_SYSSIZE 12 { "_allproc" }, -#define X_ALLPROC 10 +#define X_ALLPROC 13 { "_zombproc" }, -#define X_ZOMBPROC 11 +#define X_ZOMBPROC 14 { "_nproc" }, -#define X_NPROC 12 -#define X_LAST 12 -#if defined(hp300) - { "_Sysseg" }, -#define X_SYSSEG (X_LAST+1) - { "_lowram" }, -#define X_LOWRAM (X_LAST+2) -#endif -#if defined(i386) +#define X_NPROC 15 +#define X_LAST 15 { "_IdlePTD" }, #define X_IdlePTD (X_LAST+1) -#endif { "" }, }; static off_t Vtophys(); static void klseek(), seterr(), setsyserr(), vstodb(); static int getkvars(), kvm_doprocs(), kvm_init(); -#ifdef NEWVM -static int vatosw(); static int findpage(); -#endif /* * returns 0 if files were opened now, @@ -305,12 +259,6 @@ kvm_close() kvminit = 0; kvmfilesopen = 0; deadkernel = 0; -#ifndef NEWVM - if (Sysmap) { - free(Sysmap); - Sysmap = NULL; - } -#endif } kvm_nlist(nl) @@ -430,9 +378,10 @@ kvm_getprocs(what, arg) return (-1); } copysize = ret; - if (copysize > ocopysize && - (kvmprocbase = (struct kinfo_proc *)malloc(copysize)) - == NULL) { + if ((copysize > ocopysize || + kvmprocbase == (struct kinfo_proc *) NULL) && + (kvmprocbase = (struct kinfo_proc *) + realloc(kvmprocbase, copysize)) == NULL) { seterr("out of memory"); return (-1); } @@ -489,9 +438,6 @@ kvm_doprocs(what, arg, buff) struct pgrp pgrp; struct session sess; struct tty tty; -#ifndef NEWVM - struct text text; -#endif /* allproc */ if (kvm_read((void *) nl[X_ALLPROC].n_value, &p, @@ -507,7 +453,6 @@ again: seterr("can't read proc at %x", p); return (-1); } -#ifdef NEWVM if (kvm_read(proc.p_cred, &eproc.e_pcred, sizeof (struct pcred)) == sizeof (struct pcred)) (void) kvm_read(eproc.e_pcred.pc_ucred, &eproc.e_ucred, @@ -530,26 +475,6 @@ again: continue; break; } -#else - switch(ki_op(what)) { - - case KINFO_PROC_PID: - if (proc.p_pid != (pid_t)arg) - continue; - break; - - - case KINFO_PROC_UID: - if (proc.p_uid != (uid_t)arg) - continue; - break; - - case KINFO_PROC_RUID: - if (proc.p_ruid != (uid_t)arg) - continue; - break; - } -#endif /* * gather eproc */ @@ -589,23 +514,10 @@ again: eproc.e_tdev = NODEV; if (proc.p_wmesg) kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN); -#ifdef NEWVM (void) kvm_read(proc.p_vmspace, &eproc.e_vm, sizeof (struct vmspace)); eproc.e_xsize = eproc.e_xrssize = eproc.e_xccount = eproc.e_xswrss = 0; -#else - if (proc.p_textp) { - kvm_read(proc.p_textp, &text, sizeof (text)); - eproc.e_xsize = text.x_size; - eproc.e_xrssize = text.x_rssize; - eproc.e_xccount = text.x_ccount; - eproc.e_xswrss = text.x_swrss; - } else { - eproc.e_xsize = eproc.e_xrssize = - eproc.e_xccount = eproc.e_xswrss = 0; - } -#endif switch(ki_op(what)) { @@ -648,7 +560,9 @@ kvm_nextproc() if (!kvmprocbase && kvm_getprocs(0, 0) == -1) return (NULL); if (kvmprocptr >= (kvmprocbase + kvmnprocs)) { +#if 0 seterr("end of proc list"); +#endif return (NULL); } return((struct proc *)(kvmprocptr++)); @@ -675,12 +589,29 @@ kvm_freeprocs() } } -#ifdef i386 -/* See also ./sys/kern/kern_execve.c */ -#define ARGSIZE (roundup(ARG_MAX, NBPG)) -#endif +proc_getmem(const struct proc *p, void *buffer, vm_offset_t size, vm_offset_t offset) { + int fd; + char fn[512+1]; + sprintf(fn,"/proc/%d",p->p_pid); + if (p->p_flag & SSYS) + return 0; + fd = open(fn,O_RDONLY); + if (fd == -1) { + return 0; + } + + if (lseek(fd, offset, 0) == -1) { + close(fd); + return 0; + } + if (read(fd, buffer, size) <= 0) { + close(fd); + return 0; + } + close(fd); + return 1; +} -#ifdef NEWVM struct user * kvm_getu(p) const struct proc *p; @@ -689,7 +620,7 @@ kvm_getu(p) register int i; register char *up; u_int vaddr; - struct swapblk swb; + int arg_size; if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) return (NULL); @@ -698,48 +629,15 @@ kvm_getu(p) return (NULL); } - argaddr0 = argaddr1 = swaddr = 0; - if ((p->p_flag & SLOAD) == 0) { - vm_offset_t maddr; - - if (swap < 0) { - seterr("no swap"); - return (NULL); - } - /* - * Costly operation, better set enable_swap to zero - * in vm/vm_glue.c, since paging of user pages isn't - * done yet anyway. - */ - if (vatosw(p, USRSTACK + i * NBPG, &maddr, &swb) == 0) - return NULL; - - if (maddr == 0 && swb.size < UPAGES * NBPG) - return NULL; - - for (i = 0; i < UPAGES; i++) { - if (maddr) { - (void) lseek(mem, maddr + i * NBPG, 0); - if (read(mem, - (char *)user.upages[i], NBPG) != NBPG) { - seterr( - "can't read u for pid %d from %s", - p->p_pid, swapf); - return NULL; - } - } else { - (void) lseek(swap, swb.offset + i * NBPG, 0); - if (read(swap, - (char *)user.upages[i], NBPG) != NBPG) { - seterr( - "can't read u for pid %d from %s", - p->p_pid, swapf); - return NULL; - } - } + if (!deadkernel) { + if (proc_getmem(p, user.upages, sizeof user.upages, USRSTACK)) { + kp->kp_eproc.e_vm.vm_rssize = + kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */ + return &user.user; } - return(&user.user); } + + argaddr0 = argaddr1 = 0; /* * Read u-area one page at a time for the benefit of post-mortems */ @@ -753,31 +651,17 @@ kvm_getu(p) } up += CLBYTES; } + pcbpf = (int) btop(p->p_addr); /* what should this be really? */ /* * Conjure up a physical address for the arguments. */ -#ifdef hp300 - if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) { - struct pte pte[CLSIZE*2]; - - klseek(kmem, - (long)&kp->kp_eproc.e_vm.vm_pmap.pm_ptab - [btoc(USRSTACK-CLBYTES*2)], 0); - if (read(kmem, (char *)&pte, sizeof(pte)) == sizeof(pte)) { -#if CLBYTES < 2048 - argaddr0 = ctob(pftoc(pte[CLSIZE*0].pg_pfnum)); -#endif - argaddr1 = ctob(pftoc(pte[CLSIZE*1].pg_pfnum)); - } - } -#endif kp->kp_eproc.e_vm.vm_rssize = kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */ - vaddr = (u_int)kp->kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ - ARGSIZE; + vaddr = (u_int)kp->kp_eproc.e_vm.vm_minsaddr; + arg_size = USRSTACK - vaddr; -#ifdef i386 if (kp->kp_eproc.e_vm.vm_pmap.pm_pdir) { struct pde pde; @@ -794,239 +678,116 @@ kvm_getu(p) seterr("kvm_getu: lseek"); if (read(mem, (char *)&pte, sizeof pte) == sizeof pte) { if (pte.pg_v) { - argaddr1 = (long)ctob(pte.pg_pfnum); - } else { - goto hard; + argaddr1 = (pte.pg_pfnum << PGSHIFT) | + ((u_long)vaddr & (NBPG-1)); } } else { seterr("kvm_getu: read"); } - } else { - goto hard; } } -#endif /* i386 */ - -hard: - if (vatosw(p, vaddr, &argaddr1, &swb)) { - if (argaddr1 == 0 && swb.size >= ARGSIZE) - swaddr = swb.offset; - } return(&user.user); } -#else -struct user * -kvm_getu(p) - const struct proc *p; -{ - struct pte *pteaddr, apte; - struct pte arguutl[HIGHPAGES+(CLSIZE*2)]; - register int i; - int ncl; - - if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) - return (NULL); - if (p->p_stat == SZOMB) { - seterr("zombie process"); - return (NULL); - } - if ((p->p_flag & SLOAD) == 0) { - if (swap < 0) { - seterr("no swap"); - return (NULL); - } - (void) lseek(swap, (long)dtob(p->p_swaddr), 0); - if (read(swap, (char *)&user.user, sizeof (struct user)) != - sizeof (struct user)) { - seterr("can't read u for pid %d from %s", - p->p_pid, swapf); - return (NULL); - } - pcbpf = 0; - argaddr0 = 0; - argaddr1 = 0; - return (&user.user); - } - pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1]; - klseek(kmem, (long)pteaddr, 0); - if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) { - seterr("can't read indir pte to get u for pid %d from %s", - p->p_pid, kmemf); - return (NULL); - } - lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0); - if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) { - seterr("can't read page table for u of pid %d from %s", - p->p_pid, memf); - return (NULL); - } - if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum) - argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum)); - else - argaddr0 = 0; - if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum) - argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum)); - else - argaddr1 = 0; - pcbpf = arguutl[CLSIZE*2].pg_pfnum; - ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES; - while (--ncl >= 0) { - i = ncl * CLSIZE; - lseek(mem, - (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0); - if (read(mem, user.upages[i], CLBYTES) != CLBYTES) { - seterr("can't read page %d of u of pid %d from %s", - arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf); - return(NULL); - } - } - return (&user.user); -} -#endif char * kvm_getargs(p, up) const struct proc *p; const struct user *up; { -#ifdef i386 - /* See also ./sys/kern/kern_execve.c */ - static char cmdbuf[ARGSIZE]; - static union { - char argc[ARGSIZE]; - int argi[ARGSIZE/sizeof (int)]; - } argspac; -#else - static char cmdbuf[CLBYTES*2]; - static union { - char argc[CLBYTES*2]; - int argi[CLBYTES*2/sizeof (int)]; - } argspac; -#endif + int arg_size, arg_offset; + static char cmdbuf[ARG_MAX]; + char argc[ARG_MAX*3]; + int *argv; register char *cp; - register int *ip; char c; int nbad; -#ifndef NEWVM - struct dblock db; + char *cmdbufp; + vm_offset_t vaddr; + char procfile[16]; + int mmfd; +#if 0 + char *argc = NULL; #endif - const char *file; - int stkoff = 0; -#if defined(NEWVM) && defined(hp300) - stkoff = 20; /* XXX for sigcode */ -#endif - if (up == NULL || p->p_pid == 0 || p->p_pid == 2) - goto retucomm; - if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) { -#ifdef NEWVM - if (swaddr == 0) - goto retucomm; /* XXX for now */ -#ifdef i386 - (void) lseek(swap, swaddr, 0); - if (read(swap, &argspac.argc[0], ARGSIZE) != ARGSIZE) - goto bad; -#else - if (argaddr0) { - lseek(swap, (long)argaddr0, 0); - if (read(swap, (char *)&argspac, CLBYTES) != CLBYTES) - goto bad; - } else - bzero(&argspac, CLBYTES); - lseek(swap, (long)argaddr1, 0); - if (read(swap, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) - goto bad; -#endif -#else - if (swap < 0 || p->p_ssize == 0) - goto retucomm; - vstodb(0, CLSIZE, &up->u_smap, &db, 1); - (void) lseek(swap, (long)dtob(db.db_base), 0); - if (read(swap, (char *)&argspac.argc[CLBYTES], CLBYTES) - != CLBYTES) - goto bad; - vstodb(1, CLSIZE, &up->u_smap, &db, 1); - (void) lseek(swap, (long)dtob(db.db_base), 0); - if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES) - goto bad; - file = swapf; + *cmdbuf = 0; + + vaddr = (u_int)((struct kinfo_proc *)p)->kp_eproc.e_vm.vm_minsaddr; + arg_size = USRSTACK - vaddr; + + if (arg_size >= 3*ARG_MAX) + goto bad; + +#if 0 + sprintf(procfile, "/proc/%d", p->p_pid); + if ((mmfd = open(procfile, O_RDONLY, 0)) == -1) { +printf("failed to open %s\n",procfile); + goto bad; + } + + if ((argc = mmap(0, arg_size, PROT_READ, MAP_FILE, mmfd, vaddr)) + == (char *)-1) { +printf("failed to mmap %s error=%s\n", procfile, strerror(errno)); + goto bad; + } #endif - } else { -#ifdef i386 - lseek(mem, (long)argaddr1, 0); - if (read(mem, &argspac.argc[0], ARGSIZE) != ARGSIZE) + + if (!proc_getmem(p, argc, arg_size, vaddr)) { + if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) { goto bad; -#else - if (argaddr0) { - lseek(mem, (long)argaddr0, 0); - if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES) + } else { + lseek(mem, (long)argaddr1, 0); + if (read(mem, argc, arg_size) != arg_size) goto bad; - } else - bzero(&argspac, CLBYTES); - lseek(mem, (long)argaddr1, 0); - if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) - goto bad; -#endif - file = (char *) memf; + } } + argv = (int *)argc; + + arg_offset = argv[0] - vaddr; + if (arg_offset >= 3*ARG_MAX) + goto bad; + nbad = 0; -#ifdef i386 - ip = &argspac.argi[(ARGSIZE-ARG_MAX)/sizeof (int)]; - - for (cp = (char *)ip; cp < &argspac.argc[ARGSIZE-stkoff]; cp++) { -#else - ip = &argspac.argi[CLBYTES*2/sizeof (int)]; - ip -= 2; /* last arg word and .long 0 */ - ip -= stkoff / sizeof (int); - while (*--ip) { - if (ip == argspac.argi) - goto retucomm; - } - *(char *)ip = ' '; - ip++; - for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) { -#endif - c = *cp; + cmdbufp = cmdbuf; + for (cp = &argc[arg_offset]; cp < &argc[arg_size]; cp++, cmdbufp++) { + c = *cmdbufp = *cp; if (c == 0) { /* convert null between arguments to space */ - *cp = ' '; + *cmdbufp = ' '; if (*(cp+1) == 0) break; /* if null argument follows then no more args */ } else if (c < ' ' || c > 0176) { if (++nbad >= 5*(0+1)) { /* eflg -> 0 XXX */ /* limit number of bad chars to 5 */ - *cp++ = '?'; + *cmdbufp++ = '?'; break; } - *cp = '?'; + *cmdbufp = '?'; } else if (0 == 0 && c == '=') { /* eflg -> 0 XXX */ - while (*--cp != ' ') - if (cp <= (char *)ip) + while (*--cmdbufp != ' ') + if (cmdbufp <= cmdbuf) break; break; } } - *cp = 0; - while (*--cp == ' ') - *cp = 0; - cp = (char *)ip; - (void) strcpy(cmdbuf, cp); - if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') { + *cmdbufp = 0; + + while (*--cmdbufp == ' ') + *cmdbufp = 0; + + if (cmdbuf[0] == '-' || cmdbuf[0] == '?' || cmdbuf[0] <= ' ') { +bad: (void) strcat(cmdbuf, " ("); (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm)); (void) strcat(cmdbuf, ")"); } - return (cmdbuf); - -bad: - seterr("error locating command name for pid %d from %s", - p->p_pid, file); -retucomm: - (void) strcpy(cmdbuf, " ("); - (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm)); - (void) strcat(cmdbuf, ")"); +#if 0 + if (argc && argc != (char *)-1) + munmap(argc, arg_size); + if (mmfd && mmfd != -1) + close (mmfd); +#endif return (cmdbuf); } @@ -1040,47 +801,6 @@ getkvars() /* We must do the sys map first because klseek uses it */ long addr; -#ifndef NEWVM - Syssize = nl[X_SYSSIZE].n_value; - Sysmap = (struct pte *) - calloc((unsigned) Syssize, sizeof (struct pte)); - if (Sysmap == NULL) { - seterr("out of space for Sysmap"); - return (-1); - } - addr = (long) nl[X_SYSMAP].n_value; - addr &= ~KERNBASE; - (void) lseek(kmem, addr, 0); - if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte)) - != Syssize * sizeof (struct pte)) { - seterr("can't read Sysmap"); - return (-1); - } -#endif -#if defined(hp300) - addr = (long) nl[X_LOWRAM].n_value; - (void) lseek(kmem, addr, 0); - if (read(kmem, (char *) &lowram, sizeof (lowram)) - != sizeof (lowram)) { - seterr("can't read lowram"); - return (-1); - } - lowram = btop(lowram); - Sysseg = (struct ste *) malloc(NBPG); - if (Sysseg == NULL) { - seterr("out of space for Sysseg"); - return (-1); - } - addr = (long) nl[X_SYSSEG].n_value; - (void) lseek(kmem, addr, 0); - read(kmem, (char *)&addr, sizeof(addr)); - (void) lseek(kmem, (long)addr, 0); - if (read(kmem, (char *) Sysseg, NBPG) != NBPG) { - seterr("can't read Sysseg"); - return (-1); - } -#endif -#if defined(i386) PTD = (struct pde *) malloc(NBPG); if (PTD == NULL) { seterr("out of space for PTD"); @@ -1094,12 +814,7 @@ getkvars() seterr("can't read PTD"); return (-1); } -#endif } -#ifndef NEWVM - usrpt = (struct pte *)nl[X_USRPT].n_value; - Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value; -#endif if (kvm_read((void *) nl[X_NSWAP].n_value, &nswap, sizeof (long)) != sizeof (long)) { seterr("can't read nswap"); @@ -1154,68 +869,11 @@ klseek(fd, loc, off) (void) lseek(fd, (off_t)loc, off); } -#ifndef NEWVM -/* - * Given a base/size pair in virtual swap area, - * return a physical base/size pair which is the - * (largest) initial, physically contiguous block. - */ -static void -vstodb(vsbase, vssize, dmp, dbp, rev) - register int vsbase; - int vssize; - struct dmap *dmp; - register struct dblock *dbp; -{ - register int blk = dmmin; - register swblk_t *ip = dmp->dm_map; - - vsbase = ctod(vsbase); - vssize = ctod(vssize); - if (vsbase < 0 || vsbase + vssize > dmp->dm_size) - /*panic("vstodb")*/; - while (vsbase >= blk) { - vsbase -= blk; - if (blk < dmmax) - blk *= 2; - ip++; - } - if (*ip <= 0 || *ip + blk > nswap) - /*panic("vstodb")*/; - dbp->db_size = MIN(vssize, blk - vsbase); - dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); -} -#endif - -#ifdef NEWVM static off_t Vtophys(loc) u_long loc; { off_t newloc = (off_t) -1; -#ifdef hp300 - int p, ste, pte; - - ste = *(int *)&Sysseg[loc >> SG_ISHIFT]; - if ((ste & SG_V) == 0) { - seterr("vtophys: segment not valid"); - return((off_t) -1); - } - p = btop(loc & SG_PMASK); - newloc = (ste & SG_FRAME) + (p * sizeof(struct pte)); - (void) lseek(kmem, (long)(newloc-(off_t)ptob(lowram)), 0); - if (read(kmem, (char *)&pte, sizeof pte) != sizeof pte) { - seterr("vtophys: cannot locate pte"); - return((off_t) -1); - } - newloc = pte & PG_FRAME; - if (pte == PG_NV || newloc < (off_t)ptob(lowram)) { - seterr("vtophys: page not valid"); - return((off_t) -1); - } - newloc = (newloc - (off_t)ptob(lowram)) + (loc & PGOFSET); -#endif -#ifdef i386 struct pde pde; struct pte pte; int p; @@ -1238,168 +896,17 @@ Vtophys(loc) return((off_t) -1); } newloc += (loc & PGOFSET); -#endif return((off_t) newloc); } -#else -static off_t -vtophys(loc) - long loc; -{ - int p; - off_t newloc; - register struct pte *pte; - - newloc = loc & ~KERNBASE; - p = btop(newloc); -#if defined(vax) || defined(tahoe) - if ((loc & KERNBASE) == 0) { - seterr("vtophys: translating non-kernel address"); - return((off_t) -1); - } -#endif - if (p >= Syssize) { - seterr("vtophys: page out of bound (%d>=%d)", p, Syssize); - return((off_t) -1); - } - pte = &Sysmap[p]; - if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) { - seterr("vtophys: page not valid"); - return((off_t) -1); - } -#if defined(hp300) - if (pte->pg_pfnum < lowram) { - seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram); - return((off_t) -1); - } -#endif - loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET)); - return(loc); -} -#endif - -#ifdef NEWVM /* * locate address of unwired or swapped page */ -#define DEBUG 0 #define KREAD(off, addr, len) \ (kvm_read((void *)(off), (char *)(addr), (len)) == (len)) - -static int -vatosw(p, vaddr, maddr, swb) -struct proc *p ; -vm_offset_t vaddr; -vm_offset_t *maddr; -struct swapblk *swb; -{ - register struct kinfo_proc *kp = (struct kinfo_proc *)p; - vm_map_t mp = &kp->kp_eproc.e_vm.vm_map; - struct vm_object vm_object; - struct vm_map_entry vm_entry; - struct pager_struct pager; - struct swpager swpager; - struct swblock swblock; - long addr, off; - int i; - - if (p->p_pid == 0 || p->p_pid == 2) - return 0; - - addr = (long)mp->header.next; - for (i = 0; i < mp->nentries; i++) { - /* Weed through map entries until vaddr in range */ - if (!KREAD(addr, &vm_entry, sizeof(vm_entry))) { - setsyserr("vatosw: read vm_map_entry"); - return 0; - } - if ((vaddr >= vm_entry.start) && (vaddr <= vm_entry.end) && - (vm_entry.object.vm_object != 0)) - break; - - addr = (long)vm_entry.next; - } - if (i == mp->nentries) { - seterr("%u: map not found\n", p->p_pid); - return 0; - } - - if (vm_entry.is_a_map || vm_entry.is_sub_map) { - seterr("%u: Is a map\n", p->p_pid); - return 0; - } - - /* Locate memory object */ - off = (vaddr - vm_entry.start) + vm_entry.offset; - addr = (long)vm_entry.object.vm_object; - while (1) { - if (!KREAD(addr, &vm_object, sizeof vm_object)) { - setsyserr("vatosw: read vm_object"); - return 0; - } - -#if DEBUG - fprintf(stderr, "%u: find page: object %#x offset %x\n", - p->p_pid, addr, off); -#endif - - /* Lookup in page queue */ - if (findpage(addr, off, maddr)) - return 1; - - if (vm_object.shadow == 0) - break; - -#if DEBUG - fprintf(stderr, "%u: shadow obj at %x: offset %x+%x\n", - p->p_pid, addr, off, vm_object.shadow_offset); -#endif - - addr = (long)vm_object.shadow; - off += vm_object.shadow_offset; - } - - if (!vm_object.pager) { - seterr("%u: no pager\n", p->p_pid); - return 0; - } - - /* Find address in swap space */ - if (!KREAD(vm_object.pager, &pager, sizeof pager)) { - setsyserr("vatosw: read pager"); - return 0; - } - if (pager.pg_type != PG_SWAP) { - seterr("%u: weird pager\n", p->p_pid); - return 0; - } - - /* Get swap pager data */ - if (!KREAD(pager.pg_data, &swpager, sizeof swpager)) { - setsyserr("vatosw: read swpager"); - return 0; - } - - off += vm_object.paging_offset; - - /* Read swap block array */ - if (!KREAD((long)swpager.sw_blocks + - (off/dbtob(swpager.sw_bsize)) * sizeof swblock, - &swblock, sizeof swblock)) { - setsyserr("vatosw: read swblock"); - return 0; - } - swb->offset = dbtob(swblock.swb_block)+ (off % dbtob(swpager.sw_bsize)); - swb->size = dbtob(swpager.sw_bsize) - (off % dbtob(swpager.sw_bsize)); - return 1; -} - - -#define atop(x) (((unsigned)(x)) >> page_shift) #define vm_page_hash(object, offset) \ (((unsigned)object+(unsigned)atop(offset))&vm_page_hash_mask) @@ -1452,7 +959,6 @@ static long page_shift; } return 0; } -#endif /* NEWVM */ #include <varargs.h> static char errbuf[_POSIX2_LINE_MAX]; @@ -1487,6 +993,9 @@ setsyserr(va_alist) for (cp=errbuf; *cp; cp++) ; snprintf(cp, _POSIX2_LINE_MAX - (cp - errbuf), ": %s", strerror(errno)); +#if DEBUG + (void) fprintf(stderr, "%s\n", errbuf); +#endif va_end(ap); } diff --git a/lib/libutil/login.c b/lib/libutil/login.c index 6d3ffaaaefdd..b4e4d60f773d 100644 --- a/lib/libutil/login.c +++ b/lib/libutil/login.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: login.c,v 1.2 1994/02/23 09:56:47 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/login_tty.c b/lib/libutil/login_tty.c index a5c841681905..9d5ed548483a 100644 --- a/lib/libutil/login_tty.c +++ b/lib/libutil/login_tty.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: login_tty.c,v 1.2 1994/02/23 09:56:48 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/logout.c b/lib/libutil/logout.c index 8fbed5aca884..d863dc40aba7 100644 --- a/lib/libutil/logout.c +++ b/lib/libutil/logout.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: logout.c,v 1.2 1994/02/23 09:56:50 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/logwtmp.c b/lib/libutil/logwtmp.c index 2e43d2cb4823..60ffe8e474d8 100644 --- a/lib/libutil/logwtmp.c +++ b/lib/libutil/logwtmp.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: logwtmp.c,v 1.2 1994/02/23 09:56:51 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/osname.3 b/lib/libutil/osname.3 new file mode 100644 index 000000000000..14a1739e8642 --- /dev/null +++ b/lib/libutil/osname.3 @@ -0,0 +1,47 @@ +.\" $Id: osname.3,v 1.3 1994/02/23 15:55:45 wollman Exp $ +.\" +.\" This file is in the public domain. +.\" +.Dd February 3, 1994 +.Dt OSNAME 3 +.Os +.Sh NAME +.Nm _osname +.Nd get name of running operating system +.br +.Nm _osnamever +.Nd get name and version of running operating system +.Sh SYNOPSIS +.Ft char * +.Fn _osname void +.Ft char * +.Fn _osnamever void +.Sh DESCRIPTION +The +.Fn _osname +and +.Fn _osnamever +functions return the name of the running operating system and a string +giving the name and version thereof, respectively. +The information is retrieved from the kernel using the +.Xr uname 2 +system call, which is then copied into a static buffer which is +returned to the caller. +.Sh DIAGNOSTICS +If the +.Xr uname 2 +system call returns an error, +.Dq unknown +is returned. +.Sh SEE ALSO +.Xr uname 1 , +.Xr uname 2 +.Sh HISTORY +The +.Fn _osname +and +.Fn _osnamever +functions appreared in +.Fx 1.1 . +.Sh AUTHOR +Garrett A. Wollman diff --git a/lib/libutil/osname.c b/lib/libutil/osname.c new file mode 100644 index 000000000000..c6e8db368a78 --- /dev/null +++ b/lib/libutil/osname.c @@ -0,0 +1,43 @@ +/* + * This file is in the public domain. + * Written by Garrett A. Wollman <wollman@freefall.cdrom.com>. + * + * $Id: osname.c,v 1.1 1994/02/04 02:55:24 wollman Exp $ + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/utsname.h> + +/* + * _osname - return the name of the current operating system. + */ +char * +_osname(void) { + static struct utsname uts; + if(uname(&uts)) + return "unknown"; + else + return uts.sysname; +} + +/* + * _osnamever - return the name and version of the current operating system. + */ +char * +_osnamever(void) { + static struct utsname uts; + static char name[2*SYS_NMLN + 1]; + if(uname(&uts)) { + return "unknown"; + } else { + strcpy(name, uts.sysname); + strcat(name, " "); + strcat(name, uts.release); + return name; + } +} + + + diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c index e5661dc829be..cd859d271713 100644 --- a/lib/libutil/pty.c +++ b/lib/libutil/pty.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: pty.c,v 1.2 1994/02/23 09:56:53 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/lib/libutil/pwcache.3 b/lib/libutil/pwcache.3 index 7805650641fc..3d21b1bfb356 100644 --- a/lib/libutil/pwcache.3 +++ b/lib/libutil/pwcache.3 @@ -29,7 +29,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)pwcache.3 5.4 (Berkeley) 4/19/91 +.\" from: @(#)pwcache.3 5.4 (Berkeley) 4/19/91 +.\" $Id: pwcache.3,v 1.2 1994/02/23 09:56:55 rgrimes Exp $ .\" .Dd April 19, 1991 .Dt PWCACHE 3 diff --git a/lib/libutil/pwcache.c b/lib/libutil/pwcache.c index ad6df2ed3cee..7f81e69f2e1a 100644 --- a/lib/libutil/pwcache.c +++ b/lib/libutil/pwcache.c @@ -29,6 +29,8 @@ * 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. + * + * $Id: pwcache.c,v 1.2 1994/02/23 09:56:56 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) @@ -86,7 +88,7 @@ group_from_gid(gid, nogroup) { static struct ncache { gid_t gid; - char name[UT_NAMESIZE]; + char name[UT_NAMESIZE + 1]; } c_gid[NCACHE]; static char nbuf[15]; /* 32 bits == 10 digits */ register struct group *gr; |
