VAX .s routines only work with the old stdio
[unix-history] / usr / src / lib / libc / stdio / fgets.c
CommitLineData
639aed4c
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * %sccs.include.redist.c%
9 */
10
2ce81398 11#if defined(LIBC_SCCS) && !defined(lint)
639aed4c
KB
12static char sccsid[] = "@(#)fgets.c 5.3 (Berkeley) %G%";
13#endif /* LIBC_SCCS and not lint */
b8f253e8 14
639aed4c
KB
15#include <stdio.h>
16#include <string.h>
0175c543 17
639aed4c
KB
18/*
19 * Read at most n-1 characters from the given file.
20 * Stop when a newline has been read, or the count runs out.
21 * Return first argument, or NULL if no characters were read.
22 */
0175c543 23char *
639aed4c
KB
24fgets(buf, n, fp)
25 char *buf;
26 register size_t n;
27 register FILE *fp;
0175c543 28{
639aed4c
KB
29 register size_t len;
30 register char *s;
31 register unsigned char *p, *t;
32
33 if (n < 2) /* sanity check */
34 return (NULL);
35
36 s = buf;
37 n--; /* leave space for NUL */
38 do {
39 /*
40 * If the buffer is empty, refill it.
41 */
42 if ((len = fp->_r) <= 0) {
43 if (__srefill(fp)) {
44 /* EOF/error: stop with partial or no line */
45 if (s == buf)
46 return (NULL);
47 break;
48 }
49 len = fp->_r;
50 }
51 p = fp->_p;
0175c543 52
639aed4c
KB
53 /*
54 * Scan through at most n bytes of the current buffer,
55 * looking for '\n'. If found, copy up to and including
56 * newline, and stop. Otherwise, copy entire chunk
57 * and loop.
58 */
59 if (len > n)
60 len = n;
61 t = memchr((void *)p, '\n', len);
62 if (t != NULL) {
63 len = ++t - p;
64 fp->_r -= len;
65 fp->_p = t;
66 (void) memcpy((void *)s, (void *)p, len);
67 s[len] = 0;
68 return (buf);
69 }
70 fp->_r -= len;
71 fp->_p += len;
72 (void) memcpy((void *)s, (void *)p, len);
73 s += len;
74 } while ((n -= len) != 0);
75 *s = 0;
76 return (buf);
0175c543 77}