xref: /original-bsd/lib/libc/stdio/fflush.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  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 
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)fflush.c	8.1 (Berkeley) 06/04/93";
13 #endif /* LIBC_SCCS and not lint */
14 
15 #include <errno.h>
16 #include <stdio.h>
17 #include "local.h"
18 
19 /* Flush a single file, or (if fp is NULL) all files.  */
20 fflush(fp)
21 	register FILE *fp;
22 {
23 
24 	if (fp == NULL)
25 		return (_fwalk(__sflush));
26 	if ((fp->_flags & (__SWR | __SRW)) == 0) {
27 		errno = EBADF;
28 		return (EOF);
29 	}
30 	return (__sflush(fp));
31 }
32 
33 __sflush(fp)
34 	register FILE *fp;
35 {
36 	register unsigned char *p;
37 	register int n, t;
38 
39 	t = fp->_flags;
40 	if ((t & __SWR) == 0)
41 		return (0);
42 
43 	if ((p = fp->_bf._base) == NULL)
44 		return (0);
45 
46 	n = fp->_p - p;		/* write this much */
47 
48 	/*
49 	 * Set these immediately to avoid problems with longjmp and to allow
50 	 * exchange buffering (via setvbuf) in user write function.
51 	 */
52 	fp->_p = p;
53 	fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
54 
55 	for (; n > 0; n -= t, p += t) {
56 		t = (*fp->_write)(fp->_cookie, (char *)p, n);
57 		if (t <= 0) {
58 			fp->_flags |= __SERR;
59 			return (EOF);
60 		}
61 	}
62 	return (0);
63 }
64