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