|
|
1.1 root 1: /*
2: * libc/stdio/setvbuf.c
3: * ANSI-compliant C standard i/o library.
4: * setvbuf()
5: * ANSI 4.9.5.6.
6: * Set i/o buffer.
7: */
8:
9: #include <stdio.h>
10: #include <stdlib.h>
11:
12: /*
13: * The get and put function pointers in a FILE
14: * initially contain &_fginit() and &_fpinit().
15: * The buffering characteristics of the stream
16: * are determined either by an explicit setvbuf()
17: * before the first get or put on the stream
18: * or by a setvbuf() call from finit() on the first get or put.
19: * setvbuf() allocates a buffer if necessary and
20: * initializes various fields in the FILE.
21: *
22: * For unbuffered streams, _cc == 0 and _bp == _cp == _dp == _ep == NULL.
23: * For buffered streams:
24: * _cc == 0 nothing is buffered
25: * _cc > 0 _cc input or output characters are buffered
26: * _bp base of buffer
27: * _cp current buffer pointer
28: * _dp data pointer
29: * _ep end of buffer pointer
30: * The old version of the stdio functions used
31: * _cc < 0 -(_cc) input characters are buffered
32: * _cc > 0 _cc output characters are buffered
33: * which makes much more sense but is unfortunately not compatible with
34: * the Unix version of stdio.h. This stdio gets very confused if you
35: * mix input and output calls without fflush() in between on a rw stream;
36: * this is non-ANSI compliant but works right with the old version.
37: */
38: int
39: setvbuf(stream, buf, mode, size) register FILE *stream; char *buf; int mode; size_t size;
40: {
41: register _FILE2 *f2p;
42:
43: #if _ASCII
44: register int isascii;
45:
46: isascii = stream->_ff2 & _FASCII;
47: #endif
48:
49: if (stream->_mode != _MODE_UNINIT)
50: return 1; /* Mode assigned, failure */
51:
52: /* Allocate a buffer if necessary. */
53: if (mode != _IONBF && buf == NULL) {
54: if ((buf = malloc(size)) == NULL)
55: return 1; /* Buffer allocation failure */
56: stream->_ff2 |= _FFREEB; /* Free buffer when closed */
57: }
58:
59: f2p = stream->_f2p;
60: switch(mode) {
61:
62: case _IOFBF: /* Fully buffered. */
63: stream->_ff1 |= _IOFBF;
64: stream->_mode = _MODE_FBUF;
65: #if _ASCII
66: f2p->_pt = isascii ? &_fputba : &_fputb;
67: #else
68: f2p->_pt = &_fputb;
69: #endif
70: f2p->_dp = stream->_cp = buf + boffset(stream, size);
71: lab:
72: #if _ASCII
73: f2p->_gt = isascii ? &_fgetba : &_fgetb;
74: #else
75: f2p->_gt = &_fgetb;
76: #endif
77: f2p->_bp = buf;
78: f2p->_ep = buf + size;
79: break;
80:
81: case _IOLBF: /* Line buffered */
82: stream->_ff1 |= _IOLBF;
83: stream->_mode = _MODE_LBUF;
84: #if _ASCII
85: f2p->_pt = isascii ? &_fputta : &_fputt;
86: #else
87: f2p->_pt = &_fputt;
88: #endif
89: f2p->_dp = stream->_cp = buf;
90: goto lab;
91:
92: case _IONBF: /* Unbuffered */
93: stream->_ff1 |= _IONBF;
94: stream->_mode = _MODE_NBUF;
95: #if _ASCII
96: f2p->_gt = isascii ? &_fgetca : &_fgetc;
97: f2p->_pt = isascii ? &_fputca : &_fputc;
98: #else
99: f2p->_gt = &_fgetc;
100: f2p->_pt = &_fputc;
101: #endif
102: break;
103:
104: default: /* Unrecognized mode */
105: return 1;
106: }
107:
108: if (stream->_ff1 & _FWONLY)
109: f2p->_gt = &_fgete;
110: if (stream->_ff1 & _FRONLY)
111: f2p->_pt = &_fpute;
112: stream->_cc = 0;
113: return 0; /* Success */
114: }
115:
116: /*
117: * Return the current offset of a stream.
118: * This is an attempt to keep buffered file i/o properly aligned.
119: * For example, a 200 byte file opened in append mode with a
120: * default buffer size of 512 bytes will have boffset 200
121: * and subsequent write()s will hopefully occur at 512-byte boundaries.
122: * If the user calls setvbuf() explicitly with a strange buffer size
123: * (not a multiple of the size for optimum disk i/o),
124: * the user will get degraded performance.
125: */
126: static
127: int
128: boffset(fp, size) register FILE *fp; register size_t size;
129: {
130: register long offset;
131:
132: if ((offset=lseek(fileno(fp), 0L, SEEK_CUR)) == -1L || size == 0)
133: return 0;
134: return (unsigned)offset%(unsigned)size;
135: }
136:
137: /* end of libc/stdio/setvbuf.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.