diff options
author | bk@work.mysql.com <> | 2000-07-31 21:29:14 +0200 |
---|---|---|
committer | bk@work.mysql.com <> | 2000-07-31 21:29:14 +0200 |
commit | f4c589ff6c653d1d2a09c26e46ead3c8a15655d8 (patch) | |
tree | d253a359142dfc1ed247d5d4365d86972ea31109 /mit-pthreads/stdio | |
parent | 7eec25e393727b16bb916b50d82b0aa3084e065c (diff) | |
download | mariadb-git-f4c589ff6c653d1d2a09c26e46ead3c8a15655d8.tar.gz |
Import changeset
Diffstat (limited to 'mit-pthreads/stdio')
78 files changed, 8529 insertions, 0 deletions
diff --git a/mit-pthreads/stdio/GNUmakefile.inc b/mit-pthreads/stdio/GNUmakefile.inc new file mode 100755 index 00000000000..7cb1371661d --- /dev/null +++ b/mit-pthreads/stdio/GNUmakefile.inc @@ -0,0 +1,26 @@ + +# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91 +# $Id$ + +# Thread safe stdio sources +VPATH:= ${VPATH}:${srcdir}/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 \ + 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 putc.c \ + putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \ + setbuf.c setbuffer.c setvbuf.c sscanf.c \ + stdio.c ungetc.c \ + vfscanf.c vscanf.c vsscanf.c \ + wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \ + getchar_unlocked.c strerror.c wbuf.c xprintf.c $(SRCS) + +# tempnam.c tmpnam.c tmpfile.c +# +# SRCS:= sys_errlist.c $(SRCS) +# sys_errlist.c: make_errlist +# (FOO=`pwd`; cd ${srcdir}/stdio/make_errlist; \ +# $(MAKE) CC=$(CC) srcdir=${srcdir} objdir=$${FOO}) +# `pwd`/make_errlist; diff --git a/mit-pthreads/stdio/Makefile.inc b/mit-pthreads/stdio/Makefile.inc new file mode 100644 index 00000000000..10c598c328f --- /dev/null +++ b/mit-pthreads/stdio/Makefile.inc @@ -0,0 +1,20 @@ + +# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91 +# $Id$ + +# Thread safe stdio sources +.PATH: ${srcdir}/stdio + +# SRCS+= tempnam.c tmpfile.c tmpnam.c + +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 \ + 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 putc.c \ + putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \ + setbuf.c setbuffer.c setvbuf.c sscanf.c \ + stdio.c ungetc.c \ + vfscanf.c vscanf.c vsscanf.c \ + wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \ + getchar_unlocked.c strerror.c wbuf.c xprintf.c diff --git a/mit-pthreads/stdio/README b/mit-pthreads/stdio/README new file mode 100755 index 00000000000..8e4c07909e9 --- /dev/null +++ b/mit-pthreads/stdio/README @@ -0,0 +1,41 @@ +Copyright (c) 1993, 1994 Chris Provenzano. All rights reserved. + +This is a threadsafe stdio based on the BSD stdio written by Chris Torek. +This product includes software developed by the Univeristy of California, +Berkeley and its contributors. + +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. The routine 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. + + + +Things to do. + +Fix printf so it uses the ininf function. diff --git a/mit-pthreads/stdio/clrerr.c b/mit-pthreads/stdio/clrerr.c new file mode 100644 index 00000000000..e809cfb8efd --- /dev/null +++ b/mit-pthreads/stdio/clrerr.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fclose.c b/mit-pthreads/stdio/fclose.c new file mode 100644 index 00000000000..c5db0808f6a --- /dev/null +++ b/mit-pthreads/stdio/fclose.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 (fp->_flags & __SMBF) + free((char *)fp->_bf._base); + if (HASUB(fp)) + FREEUB(fp); + if (HASLB(fp)) + FREELB(fp); + if (__sclose(fp) < 0) + r = EOF; +/* funlockfile(fp); Don't unlock. The close() already has. */ + fp->_file = -1; + fp->_flags = 0; /* release this FILE for reuse, DO THIS LAST */ + return(r); + } + errno = EBADF; + return(EOF); +} diff --git a/mit-pthreads/stdio/fdopen.c b/mit-pthreads/stdio/fdopen.c new file mode 100644 index 00000000000..4c006f24c7c --- /dev/null +++ b/mit-pthreads/stdio/fdopen.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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); + } + + __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/mit-pthreads/stdio/feof.c b/mit-pthreads/stdio/feof.c new file mode 100644 index 00000000000..10946fee581 --- /dev/null +++ b/mit-pthreads/stdio/feof.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/ferror.c b/mit-pthreads/stdio/ferror.c new file mode 100644 index 00000000000..b80ddab037e --- /dev/null +++ b/mit-pthreads/stdio/ferror.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fflush.c b/mit-pthreads/stdio/fflush.c new file mode 100644 index 00000000000..766691045b5 --- /dev/null +++ b/mit-pthreads/stdio/fflush.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <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/mit-pthreads/stdio/fgetc.c b/mit-pthreads/stdio/fgetc.c new file mode 100644 index 00000000000..c5eb2ee5986 --- /dev/null +++ b/mit-pthreads/stdio/fgetc.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> + +fgetc(fp) + FILE *fp; +{ + int ret; + + flockfile(fp); + ret = __sgetc(fp); + funlockfile(fp); + return(ret); +} + +int __getc(FILE *_p) +{ + int ret; + flockfile(_p); + ret = __sgetc(_p); + funlockfile(_p); + return(ret); +} + diff --git a/mit-pthreads/stdio/fgetline.c b/mit-pthreads/stdio/fgetline.c new file mode 100644 index 00000000000..219660612f1 --- /dev/null +++ b/mit-pthreads/stdio/fgetline.c @@ -0,0 +1,170 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, + 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) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, 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/mit-pthreads/stdio/fgetpos.c b/mit-pthreads/stdio/fgetpos.c new file mode 100644 index 00000000000..c81b48e3cc8 --- /dev/null +++ b/mit-pthreads/stdio/fgetpos.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <unistd.h> +#include <stdio.h> +#include "local.h" + +fgetpos(fp, pos) + FILE *fp; + 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 = __sseek(fp, (off_t)0, SEEK_CUR); + } + + if (*pos != (fpos_t)-1) { + 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) == (fpos_t)-1); +} diff --git a/mit-pthreads/stdio/fgets.c b/mit-pthreads/stdio/fgets.c new file mode 100644 index 00000000000..5ee5c4d6608 --- /dev/null +++ b/mit-pthreads/stdio/fgets.c @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.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) memcpy((void *)s, (void *)p, len); + s += len; + break; + } + fp->_r -= len; + fp->_p += len; + (void) memcpy((void *)s, (void *)p, len); + s += len; + } while ((n -= len) != 0); + + *s = 0; + funlockfile(fp); + return (buf); +} diff --git a/mit-pthreads/stdio/fileno.c b/mit-pthreads/stdio/fileno.c new file mode 100644 index 00000000000..475bd509993 --- /dev/null +++ b/mit-pthreads/stdio/fileno.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/findfp.c b/mit-pthreads/stdio/findfp.c new file mode 100644 index 00000000000..35817eb6a5f --- /dev/null +++ b/mit-pthreads/stdio/findfp.c @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.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 }; +FILE *__iob = __sF; +FILE *_iob = __sF; + +pthread_mutex_t __sfp_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t __sfp_cond = PTHREAD_COND_INITIALIZER; +/* + * __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(struct glue) + 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. + * Do the pthread_once stuff here to keep pthread_once_t out of the + * header files. No reason sprintf.c &c should need to include pthread.h... + */ +static void __s_real_init () +{ + /* make sure we clean up on exit */ + __cleanup = _cleanup; +} + +static pthread_once_t sdidinit = PTHREAD_ONCE_INIT; + +void __sinit () +{ + pthread_once (&sdidinit, __s_real_init); +} diff --git a/mit-pthreads/stdio/flags.c b/mit-pthreads/stdio/flags.c new file mode 100644 index 00000000000..c0971003312 --- /dev/null +++ b/mit-pthreads/stdio/flags.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.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/mit-pthreads/stdio/floatio.h b/mit-pthreads/stdio/floatio.h new file mode 100644 index 00000000000..cf3821488ae --- /dev/null +++ b/mit-pthreads/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$ + */ + +/* + * 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/mit-pthreads/stdio/fopen.c b/mit-pthreads/stdio/fopen.c new file mode 100644 index 00000000000..d44c17b633f --- /dev/null +++ b/mit-pthreads/stdio/fopen.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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); + } + + __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, (off_t)0, SEEK_END); + } + pthread_mutex_unlock(&__sfp_mutex); + return (fp); +} diff --git a/mit-pthreads/stdio/fprintf.c b/mit-pthreads/stdio/fprintf.c new file mode 100644 index 00000000000..bdeb49c054d --- /dev/null +++ b/mit-pthreads/stdio/fprintf.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fpurge.c b/mit-pthreads/stdio/fpurge.c new file mode 100644 index 00000000000..7edbb0b30cd --- /dev/null +++ b/mit-pthreads/stdio/fpurge.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fputc.c b/mit-pthreads/stdio/fputc.c new file mode 100644 index 00000000000..e6dd752f81b --- /dev/null +++ b/mit-pthreads/stdio/fputc.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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); +} + +int __putc(int _c, FILE *_p) +{ + int ret; + flockfile(_p); + ret = __sputc(_c, _p); + funlockfile(_p); + return(ret); +} + +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)); +} + diff --git a/mit-pthreads/stdio/fputs.c b/mit-pthreads/stdio/fputs.c new file mode 100644 index 00000000000..882b828409e --- /dev/null +++ b/mit-pthreads/stdio/fputs.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fread.c b/mit-pthreads/stdio/fread.c new file mode 100644 index 00000000000..0d8ec6186c7 --- /dev/null +++ b/mit-pthreads/stdio/fread.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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) memcpy((void *)p, (void *)fp->_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) memcpy((void *)p, (void *)fp->_p, resid); + fp->_r -= resid; + fp->_p += resid; +done_fread:; + funlockfile(fp); + return (count); +} diff --git a/mit-pthreads/stdio/freopen.c b/mit-pthreads/stdio/freopen.c new file mode 100644 index 00000000000..f45571c8ea0 --- /dev/null +++ b/mit-pthreads/stdio/freopen.c @@ -0,0 +1,149 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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); + } + + __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; + } else { + /* unlock __sfp_mutex, and try again later */ + pthread_mutex_unlock(&__sfp_mutex); + pthread_yield(); + continue; + } + /* @@ Yo, Chris! Between the "break" and "continue" statements + above, the program will never get here. What gives? */ + pthread_mutex_unlock(&__sfp_mutex); + funlockfile(fp); + return(ret); + } + (void)fclose(fp); + return(NULL); +} diff --git a/mit-pthreads/stdio/fscanf.c b/mit-pthreads/stdio/fscanf.c new file mode 100644 index 00000000000..8fbbac5d102 --- /dev/null +++ b/mit-pthreads/stdio/fscanf.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/fseek.c b/mit-pthreads/stdio/fseek.c new file mode 100644 index 00000000000..5c7feda638f --- /dev/null +++ b/mit-pthreads/stdio/fseek.c @@ -0,0 +1,248 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#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 */ + __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, (off_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, (off_t)0, 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, (off_t)curoff, SEEK_SET) != 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, (off_t)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/mit-pthreads/stdio/fsetpos.c b/mit-pthreads/stdio/fsetpos.c new file mode 100644 index 00000000000..a421d405f51 --- /dev/null +++ b/mit-pthreads/stdio/fsetpos.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/ftell.c b/mit-pthreads/stdio/ftell.c new file mode 100644 index 00000000000..e5961fa50b6 --- /dev/null +++ b/mit-pthreads/stdio/ftell.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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; +{ + long pos; + + flockfile((FILE *)fp); + + /* + * Find offset of underlying I/O object, then + * adjust for buffered bytes. + */ + if (fp->_flags & __SOFF) { + pos = fp->_offset; + } else { + pos = (long)__sseek((FILE *)fp, (off_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((FILE *)fp); + return (pos); +} diff --git a/mit-pthreads/stdio/funopen.c b/mit-pthreads/stdio/funopen.c new file mode 100644 index 00000000000..f8b37ed0ae4 --- /dev/null +++ b/mit-pthreads/stdio/funopen.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdlib.h> +#include <fcntl.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 = (off_t(*)())seekfn; + fd_ops->read = (pthread_ssize_t(*)())readfn; + fd_ops->write = (pthread_ssize_t(*)())writefn; + fd_ops->close = closefn; + fd_ops->use_kfds = 2; + + /* Alloc space for funtion pointer table */ + fd_table[fd]->type = FD_HALF_DUPLEX; + fd_table[fd]->ops = fd_ops; + fd_table[fd]->flags = O_RDWR; + + /* Save the cookie, it's important */ + fd_table[fd]->fd.ptr = (void *)cookie; + + if (fp = fdopen(fd, flags)) + return(fp); + + fd_free(fd); + } + free(fd_ops); + } + return(NULL); +} diff --git a/mit-pthreads/stdio/fvwrite.c b/mit-pthreads/stdio/fvwrite.c new file mode 100644 index 00000000000..5ed25b4e7b4 --- /dev/null +++ b/mit-pthreads/stdio/fvwrite.c @@ -0,0 +1,190 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.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) memcpy((void *)fp->_p, (void *)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/mit-pthreads/stdio/fvwrite.h b/mit-pthreads/stdio/fvwrite.h new file mode 100644 index 00000000000..b3474563a4e --- /dev/null +++ b/mit-pthreads/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$ + */ + +/* + * 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/mit-pthreads/stdio/fwalk.c b/mit-pthreads/stdio/fwalk.c new file mode 100644 index 00000000000..58a199e0707 --- /dev/null +++ b/mit-pthreads/stdio/fwalk.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 = n; + saveg = g; + savefp = fp; + continue; + } + } else { + ret |= __sflush(fp); + funlockfile(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)) { + flockfile(fp); + ret |= __sflush(fp); + funlockfile(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/mit-pthreads/stdio/fwrite.c b/mit-pthreads/stdio/fwrite.c new file mode 100644 index 00000000000..5eada4ee84b --- /dev/null +++ b/mit-pthreads/stdio/fwrite.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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; + if (! n) + return(0); + + 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/mit-pthreads/stdio/getc.c b/mit-pthreads/stdio/getc.c new file mode 100644 index 00000000000..6896e78bc7e --- /dev/null +++ b/mit-pthreads/stdio/getc.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/getc_unlocked.c b/mit-pthreads/stdio/getc_unlocked.c new file mode 100644 index 00000000000..01db3bcea2a --- /dev/null +++ b/mit-pthreads/stdio/getc_unlocked.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/getchar.c b/mit-pthreads/stdio/getchar.c new file mode 100644 index 00000000000..6e631c6c1b1 --- /dev/null +++ b/mit-pthreads/stdio/getchar.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/getchar_unlocked.c b/mit-pthreads/stdio/getchar_unlocked.c new file mode 100644 index 00000000000..40945c5dd57 --- /dev/null +++ b/mit-pthreads/stdio/getchar_unlocked.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/gets.c b/mit-pthreads/stdio/gets.c new file mode 100644 index 00000000000..0e7967ae3fe --- /dev/null +++ b/mit-pthreads/stdio/gets.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#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/mit-pthreads/stdio/getw.c b/mit-pthreads/stdio/getw.c new file mode 100644 index 00000000000..623ba6258a1 --- /dev/null +++ b/mit-pthreads/stdio/getw.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/glue.h b/mit-pthreads/stdio/glue.h new file mode 100644 index 00000000000..e5103bbb0b3 --- /dev/null +++ b/mit-pthreads/stdio/glue.h @@ -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. + * + * from: @(#)glue.h 5.1 (Berkeley) 1/20/91 + * $Id$ + */ + +/* + * The first few FILEs are statically allocated; others are dynamically + * allocated and linked in via this glue structure. + */ +typedef struct glue { + struct glue *next; + int niobs; + FILE *iobs; +} __sglue_type; +extern struct glue __sglue; diff --git a/mit-pthreads/stdio/local.h b/mit-pthreads/stdio/local.h new file mode 100644 index 00000000000..068754fad38 --- /dev/null +++ b/mit-pthreads/stdio/local.h @@ -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. + * + * from: @(#)local.h 5.3 (Berkeley) 5/6/93 + * $Id$ + */ + +/* + * Information local to this implementation of stdio, + * in particular, macros and private variables. + */ + +#include <sys/types.h> +#include <stddef.h> + +extern FILE *__sfp __P_((void)); +extern int __sflush __P_((FILE *)); +extern int __srefill __P_((FILE *)); +extern int __swrite __P_((FILE *, const char *, int)); +extern int __sread __P_((FILE *, char *, int)); +extern fpos_t __sseek __P_((FILE *, off_t, int)); +extern int __sclose __P_((FILE *)); +extern void __sinit __P_((void)); +extern void _cleanup __P_((void)); +extern void __smakebuf __P_((FILE *)); +extern int __swhatbuf __P_((FILE *, size_t *, int *)); +extern int __swalk_sflush __P_(()); +extern int __swsetup __P_((FILE *)); +extern int __sflags __P_((const char *, int *)); + +extern void (*__cleanup) __P_((void)); + +/* + * 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/mit-pthreads/stdio/makebuf.c b/mit-pthreads/stdio/makebuf.c new file mode 100644 index 00000000000..316abe054b6 --- /dev/null +++ b/mit-pthreads/stdio/makebuf.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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" + +void (*__cleanup) __P_((void)); + +/* + * 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/mit-pthreads/stdio/mktemp.c b/mit-pthreads/stdio/mktemp.c new file mode 100644 index 00000000000..7fdc631ad0b --- /dev/null +++ b/mit-pthreads/stdio/mktemp.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)mktemp.c 5.10 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> + +static int _gettemp(); + +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd) ? fd : -1); +} + +char * +mktemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); +} + +static +_gettemp(path, doopen) + char *path; + register int *doopen; +{ + extern int errno; + register char *start, *trv; + struct stat sbuf; + u_int pid; + + pid = getpid(); + for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } + else if (stat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return(0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit(*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +} diff --git a/mit-pthreads/stdio/perror.c b/mit-pthreads/stdio/perror.c new file mode 100644 index 00000000000..19fe52f5010 --- /dev/null +++ b/mit-pthreads/stdio/perror.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * Copyright (c) 1993, 1994 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)perror.c 5.11 (Berkeley) 2/24/91"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +char *strerror(int); /* For systems that don't prototype it in string.h */ + +void +perror(s) + const char *s; +{ + char * e; + + if (fd_lock(STDERR_FILENO, FD_WRITE, NULL) == OK) { + if (s && *s) { + fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd, + fd_table[STDERR_FILENO]->flags, s, strlen(s), NULL); + fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd, + fd_table[STDERR_FILENO]->flags, ": ", 2, NULL); + } + e = strerror(errno); + fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd, + fd_table[STDERR_FILENO]->flags, e, strlen(e), NULL); + fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd, + fd_table[STDERR_FILENO]->flags, "\n", 1, NULL); + fd_unlock(STDERR_FILENO, FD_WRITE); + } +} diff --git a/mit-pthreads/stdio/printf.c b/mit-pthreads/stdio/printf.c new file mode 100644 index 00000000000..a298509d341 --- /dev/null +++ b/mit-pthreads/stdio/printf.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#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/mit-pthreads/stdio/putc.c b/mit-pthreads/stdio/putc.c new file mode 100644 index 00000000000..ac71e35ff25 --- /dev/null +++ b/mit-pthreads/stdio/putc.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/putc_unlocked.c b/mit-pthreads/stdio/putc_unlocked.c new file mode 100644 index 00000000000..7c9c78ff1e8 --- /dev/null +++ b/mit-pthreads/stdio/putc_unlocked.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/putchar.c b/mit-pthreads/stdio/putchar.c new file mode 100644 index 00000000000..c22a11ea25d --- /dev/null +++ b/mit-pthreads/stdio/putchar.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/putchar_unlocked.c b/mit-pthreads/stdio/putchar_unlocked.c new file mode 100644 index 00000000000..df27a501211 --- /dev/null +++ b/mit-pthreads/stdio/putchar_unlocked.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/puts.c b/mit-pthreads/stdio/puts.c new file mode 100644 index 00000000000..97f8b3599f2 --- /dev/null +++ b/mit-pthreads/stdio/puts.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/putw.c b/mit-pthreads/stdio/putw.c new file mode 100644 index 00000000000..79473f0e243 --- /dev/null +++ b/mit-pthreads/stdio/putw.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/refill.c b/mit-pthreads/stdio/refill.c new file mode 100644 index 00000000000..396895e56ff --- /dev/null +++ b/mit-pthreads/stdio/refill.c @@ -0,0 +1,189 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 = n; + saveg = g; + savefp = fp; + continue; + } + } else { + (void) __sflush(fp); + funlockfile(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)) { + flockfile(fp); + (void) __sflush(fp); + funlockfile(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 */ + __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->_file == -1) { + fp->_flags |= __SEOF; + return(EOF); + } + + 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/mit-pthreads/stdio/remove.c b/mit-pthreads/stdio/remove.c new file mode 100644 index 00000000000..116537e3a0f --- /dev/null +++ b/mit-pthreads/stdio/remove.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <unistd.h> + +remove(file) + const char *file; +{ + return (unlink(file)); +} diff --git a/mit-pthreads/stdio/rewind.c b/mit-pthreads/stdio/rewind.c new file mode 100644 index 00000000000..17d4418db39 --- /dev/null +++ b/mit-pthreads/stdio/rewind.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/rget.c b/mit-pthreads/stdio/rget.c new file mode 100644 index 00000000000..a2b19afb130 --- /dev/null +++ b/mit-pthreads/stdio/rget.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/scanf.c b/mit-pthreads/stdio/scanf.c new file mode 100644 index 00000000000..9f9f5a6665e --- /dev/null +++ b/mit-pthreads/stdio/scanf.c @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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); + funlockfile(stdin); + va_end(ap); + return (ret); +} diff --git a/mit-pthreads/stdio/setbuf.c b/mit-pthreads/stdio/setbuf.c new file mode 100644 index 00000000000..af8d088089d --- /dev/null +++ b/mit-pthreads/stdio/setbuf.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/setbuffer.c b/mit-pthreads/stdio/setbuffer.c new file mode 100644 index 00000000000..0c79e55fd93 --- /dev/null +++ b/mit-pthreads/stdio/setbuffer.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/setvbuf.c b/mit-pthreads/stdio/setvbuf.c new file mode 100644 index 00000000000..288d8c32db0 --- /dev/null +++ b/mit-pthreads/stdio/setvbuf.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 = size; /* Was 0 (mevans) */ + 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/mit-pthreads/stdio/snprintf.c b/mit-pthreads/stdio/snprintf.c new file mode 100644 index 00000000000..dd9bca24f73 --- /dev/null +++ b/mit-pthreads/stdio/snprintf.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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._file = -1; + 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/mit-pthreads/stdio/sprintf.c b/mit-pthreads/stdio/sprintf.c new file mode 100644 index 00000000000..a500e8d4afa --- /dev/null +++ b/mit-pthreads/stdio/sprintf.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <limits.h> +#include <stdio.h> +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#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._file = -1; + 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/mit-pthreads/stdio/sscanf.c b/mit-pthreads/stdio/sscanf.c new file mode 100644 index 00000000000..50148192b9c --- /dev/null +++ b/mit-pthreads/stdio/sscanf.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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/mit-pthreads/stdio/stdio.c b/mit-pthreads/stdio/stdio.c new file mode 100644 index 00000000000..0b676eeb09b --- /dev/null +++ b/mit-pthreads/stdio/stdio.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 (fd_table[fp->_file]->ops->use_kfds < 2) { + ret = fd_table[fp->_file]->ops->read(fd_table[fp->_file]->fd, + fd_table[fp->_file]->flags, buf, n, NULL); + } else { + pthread_ssize_t (*readfn)() = fd_table[fp->_file]->ops->read; + ret = readfn(fd_table[fp->_file]->fd, buf, n); + } + if (ret >= 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 */ + if (fd_table[fp->_file]->ops->use_kfds < 2) { + return(fd_table[fp->_file]->ops->write(fd_table[fp->_file]->fd, + fd_table[fp->_file]->flags, buf, n, NULL)); + } else { + pthread_ssize_t (*writefn)() = fd_table[fp->_file]->ops->write; + return(writefn(fd_table[fp->_file]->fd,buf,n)); + } +} + +fpos_t __sseek(FILE *fp, off_t offset, int whence) +{ + register fpos_t ret; + + ret = (fpos_t)lseek(fp->_file, 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/mit-pthreads/stdio/strerror.c b/mit-pthreads/stdio/strerror.c new file mode 100644 index 00000000000..5aea7e7a4fc --- /dev/null +++ b/mit-pthreads/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/mit-pthreads/stdio/tempnam.c b/mit-pthreads/stdio/tempnam.c new file mode 100644 index 00000000000..88150a18019 --- /dev/null +++ b/mit-pthreads/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$"; +#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/mit-pthreads/stdio/tmpfile.c b/mit-pthreads/stdio/tmpfile.c new file mode 100644 index 00000000000..471bed33716 --- /dev/null +++ b/mit-pthreads/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$"; +#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)]; + + memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1); + memcpy( buf + sizeof(_PATH_TMP) - 1, TRAILER, 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/mit-pthreads/stdio/tmpnam.c b/mit-pthreads/stdio/tmpnam.c new file mode 100644 index 00000000000..8d65b21b037 --- /dev/null +++ b/mit-pthreads/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$"; +#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/mit-pthreads/stdio/ungetc.c b/mit-pthreads/stdio/ungetc.c new file mode 100644 index 00000000000..e035f93d5f2 --- /dev/null +++ b/mit-pthreads/stdio/ungetc.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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) memcpy((void *)(p + i), (void *)p, (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); + __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/mit-pthreads/stdio/vfprintf.c b/mit-pthreads/stdio/vfprintf.c new file mode 100644 index 00000000000..fd990bb1889 --- /dev/null +++ b/mit-pthreads/stdio/vfprintf.c @@ -0,0 +1,788 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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 <stdarg.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; + pthread_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; + pthread_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 + +#if defined (__alpha) && !defined(_GNUC_) +#define quad_t long +#define u_quad_t unsigned long +#else /* 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)(size_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'; +/* #if !defined(__alpha__) && !defined(hpux) */ +#ifndef THIS_IS_NEVER_DEFINED + digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); +#else + { char *ecvt(double,int,int*,int*); + + digits = ecvt(value, ndigits, decpt, &dsgn); + rve = (digits + (int)strlen(digits)); + } +#endif + 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/mit-pthreads/stdio/vfscanf.c b/mit-pthreads/stdio/vfscanf.c new file mode 100644 index 00000000000..f6d0a40aa51 --- /dev/null +++ b/mit-pthreads/stdio/vfscanf.c @@ -0,0 +1,750 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#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; + pthread_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/mit-pthreads/stdio/vprintf.c b/mit-pthreads/stdio/vprintf.c new file mode 100644 index 00000000000..4999c4fb239 --- /dev/null +++ b/mit-pthreads/stdio/vprintf.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#include <stdio.h> + +vprintf(fmt, ap) + char const *fmt; + pthread_va_list ap; +{ + return (vfprintf(stdout, fmt, ap)); +} diff --git a/mit-pthreads/stdio/vscanf.c b/mit-pthreads/stdio/vscanf.c new file mode 100644 index 00000000000..5a562f89528 --- /dev/null +++ b/mit-pthreads/stdio/vscanf.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#include <stdio.h> + +vscanf(fmt, ap) + const char *fmt; + pthread_va_list ap; +{ + int r; + flockfile(stdin); + r = __svfscanf(stdin, fmt, ap); + funlockfile(stdin); + return(r); +} diff --git a/mit-pthreads/stdio/vsnprintf.c b/mit-pthreads/stdio/vsnprintf.c new file mode 100644 index 00000000000..8fd1e6d8613 --- /dev/null +++ b/mit-pthreads/stdio/vsnprintf.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> + +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + const char *fmt; + pthread_va_list ap; +{ + int ret; + FILE f; + + if ((int)n < 1) + return (EOF); + f._file = -1; + 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/mit-pthreads/stdio/vsprintf.c b/mit-pthreads/stdio/vsprintf.c new file mode 100644 index 00000000000..c6cdb708be3 --- /dev/null +++ b/mit-pthreads/stdio/vsprintf.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#include <limits.h> +#include <stdio.h> + +vsprintf(str, fmt, ap) + char *str; + const char *fmt; + pthread_va_list ap; +{ + int ret; + FILE f; + + f._file = -1; + 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/mit-pthreads/stdio/vsscanf.c b/mit-pthreads/stdio/vsscanf.c new file mode 100644 index 00000000000..9d9cdcffeeb --- /dev/null +++ b/mit-pthreads/stdio/vsscanf.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +vsscanf(str, fmt, ap) + const char *str; + const char *fmt; + pthread_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/mit-pthreads/stdio/wbuf.c b/mit-pthreads/stdio/wbuf.c new file mode 100644 index 00000000000..58cb9ad058e --- /dev/null +++ b/mit-pthreads/stdio/wbuf.c @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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/mit-pthreads/stdio/wsetup.c b/mit-pthreads/stdio/wsetup.c new file mode 100644 index 00000000000..1c86f45a973 --- /dev/null +++ b/mit-pthreads/stdio/wsetup.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * Copyright (c) 1993, 1994 Chris Provenzano. + * 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$"; +#endif /* LIBC_SCCS and not lint */ + +#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 */ + __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/mit-pthreads/stdio/xprintf.c b/mit-pthreads/stdio/xprintf.c new file mode 100644 index 00000000000..668e8bc0605 --- /dev/null +++ b/mit-pthreads/stdio/xprintf.c @@ -0,0 +1,883 @@ +/* +** It turns out that the printf functions in the stock MIT pthread library +** is busted. It isn't thread safe. If two threads try to do a printf +** of a floating point value at the same time, a core-dump might result. +** So this code is substituted. +*/ +/* +** NAME: $Source$ +** VERSION: $Revision$ +** DATE: $Date$ +** +** ONELINER: A replacement for formatted printing programs. +** +** COPYRIGHT: +** Copyright (c) 1990 by D. Richard Hipp. This code is an original +** work and has been prepared without reference to any prior +** implementations of similar functions. No part of this code is +** subject to licensing restrictions of any telephone company or +** university. +** +** This copyright was released and the code placed in the public domain +** by the author, D. Richard Hipp, on October 3, 1996. +** +** DESCRIPTION: +** This program is an enhanced replacement for the "printf" programs +** found in the standard library. The following enhancements are +** supported: +** +** + Additional functions. The standard set of "printf" functions +** includes printf, fprintf, sprintf, vprintf, vfprintf, and +** vsprintf. This module adds the following: +** +** * snprintf -- Works like sprintf, but has an extra argument +** which is the size of the buffer written to. +** +** * mprintf -- Similar to sprintf. Writes output to memory +** obtained from mem_alloc. +** +** * xprintf -- Calls a function to dispose of output. +** +** * nprintf -- No output, but returns the number of characters +** that would have been output by printf. +** +** * A v- version (ex: vsnprintf) of every function is also +** supplied. +** +** + A few extensions to the formatting notation are supported: +** +** * The "=" flag (similar to "-") causes the output to be +** be centered in the appropriately sized field. +** +** * The %b field outputs an integer in binary notation. +** +** * The %c field now accepts a precision. The character output +** is repeated by the number of times the precision specifies. +** +** * The %' field works like %c, but takes as its character the +** next character of the format string, instead of the next +** argument. For example, printf("%.78'-") prints 78 minus +** signs, the same as printf("%.78c",'-'). +** +** + When compiled using GCC on a SPARC, this version of printf is +** faster than the library printf for SUN OS 4.1. +** +** + All functions are fully reentrant. +** +*/ +/* +** Undefine COMPATIBILITY to make some slight changes in the way things +** work. I think the changes are an improvement, but they are not +** backwards compatible. +*/ +/* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */ +#include <stdio.h> +#include <stdarg.h> +#include <ctype.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +/* +** The maximum number of digits of accuracy in a floating-point conversion. +*/ +#define MAXDIG 20 + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +enum e_type { /* The type of the format field */ + RADIX, /* Integer types. %d, %x, %o, and so forth */ + FLOAT, /* Floating point. %f */ + EXP, /* Exponentional notation. %e and %E */ + GENERIC, /* Floating or exponential, depending on exponent. %g */ + SIZE, /* Return number of characters processed so far. %n */ + STRING, /* Strings. %s */ + PERCENT, /* Percent symbol. %% */ + CHAR, /* Characters. %c */ + ERROR, /* Used to indicate no such conversion type */ +/* The rest are extensions, not normally found in printf() */ + CHARLIT, /* Literal characters. %' */ + SEEIT, /* Strings with visible control characters. %S */ + MEM_STRING, /* A string which should be deleted after use. %z */ + ORDINAL, /* 1st, 2nd, 3rd and so forth */ +}; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct s_info { /* Information about each format field */ + int fmttype; /* The format field code letter */ + int base; /* The base for radix conversion */ + char *charset; /* The character set for conversion */ + int flag_signed; /* Is the quantity signed? */ + char *prefix; /* Prefix on non-zero values in alt format */ + enum e_type type; /* Conversion paradigm */ +} info; + +/* +** The following table is searched linearly, so it is good to put the +** most frequently used conversion types first. +*/ +static info fmtinfo[] = { + { 'd', 10, "0123456789", 1, 0, RADIX, }, + { 's', 0, 0, 0, 0, STRING, }, + { 'S', 0, 0, 0, 0, SEEIT, }, + { 'z', 0, 0, 0, 0, MEM_STRING, }, + { 'c', 0, 0, 0, 0, CHAR, }, + { 'o', 8, "01234567", 0, "0", RADIX, }, + { 'u', 10, "0123456789", 0, 0, RADIX, }, + { 'x', 16, "0123456789abcdef", 0, "x0", RADIX, }, + { 'X', 16, "0123456789ABCDEF", 0, "X0", RADIX, }, + { 'r', 10, "0123456789", 0, 0, ORDINAL, }, + { 'f', 0, 0, 1, 0, FLOAT, }, + { 'e', 0, "e", 1, 0, EXP, }, + { 'E', 0, "E", 1, 0, EXP, }, + { 'g', 0, "e", 1, 0, GENERIC, }, + { 'G', 0, "E", 1, 0, GENERIC, }, + { 'i', 10, "0123456789", 1, 0, RADIX, }, + { 'n', 0, 0, 0, 0, SIZE, }, + { 'S', 0, 0, 0, 0, SEEIT, }, + { '%', 0, 0, 0, 0, PERCENT, }, + { 'b', 2, "01", 0, "b0", RADIX, }, /* Binary notation */ + { 'p', 10, "0123456789", 0, 0, RADIX, }, /* Pointers */ + { '\'', 0, 0, 0, 0, CHARLIT, }, /* Literal char */ +}; +#define NINFO (sizeof(fmtinfo)/sizeof(info)) /* Size of the fmtinfo table */ + +/* +** If NOFLOATINGPOINT is defined, then none of the floating point +** conversions will work. +*/ +#ifndef NOFLOATINGPOINT +/* +** "*val" is a double such that 0.1 <= *val < 10.0 +** Return the ascii code for the leading digit of *val, then +** multiply "*val" by 10.0 to renormalize. +** +** Example: +** input: *val = 3.14159 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static int getdigit(long double *val, int *cnt){ + int digit; + long double d; + if( (*cnt)++ >= MAXDIG ) return '0'; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return digit; +} +#endif + +/* +** Setting the size of the BUFFER involves trade-offs. No %d or %f +** conversion can have more than BUFSIZE characters. If the field +** width is larger than BUFSIZE, it is silently shortened. On the +** other hand, this routine consumes more stack space with larger +** BUFSIZEs. If you have some threads for which you want to minimize +** stack space, you should keep BUFSIZE small. +*/ +#define BUFSIZE 100 /* Size of the output buffer */ + +/* +** The root program. All variations call this core. +** +** INPUTS: +** func This is a pointer to a function taking three arguments +** 1. A pointer to the list of characters to be output +** (Note, this list is NOT null terminated.) +** 2. An integer number of characters to be output. +** (Note: This number might be zero.) +** 3. A pointer to anything. Same as the "arg" parameter. +** +** arg This is the pointer to anything which will be passed as the +** third argument to "func". Use it for whatever you like. +** +** fmt This is the format string, as in the usual print. +** +** ap This is a pointer to a list of arguments. Same as in +** vfprint. +** +** OUTPUTS: +** The return value is the total number of characters sent to +** the function "func". Returns -1 on a error. +** +** Note that the order in which automatic variables are declared below +** seems to make a big difference in determining how fast this beast +** will run. +*/ +static int vxprintf(func,arg,format,ap) + void (*func)(char*,int,void*); + void *arg; + const char *format; + va_list ap; +{ + register const char *fmt; /* The format string. */ + register int c; /* Next character in the format string */ + register char *bufpt; /* Pointer to the conversion buffer */ + register int precision; /* Precision of the current field */ + register int length; /* Length of the field */ + register int idx; /* A general purpose loop counter */ + int count; /* Total number of characters output */ + int width; /* Width of the current field */ + int flag_leftjustify; /* True if "-" flag is present */ + int flag_plussign; /* True if "+" flag is present */ + int flag_blanksign; /* True if " " flag is present */ + int flag_alternateform; /* True if "#" flag is present */ + int flag_zeropad; /* True if field width constant starts with zero */ + int flag_long; /* True if "l" flag is present */ + int flag_center; /* True if "=" flag is present */ + unsigned long longvalue; /* Value for integer types */ + long double realvalue; /* Value for real types */ + info *infop; /* Pointer to the appropriate info structure */ + char buf[BUFSIZE]; /* Conversion buffer */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + int errorflag = 0; /* True if an error is encountered */ + enum e_type xtype; /* Conversion paradigm */ + char *zMem; /* String to be freed */ + static char spaces[] = + " "; +#define SPACESIZE (sizeof(spaces)-1) +#ifndef NOFLOATINGPOINT + int exp; /* exponent of real numbers */ + long double rounder; /* Used for rounding floating point values */ + int flag_dp; /* True if decimal point should be shown */ + int flag_rtz; /* True if trailing zeros should be removed */ + int flag_exp; /* True to force display of the exponent */ + int nsd; /* Number of significant digits returned */ +#endif + + fmt = format; /* Put in a register for speed */ + count = length = 0; + bufpt = 0; + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + register int amt; + bufpt = (char *)fmt; + amt = 1; + while( (c=(*++fmt))!='%' && c!=0 ) amt++; + (*func)(bufpt,amt,arg); + count += amt; + if( c==0 ) break; + } + if( (c=(*++fmt))==0 ){ + errorflag = 1; + (*func)("%",1,arg); + count++; + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_plussign = flag_blanksign = + flag_alternateform = flag_zeropad = flag_center = 0; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; c = 0; break; + case '+': flag_plussign = 1; c = 0; break; + case ' ': flag_blanksign = 1; c = 0; break; + case '#': flag_alternateform = 1; c = 0; break; + case '0': flag_zeropad = 1; c = 0; break; + case '=': flag_center = 1; c = 0; break; + default: break; + } + }while( c==0 && (c=(*++fmt))!=0 ); + if( flag_center ) flag_leftjustify = 0; + /* Get the field width */ + width = 0; + if( c=='*' ){ + width = va_arg(ap,int); + if( width<0 ){ + flag_leftjustify = 1; + width = -width; + } + c = *++fmt; + }else{ + while( isdigit(c) ){ + width = width*10 + c - '0'; + c = *++fmt; + } + } + if( width > BUFSIZE-10 ){ + width = BUFSIZE-10; + } + /* Get the precision */ + if( c=='.' ){ + precision = 0; + c = *++fmt; + if( c=='*' ){ + precision = va_arg(ap,int); +#ifndef COMPATIBILITY + /* This is sensible, but SUN OS 4.1 doesn't do it. */ + if( precision<0 ) precision = -precision; +#endif + c = *++fmt; + }else{ + while( isdigit(c) ){ + precision = precision*10 + c - '0'; + c = *++fmt; + } + } + /* Limit the precision to prevent overflowing buf[] during conversion */ + if( precision>BUFSIZE-40 ) precision = BUFSIZE-40; + }else{ + precision = -1; + } + /* Get the conversion type modifier */ + if( c=='l' ){ + flag_long = 1; + c = *++fmt; + }else{ + flag_long = 0; + } + /* Fetch the info entry for the field */ + infop = 0; + for(idx=0; idx<NINFO; idx++){ + if( c==fmtinfo[idx].fmttype ){ + infop = &fmtinfo[idx]; + break; + } + } + /* No info entry found. It must be an error. */ + if( infop==0 ){ + xtype = ERROR; + }else{ + xtype = infop->type; + } + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_plussign TRUE if a '+' is present. + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long TRUE if the letter 'l' (ell) prefixed + ** the conversion character. + ** flag_blanksign TRUE if a ' ' is present. + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + switch( xtype ){ + case ORDINAL: + case RADIX: + if( flag_long ) longvalue = va_arg(ap,long); + else longvalue = va_arg(ap,int); +#ifdef COMPATIBILITY + /* For the format %#x, the value zero is printed "0" not "0x0". + ** I think this is stupid. */ + if( longvalue==0 ) flag_alternateform = 0; +#else + /* More sensible: turn off the prefix for octal (to prevent "00"), + ** but leave the prefix for hex. */ + if( longvalue==0 && infop->base==8 ) flag_alternateform = 0; +#endif + if( infop->flag_signed ){ + if( *(long*)&longvalue<0 ){ + longvalue = -*(long*)&longvalue; + prefix = '-'; + }else if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + }else prefix = 0; + if( flag_zeropad && precision<width-(prefix!=0) ){ + precision = width-(prefix!=0); + } + bufpt = &buf[BUFSIZE]; + if( xtype==ORDINAL ){ + long a,b; + a = longvalue%10; + b = longvalue%100; + bufpt -= 2; + if( a==0 || a>3 || (b>10 && b<14) ){ + bufpt[0] = 't'; + bufpt[1] = 'h'; + }else if( a==1 ){ + bufpt[0] = 's'; + bufpt[1] = 't'; + }else if( a==2 ){ + bufpt[0] = 'n'; + bufpt[1] = 'd'; + }else if( a==3 ){ + bufpt[0] = 'r'; + bufpt[1] = 'd'; + } + } + { + register char *cset; /* Use registers for speed */ + register int base; + cset = infop->charset; + base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&buf[BUFSIZE]-bufpt); + for(idx=precision-length; idx>0; idx--){ + *(--bufpt) = '0'; /* Zero pad */ + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + char *pre, x; + pre = infop->prefix; + if( *bufpt!=pre[0] ){ + for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + } + length = (int)(&buf[BUFSIZE]-bufpt); + break; + case FLOAT: + case EXP: + case GENERIC: + realvalue = va_arg(ap,double); +#ifndef NOFLOATINGPOINT + if( precision<0 ) precision = 6; /* Set default precision */ + if( precision>BUFSIZE-10 ) precision = BUFSIZE-10; + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; + }else{ + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + if( infop->type==GENERIC && precision>0 ) precision--; + rounder = 0.0; +#ifdef COMPATIBILITY + /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ + for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); +#else + /* It makes more sense to use 0.5 */ + if( precision>MAXDIG-1 ) idx = MAXDIG-1; + else idx = precision; + for(rounder=0.5; idx>0; idx--, rounder*=0.1); +#endif + if( infop->type==FLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( realvalue>0.0 ){ + int k = 0; + while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; } + while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; } + while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; } + if( k>=100 ){ + bufpt = "NaN"; + length = 3; + break; + } + } + bufpt = buf; + /* + ** If the field type is GENERIC, then convert to either EXP + ** or FLOAT, as appropriate. + */ + flag_exp = xtype==EXP; + if( xtype!=FLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + if( xtype==GENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = EXP; + }else{ + precision = precision - exp; + xtype = FLOAT; + } + }else{ + flag_rtz = 0; + } + /* + ** The "exp+precision" test causes output to be of type EXP if + ** the precision is too large to fit in buf[]. + */ + nsd = 0; + if( xtype==FLOAT && exp+precision<BUFSIZE-30 ){ + flag_dp = (precision>0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ + else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue,&nsd); + if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ + for(exp++; exp<0 && precision>0; precision--, exp++){ + *(bufpt++) = '0'; + } + while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd); + *(bufpt--) = 0; /* Null terminate */ + if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + }else{ /* EXP or GENERIC */ + flag_dp = (precision>0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + *(bufpt++) = getdigit(&realvalue,&nsd); /* First digit */ + if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ + while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd); + bufpt--; /* point to last digit */ + if( flag_rtz && flag_dp ){ /* Remove tail zeros */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + if( exp || flag_exp ){ + *(bufpt++) = infop->charset[0]; + if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ + else { *(bufpt++) = '+'; } + if( exp>=100 ){ + *(bufpt++) = (exp/100)+'0'; /* 100's digit */ + exp %= 100; + } + *(bufpt++) = exp/10+'0'; /* 10's digit */ + *(bufpt++) = exp%10+'0'; /* 1's digit */ + } + } + /* The converted number is in buf[] and zero terminated. Output it. + ** Note that the number is in the usual order, not reversed as with + ** integer conversions. */ + length = (int)(bufpt-buf); + bufpt = buf; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } +#endif + break; + case SIZE: + *(va_arg(ap,int*)) = count; + length = width = 0; + break; + case PERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case CHARLIT: + case CHAR: + c = buf[0] = (xtype==CHAR ? va_arg(ap,int) : *++fmt); + if( precision>=0 ){ + for(idx=1; idx<precision; idx++) buf[idx] = c; + length = precision; + }else{ + length =1; + } + bufpt = buf; + break; + case STRING: + case MEM_STRING: + zMem = bufpt = va_arg(ap,char*); + if( bufpt==0 ) bufpt = "(null)"; + length = strlen(bufpt); + if( precision>=0 && precision<length ) length = precision; + break; + case SEEIT: + { + int i; + int c; + char *arg = va_arg(ap,char*); + for(i=0; i<BUFSIZE-1 && (c = *arg++)!=0; i++){ + if( c<0x20 || c>=0x7f ){ + buf[i++] = '^'; + buf[i] = (c&0x1f)+0x40; + }else{ + buf[i] = c; + } + } + bufpt = buf; + length = i; + if( precision>=0 && precision<length ) length = precision; + } + break; + case ERROR: + buf[0] = '%'; + buf[1] = c; + errorflag = 0; + idx = 1+(c!=0); + (*func)("%",idx,arg); + count += idx; + if( c==0 ) fmt--; + break; + }/* End switch over the format type */ + /* + ** The text of the conversion is pointed to by "bufpt" and is + ** "length" characters long. The field width is "width". Do + ** the output. + */ + if( !flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + if( flag_center ){ + nspace = nspace/2; + width -= nspace; + flag_leftjustify = 1; + } + count += nspace; + while( nspace>=SPACESIZE ){ + (*func)(spaces,SPACESIZE,arg); + nspace -= SPACESIZE; + } + if( nspace>0 ) (*func)(spaces,nspace,arg); + } + } + if( length>0 ){ + (*func)(bufpt,length,arg); + count += length; + } + if( xtype==MEM_STRING && zMem ){ + free(zMem); + } + if( flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + count += nspace; + while( nspace>=SPACESIZE ){ + (*func)(spaces,SPACESIZE,arg); + nspace -= SPACESIZE; + } + if( nspace>0 ) (*func)(spaces,nspace,arg); + } + } + }/* End for loop over the format string */ + return errorflag ? -1 : count; +} /* End of function */ + +/* +** This non-standard function is still occasionally useful.... +*/ +int xprintf( + void (*func)(char*,int,void*), + void *arg, + const char *format, + ... +){ + va_list ap; + va_start(ap,format); + return vxprintf(func,arg,format,ap); +} + +/* +** Now for string-print, also as found in any standard library. +** Add to this the snprint function which stops added characters +** to the string at a given length. +** +** Note that snprint returns the length of the string as it would +** be if there were no limit on the output. +*/ +struct s_strargument { /* Describes the string being written to */ + char *next; /* Next free slot in the string */ + char *last; /* Last available slot in the string */ +}; + +static void sout(txt,amt,arg) + char *txt; + int amt; + void *arg; +{ + register char *head; + register const char *t; + register int a; + register char *tail; + a = amt; + t = txt; + head = ((struct s_strargument*)arg)->next; + tail = ((struct s_strargument*)arg)->last; + if( tail ){ + while( a-- >0 && head<tail ) *(head++) = *(t++); + }else{ + while( a-- >0 ) *(head++) = *(t++); + } + *head = 0; + ((struct s_strargument*)arg)->next = head; +} + +int sprintf(char *buf, const char *fmt, ...){ + int rc; + va_list ap; + struct s_strargument arg; + + va_start(ap,fmt); + arg.next = buf; + arg.last = 0; + *arg.next = 0; + rc = vxprintf(sout,&arg,fmt,ap); + va_end(ap); +} +int vsprintf(char *buf,const char *fmt,va_list ap){ + struct s_strargument arg; + arg.next = buf; + arg.last = 0; + *buf = 0; + return vxprintf(sout,&arg,fmt,ap); +} +int snprintf(char *buf, size_t n, const char *fmt, ...){ + int rc; + va_list ap; + struct s_strargument arg; + + va_start(ap,fmt); + arg.next = buf; + arg.last = &arg.next[n-1]; + *arg.next = 0; + rc = vxprintf(sout,&arg,fmt,ap); + va_end(ap); +} +int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap){ + struct s_strargument arg; + arg.next = buf; + arg.last = &buf[n-1]; + *buf = 0; + return vxprintf(sout,&arg,fmt,ap); +} + +/* +** The following section of code handles the mprintf routine, that +** writes to memory obtained from malloc(). +*/ + +/* This structure is used to store state information about the +** write in progress +*/ +struct sgMprintf { + char *zBase; /* A base allocation */ + char *zText; /* The string collected so far */ + int nChar; /* Length of the string so far */ + int nAlloc; /* Amount of space allocated in zText */ +}; + +/* The xprintf callback function. */ +static void mout(zNewText,nNewChar,arg) + char *zNewText; + int nNewChar; + void *arg; +{ + struct sgMprintf *pM = (struct sgMprintf*)arg; + if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ + pM->nAlloc = pM->nChar + nNewChar*2 + 1; + if( pM->zText==pM->zBase ){ + pM->zText = malloc(pM->nAlloc); + if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar); + }else{ + pM->zText = realloc(pM->zText, pM->nAlloc); + } + } + if( pM->zText ){ + memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); + pM->nChar += nNewChar; + pM->zText[pM->nChar] = 0; + } +} + +/* +** mprintf() works like printf(), but allocations memory to hold the +** resulting string and returns a pointer to the allocated memory. +** +** We changed the name to TclMPrint() to conform with the Tcl private +** routine naming conventions. +*/ +char *mprintf(const char *zFormat, ...){ + va_list ap; + struct sgMprintf sMprintf; + char *zNew; + char zBuf[200]; + + va_start(ap,zFormat); + sMprintf.nChar = 0; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zText = zBuf; + sMprintf.zBase = zBuf; + vxprintf(mout,&sMprintf,zFormat,ap); + va_end(ap); + if( sMprintf.zText==sMprintf.zBase ){ + zNew = malloc( sMprintf.nChar+1 ); + if( zNew ) strcpy(zNew,zBuf); + }else{ + zNew = realloc(sMprintf.zText,sMprintf.nChar+1); + } + + return zNew; +} + +/* This is the varargs version of mprintf. +** +** The name is changed to TclVMPrintf() to conform with Tcl naming +** conventions. +*/ +char *vmprintf(const char *zFormat,va_list ap){ + struct sgMprintf sMprintf; + char zBuf[200]; + sMprintf.nChar = 0; + sMprintf.zText = zBuf; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zBase = zBuf; + vxprintf(mout,&sMprintf,zFormat,ap); + if( sMprintf.zText==sMprintf.zBase ){ + sMprintf.zText = malloc( strlen(zBuf)+1 ); + if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf); + }else{ + sMprintf.zText = realloc(sMprintf.zText,sMprintf.nChar+1); + } + return sMprintf.zText; +} + +/* +** The following section of code handles the standard fprintf routines +** for pthreads. +*/ + +/* The xprintf callback function. */ +static void fout(zNewText,nNewChar,arg) + char *zNewText; + int nNewChar; + void *arg; +{ + fwrite(zNewText,1,nNewChar,(FILE*)arg); +} + +/* The public interface routines */ +int fprintf(FILE *pOut, const char *zFormat, ...){ + va_list ap; + int retc; + + va_start(ap,zFormat); + retc = vxprintf(fout,pOut,zFormat,ap); + va_end(ap); + return retc; +} +int vfprintf(FILE *pOut, const char *zFormat, va_list ap){ + return vxprintf(fout,pOut,zFormat,ap); +} +int printf(const char *zFormat, ...){ + va_list ap; + int retc; + + va_start(ap,zFormat); + retc = vxprintf(fout,stdout,zFormat,ap); + va_end(ap); + return retc; +} +int vprintf(const char *zFormat, va_list ap){ + return vxprintf(fout,stdout,zFormat,ap); +} |