genericopenlibs/openenvcore/libc/src/stdio/refill.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*-
       
     2  * © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
     3  * Copyright (c) 1990, 1993
       
     4  *	The Regents of the University of California.  All rights reserved.
       
     5  *
       
     6  * This code is derived from software contributed to Berkeley by
       
     7  * Chris Torek.
       
     8  *
       
     9  * Redistribution and use in source and binary forms, with or without
       
    10  * modification, are permitted provided that the following conditions
       
    11  * are met:
       
    12  * 1. Redistributions of source code must retain the above copyright
       
    13  *    notice, this list of conditions and the following disclaimer.
       
    14  * 2. Redistributions in binary form must reproduce the above copyright
       
    15  *    notice, this list of conditions and the following disclaimer in the
       
    16  *    documentation and/or other materials provided with the distribution.
       
    17  * 4. Neither the name of the University nor the names of its contributors
       
    18  *    may be used to endorse or promote products derived from this software
       
    19  *    without specific prior written permission.
       
    20  *
       
    21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
       
    22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
       
    25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    31  * SUCH DAMAGE.
       
    32  * © Portions copyright (c) 2005-2006  Nokia Corporation.  All rights reserved.
       
    33  */
       
    34 
       
    35 #if defined(LIBC_SCCS) && !defined(lint)
       
    36 static char sccsid[] = "@(#)refill.c	8.1 (Berkeley) 6/4/93";
       
    37 #endif /* LIBC_SCCS and not lint */
       
    38 #include <sys/cdefs.h>
       
    39 __FBSDID("$FreeBSD: src/lib/libc/stdio/refill.c,v 1.18 2002/08/13 09:30:41 tjr Exp $");
       
    40 
       
    41 #include "namespace.h"
       
    42 #include <errno.h>
       
    43 #include <stdio.h>
       
    44 #include <stdlib.h>
       
    45 #include "un-namespace.h"
       
    46 
       
    47 #include "libc_private.h"
       
    48 #include "local.h"
       
    49 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
       
    50 #include "libc_wsd_defs.h"
       
    51 #endif
       
    52 
       
    53 #ifdef EMULATOR
       
    54 int *GET_WSD_VAR_NAME(__sdidinit, g)();
       
    55 #define __sdidinit (*GET_WSD_VAR_NAME(__sdidinit, g)())
       
    56 #endif //EMULATOR
       
    57 
       
    58 static int lflush(FILE *);
       
    59 
       
    60 static int
       
    61 lflush(FILE *fp)
       
    62 {
       
    63 	int	ret = 0;
       
    64 
       
    65 	if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
       
    66 		FLOCKFILE(fp);
       
    67 		ret = __sflush(fp);
       
    68 		FUNLOCKFILE(fp);
       
    69 	}
       
    70 	return (ret);
       
    71 }
       
    72 /* Validation checks on the FILE
       
    73  * Avoid duplication of the code
       
    74  */
       
    75  int validate(FILE *fp)
       
    76 	{
       
    77 	/* make sure stdio is set up */
       
    78 	if (!__sdidinit)
       
    79 		__sinit();
       
    80 	
       
    81 	ORIENT(fp, -1);
       
    82 	
       
    83 	fp->_r = 0;		/* largely a convenience for callers */
       
    84 	
       
    85 	/* SysV does not make this test; take it out for compatibility */
       
    86 	if (fp->_flags & __SEOF)
       
    87 		return (EOF);
       
    88 	
       
    89 	/* if not already reading, have to be reading and writing */
       
    90 	if ((fp->_flags & __SRD) == 0) {
       
    91 		if ((fp->_flags & __SRW) == 0) {
       
    92 			errno = EBADF;
       
    93 			fp->_flags |= __SERR;
       
    94 			return (EOF);
       
    95 		}
       
    96 		/* switch to reading */
       
    97 		if (fp->_flags & __SWR) {
       
    98 			if (__sflush(fp))
       
    99 				return (EOF);
       
   100 			fp->_flags &= ~__SWR;
       
   101 			fp->_w = 0;
       
   102 			fp->_lbfsize = 0;
       
   103 		}
       
   104 		fp->_flags |= __SRD;
       
   105 	} else {
       
   106 		/*
       
   107 		 * We were reading.  If there is an ungetc buffer,
       
   108 		 * we must have been reading from that.  Drop it,
       
   109 		 * restoring the previous buffer (if any).  If there
       
   110 		 * is anything in that buffer, return.
       
   111 		 */
       
   112 		if (HASUB(fp)) {
       
   113 			FREEUB(fp);
       
   114 			if ((fp->_r = fp->_ur) != 0) {
       
   115 				fp->_p = fp->_extra->_up;
       
   116 				return (0);
       
   117 			}
       
   118 		}
       
   119 	}
       
   120 	return 1;
       
   121 }
       
   122 
       
   123 /*
       
   124  * Refill a stdio buffer.
       
   125  * Return EOF on eof or error, 0 otherwise.
       
   126  */
       
   127 
       
   128 int
       
   129 __srefill(FILE *fp)
       
   130 {
       
   131 	int i = 0;
       
   132 	int ret = validate(fp);
       
   133 	if(ret != 1)
       
   134 		return (ret);
       
   135 		if (fp->_bf._base == NULL)
       
   136 	{
       
   137 		__smakebuf(fp);
       
   138 		if(fp->_bf._base == NULL && errno == ENOMEM)
       
   139 		{
       
   140 			return (EOF);
       
   141 		}
       
   142 	}
       
   143 	/*
       
   144 	 * Before reading from a line buffered or unbuffered file,
       
   145 	 * flush all line buffered output files, per the ANSI C
       
   146 	 * standard.
       
   147 	 */
       
   148 	if (fp->_flags & (__SLBF|__SNBF)) {
       
   149 		/* Ignore this file in _fwalk to avoid potential deadlock. */
       
   150 		fp->_flags |= __SIGN;
       
   151 		(void) _fwalk(lflush);
       
   152 		fp->_flags &= ~__SIGN;
       
   153 
       
   154 		/* Now flush this file without locking it. */
       
   155 		if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
       
   156 			__sflush(fp);
       
   157 	}
       
   158 	fp->_p = fp->_bf._base;
       
   159 
       
   160 #ifdef __SYMBIAN32__
       
   161 	if (fp->_file == 0)
       
   162 	{
       
   163 		int offset = 0;
       
   164 		while(1)
       
   165 		{
       
   166 				i = 0;
       
   167 				offset = _sread(fp, (char *)fp->_p, fp->_bf._size);	
       
   168 				fp->_r += offset; 
       
   169 				if(offset < 0)
       
   170 					goto noinput;
       
   171 				
       
   172 				if(offset > 0)
       
   173 				{				  
       
   174 					//Check for back-space
       
   175 					if(*fp->_p == 0x08)						
       
   176 					{	
       
   177 						// Check for back - space at first place
       
   178 						if(fp->_r == 1)
       
   179 						
       
   180 							fp->_r -=1;					
       
   181 						else		
       
   182 							{
       
   183 							fp->_r -=2;					
       
   184 							fp->_p -=1;
       
   185 							}
       
   186 						continue;
       
   187 					}
       
   188 					
       
   189 					//Check for new-line
       
   190 					for (i = 0; i < offset; ++i)
       
   191 						{
       
   192 						if (*fp->_p == '\n')
       
   193 							{
       
   194 							break;
       
   195 							}
       
   196 						fp->_p++;
       
   197 						}
       
   198 					
       
   199 					if (i != offset)
       
   200 						{
       
   201 						fp->_r -= (offset - i);	
       
   202 						break;
       
   203 						}
       
   204 				}
       
   205 				else
       
   206 					break;
       
   207 		}		
       
   208 		fp->_p -= fp->_r;
       
   209 		fp->_r += (offset - i);
       
   210 	}	
       
   211 	else
       
   212 	{
       
   213 		fp->_r = _sread(fp, (char *)fp->_p, fp->_bf._size);	
       
   214 	}	
       
   215 #else
       
   216 	fp->_r = _sread(fp, (char *)fp->_p, fp->_bf._size);
       
   217 #endif
       
   218 noinput:
       
   219 	fp->_flags &= ~__SMOD;	/* buffer contents are again pristine */
       
   220 	if (fp->_r <= 0) {
       
   221 		if (fp->_r == 0)
       
   222 			fp->_flags |= __SEOF;
       
   223 		else {
       
   224 			fp->_r = 0;
       
   225 			fp->_flags |= __SERR;
       
   226 		}
       
   227 		return (EOF);
       
   228 	}
       
   229 	return (0);
       
   230 }
       
   231 
       
   232 #ifdef __SYMBIAN32__
       
   233 int __read_long(FILE *fp,char *p, size_t *resid)
       
   234 {
       
   235 		int w;
       
   236 		int ret = validate(fp);
       
   237 		if(ret != 1)
       
   238 			return (ret);
       
   239 		w = _sread(fp,p,*resid);
       
   240 		p+=w;
       
   241 		fp->_p = fp->_bf._base;
       
   242 		if (w < *resid) 
       
   243 		{
       
   244 			if (w < 0)
       
   245 				fp->_flags |= __SERR;
       
   246 			else 
       
   247 			{
       
   248 				fp->_flags |= __SEOF;
       
   249 			}
       
   250 		*resid-=w;
       
   251 		return (EOF);
       
   252 		}	
       
   253 		*resid-=w;
       
   254 	return 0;
       
   255 	}
       
   256 #endif //if __SYMBIAN32__