Commit | Line | Data |
---|---|---|
411867e7 | 1 | /*- |
7860c229 KB |
2 | * Copyright (c) 1990, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
411867e7 KB |
4 | * |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Chris Torek. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
586c39b1 DF |
9 | */ |
10 | ||
2ce81398 | 11 | #if defined(LIBC_SCCS) && !defined(lint) |
7ac0005b | 12 | static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) %G%"; |
411867e7 | 13 | #endif /* LIBC_SCCS and not lint */ |
586c39b1 | 14 | |
411867e7 KB |
15 | #include <stdio.h> |
16 | #include <string.h> | |
637f6ac3 | 17 | |
8d71d88c | 18 | size_t |
411867e7 KB |
19 | fread(buf, size, count, fp) |
20 | void *buf; | |
21 | size_t size, count; | |
22 | register FILE *fp; | |
637f6ac3 | 23 | { |
411867e7 KB |
24 | register size_t resid; |
25 | register char *p; | |
26 | register int r; | |
27 | size_t total; | |
637f6ac3 | 28 | |
7ac0005b CT |
29 | /* |
30 | * The ANSI standard requires a return value of 0 for a count | |
31 | * or a size of 0. Peculiarily, it imposes no such requirements | |
32 | * on fwrite; it only requires fread to be broken. | |
33 | */ | |
411867e7 | 34 | if ((resid = count * size) == 0) |
7ac0005b | 35 | return (0); |
411867e7 KB |
36 | if (fp->_r < 0) |
37 | fp->_r = 0; | |
38 | total = resid; | |
39 | p = buf; | |
40 | while (resid > (r = fp->_r)) { | |
594acd1e | 41 | (void)memcpy((void *)p, (void *)fp->_p, (size_t)r); |
411867e7 KB |
42 | fp->_p += r; |
43 | /* fp->_r = 0 ... done in __srefill */ | |
44 | p += r; | |
45 | resid -= r; | |
46 | if (__srefill(fp)) { | |
47 | /* no more input: return partial result */ | |
48 | return ((total - resid) / size); | |
637f6ac3 MK |
49 | } |
50 | } | |
594acd1e | 51 | (void)memcpy((void *)p, (void *)fp->_p, resid); |
411867e7 KB |
52 | fp->_r -= resid; |
53 | fp->_p += resid; | |
54 | return (count); | |
637f6ac3 | 55 | } |