Uninitialized vector entry?
[minix3.git] / lib / stdio / flushbuf.c
bloba6a8bfb92e82dd2494bfd2b717ec5dbf247b75ad
1 /*
2 * flushbuf.c - flush a buffer
3 */
4 /* $Id$ */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "loc_incl.h"
10 #include <sys/types.h>
12 off_t _lseek(int fildes, off_t offset, int whence);
13 ssize_t _write(int d, const char *buf, int nbytes);
14 int _isatty(int d);
15 extern void (*_clean)(void);
17 static int
18 do_write(int d, char *buf, int nbytes)
20 int c;
22 /* POSIX actually allows write() to return a positive value less
23 than nbytes, so loop ...
25 while ((c = _write(d, buf, nbytes)) > 0 && c < nbytes) {
26 nbytes -= c;
27 buf += c;
29 return c > 0;
32 int
33 __flushbuf(int c, FILE * stream)
35 _clean = __cleanup;
36 if (fileno(stream) < 0) return (unsigned char) c;
37 if (!io_testflag(stream, _IOWRITE)) return EOF;
38 if (io_testflag(stream, _IOREADING) && !feof(stream)) return EOF;
40 stream->_flags &= ~_IOREADING;
41 stream->_flags |= _IOWRITING;
42 if (!io_testflag(stream, _IONBF)) {
43 if (!stream->_buf) {
44 if (stream == stdout && _isatty(fileno(stdout))) {
45 if (!(stream->_buf =
46 (unsigned char *) malloc(BUFSIZ))) {
47 stream->_flags |= _IONBF;
48 } else {
49 stream->_flags |= _IOLBF|_IOMYBUF;
50 stream->_bufsiz = BUFSIZ;
51 stream->_count = -1;
53 } else {
54 if (!(stream->_buf =
55 (unsigned char *) malloc(BUFSIZ))) {
56 stream->_flags |= _IONBF;
57 } else {
58 stream->_flags |= _IOMYBUF;
59 stream->_bufsiz = BUFSIZ;
60 if (!io_testflag(stream, _IOLBF))
61 stream->_count = BUFSIZ - 1;
62 else stream->_count = -1;
65 stream->_ptr = stream->_buf;
69 if (io_testflag(stream, _IONBF)) {
70 char c1 = c;
72 stream->_count = 0;
73 if (io_testflag(stream, _IOAPPEND)) {
74 if (_lseek(fileno(stream), 0L, SEEK_END) == -1) {
75 stream->_flags |= _IOERR;
76 return EOF;
79 if (_write(fileno(stream), &c1, 1) != 1) {
80 stream->_flags |= _IOERR;
81 return EOF;
83 return (unsigned char) c;
84 } else if (io_testflag(stream, _IOLBF)) {
85 *stream->_ptr++ = c;
86 /* stream->_count has been updated in putc macro. */
87 if (c == '\n' || stream->_count == -stream->_bufsiz) {
88 int count = -stream->_count;
90 stream->_ptr = stream->_buf;
91 stream->_count = 0;
93 if (io_testflag(stream, _IOAPPEND)) {
94 if (_lseek(fileno(stream), 0L, SEEK_END) == -1) {
95 stream->_flags |= _IOERR;
96 return EOF;
99 if (! do_write(fileno(stream), (char *)stream->_buf,
100 count)) {
101 stream->_flags |= _IOERR;
102 return EOF;
105 } else {
106 int count = stream->_ptr - stream->_buf;
108 stream->_count = stream->_bufsiz - 1;
109 stream->_ptr = stream->_buf + 1;
111 if (count > 0) {
112 if (io_testflag(stream, _IOAPPEND)) {
113 if (_lseek(fileno(stream), 0L, SEEK_END) == -1) {
114 stream->_flags |= _IOERR;
115 return EOF;
118 if (! do_write(fileno(stream), (char *)stream->_buf, count)) {
119 *(stream->_buf) = c;
120 stream->_flags |= _IOERR;
121 return EOF;
124 *(stream->_buf) = c;
126 return (unsigned char) c;