Update contrib.
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
31 * © Portions copyright (c) 2005 - 2006 Nokia Corporation. All rights reserved.
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93";
36 #endif /* LIBC_SCCS and not lint */
37 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD: src/lib/libc/stdio/freopen.c,v 1.13 2004/05/22 15:19:41 tjr Exp $");
41 #include "namespace.h"
42 #include <sys/types.h>
46 #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
51 #include "un-namespace.h"
54 #include "libc_private.h"
56 #include "common_def.h"
57 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
58 #include "libc_wsd_defs.h"
62 int *GET_WSD_VAR_NAME(__sdidinit, g)();
63 #define __sdidinit (*GET_WSD_VAR_NAME(__sdidinit, g)())
66 Re-direct an existing, open (probably) file to some other file.
67 ANSI is written such that the original file gets closed if at
68 all possible, no matter what.
71 EXPORT_C FILE * wfreopen(const wchar_t * file, const wchar_t * mode, FILE *fp)
74 int dflags, flags, isopen, oflags, sverrno, wantfd;
85 siz = wcstombs(destmode, mode, 4);
88 if ((flags = __sflags(destmode, &oflags)) == 0) {
99 * If the filename is a NULL pointer, the caller is asking us to
100 * re-open the same file with a different mode. We allow this only
101 * if the modes are compatible.
104 /* See comment below regarding freopen() of closed files. */
105 if (fp->_flags == 0) {
110 if ((dflags = _fcntl(fp->_file, F_GETFL)) < 0) {
117 if ((dflags & O_ACCMODE) != O_RDWR && (dflags & O_ACCMODE) !=
118 (oflags & O_ACCMODE)) {
124 if ((oflags ^ dflags) & O_APPEND) {
126 dflags |= oflags & O_APPEND;
127 if (_fcntl(fp->_file, F_SETFL, dflags) < 0) {
135 if (oflags & O_TRUNC)
136 ftruncate(fp->_file, 0);
137 if (_fseeko(fp, 0, oflags & O_APPEND ? SEEK_END : SEEK_SET,
138 0) < 0 && errno != ESPIPE) {
153 * There are actually programs that depend on being able to "freopen"
154 * descriptors that weren't originally open. Keep this from breaking.
155 * Remember whether the stream was open to begin with, and which file
156 * descriptor (if any) was associated with it. If it was attached to
157 * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
158 * should work. This is unnecessary if it was not a Unix file.
160 if (fp->_flags == 0) {
161 fp->_flags = __SEOF; /* hold on to it */
166 /* flush the stream; ANSI doesn't require this. */
167 if (fp->_flags & __SWR)
169 /* if close is NULL, closing is a no-op, hence pointless */
170 isopen = fp->_close != NULL;
171 if ((wantfd = fp->_file) < 0 && isopen) {
172 (void) (*fp->_close)(fp->_cookie);
176 /* Get a new descriptor to refer to the new file. */
177 f = wopen(file, oflags, DEFFILEMODE);
178 if (f < 0 && isopen) {
179 /* If out of fd's close the old one and try again. */
180 if (errno == ENFILE || errno == EMFILE) {
181 (void) (*fp->_close)(fp->_cookie);
183 f = wopen(file, oflags, DEFFILEMODE);
190 * Finish closing fp. Even if the open succeeded above, we cannot
191 * keep fp->_base: it may be the wrong size. This loses the effect
192 * of any setbuffer calls, but stdio has always done this before.
195 (void) (*fp->_close)(fp->_cookie);
196 if (fp->_flags & __SMBF)
199 BackendFree((char *)fp->_bf._base);
201 free((char *)fp->_bf._base);
202 #endif//__SYMBIAN32__
208 fp->_bf._base = NULL;
217 fp->_extra->orientation = 0;
218 memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
220 if (f < 0) { /* did not get it after all */
221 fp->_flags = 0; /* set it free */
222 errno = sverrno; /* restore in case _close clobbered */
226 #ifndef __SYMBIAN32__
228 * If reopening something that was open before on a real file, try
229 * to maintain the descriptor. Various C library routines (perror)
230 * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
232 if (wantfd >= 0 && f != wantfd) {
233 if (dup2(f, wantfd) >= 0) {
239 if (wantfd >= 0 && f > wantfd){
240 if (dup2(f, wantfd) >= 0) {
251 fp->_write = __swrite;
253 fp->_close = __sclose;
255 if (oflags & O_TEXT) {
256 fp->_extra->fmode = 't';
259 fp->_extra->fmode = 'b';