new stdio
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 21 Jan 1991 13:10:43 +0000 (05:10 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 21 Jan 1991 13:10:43 +0000 (05:10 -0800)
SCCS-vsn: lib/libc/stdio/fclose.3 6.3
SCCS-vsn: lib/libc/stdio/fdopen.c 5.3
SCCS-vsn: lib/libc/stdio/ferror.3 6.5
SCCS-vsn: lib/libc/stdio/fgetc.c 5.3
SCCS-vsn: lib/libc/stdio/fgets.3 6.5
SCCS-vsn: lib/libc/stdio/fgets.c 5.3

usr/src/lib/libc/stdio/fclose.3
usr/src/lib/libc/stdio/fdopen.c
usr/src/lib/libc/stdio/ferror.3
usr/src/lib/libc/stdio/fgetc.c
usr/src/lib/libc/stdio/fgets.3
usr/src/lib/libc/stdio/fgets.c

index ed96197..d8782a5 100644 (file)
@@ -1,59 +1,59 @@
-.\"    @(#)fclose.3    6.2 (Berkeley) %G%
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
 .\"
 .\"
-.TH FCLOSE 3S  ""
-.AT 3
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
+.\" %sccs.include.redist.man%
+.\"
+.\"    @(#)fclose.3    6.3 (Berkeley) %G%
+.\"
+.TH FCLOSE 3 ""
+.UC 7
 .SH NAME
 .SH NAME
-fclose, fflush \- close or flush a stream
+fclose \- close a stream
 .SH SYNOPSIS
 .SH SYNOPSIS
-.B #include <stdio.h>
-.PP
-.B fclose(stream)
-.br
-.SM
-.B FILE
-.B *stream;
-.PP
-.B fflush(stream)
-.br
-.SM
-.B FILE
-.B *stream;
-.PP
-.B fpurge(stream)
-.br
-.SM
-.B FILE
-.B *stream;
+.nf
+.ft B
+#include <stdio.h>
+
+int
+fclose(FILE *stream);
+.ft R
+.fi
 .SH DESCRIPTION
 .I Fclose
 .SH DESCRIPTION
 .I Fclose
-causes any buffers for the named
-.I stream
-to be emptied, and the file to be closed.
-Buffers allocated by the standard input/output system
-are freed.
-.PP
-.I Fclose
-is performed automatically upon
-calling
-.IR  exit (3).
-.PP
-.I Fflush
-causes any buffered data for the named output
-.I stream
-to be written to that file.
-The stream remains open.
-.PP
-.I Fpurge
-causes any buffered data for the named
+dissociates the named
 .I stream
 .I stream
-to be lost.  The stream remains open.
+from its underlying file or set of functions.
+If the stream was being used for output, any buffered data is written
+first, using
+.IR fflush (3).
+Any allocated memory is 
+.IR free 'd.
 .SH "SEE ALSO"
 .SH "SEE ALSO"
-close(2), fopen(3), setbuf(3)
-.SH DIAGNOSTICS
-These routines return
-.SM
+close(2), fflush(3), fopen(3), free(3), setbuf(3)
+.SH "RETURN VALUE"
+Upon successful completion 0 is returned.
+Otherwise,
 .B EOF
 .B EOF
-if
-.I stream
-is not associated with an output file, or
-if buffered data cannot be transferred to that file.
+is returned and the global variable
+.I errno
+is set to indicate the error.
+In either case no further access to the stream is possible. 
+.SH ERRORS
+.TP 15
+[EBADF]
+.I Stream
+is not an open stream.
+.PP
+.I Fclose
+may also fail and set 
+.I errno
+for any of the errors specified for the routines
+.IR close (2)
+or 
+.IR fflush (3).
+.SH STANDARDS
+.I Fclose
+conforms to ANSI X3.159-1989 (``ANSI C'').
index 0782f3b..3b0b1e2 100644 (file)
@@ -1,62 +1,64 @@
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+/*-
+ * 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.
+ *
+ * %sccs.include.redist.c%
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fdopen.c   5.2 (Berkeley) %G%";
-#endif LIBC_SCCS and not lint
-
-/*
- * Unix routine to do an "fopen" on file descriptor
- * The mode has to be repeated because you can't query its
- * status
- */
+static char sccsid[] = "@(#)fdopen.c   5.3 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/file.h>
 
 #include <sys/types.h>
 #include <sys/file.h>
+#include <sys/errno.h>
 #include <stdio.h>
 #include <stdio.h>
+#include "local.h"
 
 FILE *
 fdopen(fd, mode)
 
 FILE *
 fdopen(fd, mode)
-       register char *mode;
+       int fd;
+       char *mode;
 {
 {
-       extern FILE *_findiop();
-       static int nofile = -1;
-       register FILE *iop;
+       static int nofile;
+       register FILE *fp;
+       int flags, oflags, fdflags, fdmode;
 
 
-       if (nofile < 0)
+       if (nofile == 0)
                nofile = getdtablesize();
 
                nofile = getdtablesize();
 
-       if (fd < 0 || fd >= nofile)
+       if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
+               return (NULL);
+
+       /* Make sure the mode the user wants is a subset of the actual mode. */
+       fdmode = fdflags & O_ACCMODE;
+       if (fdmode != O_RDWR && fdmode != (oflags & O_ACCMODE)) {
+               errno = EINVAL;
                return (NULL);
                return (NULL);
+       }
 
 
-       iop = _findiop();
-       if (iop == NULL)
+       if ((fp = __sfp()) == NULL)
                return (NULL);
 
                return (NULL);
 
-       iop->_cnt = 0;
-       iop->_file = fd;
-       iop->_bufsiz = 0;
-       iop->_base = iop->_ptr = NULL;
-
-       switch (*mode) {
-       case 'r':
-               iop->_flag = _IOREAD;
-               break;
-       case 'a':
-               lseek(fd, (off_t)0, L_XTND);
-               /* fall into ... */
-       case 'w':
-               iop->_flag = _IOWRT;
-               break;
-       default:
+       if ((fp->_flags = __sflags(mode, &oflags)) == 0) 
                return (NULL);
                return (NULL);
-       }
 
 
-       if (mode[1] == '+')
-               iop->_flag = _IORW;
+       /*
+        * 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;
 
 
-       return (iop);
+       fp->_file = fd;
+       fp->_cookie = fp;
+       fp->_read = __sread;
+       fp->_write = __swrite;
+       fp->_seek = __sseek;
+       fp->_close = __sclose;
+       return (fp);
 }
 }
index d329b2d..3b53f7b 100644 (file)
@@ -1,72 +1,65 @@
-.\" Copyright (c) 1980 Regents of the University of California.
-.\" All rights reserved.  The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
 .\"
 .\"
-.\"    @(#)ferror.3    6.4 (Berkeley) %G%
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
 .\"
 .\"
-.TH FERROR 3  ""
-.UC 4
+.\" %sccs.include.redist.man%
+.\"
+.\"    @(#)ferror.3    6.5 (Berkeley) %G%
+.\"
+.TH FERROR 3 ""
+.UC 7
 .SH NAME
 .SH NAME
-ferror, feof, clearerr, fileno \- stream status inquiries
+clearerr, feof, ferror, fileno \- stream status inquiries
 .SH SYNOPSIS
 .SH SYNOPSIS
-.B #include <stdio.h>
-.PP
-.B feof(stream)
-.br
-.SM
-.B FILE
-.B *stream;
-.PP
-.B ferror(stream)
-.br
-.SM
-.B FILE
-.B *stream
-.PP
-.B clearerr(stream)
-.br
-.SM
-.B FILE
-.B *stream
-.PP
-.B fileno(stream)
-.br
-.SM
-.B FILE
-.B *stream;
+.nf
+.ft B
+#include <stdio.h>
+
+void
+clearerr(FILE *stream);
+
+int
+feof(FILE *stream);
+
+int
+ferror(FILE *stream);
+
+int
+fileno(FILE *stream);
+.ft R
+.fi
 .SH DESCRIPTION
 .SH DESCRIPTION
+.I Clearerr
+clears the end-of-file and error indicators for the stream pointed
+to by 
+.IR stream .
+.PP
 .I Feof
 .I Feof
-returns non-zero when end of file is read on the named input
+tests the end-of-file indicator for the stream pointed to by
 .IR stream ,
 .IR stream ,
-otherwise zero.
-Unless cleared by
-.IR clearerr ,
-the end-of-file indication lasts until
-the stream is closed.
+returning non-zero if it is set.
+The end-of-file indicator can only be cleared by
+.IR clearerr .
 .PP
 .I Ferror
 .PP
 .I Ferror
-returns non-zero when an error has occurred reading or writing
-the named
+tests the error indicator for the stream pointed to by
 .IR stream ,
 .IR stream ,
-otherwise zero.
-Unless cleared by
-.IR clearerr ,
-the error indication lasts until
-the stream is closed.
-.PP
-.I Clearerr
-resets the error and end-of-file indicators on the named
-.IR stream .
+returning non-zero if it is set.
+The error indicator can only be cleared by
+.IR clearerr .
 .PP
 .I Fileno
 .PP
 .I Fileno
-returns the integer file descriptor
-associated with the
-.IR stream ,
-see
-.IR open (2).
-.PP
-Currently all of these functions
-are implemented as macros;
-they cannot be redeclared.
+returns the integer file descriptor associated with the
+.I stream
+(see
+.IR open (2)).
 .SH "SEE ALSO"
 .SH "SEE ALSO"
-open(2), fopen(3)
+open(2), stdio(3)
+.SH STANDARDS
+.IR Clearerr ,
+.IR feof ,
+and
+.I ferror
+conform to ANSI X3.159-1989 (``ANSI C'').
index 7d4e99f..5addbe0 100644 (file)
@@ -1,11 +1,21 @@
+/*-
+ * 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.
+ *
+ * %sccs.include.redist.c%
+ */
+
 #if defined(LIBC_SCCS) && !defined(lint)
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fgetc.c    5.2 (Berkeley) %G%";
-#endif LIBC_SCCS and not lint
+static char sccsid[] = "@(#)fgetc.c    5.3 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
 
 #include <stdio.h>
 
 fgetc(fp)
 
 #include <stdio.h>
 
 fgetc(fp)
-FILE *fp;
+       FILE *fp;
 {
 {
-       return(getc(fp));
+       return (__sgetc(fp));
 }
 }
index 939b3a2..310cfea 100644 (file)
-.\" Copyright (c) 1989 The Regents of the University of California.
+.\" Copyright (c) 1990 The Regents of the University of California.
 .\" All rights reserved.
 .\"
 .\" All rights reserved.
 .\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
 .\" %sccs.include.redist.man%
 .\"
 .\" %sccs.include.redist.man%
 .\"
-.\"    @(#)fgets.3     6.4 (Berkeley) %G%
+.\"    @(#)fgets.3     6.5 (Berkeley) %G%
 .\"
 .TH FGETS 3 ""
 .\"
 .TH FGETS 3 ""
-.AT 3
+.UC 7
 .SH NAME
 .SH NAME
-fgets - get a line from a stream
+fgets, gets \- get a line from a stream
 .SH SYNOPSIS
 .nf
 .SH SYNOPSIS
 .nf
-.B #include <stdio.h>
+.ft B
+#include <stdio.h>
+
+char *
+fgets(char *str, size_t size, FILE *stream);
 
 
-.B char *fgets(s, n, stream)
-.B char *s;
-.B int n;
-.B FILE *stream;
+char *
+gets(char *str);
+.ft R
 .fi
 .SH DESCRIPTION
 .fi
 .SH DESCRIPTION
-The
-.I fgets
-function reads at most one less than the number of characters specified
-by
-.I n
-from the stream pointed to by
+.I Fgets
+reads at most one less than the number of characters specified by
+.IR size
+from the given
 .I stream
 .I stream
-into the array pointed to by
-.IR s .
-No additional characters are read after a new-line character
-(which is retained) or after end-of-file.
-A null character is written immediately after the last character
-read into the array.
+into the string
+.IR str .
+Reading stops when a newline character is found,
+at end-of-file or error.
+The newline, if any, is retained.
+In any case a '\e0' character is appended to end the string.
 .PP
 .PP
-The
+.I Gets
+is equivalent to
 .I fgets
 .I fgets
-function returns
-.I s
-if successful.
-If end-of-file is encountered and no characters have been read
-into the array, the contents of the array remain unchanged and
-a null pointer is returned.
-If a read error occurs during the operation, the array contents
-are indeterminate and a null pointer is returned.
+with an infinite
+.I size
+and a
+.I stream
+of
+.BR stdin ,
+except that the newline character (if any) is not stored in the string.
+It is the caller's responsibility to ensure that the input line,
+if any, is sufficiently short to fit in the string.
 .SH "SEE ALSO"
 .SH "SEE ALSO"
-getc(3), ferror(3) fread(3), scanf(3)
-.SH STANDARDS
-The
+feof(3), ferror(3), fgetline(3)
+.SH "RETURN VALUE"
+.PP
+Upon successful completion,
 .I fgets
 .I fgets
-function is ANSI C compatible.
+and 
+.I gets
+return
+.IR s .
+If end-of-file or an error occurs before any characters are read, 
+they return NULL.
+Callers must use
+.I feof
+and
+.I ferror
+to determine which occurred.
+.SH ERRORS
+.TP 15
+[EBADF]
+.I Stream
+is not a readable stream.
+.PP
+.I Fgets
+may also fail and set
+.I errno
+for any of the errors specified for the routines
+.IR fflush (3),
+.IR fstat (2),
+.IR read (2),
+or
+.IR malloc (3).
+.PP
+.I Gets
+may also fail and set
+.I errno
+for any of the errors specified for the routine
+.IR getchar (3).
+.SH BUGS
+Since it is usually impossible to ensure that the next input line
+is less than some arbitrary length, and because overflowing the
+input buffer is almost invariably a security violation, programs
+should
+.B NEVER
+use
+.IR gets .
+.I Gets
+exists purely to conform to ANSI X3.159-1989.
+.SH STANDARDS
+.I Fgets
+and
+.I gets
+conform to ANSI X3.159-1989 (``ANSI C'').
index abe686e..382876f 100644 (file)
@@ -1,25 +1,77 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * %sccs.include.redist.c%
+ */
+
 #if defined(LIBC_SCCS) && !defined(lint)
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fgets.c    5.2 (Berkeley) %G%";
-#endif LIBC_SCCS and not lint
+static char sccsid[] = "@(#)fgets.c    5.3 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
 
 
-#include       <stdio.h>
+#include <stdio.h>
+#include <string.h>
 
 
+/*
+ * Read at most n-1 characters from the given file.
+ * Stop when a newline has been read, or the count runs out.
+ * Return first argument, or NULL if no characters were read.
+ */
 char *
 char *
-fgets(s, n, iop)
-char *s;
-register FILE *iop;
+fgets(buf, n, fp)
+       char *buf;
+       register size_t n;
+       register FILE *fp;
 {
 {
-       register c;
-       register char *cs;
+       register size_t len;
+       register char *s;
+       register unsigned char *p, *t;
+
+       if (n < 2)              /* sanity check */
+               return (NULL);
+
+       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)
+                                       return (NULL);
+                               break;
+                       }
+                       len = fp->_r;
+               }
+               p = fp->_p;
 
 
-       cs = s;
-       while (--n>0 && (c = getc(iop)) != EOF) {
-               *cs++ = c;
-               if (c=='\n')
-                       break;
-       }
-       if (c == EOF && cs==s)
-               return(NULL);
-       *cs++ = '\0';
-       return(s);
+               /*
+                * 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] = 0;
+                       return (buf);
+               }
+               fp->_r -= len;
+               fp->_p += len;
+               (void) memcpy((void *)s, (void *)p, len);
+               s += len;
+       } while ((n -= len) != 0);
+       *s = 0;
+       return (buf);
 }
 }