11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1990, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Chris Torek. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16249808Semaste * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 311573Srgrimes */ 321573Srgrimes 331573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 341573Srgrimesstatic char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93"; 351573Srgrimes#endif /* LIBC_SCCS and not lint */ 3692986Sobrien#include <sys/cdefs.h> 3792986Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/stdio/freopen.c 321074 2017-07-17 14:09:34Z kib $"); 381573Srgrimes 3971579Sdeischen#include "namespace.h" 401573Srgrimes#include <sys/types.h> 411573Srgrimes#include <sys/stat.h> 421573Srgrimes#include <fcntl.h> 431573Srgrimes#include <errno.h> 44176629Sjhb#include <limits.h> 451573Srgrimes#include <unistd.h> 461573Srgrimes#include <stdio.h> 471573Srgrimes#include <stdlib.h> 4871579Sdeischen#include "un-namespace.h" 4971579Sdeischen#include "libc_private.h" 501573Srgrimes#include "local.h" 511573Srgrimes 528870Srgrimes/* 538870Srgrimes * Re-direct an existing, open (probably) file to some other file. 541573Srgrimes * ANSI is written such that the original file gets closed if at 551573Srgrimes * all possible, no matter what. 561573Srgrimes */ 571573SrgrimesFILE * 58249810Semastefreopen(const char * __restrict file, const char * __restrict mode, 59249810Semaste FILE * __restrict fp) 601573Srgrimes{ 6172373Sdeischen int f; 62109871Stjr int dflags, flags, isopen, oflags, sverrno, wantfd; 631573Srgrimes 641573Srgrimes if ((flags = __sflags(mode, &oflags)) == 0) { 65163406Sache sverrno = errno; 661573Srgrimes (void) fclose(fp); 67163406Sache errno = sverrno; 681573Srgrimes return (NULL); 691573Srgrimes } 701573Srgrimes 71321074Skib FLOCKFILE_CANCELSAFE(fp); 7253460Sdt 731573Srgrimes if (!__sdidinit) 741573Srgrimes __sinit(); 751573Srgrimes 761573Srgrimes /* 77109871Stjr * If the filename is a NULL pointer, the caller is asking us to 78109871Stjr * re-open the same file with a different mode. We allow this only 79109871Stjr * if the modes are compatible. 80109871Stjr */ 81109871Stjr if (file == NULL) { 82109871Stjr /* See comment below regarding freopen() of closed files. */ 83109871Stjr if (fp->_flags == 0) { 84109871Stjr errno = EINVAL; 85321074Skib fp = NULL; 86321074Skib goto end; 87109871Stjr } 88109871Stjr if ((dflags = _fcntl(fp->_file, F_GETFL)) < 0) { 89109871Stjr sverrno = errno; 90109871Stjr fclose(fp); 91109871Stjr errno = sverrno; 92321074Skib fp = NULL; 93321074Skib goto end; 94109871Stjr } 95291293Sngie /* Work around incorrect O_ACCMODE. */ 96291293Sngie if ((dflags & O_ACCMODE) != O_RDWR && 97291293Sngie (dflags & (O_ACCMODE | O_EXEC)) != (oflags & O_ACCMODE)) { 98109871Stjr fclose(fp); 99269482Spfg errno = EBADF; 100321074Skib fp = NULL; 101321074Skib goto end; 102109871Stjr } 103163430Sache if (fp->_flags & __SWR) 104163430Sache (void) __sflush(fp); 105109871Stjr if ((oflags ^ dflags) & O_APPEND) { 106109871Stjr dflags &= ~O_APPEND; 107109871Stjr dflags |= oflags & O_APPEND; 108109871Stjr if (_fcntl(fp->_file, F_SETFL, dflags) < 0) { 109109871Stjr sverrno = errno; 110109871Stjr fclose(fp); 111109871Stjr errno = sverrno; 112321074Skib fp = NULL; 113321074Skib goto end; 114109871Stjr } 115109871Stjr } 116163405Sache if (oflags & O_TRUNC) 117163405Sache (void) ftruncate(fp->_file, (off_t)0); 118163430Sache if (!(oflags & O_APPEND)) 119163430Sache (void) _sseek(fp, (fpos_t)0, SEEK_SET); 120243731Sjilles if (oflags & O_CLOEXEC) 121243731Sjilles (void) _fcntl(fp->_file, F_SETFD, FD_CLOEXEC); 122109871Stjr f = fp->_file; 123109871Stjr isopen = 0; 124109871Stjr wantfd = -1; 125109871Stjr goto finish; 126109871Stjr } 127109871Stjr 128109871Stjr /* 1291573Srgrimes * There are actually programs that depend on being able to "freopen" 1301573Srgrimes * descriptors that weren't originally open. Keep this from breaking. 1311573Srgrimes * Remember whether the stream was open to begin with, and which file 1321573Srgrimes * descriptor (if any) was associated with it. If it was attached to 1331573Srgrimes * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin) 1341573Srgrimes * should work. This is unnecessary if it was not a Unix file. 1351573Srgrimes */ 1361573Srgrimes if (fp->_flags == 0) { 1371573Srgrimes fp->_flags = __SEOF; /* hold on to it */ 1381573Srgrimes isopen = 0; 1391573Srgrimes wantfd = -1; 1401573Srgrimes } else { 1411573Srgrimes /* flush the stream; ANSI doesn't require this. */ 1421573Srgrimes if (fp->_flags & __SWR) 1431573Srgrimes (void) __sflush(fp); 1441573Srgrimes /* if close is NULL, closing is a no-op, hence pointless */ 1451573Srgrimes isopen = fp->_close != NULL; 1461573Srgrimes if ((wantfd = fp->_file) < 0 && isopen) { 1471573Srgrimes (void) (*fp->_close)(fp->_cookie); 1481573Srgrimes isopen = 0; 1491573Srgrimes } 1501573Srgrimes } 1511573Srgrimes 1521573Srgrimes /* Get a new descriptor to refer to the new file. */ 15356698Sjasone f = _open(file, oflags, DEFFILEMODE); 154269624Sache /* If out of fd's close the old one and try again. */ 155269624Sache if (f < 0 && isopen && wantfd > STDERR_FILENO && 156269624Sache (errno == ENFILE || errno == EMFILE)) { 157269624Sache (void) (*fp->_close)(fp->_cookie); 158269624Sache isopen = 0; 159269624Sache wantfd = -1; 160269624Sache f = _open(file, oflags, DEFFILEMODE); 161269624Sache } 1621573Srgrimes sverrno = errno; 1631573Srgrimes 164109871Stjrfinish: 1651573Srgrimes /* 1661573Srgrimes * Finish closing fp. Even if the open succeeded above, we cannot 1671573Srgrimes * keep fp->_base: it may be the wrong size. This loses the effect 1681573Srgrimes * of any setbuffer calls, but stdio has always done this before. 169216334Sjhb * 170216334Sjhb * Leave the existing file descriptor open until dup2() is called 171216334Sjhb * below to avoid races where a concurrent open() in another thread 172216334Sjhb * could claim the existing descriptor. 1731573Srgrimes */ 1741573Srgrimes if (fp->_flags & __SMBF) 1751573Srgrimes free((char *)fp->_bf._base); 1761573Srgrimes fp->_w = 0; 1771573Srgrimes fp->_r = 0; 1781573Srgrimes fp->_p = NULL; 1791573Srgrimes fp->_bf._base = NULL; 1801573Srgrimes fp->_bf._size = 0; 1811573Srgrimes fp->_lbfsize = 0; 1821573Srgrimes if (HASUB(fp)) 1831573Srgrimes FREEUB(fp); 1841573Srgrimes fp->_ub._size = 0; 1851573Srgrimes if (HASLB(fp)) 1861573Srgrimes FREELB(fp); 1871573Srgrimes fp->_lb._size = 0; 188178287Sjhb fp->_orientation = 0; 189178287Sjhb memset(&fp->_mbstate, 0, sizeof(mbstate_t)); 190290544Sache fp->_flags2 = 0; 1911573Srgrimes 1921573Srgrimes if (f < 0) { /* did not get it after all */ 193216334Sjhb if (isopen) 194216334Sjhb (void) (*fp->_close)(fp->_cookie); 1951573Srgrimes fp->_flags = 0; /* set it free */ 1961573Srgrimes errno = sverrno; /* restore in case _close clobbered */ 197321074Skib fp = NULL; 198321074Skib goto end; 1991573Srgrimes } 2001573Srgrimes 2011573Srgrimes /* 2021573Srgrimes * If reopening something that was open before on a real file, try 2031573Srgrimes * to maintain the descriptor. Various C library routines (perror) 2041573Srgrimes * assume stderr is always fd STDERR_FILENO, even if being freopen'd. 2051573Srgrimes */ 206216334Sjhb if (wantfd >= 0) { 207243731Sjilles if ((oflags & O_CLOEXEC ? _fcntl(f, F_DUP2FD_CLOEXEC, wantfd) : 208243731Sjilles _dup2(f, wantfd)) >= 0) { 20956698Sjasone (void)_close(f); 2101573Srgrimes f = wantfd; 211216334Sjhb } else 212216334Sjhb (void)_close(fp->_file); 2131573Srgrimes } 2141573Srgrimes 215176628Sjhb /* 216176628Sjhb * File descriptors are a full int, but _file is only a short. 217176628Sjhb * If we get a valid file descriptor that is greater than 218176628Sjhb * SHRT_MAX, then the fd will get sign-extended into an 219176628Sjhb * invalid file descriptor. Handle this case by failing the 220176628Sjhb * open. 221176628Sjhb */ 222176628Sjhb if (f > SHRT_MAX) { 223176628Sjhb fp->_flags = 0; /* set it free */ 224176628Sjhb errno = EMFILE; 225321074Skib fp = NULL; 226321074Skib goto end; 227176628Sjhb } 228176628Sjhb 2291573Srgrimes fp->_flags = flags; 2301573Srgrimes fp->_file = f; 2311573Srgrimes fp->_cookie = fp; 2321573Srgrimes fp->_read = __sread; 2331573Srgrimes fp->_write = __swrite; 2341573Srgrimes fp->_seek = __sseek; 2351573Srgrimes fp->_close = __sclose; 236163430Sache /* 237163430Sache * When opening in append mode, even though we use O_APPEND, 238163430Sache * we need to seek to the end so that ftell() gets the right 239163430Sache * answer. If the user then alters the seek pointer, or 240163430Sache * the file extends, this will fail, but there is not much 241163430Sache * we can do about this. (We could set __SAPP and check in 242163430Sache * fseek and ftell.) 243163430Sache */ 244290544Sache if (oflags & O_APPEND) { 245290544Sache fp->_flags2 |= __S2OAP; 246163430Sache (void) _sseek(fp, (fpos_t)0, SEEK_END); 247290544Sache } 248321074Skibend: 249321074Skib FUNLOCKFILE_CANCELSAFE(); 2501573Srgrimes return (fp); 2511573Srgrimes} 252