about summary refs log tree commit diff
path: root/sysdeps/posix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-01-13 13:27:46 -0500
committerUlrich Drepper <drepper@gmail.com>2011-01-13 13:27:46 -0500
commitcfa28e560ef69372b9e15e9a2d924a0fbcfc7bca (patch)
tree21155ae0a762cd0cc6d173622c5aa9fc682f9ef1 /sysdeps/posix
parent1086d70d916fd0eb969b3d89ff88abd35f6a5c34 (diff)
downloadglibc-cfa28e560ef69372b9e15e9a2d924a0fbcfc7bca.tar.gz
glibc-cfa28e560ef69372b9e15e9a2d924a0fbcfc7bca.tar.xz
glibc-cfa28e560ef69372b9e15e9a2d924a0fbcfc7bca.zip
Relax requirement on close in child created by posix_spawn.
Diffstat (limited to 'sysdeps/posix')
-rw-r--r--sysdeps/posix/spawni.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sysdeps/posix/spawni.c b/sysdeps/posix/spawni.c
index 29803a8461..c5a827d6d7 100644
--- a/sysdeps/posix/spawni.c
+++ b/sysdeps/posix/spawni.c
@@ -1,5 +1,5 @@
 /* Guts of POSIX spawn interface.  Generic POSIX.1 version.
-   Copyright (C) 2000-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2000-2005, 2006, 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
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/resource.h>
 #include "spawn_int.h"
 #include <not-cancel.h>
 #include <local-setxid.h>
@@ -164,6 +165,8 @@ __spawni (pid_t *pid, const char *file,
   if (file_actions != NULL)
     {
       int cnt;
+      struct rlimit64 fdlimit;
+      bool have_fdlimit = false;
 
       for (cnt = 0; cnt < file_actions->__used; ++cnt)
 	{
@@ -173,8 +176,19 @@ __spawni (pid_t *pid, const char *file,
 	    {
 	    case spawn_do_close:
 	      if (close_not_cancel (action->action.close_action.fd) != 0)
-		/* Signal the error.  */
-		_exit (SPAWN_ERROR);
+		{
+		  if (! have_fdlimit)
+		    {
+		      getrlimit64 (RLIMIT_NOFILE, &fdlimit);
+		      have_fdlimit = true;
+		    }
+
+		  /* Only signal errors for file descriptors out of range.  */
+		  if (action->action.close_action.fd < 0
+		      || action->action.close_action.fd >= fdlimit.rlim_cur)
+		    /* Signal the error.  */
+		    _exit (SPAWN_ERROR);
+		}
 	      break;
 
 	    case spawn_do_open: