genericopenlibs/openenvcore/libc/src/stdio/wsetup.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*-
       
     2  * Copyright (c) 1990, 1993
       
     3  *	The Regents of the University of California.  All rights reserved.
       
     4  *
       
     5  * This code is derived from software contributed to Berkeley by
       
     6  * Chris Torek.
       
     7  *
       
     8  * Redistribution and use in source and binary forms, with or without
       
     9  * modification, are permitted provided that the following conditions
       
    10  * are met:
       
    11  * 1. Redistributions of source code must retain the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer.
       
    13  * 2. Redistributions in binary form must reproduce the above copyright
       
    14  *    notice, this list of conditions and the following disclaimer in the
       
    15  *    documentation and/or other materials provided with the distribution.
       
    16  * 4. Neither the name of the University nor the names of its contributors
       
    17  *    may be used to endorse or promote products derived from this software
       
    18  *    without specific prior written permission.
       
    19  *
       
    20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
       
    21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
       
    24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    30  * SUCH DAMAGE.
       
    31  */
       
    32 
       
    33 #if defined(LIBC_SCCS) && !defined(lint)
       
    34 static char sccsid[] = "@(#)wsetup.c	8.1 (Berkeley) 6/4/93";
       
    35 #endif /* LIBC_SCCS and not lint */
       
    36 #include <sys/cdefs.h>
       
    37 __FBSDID("$FreeBSD: src/lib/libc/stdio/wsetup.c,v 1.9 2004/06/08 05:44:52 das Exp $");
       
    38 
       
    39 #include <errno.h>
       
    40 #include <stdio.h>
       
    41 #include <stdlib.h>
       
    42 #include "local.h"
       
    43 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
       
    44 #include "libc_wsd_defs.h"
       
    45 #endif
       
    46 
       
    47 #ifdef EMULATOR
       
    48 int *GET_WSD_VAR_NAME(__sdidinit, g)();
       
    49 #define __sdidinit (*GET_WSD_VAR_NAME(__sdidinit, g)())
       
    50 #endif //EMULATOR
       
    51 
       
    52 /*
       
    53  * Various output routines call wsetup to be sure it is safe to write,
       
    54  * because either _flags does not include __SWR, or _buf is NULL.
       
    55  * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
       
    56  */
       
    57 int
       
    58 __swsetup(fp)
       
    59 	FILE *fp;
       
    60 {
       
    61 	/* make sure stdio is set up */
       
    62 	if (!__sdidinit)
       
    63 		__sinit();
       
    64 
       
    65 	/*
       
    66 	 * If we are not writing, we had better be reading and writing.
       
    67 	 */
       
    68 	if ((fp->_flags & __SWR) == 0) {
       
    69 		if ((fp->_flags & __SRW) == 0) {
       
    70 			errno = EBADF;
       
    71 #ifdef __SYMBIAN32__
       
    72 			fp->_flags |= __SERR;
       
    73 #endif			
       
    74 			return (EOF);
       
    75 		}
       
    76 		if (fp->_flags & __SRD) {
       
    77 			/* clobber any ungetc data */
       
    78 			if (HASUB(fp))
       
    79 				FREEUB(fp);
       
    80 			fp->_flags &= ~(__SRD|__SEOF);
       
    81 			
       
    82 			/*   Need to adjust the real-byte offset of the file
       
    83 			 *   depending on the value of fp->_r 
       
    84 			 *   before resetting its value.
       
    85 			 *   In binary-mode: seekBackCount = No. of unread bytes in buffer
       
    86 			 *   In text-mode: seekBackCount = (No. of unread chars in buffer + No. of newlines present as part of unread chars in buffer)
       
    87 			 */
       
    88 			if(fp->_r)
       
    89 			    {
       
    90 	            fpos_t offset = 0;
       
    91 	            
       
    92 	            /* Count newlines present as part of unread characters
       
    93 	             * in buffer denoted by ( fp->_r ) only in text-mode
       
    94 	             */ 
       
    95 	            if( fp->_extra->fmode == 't')
       
    96 	                {
       
    97 	                int newlines = 0, len = 0;
       
    98 	                char *p = NULL;
       
    99 	                p = (char*)(fp->_p);
       
   100 	                while( len++ < fp->_r )
       
   101 	                    {
       
   102 	                    if( *p++ == '\n' )
       
   103 	                        newlines++;
       
   104 	                    }
       
   105 	                offset += newlines;
       
   106 	                }
       
   107 	            
       
   108 	            offset += fp->_r;  
       
   109 			    if( (_sseek(fp, -(fpos_t)offset, SEEK_CUR)) == (-(fpos_t)1) )
       
   110 			        return (-1);
       
   111 			    }
       
   112 			fp->_r = 0;
       
   113 			fp->_p = fp->_bf._base;
       
   114 		}
       
   115 		fp->_flags |= __SWR;
       
   116 	}
       
   117 
       
   118 	/*
       
   119 	 * Make a buffer if necessary, then set _w.
       
   120 	 */
       
   121 	if (fp->_bf._base == NULL)
       
   122 	{
       
   123 		__smakebuf(fp);
       
   124 		if(fp->_bf._base == NULL && errno == ENOMEM)
       
   125 		{
       
   126 			return (EOF);
       
   127 		}
       
   128 	}
       
   129 	if (fp->_flags & __SLBF) {
       
   130 		/*
       
   131 		 * It is line buffered, so make _lbfsize be -_bufsize
       
   132 		 * for the putc() macro.  We will change _lbfsize back
       
   133 		 * to 0 whenever we turn off __SWR.
       
   134 		 */
       
   135 		fp->_w = 0;
       
   136 		fp->_lbfsize = -fp->_bf._size;
       
   137 	} else
       
   138 		fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
       
   139 	return (0);
       
   140 }