diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-05-15 15:28:46 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-05-15 15:28:46 -0400 |
commit | 94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf (patch) | |
tree | 2ddc8ca200024ecca3faf0f2efffaea15e21a04f /libio/fileops.c | |
parent | bd25564e1e98910ed69043ed6a6f884ce60e5780 (diff) | |
download | glibc-94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf.tar.gz glibc-94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf.tar.xz glibc-94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf.zip |
Fix a few problems in fopen and freopen
fopen should set the FD_CLOEXEC flag if requested evenif the kernel does not support an aotmic operation. freopen should reuse the file descriptor for the stream. This is especially important for calls to change the standard streams (stin, stdout, stderr).
Diffstat (limited to 'libio/fileops.c')
-rw-r--r-- | libio/fileops.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/libio/fileops.c b/libio/fileops.c index 343afa68b5..2b696ab1e0 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -180,7 +180,8 @@ _IO_new_file_close_it (fp) INTUSE(_IO_unsave_markers) (fp); - int close_status = _IO_SYSCLOSE (fp); + int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 + ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T @@ -328,11 +329,12 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) case 'c': fp->_flags2 |= _IO_FLAGS2_NOTCANCEL; continue; -#ifdef O_CLOEXEC case 'e': +#ifdef O_CLOEXEC oflags |= O_CLOEXEC; - continue; #endif + fp->_flags2 |= _IO_FLAGS2_CLOEXEC; + continue; default: /* Ignore. */ continue; @@ -343,6 +345,18 @@ _IO_new_file_fopen (fp, filename, mode, is32not64) result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, is32not64); +#ifndef __ASSUME_O_CLOEXEC + if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0) + { + if (__have_o_cloexec == 0) + { + int flags = __fcntl (fd, F_GETFD); + __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; + } + if (__have_o_cloexec < 0) + __fcntl (fd, F_SETFD, FD_CLOEXEC); + } +#endif #ifdef _LIBC if (result != NULL) |