source: trunk/minix/lib/stdio/flushbuf.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 2.9 KB
Line 
1/*
2 * flushbuf.c - flush a buffer
3 */
4/* $Id: flushbuf.c,v 1.1.1.1 2005/04/21 14:56:35 beng Exp $ */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include "loc_incl.h"
9
10#include <sys/types.h>
11
12off_t _lseek(int fildes, off_t offset, int whence);
13ssize_t _write(int d, const char *buf, int nbytes);
14int _isatty(int d);
15extern void (*_clean)(void);
16
17static int
18do_write(int d, char *buf, int nbytes)
19{
20 int c;
21
22 /* POSIX actually allows write() to return a positive value less
23 than nbytes, so loop ...
24 */
25 while ((c = _write(d, buf, nbytes)) > 0 && c < nbytes) {
26 nbytes -= c;
27 buf += c;
28 }
29 return c > 0;
30}
31
32int
33__flushbuf(int c, FILE * stream)
34{
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;
39
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;
52 }
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;
63 }
64 }
65 stream->_ptr = stream->_buf;
66 }
67 }
68
69 if (io_testflag(stream, _IONBF)) {
70 char c1 = c;
71
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;
77 }
78 }
79 if (_write(fileno(stream), &c1, 1) != 1) {
80 stream->_flags |= _IOERR;
81 return EOF;
82 }
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;
89
90 stream->_ptr = stream->_buf;
91 stream->_count = 0;
92
93 if (io_testflag(stream, _IOAPPEND)) {
94 if (_lseek(fileno(stream), 0L, SEEK_END) == -1) {
95 stream->_flags |= _IOERR;
96 return EOF;
97 }
98 }
99 if (! do_write(fileno(stream), (char *)stream->_buf,
100 count)) {
101 stream->_flags |= _IOERR;
102 return EOF;
103 }
104 }
105 } else {
106 int count = stream->_ptr - stream->_buf;
107
108 stream->_count = stream->_bufsiz - 1;
109 stream->_ptr = stream->_buf + 1;
110
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;
116 }
117 }
118 if (! do_write(fileno(stream), (char *)stream->_buf, count)) {
119 *(stream->_buf) = c;
120 stream->_flags |= _IOERR;
121 return EOF;
122 }
123 }
124 *(stream->_buf) = c;
125 }
126 return (unsigned char) c;
127}
Note: See TracBrowser for help on using the repository browser.