Subversion Repositories Kolibri OS

Rev

Rev 4921 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4921 Rev 6536
1
/*
1
/*
2
 * Copyright (c) 1990 The Regents of the University of California.
2
 * Copyright (c) 1990 The Regents of the University of California.
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms are permitted
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
16
 */
17
 
17
 
18
/*
18
/*
19
FUNCTION
19
FUNCTION
20
<>---specify file or stream buffering
20
<>---specify file or stream buffering
21
 
21
 
22
INDEX
22
INDEX
23
	setvbuf
23
	setvbuf
24
 
24
 
25
ANSI_SYNOPSIS
25
ANSI_SYNOPSIS
26
	#include 
26
	#include 
27
	int setvbuf(FILE *<[fp]>, char *<[buf]>,
27
	int setvbuf(FILE *<[fp]>, char *<[buf]>,
28
	            int <[mode]>, size_t <[size]>);
28
	            int <[mode]>, size_t <[size]>);
29
 
29
 
30
TRAD_SYNOPSIS
30
TRAD_SYNOPSIS
31
	#include 
31
	#include 
32
	int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>)
32
	int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>)
33
	FILE *<[fp]>;
33
	FILE *<[fp]>;
34
	char *<[buf]>;
34
	char *<[buf]>;
35
	int <[mode]>;
35
	int <[mode]>;
36
	size_t <[size]>;
36
	size_t <[size]>;
37
 
37
 
38
DESCRIPTION
38
DESCRIPTION
39
Use <> to specify what kind of buffering you want for the
39
Use <> to specify what kind of buffering you want for the
40
file or stream identified by <[fp]>, by using one of the following
40
file or stream identified by <[fp]>, by using one of the following
41
values (from <>) as the <[mode]> argument:
41
values (from <>) as the <[mode]> argument:
42
 
42
 
43
o+
43
o+
44
o _IONBF
44
o _IONBF
45
Do not use a buffer: send output directly to the host system for the
45
Do not use a buffer: send output directly to the host system for the
46
file or stream identified by <[fp]>.
46
file or stream identified by <[fp]>.
47
 
47
 
48
o _IOFBF
48
o _IOFBF
49
Use full output buffering: output will be passed on to the host system
49
Use full output buffering: output will be passed on to the host system
50
only when the buffer is full, or when an input operation intervenes.
50
only when the buffer is full, or when an input operation intervenes.
51
 
51
 
52
o _IOLBF
52
o _IOLBF
53
Use line buffering: pass on output to the host system at every
53
Use line buffering: pass on output to the host system at every
54
newline, as well as when the buffer is full, or when an input
54
newline, as well as when the buffer is full, or when an input
55
operation intervenes.
55
operation intervenes.
56
o-
56
o-
57
 
57
 
58
Use the <[size]> argument to specify how large a buffer you wish.  You
58
Use the <[size]> argument to specify how large a buffer you wish.  You
59
can supply the buffer itself, if you wish, by passing a pointer to a
59
can supply the buffer itself, if you wish, by passing a pointer to a
60
suitable area of memory as <[buf]>.  Otherwise, you may pass <>
60
suitable area of memory as <[buf]>.  Otherwise, you may pass <>
61
as the <[buf]> argument, and <> will allocate the buffer.
61
as the <[buf]> argument, and <> will allocate the buffer.
62
 
62
 
63
WARNINGS
63
WARNINGS
64
You may only use <> before performing any file operation other
64
You may only use <> before performing any file operation other
65
than opening the file.
65
than opening the file.
66
 
66
 
67
If you supply a non-null <[buf]>, you must ensure that the associated
67
If you supply a non-null <[buf]>, you must ensure that the associated
68
storage continues to be available until you close the stream
68
storage continues to be available until you close the stream
69
identified by <[fp]>.
69
identified by <[fp]>.
70
 
70
 
71
RETURNS
71
RETURNS
72
A <<0>> result indicates success, <> failure (invalid <[mode]> or
72
A <<0>> result indicates success, <> failure (invalid <[mode]> or
73
<[size]> can cause failure).
73
<[size]> can cause failure).
74
 
74
 
75
PORTABILITY
75
PORTABILITY
76
Both ANSI C and the System V Interface Definition (Issue 2) require
76
Both ANSI C and the System V Interface Definition (Issue 2) require
77
<>. However, they differ on the meaning of a <> buffer
77
<>. However, they differ on the meaning of a <> buffer
78
pointer: the SVID issue 2 specification says that a <> buffer
78
pointer: the SVID issue 2 specification says that a <> buffer
79
pointer requests unbuffered output.  For maximum portability, avoid
79
pointer requests unbuffered output.  For maximum portability, avoid
80
<> buffer pointers.
80
<> buffer pointers.
81
 
81
 
82
Both specifications describe the result on failure only as a
82
Both specifications describe the result on failure only as a
83
nonzero value.
83
nonzero value.
84
 
84
 
85
Supporting OS subroutines required: <>, <>, <>,
85
Supporting OS subroutines required: <>, <>, <>,
86
<>, <>, <>, <>.
86
<>, <>, <>, <>.
87
*/
87
*/
88
 
88
 
89
#include <_ansi.h>
89
#include <_ansi.h>
90
#include 
90
#include 
91
#include 
91
#include 
92
#include "local.h"
92
#include "local.h"
93
 
93
 
94
/*
94
/*
95
 * Set one of the three kinds of buffering, optionally including a buffer.
95
 * Set one of the three kinds of buffering, optionally including a buffer.
96
 */
96
 */
97
 
97
 
98
int
98
int
99
_DEFUN(setvbuf, (fp, buf, mode, size),
99
_DEFUN(setvbuf, (fp, buf, mode, size),
100
       register FILE * fp _AND
100
       register FILE * fp _AND
101
       char *buf          _AND
101
       char *buf          _AND
102
       register int mode  _AND
102
       register int mode  _AND
103
       register size_t size)
103
       register size_t size)
104
{
104
{
105
  int ret = 0;
105
  int ret = 0;
106
  struct _reent *reent = _REENT;
106
  struct _reent *reent = _REENT;
-
 
107
  size_t iosize;
-
 
108
  int ttyflag;
107
 
109
 
108
  CHECK_INIT (reent, fp);
110
  CHECK_INIT (reent, fp);
109
 
-
 
110
  _newlib_flockfile_start (fp);
-
 
111
 
111
 
112
  /*
112
  /*
113
   * Verify arguments.  The `int' limit on `size' is due to this
113
   * Verify arguments.  The `int' limit on `size' is due to this
-
 
114
   * particular implementation.  Note, buf and size are ignored
114
   * particular implementation.
115
   * when setting _IONBF.
115
   */
-
 
-
 
116
   */
116
 
117
  if (mode != _IONBF)
117
  if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
-
 
118
    {
-
 
119
      _newlib_flockfile_exit (fp);
118
    if ((mode != _IOFBF && mode != _IOLBF) || (int)(_POINTER_INT) size < 0)
120
      return (EOF);
119
      return (EOF);
121
    }
120
 
122
 
121
 
123
  /*
122
  /*
124
   * Write current buffer, if any; drop read count, if any.
123
   * Write current buffer, if any; drop read count, if any.
125
   * Make sure putc() will not think fp is line buffered.
124
   * Make sure putc() will not think fp is line buffered.
126
   * Free old buffer if it was from malloc().  Clear line and
125
   * Free old buffer if it was from malloc().  Clear line and
127
   * non buffer flags, and clear malloc flag.
126
   * non buffer flags, and clear malloc flag.
128
   */
127
   */
129
 
-
 
-
 
128
  _newlib_flockfile_start (fp);
130
  _fflush_r (reent, fp);
129
  _fflush_r (reent, fp);
131
  fp->_r = 0;
130
  if (HASUB(fp))
-
 
131
    FREEUB(reent, fp);
132
  fp->_lbfsize = 0;
132
  fp->_r = fp->_lbfsize = 0;
133
  if (fp->_flags & __SMBF)
133
  if (fp->_flags & __SMBF)
134
    _free_r (reent, (_PTR) fp->_bf._base);
134
    _free_r (reent, (_PTR) fp->_bf._base);
135
  fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
135
  fp->_flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF);
136
 
136
 
137
  if (mode == _IONBF)
137
  if (mode == _IONBF)
138
    goto nbf;
138
    goto nbf;
139
 
139
 
140
  /*
140
  /*
-
 
141
   * Find optimal I/O size for seek optimization.  This also returns
-
 
142
   * a `tty flag' to suggest that we check isatty(fd), but we do not
-
 
143
   * care since our caller told us how to buffer.
-
 
144
   */
-
 
145
  fp->_flags |= __swhatbuf_r (reent, fp, &iosize, &ttyflag);
-
 
146
  if (size == 0)
-
 
147
    {
-
 
148
      buf = NULL;
-
 
149
      size = iosize;
-
 
150
    }
-
 
151
 
141
   * Allocate buffer if needed. */
152
  /* Allocate buffer if needed. */
142
  if (buf == NULL)
153
  if (buf == NULL)
143
    {
154
    {
144
      /* we need this here because malloc() may return a pointer
-
 
145
	 even if size == 0 */
-
 
146
      if (!size) size = BUFSIZ;
-
 
147
      if ((buf = malloc (size)) == NULL)
155
      if ((buf = malloc (size)) == NULL)
148
	{
156
	{
-
 
157
	  /*
-
 
158
	   * Unable to honor user's request.  We will return
-
 
159
	   * failure, but try again with file system size.
-
 
160
	   */
149
	  ret = EOF;
161
	  ret = EOF;
150
	  /* Try another size... */
162
	  if (size != iosize)
-
 
163
	    {
-
 
164
	      size = iosize;
151
	  buf = malloc (BUFSIZ);
165
	      buf = malloc (size);
152
	  size = BUFSIZ;
166
	    }
153
	}
167
	}
154
      if (buf == NULL)
168
      if (buf == NULL)
155
        {
169
        {
156
          /* Can't allocate it, let's try another approach */
170
          /* No luck; switch to unbuffered I/O. */
157
nbf:
171
nbf:
158
          fp->_flags |= __SNBF;
172
          fp->_flags |= __SNBF;
159
          fp->_w = 0;
173
          fp->_w = 0;
160
          fp->_bf._base = fp->_p = fp->_nbuf;
174
          fp->_bf._base = fp->_p = fp->_nbuf;
161
          fp->_bf._size = 1;
175
          fp->_bf._size = 1;
162
          _newlib_flockfile_exit (fp);
176
          _newlib_flockfile_exit (fp);
163
          return (ret);
177
          return (ret);
164
        }
178
        }
165
      fp->_flags |= __SMBF;
179
      fp->_flags |= __SMBF;
166
    }
180
    }
-
 
181
 
167
  /*
182
  /*
168
   * Now put back whichever flag is needed, and fix _lbfsize
-
 
169
   * if line buffered.  Ensure output flush on exit if the
183
   * We're committed to buffering from here, so make sure we've
170
   * stream will be buffered at all.
184
   * registered to flush buffers on exit.
171
   * If buf is NULL then make _lbfsize 0 to force the buffer
-
 
172
   * to be flushed and hence malloced on first use
-
 
173
   */
185
   */
-
 
186
  if (!reent->__sdidinit)
-
 
187
    __sinit(reent);
-
 
188
 
-
 
189
#ifdef _FSEEK_OPTIMIZATION
-
 
190
  /*
174
 
191
   * Kill any seek optimization if the buffer is not the
-
 
192
   * right size.
-
 
193
   *
175
  switch (mode)
194
   * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
176
    {
195
   */
177
    case _IOLBF:
196
  if (size != iosize)
178
      fp->_flags |= __SLBF;
-
 
179
      fp->_lbfsize = buf ? -size : 0;
197
     fp->_flags |= __SNPT;
-
 
198
#endif
-
 
199
 
-
 
200
  /*
180
      /* FALLTHROUGH */
201
   * Fix up the FILE fields, and set __cleanup for output flush on
181
 
202
   * exit (since we are buffered in some way).
182
    case _IOFBF:
203
   */
183
      /* no flag */
204
  if (mode == _IOLBF)
184
      reent->__cleanup = _cleanup_r;
205
      fp->_flags |= __SLBF;
-
 
206
      fp->_bf._base = fp->_p = (unsigned char *) buf;
185
      fp->_bf._base = fp->_p = (unsigned char *) buf;
207
      fp->_bf._size = size;
186
      fp->_bf._size = size;
208
  /* fp->_lbfsize is still 0 */
187
      break;
-
 
188
    }
209
  if (fp->_flags & __SWR)
-
 
210
    {
189
 
211
  /*
190
  /*
212
       * Begin or continue writing: see __swsetup().  Note
-
 
213
       * that __SNBF is impossible (it was handled earlier).
-
 
214
   */
-
 
215
      if (fp->_flags & __SLBF)
-
 
216
	{
191
   * Patch up write count if necessary.
217
	  fp->_w = 0;
-
 
218
	  fp->_lbfsize = -fp->_bf._size;
192
   */
219
	}
-
 
220
      else
-
 
221
        fp->_w = size;
-
 
222
    }
193
 
223
  else
-
 
224
    {
-
 
225
      /* begin/continue reading, or stay in intermediate state */
194
  if (fp->_flags & __SWR)
226
      fp->_w = 0;
195
    fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
227
    }
196
 
228
 
197
  _newlib_flockfile_end (fp);
229
  _newlib_flockfile_end (fp);
198
  return 0;
230
  return 0;
199
}
231
}