summary refs log tree commit diff
path: root/sysdeps/mach/hurd/dup2.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-05-04 09:00:10 +0000
committerRoland McGrath <roland@gnu.org>1995-05-04 09:00:10 +0000
commite4448b6f58406744ff1a5f400b492ba27e466b56 (patch)
tree84725f363a935ae8498d5f0eaa3a44239af3b5df /sysdeps/mach/hurd/dup2.c
parentd66e34cd423425c348bcc83df127dd19711b0b9a (diff)
downloadglibc-e4448b6f58406744ff1a5f400b492ba27e466b56.tar.gz
glibc-e4448b6f58406744ff1a5f400b492ba27e466b56.tar.xz
glibc-e4448b6f58406744ff1a5f400b492ba27e466b56.zip
Wed May 3 11:56:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
	* sysdeps/mach/hurd/dup2.c: Fixed broken test in last change.

	* elf/dl-error.c (_dl_catch_error): Actually call the OPERATE
 	function.  Duh.

	* hurd/Makefile (distribute): Added hurdstartup.h.
	* hurd/hurd.h: Remove _hurd_startup decl.

	* hurd/hurd/ioctl.h (_HURD_HANDLE_IOCTLS): Use __attribute__
 	((__unused__)) instead of gratuitous self reference.

	* sysdeps/mach/hurd/dup2.c: Call _hurd_alloc_fd to expand the
 	table if FD2 doesn't fit.

	* sysdeps/mach/hurd/getdtsz.c: Return the RLIM_NOFILE soft limit,
 	not the current table size.

	* sysdeps/i386/init-first.c: New file.
	* sysdeps/stub/init-first.c: New file.
	
Diffstat (limited to 'sysdeps/mach/hurd/dup2.c')
-rw-r--r--sysdeps/mach/hurd/dup2.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/sysdeps/mach/hurd/dup2.c b/sysdeps/mach/hurd/dup2.c
index f4ec623b05..c4b16698b8 100644
--- a/sysdeps/mach/hurd/dup2.c
+++ b/sysdeps/mach/hurd/dup2.c
@@ -58,8 +58,7 @@ DEFUN(__dup2, (fd, fd2), int fd AND int fd2)
       io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
       io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D.  */
 
-      __mutex_lock (&_hurd_dtable_lock);
-      if (fd2 < 0 || fd2 >= _hurd_dtablesize)
+      if (fd2 < 0)
 	{
 	  errno = EBADF;
 	  fd2 = -1;
@@ -67,16 +66,37 @@ DEFUN(__dup2, (fd, fd2), int fd AND int fd2)
       else
 	{
 	  /* Get a hold of the destination descriptor.  */
-	  struct hurd_fd *d2 = _hurd_dtable[fd2];
-	  if (d2 == NULL)
+	  struct hurd_fd *d2;
+
+	  if (fd2 >= _hurd_dtablesize)
+	    {
+	      /* The table is not large enough to hold the destination
+		 descriptor.  Enlarge it as necessary to allocate this
+		 descriptor.  */
+	      __mutex_unlock (&_hurd_dtable_lock);
+	      /* We still hold FD1's lock, but this is safe because
+		 _hurd_alloc_fd will only examine the cells starting
+		 at FD2.  */
+	      d2 = _hurd_alloc_fd (NULL, fd2);
+	      if (d2)
+		__spin_unlock (&d2->port.lock);
+	      __mutex_lock (&_hurd_dtable_lock);
+	    }
+	  else
 	    {
-	      /* Must allocate a new one.  We don't initialize the port cells
-		 with this call so that if it fails (out of memory), we will
-		 not have already added user references for the ports, which we
-		 would then have to deallocate.  */
-	      d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
-						     MACH_PORT_NULL);
+	      d2 = _hurd_dtable[fd2];
+	      if (d2 == NULL)
+		{
+		  /* Must allocate a new one.  We don't initialize the port
+		     cells with this call so that if it fails (out of
+		     memory), we will not have already added user
+		     references for the ports, which we would then have to
+		     deallocate.  */
+		  d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
+							 MACH_PORT_NULL);
+		}
 	    }
+
 	  if (d2 == NULL)
 	    {
 	      fd2 = -1;