void _IO_wdefault_finish (FILE *fp, int dummy) { struct _IO_marker *mark; if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) { free (fp->_wide_data->_IO_buf_base); fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL; } for (mark = fp->_markers; mark != NULL; mark = mark->_next) mark->_sbuf = NULL; if (fp->_IO_save_base) { free (fp->_wide_data->_IO_save_base); fp->_IO_save_base = NULL; } #ifdef _IO_MTSAFE_IO if (fp->_lock != NULL) _IO_lock_fini (*fp->_lock); #endif _IO_un_link ((struct _IO_FILE_plus *) fp); }
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; }
int attribute_compat_text_section _IO_old_file_close_it (_IO_FILE *fp) { int write_status, close_status; if (!_IO_file_is_open (fp)) return EOF; write_status = _IO_old_do_flush (fp); _IO_unsave_markers (fp); close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ _IO_setb (fp, NULL, NULL, 0); _IO_setg (fp, NULL, NULL, NULL); _IO_setp (fp, NULL, NULL); _IO_un_link ((struct _IO_FILE_plus *) fp); fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; fp->_fileno = -1; fp->_old_offset = _IO_pos_BAD; return close_status ? close_status : write_status; }
int _IO_vdprintf (int d, const char *format, _IO_va_list arg) { struct _IO_FILE_plus tmpfil; struct _IO_wide_data wd; int done; #ifdef _IO_MTSAFE_IO tmpfil.file._lock = NULL; #endif _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); _IO_JUMPS (&tmpfil) = &_IO_file_jumps; _IO_new_file_init_internal (&tmpfil); #if !_IO_UNIFIED_JUMPTABLES tmpfil.vtable = NULL; #endif if (_IO_file_attach (&tmpfil.file, d) == NULL) { _IO_un_link (&tmpfil); return EOF; } tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; _IO_mask_flags (&tmpfil.file, _IO_NO_READS, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); done = _IO_vfprintf (&tmpfil.file, format, arg); if (done != EOF && _IO_do_flush (&tmpfil.file) == EOF) done = EOF; _IO_FINISH (&tmpfil.file); return done; }
_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; }
int __vdprintf_chk (int d, int flags, const char *format, va_list arg) { struct _IO_FILE_plus tmpfil; struct _IO_wide_data wd; int done; #ifdef _IO_MTSAFE_IO tmpfil.file._lock = NULL; #endif _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); _IO_JUMPS (&tmpfil) = &_IO_file_jumps; _IO_new_file_init_internal (&tmpfil); if (_IO_file_attach (&tmpfil.file, d) == NULL) { _IO_un_link (&tmpfil); return EOF; } tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; _IO_mask_flags (&tmpfil.file, _IO_NO_READS, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ if (flags > 0) tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY; done = _IO_vfprintf (&tmpfil.file, format, arg); _IO_FINISH (&tmpfil.file); return done; }
int _IO_new_fclose (_IO_FILE *fp) { int status; CHECK_FILE(fp, EOF); #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) /* We desperately try to help programs which are using streams in a strange way and mix old and new functions. Detect old streams here. */ if (_IO_vtable_offset (fp) != 0) return _IO_old_fclose (fp); #endif /* 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_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; _IO_release_lock (fp); _IO_FINISH (fp); if (fp->_mode > 0) { #if _LIBC /* This stream has a wide orientation. This means we have to free the conversion functions. */ struct _IO_codecvt *cc = fp->_codecvt; __libc_lock_lock (__gconv_lock); __gconv_release_step (cc->__cd_in.__cd.__steps); __gconv_release_step (cc->__cd_out.__cd.__steps); __libc_lock_unlock (__gconv_lock); #endif } else { 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; }
int _IO_new_file_close_it (_IO_FILE *fp) { int write_status; if (!_IO_file_is_open (fp)) return EOF; if ((fp->_flags & _IO_NO_WRITES) == 0 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) write_status = _IO_do_flush (fp); else write_status = 0; _IO_unsave_markers (fp); int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (fp->_mode > 0) { if (_IO_have_wbackup (fp)) _IO_free_wbackup_area (fp); _IO_wsetb (fp, NULL, NULL, 0); _IO_wsetg (fp, NULL, NULL, NULL); _IO_wsetp (fp, NULL, NULL); } #endif _IO_setb (fp, NULL, NULL, 0); _IO_setg (fp, NULL, NULL, NULL); _IO_setp (fp, NULL, NULL); _IO_un_link ((struct _IO_FILE_plus *) fp); fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; fp->_fileno = -1; fp->_offset = _IO_pos_BAD; return close_status ? close_status : write_status; }
attribute_compat_text_section _IO_old_fdopen (int fd, const char *mode) { int read_write; int posix_mode = 0; struct locked_FILE { struct _IO_FILE_complete_plus fp; #ifdef _IO_MTSAFE_IO _IO_lock_t lock; #endif } *new_f; int fd_flags; switch (*mode++) { case 'r': read_write = _IO_NO_WRITES; break; case 'w': read_write = _IO_NO_READS; break; case 'a': posix_mode = O_APPEND; read_write = _IO_NO_READS|_IO_IS_APPENDING; break; default: MAYBE_SET_EINVAL; return NULL; } if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) read_write &= _IO_IS_APPENDING; #ifdef F_GETFL fd_flags = _IO_fcntl (fd, F_GETFL); #ifndef O_ACCMODE #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #endif if (fd_flags == -1 || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) return NULL; /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b) [System Application Program Interface (API) Amendment 1: Realtime Extensions], Rationale B.8.3.3 Open a Stream on a File Descriptor says: Although not explicitly required by POSIX.1, a good implementation of append ("a") mode would cause the O_APPEND flag to be set. (Historical implementations [such as Solaris2] do a one-time seek in fdopen.) However, we do not turn O_APPEND off if the mode is "w" (even though that would seem consistent) because that would be more likely to break historical programs. */ if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) { #ifdef F_SETFL if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) #endif return NULL; } #endif new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) return NULL; #ifdef _IO_MTSAFE_IO new_f->fp.file._file._lock = &new_f->lock; #endif _IO_old_init (&new_f->fp.file._file, 0); _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps; _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp); #if !_IO_UNIFIED_JUMPTABLES new_f->fp.vtable = NULL; #endif if (_IO_old_file_attach (&new_f->fp.file._file, fd) == NULL) { _IO_un_link ((struct _IO_FILE_plus *) &new_f->fp); free (new_f); return NULL; } new_f->fp.file._file._flags &= ~_IO_DELETE_DONT_CLOSE; _IO_mask_flags (&new_f->fp.file._file, read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); return (_IO_FILE *) &new_f->fp; }