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