_IO_FILE * __fopen_internal (const char *filename, const char *mode, int is32) { struct locked_FILE { struct _IO_FILE_plus fp; #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif struct _IO_wide_data wd; } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) return NULL; #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); #else _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL); #endif _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; _IO_new_file_init_internal (&new_f->fp); #if !_IO_UNIFIED_JUMPTABLES new_f->fp.vtable = NULL; #endif if (_IO_file_fopen ((_IO_FILE *) new_f, filename, mode, is32) != NULL) return __fopen_maybe_mmap (&new_f->fp.file); _IO_un_link (&new_f->fp); free (new_f); return NULL; }
FILE * __fopen_internal (const char *filename, const char *mode, int is32) { struct locked_FILE { struct _IO_FILE_plus fp; #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif struct _IO_wide_data wd; } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) return NULL; #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; _IO_new_file_init_internal (&new_f->fp); if (_IO_file_fopen ((FILE *) new_f, filename, mode, is32) != NULL) return __fopen_maybe_mmap (&new_f->fp.file); _IO_un_link (&new_f->fp); free (new_f); return NULL; }
FILE * freopen64 (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; _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, 0); fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE; if (result != NULL) result = __fopen_maybe_mmap (result); 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; }
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; }
FILE * freopen64 (const char *filename, const char *mode, FILE *fp) { FILE *result = NULL; char fdfilename[FD_TO_FILENAME_SIZE]; CHECK_FILE (fp, NULL); _IO_acquire_lock (fp); /* First flush the stream (failure should be ignored). */ _IO_SYNC (fp); if (!(fp->_flags & _IO_IS_FILEBUF)) goto end; int fd = _IO_fileno (fp); const char *gfilename = filename != NULL ? filename : fd_to_filename (fd, fdfilename); fp->_flags2 |= _IO_FLAGS2_NOCLOSE; _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, 0); fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE; if (result != NULL) result = __fopen_maybe_mmap (result); if (result != NULL) { /* unbound stream orientation */ result->_mode = 0; if (fd != -1 && _IO_fileno (result) != fd) { /* At this point we have both file descriptors already allocated, so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But we still need to check for EINVAL and, due Linux internal implementation, EBUSY. It is because on how it internally opens the file by splitting the buffer allocation operation and VFS opening (a dup operation may run when a file is still pending 'install' on VFS). */ if (__dup3 (_IO_fileno (result), fd, (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 ? O_CLOEXEC : 0) == -1) { _IO_file_close_it (result); result = NULL; goto end; } __close (_IO_fileno (result)); _IO_fileno (result) = fd; } } else if (fd != -1) __close (fd); end: _IO_release_lock (fp); return result; }