genericopenlibs/cstdlib/LSTDIO/FREOPEN.C
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* FREOPEN.C
       
     2  * 
       
     3  * Portions Copyright (c) 1990-1999 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 <<freopen>>---open a file using an existing file descriptor
       
    27 
       
    28 INDEX
       
    29 	freopen
       
    30 
       
    31 ANSI_SYNOPSIS
       
    32 	#include <stdio.h>
       
    33 	FILE *freopen(const char *<[file]>, const char *<[mode]>,
       
    34 		      FILE *<[fp]>);
       
    35 
       
    36 TRAD_SYNOPSIS
       
    37 	#include <stdio.h>
       
    38 	FILE *freopen(<[file]>, <[mode]>, <[fp]>)
       
    39 	char *<[file]>;
       
    40 	char *<[mode]>;
       
    41 	FILE *<[fp]>;
       
    42 
       
    43 DESCRIPTION
       
    44 Use this variant of <<fopen>> if you wish to specify a particular file
       
    45 descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for
       
    46 the file.
       
    47 
       
    48 If <[fp]> was associated with another file or stream, <<freopen>>
       
    49 closes that other file or stream (but ignores any errors while closing
       
    50 it).
       
    51 
       
    52 <[file]> and <[mode]> are used just as in <<fopen>>.
       
    53 
       
    54 RETURNS
       
    55 If successful, the result is the same as the argument <[fp]>.  If the
       
    56 file cannot be opened as specified, the result is <<NULL>>.
       
    57 
       
    58 PORTABILITY
       
    59 ANSI C requires <<freopen>>.
       
    60 
       
    61 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
       
    62 <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
       
    63 */
       
    64 
       
    65 #include <time.h>
       
    66 #include <stdio_r.h>
       
    67 #include <fcntl.h>
       
    68 #include <stdlib_r.h>
       
    69 #include "LOCAL.H"
       
    70 #include <errno.h>
       
    71 
       
    72 /*
       
    73  * Re-direct an existing, open (probably) file to some other file.
       
    74  */
       
    75 
       
    76 #define MaxFullName 255
       
    77 
       
    78 /**
       
    79 Reopen a stream with a different file and mode.
       
    80 @return If the file has been succesfully reopened the function returns a pointer to the file.
       
    81 Otherwise a NULL pointer is returned.
       
    82 @param file name of the file to be opened. 
       
    83 This paramenter must follow operating system's specifications and can include a path 
       
    84 if the system supports it.
       
    85 @param mode type of access requested.
       
    86 @param fp pointer to open file that has to be reopened.
       
    87 */
       
    88 EXPORT_C FILE * freopen (const char *file, const char *mode, FILE *fp)
       
    89 {
       
    90   	wchar_t _wfile[MaxFullName+1];	
       
    91 	wchar_t _wmode[MaxFullName+1];
       
    92 	struct _reent *ptr;
       
    93 
       
    94 	if ((-1 != mbstowcs(_wfile, file, MaxFullName)) && 
       
    95 		(-1 != mbstowcs(_wmode, mode, MaxFullName)))
       
    96 	{
       
    97 		return wfreopen(_wfile, _wmode, fp);
       
    98 	}
       
    99 
       
   100 	CHECK_INIT (fp);
       
   101 	ptr = fp->_data;
       
   102 	ptr->_errno = EILSEQ;
       
   103 	return NULL;
       
   104 }
       
   105 
       
   106 EXPORT_C FILE * wfreopen (const wchar_t *file, const wchar_t *mode, FILE *fp)
       
   107 {
       
   108   register int f;
       
   109   int isopen, flags, oflags, e;
       
   110   struct _reent *ptr;
       
   111 
       
   112   CHECK_INIT (fp);
       
   113   ptr = fp->_data;
       
   114 
       
   115   if ((flags = __sflags (ptr, mode, &oflags)) == 0)
       
   116     {
       
   117       (void) fclose (fp);
       
   118       return NULL;
       
   119     }
       
   120 
       
   121   /*
       
   122    * Remember whether the stream was open to begin with, and
       
   123    * which file descriptor (if any) was associated with it.
       
   124    * If it was attached to a descriptor, defer closing it,
       
   125    * so that, e.g., freopen("/dev/stdin", "r", stdin) works.
       
   126    * This is unnecessary if it was not a Unix file.
       
   127    */
       
   128 
       
   129   if (fp->_flags == 0)
       
   130     {
       
   131       fp->_flags = __SEOF;	/* hold on to it */
       
   132       isopen = 0;
       
   133     }
       
   134   else
       
   135     {
       
   136       if (fp->_flags & __SWR)
       
   137 	(void) fflush (fp);
       
   138       /* if close is NULL, closing is a no-op, hence pointless */
       
   139       isopen = fp->_close != NULL;
       
   140       if (fp->_file < 0 && isopen)
       
   141 	{
       
   142 	  (void) (*fp->_close) (fp->_cookie);
       
   143 	  isopen = 0;
       
   144 	}
       
   145     }
       
   146 
       
   147   /*
       
   148    * Now get a new descriptor to refer to the new file.
       
   149    */
       
   150 
       
   151   f = _wopen_r (ptr, (wchar_t *)file, oflags, 0666);
       
   152   if (f < 0 && isopen)
       
   153     {
       
   154       /*
       
   155        * May have used up all descriptors, so close the old
       
   156        * and try again.
       
   157        */
       
   158       (void) (*fp->_close) (fp->_cookie);
       
   159       isopen = 0;
       
   160       f = _wopen_r (ptr, (wchar_t *) file, oflags, 0666);
       
   161     }
       
   162   e = ptr->_errno;
       
   163 
       
   164   /*
       
   165    * Finish closing fp.  Even if the open succeeded above,
       
   166    * we cannot keep fp->_base: it may be the wrong size.
       
   167    * This loses the effect of any setbuffer calls,
       
   168    * but stdio has always done this before.
       
   169    */
       
   170 
       
   171   if (isopen)
       
   172     (void) (*fp->_close) (fp->_cookie);
       
   173   if (fp->_flags & __SMBF)
       
   174     _free_r (ptr, (char *) fp->_bf._base);
       
   175   fp->_w = 0;
       
   176   fp->_r = 0;
       
   177   fp->_p = NULL;
       
   178   fp->_bf._base = NULL;
       
   179   fp->_bf._size = 0;
       
   180   fp->_lbfsize = 0;
       
   181   if (HASUB (fp))
       
   182     FREEUB (fp);
       
   183   fp->_ub._size = 0;
       
   184   if (HASLB (fp))
       
   185     FREELB (fp);
       
   186   fp->_lb._size = 0;
       
   187 
       
   188   if (f < 0)
       
   189     {				/* did not get it after all */
       
   190       fp->_flags = 0;		/* set it free */
       
   191       ptr->_errno = e;		/* restore in case _close clobbered */
       
   192       return NULL;
       
   193     }
       
   194 
       
   195   fp->_flags = (short)flags;
       
   196   fp->_file = (short)f;
       
   197   fp->_cookie = (void*) fp;
       
   198   fp->_read = __sread;
       
   199   fp->_write = __swrite;
       
   200   fp->_seek = __sseek;
       
   201   fp->_close = __sclose;
       
   202   return fp;
       
   203 }