1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 /* 19 FUNCTION 20 <<freopen>>---open a file using an existing file descriptor 21 22 INDEX 23 freopen 24 INDEX 25 _freopen_r 26 27 ANSI_SYNOPSIS 28 #include <stdio.h> 29 FILE *freopen(const char *<[file]>, const char *<[mode]>, 30 FILE *<[fp]>); 31 FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>, 32 const char *<[mode]>, FILE *<[fp]>); 33 34 TRAD_SYNOPSIS 35 #include <stdio.h> 36 FILE *freopen(<[file]>, <[mode]>, <[fp]>) 37 char *<[file]>; 38 char *<[mode]>; 39 FILE *<[fp]>; 40 41 FILE *_freopen_r(<[ptr]>, <[file]>, <[mode]>, <[fp]>) 42 struct _reent *<[ptr]>; 43 char *<[file]>; 44 char *<[mode]>; 45 FILE *<[fp]>; 46 47 DESCRIPTION 48 Use this variant of <<fopen>> if you wish to specify a particular file 49 descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for 50 the file. 51 52 If <[fp]> was associated with another file or stream, <<freopen>> 53 closes that other file or stream (but ignores any errors while closing 54 it). 55 56 <[file]> and <[mode]> are used just as in <<fopen>>. 57 58 RETURNS 59 If successful, the result is the same as the argument <[fp]>. If the 60 file cannot be opened as specified, the result is <<NULL>>. 61 62 PORTABILITY 63 ANSI C requires <<freopen>>. 64 65 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, 66 <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. 67 */ 68 69 #include <time.h> 70 #include <stdio.h> 71 #include <fcntl.h> 72 #include <stdlib.h> 73 #include "local.h" 74 #include <sys/lock.h> 75 76 /* 77 * Re-direct an existing, open (probably) file to some other file. 78 */ 79 80 FILE * 81 _DEFUN (_freopen_r, (ptr, file, mode, fp), 82 struct _reent *ptr _AND 83 _CONST char *file _AND 84 _CONST char *mode _AND 85 register FILE *fp) 86 { 87 register int f; 88 int flags, oflags, e; 89 90 _flockfile(fp); 91 92 CHECK_INIT (fp); 93 94 if ((flags = __sflags (ptr, mode, &oflags)) == 0) 95 { 96 (void) fclose (fp); 97 _funlockfile(fp); 98 return NULL; 99 } 100 101 /* 102 * Remember whether the stream was open to begin with, and 103 * which file descriptor (if any) was associated with it. 104 * If it was attached to a descriptor, defer closing it, 105 * so that, e.g., freopen("/dev/stdin", "r", stdin) works. 106 * This is unnecessary if it was not a Unix file. 107 */ 108 109 if (fp->_flags == 0) 110 fp->_flags = __SEOF; /* hold on to it */ 111 else 112 { 113 if (fp->_flags & __SWR) 114 (void) fflush (fp); 115 /* if close is NULL, closing is a no-op, hence pointless */ 116 if (fp->_close != NULL) 117 (void) (*fp->_close) (fp->_cookie); 118 } 119 120 /* 121 * Now get a new descriptor to refer to the new file. 122 */ 123 124 f = _open_r (ptr, (char *) file, oflags, 0666); 125 e = ptr->_errno; 126 127 /* 128 * Finish closing fp. Even if the open succeeded above, 129 * we cannot keep fp->_base: it may be the wrong size. 130 * This loses the effect of any setbuffer calls, 131 * but stdio has always done this before. 132 */ 133 134 if (fp->_flags & __SMBF) 135 _free_r (ptr, (char *) fp->_bf._base); 136 fp->_w = 0; 137 fp->_r = 0; 138 fp->_p = NULL; 139 fp->_bf._base = NULL; 140 fp->_bf._size = 0; 141 fp->_lbfsize = 0; 142 if (HASUB (fp)) 143 FREEUB (fp); 144 fp->_ub._size = 0; 145 if (HASLB (fp)) 146 FREELB (fp); 147 fp->_lb._size = 0; 148 149 if (f < 0) 150 { /* did not get it after all */ 151 ptr->_errno = e; /* restore in case _close clobbered */ 152 _funlockfile(fp); 153 #ifndef __SINGLE_THREAD__ 154 __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); 155 #endif 156 fp->_flags = 0; /* set it free */ 157 return NULL; 158 } 159 160 fp->_flags = flags; 161 fp->_file = f; 162 fp->_cookie = (_PTR) fp; 163 fp->_read = __sread; 164 fp->_write = __swrite; 165 fp->_seek = __sseek; 166 fp->_close = __sclose; 167 168 #ifdef __SCLE 169 if (__stextmode(fp->_file)) 170 fp->_flags |= __SCLE; 171 #endif 172 173 _funlockfile(fp); 174 return fp; 175 } 176 177 #ifndef _REENT_ONLY 178 179 FILE * 180 _DEFUN (freopen, (file, mode, fp), 181 _CONST char *file _AND 182 _CONST char *mode _AND 183 register FILE *fp) 184 { 185 return _freopen_r (_REENT, file, mode, fp); 186 } 187 188 #endif /*!_REENT_ONLY */ 189