os/ossrv/genericopenlibs/cstdlib/LSTDIO/SETVBUF.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* SETVBUF.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
/*
sl@0
     8
 * Copyright (c) 1990 The Regents of the University of California.
sl@0
     9
 * All rights reserved.
sl@0
    10
 *
sl@0
    11
 * Redistribution and use in source and binary forms are permitted
sl@0
    12
 * provided that the above copyright notice and this paragraph are
sl@0
    13
 * duplicated in all such forms and that any documentation,
sl@0
    14
 * advertising materials, and other materials related to such
sl@0
    15
 * distribution and use acknowledge that the software was developed
sl@0
    16
 * by the University of California, Berkeley.  The name of the
sl@0
    17
 * University may not be used to endorse or promote products derived
sl@0
    18
 * from this software without specific prior written permission.
sl@0
    19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
sl@0
    20
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
sl@0
    21
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
sl@0
    22
 */
sl@0
    23
sl@0
    24
/*
sl@0
    25
FUNCTION
sl@0
    26
<<setvbuf>>---specify file or stream buffering
sl@0
    27
sl@0
    28
INDEX
sl@0
    29
	setvbuf
sl@0
    30
sl@0
    31
ANSI_SYNOPSIS
sl@0
    32
	#include <stdio.h>
sl@0
    33
	int setvbuf(FILE *<[fp]>, char *<[buf]>,
sl@0
    34
	            int <[mode]>, size_t <[size]>);
sl@0
    35
sl@0
    36
TRAD_SYNOPSIS
sl@0
    37
	#include <stdio.h>
sl@0
    38
	int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>)
sl@0
    39
	FILE *<[fp]>;
sl@0
    40
	char *<[buf]>;
sl@0
    41
	int <[mode]>;
sl@0
    42
	size_t <[size]>;
sl@0
    43
sl@0
    44
DESCRIPTION
sl@0
    45
Use <<setvbuf>> to specify what kind of buffering you want for the
sl@0
    46
file or stream identified by <[fp]>, by using one of the following
sl@0
    47
values (from <<stdio.h>>) as the <[mode]> argument:
sl@0
    48
sl@0
    49
o+
sl@0
    50
o _IONBF
sl@0
    51
Do not use a buffer: send output directly to the host system for the
sl@0
    52
file or stream identified by <[fp]>.
sl@0
    53
sl@0
    54
o _IOFBF
sl@0
    55
Use full output buffering: output will be passed on to the host system
sl@0
    56
only when the buffer is full, or when an input operation intervenes.
sl@0
    57
sl@0
    58
o _IOLBF
sl@0
    59
Use line buffering: pass on output to the host system at every
sl@0
    60
newline, as well as when the buffer is full, or when an input
sl@0
    61
operation intervenes.
sl@0
    62
o-
sl@0
    63
sl@0
    64
Use the <[size]> argument to specify how large a buffer you wish.  You
sl@0
    65
can supply the buffer itself, if you wish, by passing a pointer to a
sl@0
    66
suitable area of memory as <[buf]>.  Otherwise, you may pass <<NULL>>
sl@0
    67
as the <[buf]> argument, and <<setvbuf>> will allocate the buffer.
sl@0
    68
sl@0
    69
WARNINGS
sl@0
    70
You may only use <<setvbuf>> before performing any file operation other
sl@0
    71
than opening the file.
sl@0
    72
sl@0
    73
If you supply a non-null <[buf]>, you must ensure that the associated
sl@0
    74
storage continues to be available until you close the stream
sl@0
    75
identified by <[fp]>.
sl@0
    76
sl@0
    77
RETURNS
sl@0
    78
A <<0>> result indicates success, <<EOF>> failure (invalid <[mode]> or
sl@0
    79
<[size]> can cause failure).
sl@0
    80
sl@0
    81
PORTABILITY
sl@0
    82
Both ANSI C and the System V Interface Definition (Issue 2) require
sl@0
    83
<<setvbuf>>. However, they differ on the meaning of a <<NULL>> buffer
sl@0
    84
pointer: the SVID issue 2 specification says that a <<NULL>> buffer
sl@0
    85
pointer requests unbuffered output.  For maximum portability, avoid
sl@0
    86
<<NULL>> buffer pointers.
sl@0
    87
sl@0
    88
Both specifications describe the result on failure only as a
sl@0
    89
nonzero value.
sl@0
    90
sl@0
    91
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0
    92
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
sl@0
    93
*/
sl@0
    94
sl@0
    95
#include <stdio_r.h>
sl@0
    96
#include <stdlib_r.h>
sl@0
    97
#include "LOCAL.H"
sl@0
    98
sl@0
    99
/**
sl@0
   100
Change stream buffering.
sl@0
   101
Changes the buffer to be used for I/O operations with the specified stream.
sl@0
   102
Size and mode for the buffer can be specified.
sl@0
   103
This function should be called once the file associated with the stream 
sl@0
   104
has been opened but before any input or output operation has been done.
sl@0
   105
The size of the buffer is specified by the size parameter,
sl@0
   106
and can be any value between 2 and 32767 in bytes, 
sl@0
   107
this value may be rounded down by some system due to specific alignment.
sl@0
   108
buffer can be NULL.
sl@0
   109
@return If the buffer is correctly assigned to the file a 0 value is returned.
sl@0
   110
On error, a non-zero value is returned. This can be because an invalid type or size has been specified or because an error allocating memory (if NULL buffer was specified).
sl@0
   111
@param fp pointer to an open file. 
sl@0
   112
@param buf User allocated buffer. Must have at least a size of size bytes. 
sl@0
   113
@param mode Specifies a mode for file buffering
sl@0
   114
@param Buffer size in bytes, must be more than 0 and less than 32768, this value may be rounded down by some systems due to specific alignment, in which case the minimum value should be 2.
sl@0
   115
*/
sl@0
   116
EXPORT_C int
sl@0
   117
setvbuf (FILE * fp, char *buf, int mode, size_t size)
sl@0
   118
{
sl@0
   119
  int ret = 0;
sl@0
   120
  CHECK_INIT (fp);
sl@0
   121
sl@0
   122
  /*
sl@0
   123
   * Verify arguments.  The `int' limit on `size' is due to this
sl@0
   124
   * particular implementation.
sl@0
   125
   */
sl@0
   126
sl@0
   127
  if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int) size < 0)
sl@0
   128
    return (EOF);
sl@0
   129
sl@0
   130
  /*
sl@0
   131
   * Write current buffer, if any; drop read count, if any.
sl@0
   132
   * Make sure putc() will not think fp is line buffered.
sl@0
   133
   * Free old buffer if it was from malloc().  Clear line and
sl@0
   134
   * non buffer flags, and clear malloc flag.
sl@0
   135
   */
sl@0
   136
sl@0
   137
  (void) fflush (fp);
sl@0
   138
  fp->_r = 0;
sl@0
   139
  fp->_lbfsize = 0;
sl@0
   140
  if (fp->_flags & __SMBF)
sl@0
   141
    _free_r (fp->_data, (void *) fp->_bf._base);
sl@0
   142
  fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
sl@0
   143
sl@0
   144
  if (mode == _IONBF)
sl@0
   145
    goto nbf;
sl@0
   146
sl@0
   147
  /*
sl@0
   148
   * Allocate buffer if needed. */
sl@0
   149
  if (buf == NULL)
sl@0
   150
    {
sl@0
   151
      if ((buf = (char *)malloc (size)) == NULL)
sl@0
   152
	{
sl@0
   153
	  ret = EOF;
sl@0
   154
	  /* Try another size... */
sl@0
   155
	  buf = (char *)malloc (BUFSIZ);
sl@0
   156
	}
sl@0
   157
      if (buf == NULL)
sl@0
   158
	{
sl@0
   159
	  /* Can't allocate it, let's try another approach */
sl@0
   160
nbf:
sl@0
   161
	  fp->_flags |= __SNBF;
sl@0
   162
	  fp->_w = 0;
sl@0
   163
	  fp->_bf._base = fp->_p = fp->_nbuf;
sl@0
   164
	  fp->_bf._size = 1;
sl@0
   165
	  return (ret);
sl@0
   166
	}
sl@0
   167
      fp->_flags |= __SMBF;
sl@0
   168
    }
sl@0
   169
  /*
sl@0
   170
   * Now put back whichever flag is needed, and fix _lbfsize
sl@0
   171
   * if line buffered.  Ensure output flush on exit if the
sl@0
   172
   * stream will be buffered at all.
sl@0
   173
   * Force the buffer to be flushed and hence malloced on first use
sl@0
   174
   */
sl@0
   175
sl@0
   176
  switch (mode)
sl@0
   177
    {
sl@0
   178
    case _IOLBF:
sl@0
   179
      fp->_flags |= __SLBF;
sl@0
   180
      fp->_lbfsize = -(int)size;
sl@0
   181
      /* FALLTHROUGH */
sl@0
   182
sl@0
   183
    case _IOFBF:
sl@0
   184
      /* no flag */
sl@0
   185
      fp->_data->__cleanup = _cleanup_r;
sl@0
   186
      fp->_bf._base = fp->_p = (unsigned char *) buf;
sl@0
   187
      fp->_bf._size = size;
sl@0
   188
      break;
sl@0
   189
    }
sl@0
   190
sl@0
   191
  /*
sl@0
   192
   * Patch up write count if necessary.
sl@0
   193
   */
sl@0
   194
sl@0
   195
  if (fp->_flags & __SWR)
sl@0
   196
    fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
sl@0
   197
sl@0
   198
  return 0;
sl@0
   199
}