1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LSTDIO/FREOPEN.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,203 @@
1.4 +/* FREOPEN.C
1.5 + *
1.6 + * Portions Copyright (c) 1990-1999 Nokia Corporation and/or its subsidiary(-ies).
1.7 + * All rights reserved.
1.8 + */
1.9 +
1.10 +/*
1.11 + * Copyright (c) 1990 The Regents of the University of California.
1.12 + * All rights reserved.
1.13 + *
1.14 + * Redistribution and use in source and binary forms are permitted
1.15 + * provided that the above copyright notice and this paragraph are
1.16 + * duplicated in all such forms and that any documentation,
1.17 + * advertising materials, and other materials related to such
1.18 + * distribution and use acknowledge that the software was developed
1.19 + * by the University of California, Berkeley. The name of the
1.20 + * University may not be used to endorse or promote products derived
1.21 + * from this software without specific prior written permission.
1.22 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1.23 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1.24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1.25 + */
1.26 +
1.27 +/*
1.28 +FUNCTION
1.29 +<<freopen>>---open a file using an existing file descriptor
1.30 +
1.31 +INDEX
1.32 + freopen
1.33 +
1.34 +ANSI_SYNOPSIS
1.35 + #include <stdio.h>
1.36 + FILE *freopen(const char *<[file]>, const char *<[mode]>,
1.37 + FILE *<[fp]>);
1.38 +
1.39 +TRAD_SYNOPSIS
1.40 + #include <stdio.h>
1.41 + FILE *freopen(<[file]>, <[mode]>, <[fp]>)
1.42 + char *<[file]>;
1.43 + char *<[mode]>;
1.44 + FILE *<[fp]>;
1.45 +
1.46 +DESCRIPTION
1.47 +Use this variant of <<fopen>> if you wish to specify a particular file
1.48 +descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for
1.49 +the file.
1.50 +
1.51 +If <[fp]> was associated with another file or stream, <<freopen>>
1.52 +closes that other file or stream (but ignores any errors while closing
1.53 +it).
1.54 +
1.55 +<[file]> and <[mode]> are used just as in <<fopen>>.
1.56 +
1.57 +RETURNS
1.58 +If successful, the result is the same as the argument <[fp]>. If the
1.59 +file cannot be opened as specified, the result is <<NULL>>.
1.60 +
1.61 +PORTABILITY
1.62 +ANSI C requires <<freopen>>.
1.63 +
1.64 +Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
1.65 +<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
1.66 +*/
1.67 +
1.68 +#include <time.h>
1.69 +#include <stdio_r.h>
1.70 +#include <fcntl.h>
1.71 +#include <stdlib_r.h>
1.72 +#include "LOCAL.H"
1.73 +#include <errno.h>
1.74 +
1.75 +/*
1.76 + * Re-direct an existing, open (probably) file to some other file.
1.77 + */
1.78 +
1.79 +#define MaxFullName 255
1.80 +
1.81 +/**
1.82 +Reopen a stream with a different file and mode.
1.83 +@return If the file has been succesfully reopened the function returns a pointer to the file.
1.84 +Otherwise a NULL pointer is returned.
1.85 +@param file name of the file to be opened.
1.86 +This paramenter must follow operating system's specifications and can include a path
1.87 +if the system supports it.
1.88 +@param mode type of access requested.
1.89 +@param fp pointer to open file that has to be reopened.
1.90 +*/
1.91 +EXPORT_C FILE * freopen (const char *file, const char *mode, FILE *fp)
1.92 +{
1.93 + wchar_t _wfile[MaxFullName+1];
1.94 + wchar_t _wmode[MaxFullName+1];
1.95 + struct _reent *ptr;
1.96 +
1.97 + if ((-1 != mbstowcs(_wfile, file, MaxFullName)) &&
1.98 + (-1 != mbstowcs(_wmode, mode, MaxFullName)))
1.99 + {
1.100 + return wfreopen(_wfile, _wmode, fp);
1.101 + }
1.102 +
1.103 + CHECK_INIT (fp);
1.104 + ptr = fp->_data;
1.105 + ptr->_errno = EILSEQ;
1.106 + return NULL;
1.107 +}
1.108 +
1.109 +EXPORT_C FILE * wfreopen (const wchar_t *file, const wchar_t *mode, FILE *fp)
1.110 +{
1.111 + register int f;
1.112 + int isopen, flags, oflags, e;
1.113 + struct _reent *ptr;
1.114 +
1.115 + CHECK_INIT (fp);
1.116 + ptr = fp->_data;
1.117 +
1.118 + if ((flags = __sflags (ptr, mode, &oflags)) == 0)
1.119 + {
1.120 + (void) fclose (fp);
1.121 + return NULL;
1.122 + }
1.123 +
1.124 + /*
1.125 + * Remember whether the stream was open to begin with, and
1.126 + * which file descriptor (if any) was associated with it.
1.127 + * If it was attached to a descriptor, defer closing it,
1.128 + * so that, e.g., freopen("/dev/stdin", "r", stdin) works.
1.129 + * This is unnecessary if it was not a Unix file.
1.130 + */
1.131 +
1.132 + if (fp->_flags == 0)
1.133 + {
1.134 + fp->_flags = __SEOF; /* hold on to it */
1.135 + isopen = 0;
1.136 + }
1.137 + else
1.138 + {
1.139 + if (fp->_flags & __SWR)
1.140 + (void) fflush (fp);
1.141 + /* if close is NULL, closing is a no-op, hence pointless */
1.142 + isopen = fp->_close != NULL;
1.143 + if (fp->_file < 0 && isopen)
1.144 + {
1.145 + (void) (*fp->_close) (fp->_cookie);
1.146 + isopen = 0;
1.147 + }
1.148 + }
1.149 +
1.150 + /*
1.151 + * Now get a new descriptor to refer to the new file.
1.152 + */
1.153 +
1.154 + f = _wopen_r (ptr, (wchar_t *)file, oflags, 0666);
1.155 + if (f < 0 && isopen)
1.156 + {
1.157 + /*
1.158 + * May have used up all descriptors, so close the old
1.159 + * and try again.
1.160 + */
1.161 + (void) (*fp->_close) (fp->_cookie);
1.162 + isopen = 0;
1.163 + f = _wopen_r (ptr, (wchar_t *) file, oflags, 0666);
1.164 + }
1.165 + e = ptr->_errno;
1.166 +
1.167 + /*
1.168 + * Finish closing fp. Even if the open succeeded above,
1.169 + * we cannot keep fp->_base: it may be the wrong size.
1.170 + * This loses the effect of any setbuffer calls,
1.171 + * but stdio has always done this before.
1.172 + */
1.173 +
1.174 + if (isopen)
1.175 + (void) (*fp->_close) (fp->_cookie);
1.176 + if (fp->_flags & __SMBF)
1.177 + _free_r (ptr, (char *) fp->_bf._base);
1.178 + fp->_w = 0;
1.179 + fp->_r = 0;
1.180 + fp->_p = NULL;
1.181 + fp->_bf._base = NULL;
1.182 + fp->_bf._size = 0;
1.183 + fp->_lbfsize = 0;
1.184 + if (HASUB (fp))
1.185 + FREEUB (fp);
1.186 + fp->_ub._size = 0;
1.187 + if (HASLB (fp))
1.188 + FREELB (fp);
1.189 + fp->_lb._size = 0;
1.190 +
1.191 + if (f < 0)
1.192 + { /* did not get it after all */
1.193 + fp->_flags = 0; /* set it free */
1.194 + ptr->_errno = e; /* restore in case _close clobbered */
1.195 + return NULL;
1.196 + }
1.197 +
1.198 + fp->_flags = (short)flags;
1.199 + fp->_file = (short)f;
1.200 + fp->_cookie = (void*) fp;
1.201 + fp->_read = __sread;
1.202 + fp->_write = __swrite;
1.203 + fp->_seek = __sseek;
1.204 + fp->_close = __sclose;
1.205 + return fp;
1.206 +}