This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch, master, updated. glibc-2.13-188-g94b7cc3


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf (commit)
      from  bd25564e1e98910ed69043ed6a6f884ce60e5780 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf

commit 94b7cc3711b0b74c1d3ae18b9a2e019e51a8e0bf
Author: Ulrich Drepper <drepper@gmail.com>
Date:   Sun May 15 15:28:46 2011 -0400

    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).

diff --git a/ChangeLog b/ChangeLog
index 0c0aa6a..1cb8f4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2011-05-15  Ulrich Drepper  <drepper@gmail.com>
 
+	* libio/freopen.c (freopen): Don't close old file descriptor
+	before the new one is opened.  Instead dup the new file descriptor
+	to the old one after the new stream is created.
+	* libio/freopen64.c (freopen64): Likewise.
+	* libio/libio.h: Define _IO_FLAGS2_NOCLOSE and _IO_FLAGS2_CLOEXEC.
+	* libio/fileops.c (_IO_new_file_close_it): Handle new
+	_IO_FLAGS2_NOCLOSE flag.
+	(_IO_new_file_fopen): Set _IO_FLAGS2_CLOEXEC for "e" mode.
+	If _IO_file_open didn't set FD_CLOEXEC do it after the call.
+	* libio/oldfileops.c (_IO_old_file_close_it): Handle new
+	_IO_FLAGS2_NOCLOSE flag.
+	* include/unistd.h: Add hidden_proto for dup3.
+	Define __have_dup3.
+	* io/dup3.c: Define hidden symbol.
+	* sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_DUP3.
+
 	[BZ #7101]
 	* posix/getopt.c (_getopt_internal_r): List all ambigious possibilities
 	when an incomplete long option is used.
diff --git a/include/unistd.h b/include/unistd.h
index 0ad2983..5014e2e 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -79,6 +79,7 @@ char *__canonicalize_directory_name_internal (__const char *__thisdir,
 extern int __dup (int __fd);
 extern int __dup2 (int __fd, int __fd2);
 libc_hidden_proto (__dup2)
+libc_hidden_proto (dup3)
 extern int __execve (__const char *__path, char *__const __argv[],
 		     char *__const __envp[]);
 extern long int __pathconf (__const char *__path, int __name);
@@ -175,6 +176,7 @@ extern int __have_sock_cloexec;
    SOCK_CLOEXEC.  Avoid defining separate variables for all of them
    unless it is really necessary.  */
 #define __have_pipe2 __have_sock_cloexec
+#define __have_dup3 __have_sock_cloexec
 
 extern int __getlogin_r_loginuid (char *name, size_t namesize)
      attribute_hidden;
diff --git a/io/dup3.c b/io/dup3.c
index 162ab4e..17bc88a 100644
--- a/io/dup3.c
+++ b/io/dup3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -43,6 +43,7 @@ dup3 (fd, fd2, flags)
   __set_errno (ENOSYS);
   return -1;
 }
+libc_hidden_def (dup3)
 stub_warning (dup3)
 
 #include <stub-tag.h>
diff --git a/libio/fileops.c b/libio/fileops.c
index 343afa6..2b696ab 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)
diff --git a/libio/freopen.c b/libio/freopen.c
index d80815f..20eda9d 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,95,96,97,98,2000,2001,2002,2003,2008
+/* Copyright (C) 1993,95,96,97,98,2000,2001,2002,2003,2008,2011
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -28,7 +28,9 @@
 
 #include "libioP.h"
 #include "stdio.h"
+#include <fcntl.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <shlib-compat.h>
 #include <fd_to_filename.h>
@@ -40,17 +42,14 @@ freopen (filename, mode, fp)
      FILE* fp;
 {
   FILE *result;
-  int fd = -1;
   CHECK_FILE (fp, NULL);
   if (!(fp->_flags & _IO_IS_FILEBUF))
     return NULL;
   _IO_acquire_lock (fp);
-  if (filename == NULL && _IO_fileno (fp) >= 0)
-    {
-      fd = __dup (_IO_fileno (fp));
-      if (fd != -1)
-	filename = fd_to_filename (fd);
-    }
+  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)
     {
@@ -61,7 +60,7 @@ freopen (filename, mode, fp)
 	 up here. */
       _IO_old_file_close_it (fp);
       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_old_file_jumps;
-      result = _IO_old_file_fopen (fp, filename, mode);
+      result = _IO_old_file_fopen (fp, gfilename, mode);
     }
   else
 #endif
@@ -70,18 +69,53 @@ freopen (filename, mode, fp)
       _IO_JUMPS ((struct _IO_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 = INTUSE(_IO_file_fopen) (fp, filename, mode, 1);
+      result = INTUSE(_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)
     {
-      __close (fd);
-      free ((char *) filename);
+      /* 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;
 }
diff --git a/libio/freopen64.c b/libio/freopen64.c
index 2dad6d7..99045c6 100644
--- a/libio/freopen64.c
+++ b/libio/freopen64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002, 2003, 2008
+/* Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002, 2003, 2008, 2011
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -28,7 +28,9 @@
 
 #include "libioP.h"
 #include "stdio.h"
+#include <fcntl.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <fd_to_filename.h>
 
@@ -40,32 +42,63 @@ freopen64 (filename, mode, fp)
 {
 #ifdef _G_OPEN64
   FILE *result;
-  int fd = -1;
   CHECK_FILE (fp, NULL);
   if (!(fp->_flags & _IO_IS_FILEBUF))
     return NULL;
   _IO_acquire_lock (fp);
-  if (filename == NULL && _IO_fileno (fp) >= 0)
-    {
-      fd = __dup (_IO_fileno (fp));
-      if (fd != -1)
-	filename = fd_to_filename (fd);
-    }
+  int fd = _IO_fileno (fp);
+  const char *gfilename = (filename == NULL && fd >= 0
+			   ? fd_to_filename (fd) : filename);
+  fp->_flags2 |= _IO_FLAGS2_NOCLOSE;
   INTUSE(_IO_file_close_it) (fp);
   _IO_JUMPS ((struct _IO_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 = INTUSE(_IO_file_fopen) (fp, filename, mode, 0);
+  result = INTUSE(_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)
     {
-      __close (fd);
-      free ((char *) filename);
+      /* 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;
 #else
diff --git a/libio/libio.h b/libio/libio.h
index 3c9f2bd..bebc112 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1995,1997-2006,2007,2009 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1995,1997-2006,2007,2009,2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Per Bothner <bothner@cygnus.com>.
 
@@ -145,6 +145,8 @@
 #define _IO_FLAGS2_USER_WBUF 8
 #ifdef _LIBC
 # define _IO_FLAGS2_SCANF_STD 16
+# define _IO_FLAGS2_NOCLOSE 32
+# define _IO_FLAGS2_CLOEXEC 64
 #endif
 
 /* These are "formatting flags" matching the iostream fmtflags enum values. */
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index be99a25..3e3daa8 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -155,7 +155,8 @@ _IO_old_file_close_it (fp)
 
   INTUSE(_IO_unsave_markers) (fp);
 
-  close_status = _IO_SYSCLOSE (fp);
+  close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
+		  ? _IO_SYSCLOSE (fp) : 0);
 
   /* Free buffer. */
   INTUSE(_IO_setb) (fp, NULL, NULL, 0);
@@ -676,7 +677,7 @@ _IO_old_file_write (f, data, n)
 	{
 	  f->_flags |= _IO_ERR_SEEN;
 	  break;
-        }
+	}
       to_do -= count;
       data = (void *) ((char *) data + count);
     }
@@ -763,12 +764,12 @@ _IO_old_file_xsputn (f, data, n)
       do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
 
       if (do_write)
-        {
+	{
 	  count = old_do_write (f, s, do_write);
 	  to_do -= count;
 	  if (count < do_write)
 	    return n - to_do;
-        }
+	}
 
       /* Now write out the remainder.  Normally, this will fit in the
 	 buffer, but it's somewhat messier for line-buffered files,
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index c220dca..d78f101 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -1,6 +1,6 @@
 /* Set flags signalling availability of kernel features based on given
    kernel version number.
-   Copyright (C) 1999-2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1999-2009, 2010, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -496,6 +496,7 @@
 # define __ASSUME_PIPE2		1
 # define __ASSUME_EVENTFD2	1
 # define __ASSUME_SIGNALFD4	1
+# define __ASSUME_DUP3		1
 #endif
 
 /* Support for the accept4 syscall was added in 2.6.28.  */

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                 |   16 +++++++
 include/unistd.h                          |    2 +
 io/dup3.c                                 |    3 +-
 libio/fileops.c                           |   20 ++++++++-
 libio/freopen.c                           |   64 ++++++++++++++++++++++-------
 libio/freopen64.c                         |   61 +++++++++++++++++++++------
 libio/libio.h                             |    4 +-
 libio/oldfileops.c                        |    9 ++--
 sysdeps/unix/sysv/linux/kernel-features.h |    3 +-
 9 files changed, 143 insertions(+), 39 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]