int attribute_compat_text_section _IO_old_fclose (_IO_FILE *fp) { int status; CHECK_FILE(fp, EOF); /* We desperately try to help programs which are using streams in a strange way and mix old and new functions. Detect new streams here. */ if (fp->_vtable_offset == 0) return _IO_new_fclose (fp); /* First unlink the stream. */ if (fp->_IO_file_flags & _IO_IS_FILEBUF) _IO_un_link ((struct _IO_FILE_plus *) fp); _IO_acquire_lock (fp); if (fp->_IO_file_flags & _IO_IS_FILEBUF) status = _IO_old_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; _IO_release_lock (fp); _IO_FINISH (fp); if (_IO_have_backup (fp)) _IO_free_backup_area (fp); if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) { fp->_IO_file_flags = 0; free(fp); } return status; }
FILE * freopen (const char *filename, const char *mode, FILE *fp) { FILE *result; CHECK_FILE (fp, NULL); if (!(fp->_flags & _IO_IS_FILEBUF)) return NULL; _IO_acquire_lock (fp); int fd = _IO_fileno (fp); const char *gfilename = (filename == NULL && fd >= 0 ? fd_to_filename (fd) : filename); fp->_flags2 |= _IO_FLAGS2_NOCLOSE; #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) if (&_IO_stdin_used == NULL) { /* If the shared C library is used by the application binary which was linked against the older version of libio, we just use the older one even for internal use to avoid trouble since a pointer to the old libio may be passed into shared C library and wind up here. */ _IO_old_file_close_it (fp); _IO_JUMPS_FILE_plus (fp) = &_IO_old_file_jumps; result = _IO_old_file_fopen (fp, gfilename, mode); } else #endif { _IO_file_close_it (fp); _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL) fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; result = _IO_file_fopen (fp, gfilename, mode, 1); if (result != NULL) result = __fopen_maybe_mmap (result); } fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE; if (result != NULL) { /* unbound stream orientation */ result->_mode = 0; if (fd != -1) { #ifdef O_CLOEXEC # ifndef __ASSUME_DUP3 int newfd; if (__have_dup3 < 0) newfd = -1; else newfd = # endif __dup3 (_IO_fileno (result), fd, (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 ? O_CLOEXEC : 0); #else # define newfd 1 #endif #ifndef __ASSUME_DUP3 if (newfd < 0) { if (errno == ENOSYS) __have_dup3 = -1; __dup2 (_IO_fileno (result), fd); if ((result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0) __fcntl (fd, F_SETFD, FD_CLOEXEC); } #endif __close (_IO_fileno (result)); _IO_fileno (result) = fd; } } else if (fd != -1) __close (fd); if (filename == NULL) free ((char *) gfilename); _IO_release_lock (fp); return result; }