about summary refs log tree commit diff
path: root/sysdeps/mach
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/hurd/dup2.c40
-rw-r--r--sysdeps/mach/hurd/getdtsz.c6
-rw-r--r--sysdeps/mach/hurd/start.c314
3 files changed, 33 insertions, 327 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;
diff --git a/sysdeps/mach/hurd/getdtsz.c b/sysdeps/mach/hurd/getdtsz.c
index e506963ac3..3e6385f64e 100644
--- a/sysdeps/mach/hurd/getdtsz.c
+++ b/sysdeps/mach/hurd/getdtsz.c
@@ -29,9 +29,9 @@ DEFUN_VOID(__getdtablesize)
 {
   int size;
   HURD_CRITICAL_BEGIN;
-  __mutex_lock (&_hurd_dtable_lock);
-  size = _hurd_dtablesize;
-  __mutex_unlock (&_hurd_dtable_lock);
+  __mutex_lock (&_hurd_rlimits_lock);
+  size = _hurd_rlimits[RLIM_NOFILE].rlim_cur; /* XXX RLIM_INFINITY?? */
+  __mutex_unlock (&_hurd_rlimits_lock);
   HURD_CRITICAL_END;
   return size;
 }
diff --git a/sysdeps/mach/hurd/start.c b/sysdeps/mach/hurd/start.c
deleted file mode 100644
index 9a70e0ddd4..0000000000
--- a/sysdeps/mach/hurd/start.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <hurd.h>
-#include <hurd/exec.h>
-#include <sysdep.h>
-#include <hurd/threadvar.h>
-#include <unistd.h>
-#include "set-hooks.h"
-#include "hurdmalloc.h"		/* XXX */
-
-/* The first piece of initialized data.  */
-int __data_start = 0;
-weak_alias (__data_start, data_start)
-
-mach_port_t *_hurd_init_dtable;
-mach_msg_type_number_t _hurd_init_dtablesize;
-
-unsigned int __hurd_threadvar_max;
-unsigned long int __hurd_threadvar_stack_mask;
-unsigned long int __hurd_threadvar_stack_offset;
-
-/* These are set up by _hurdsig_init.  */
-unsigned long int __hurd_sigthread_stack_base;
-unsigned long int __hurd_sigthread_stack_end;
-unsigned long int *__hurd_sigthread_variables;
-
-vm_address_t _hurd_stack_base;
-vm_size_t _hurd_stack_size;
-
-/* Things that want to be run before _hurd_init or much anything else.
-   Importantly, these are called before anything tries to use malloc.  */
-DEFINE_HOOK (_hurd_preinit_hook, (void));
-
-extern void __mach_init (void);
-extern void __libc_init (int argc, char **argv, char **envp);
-extern int main (int argc, char **argv, char **envp);
-
-void *(*_cthread_init_routine) (void); /* Returns new SP to use.  */
-void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
-
-int _hurd_split_args (char *, size_t, char **);
-
-/* These communicate values from _start to start1,
-   where we cannot use the stack for anything.  */
-static char *args, *env;
-static mach_port_t *portarray;
-static int *intarray;
-static mach_msg_type_number_t argslen, envlen, portarraysize, intarraysize;
-static int flags;
-static char **argv, **envp;
-static int argc;
-
-
-static void start1 (void) __attribute__ ((__noreturn__));
-
-
-/* Entry point.  This is the first thing in the text segment.
-
-   The exec server started the initial thread in our task with this spot the
-   PC, and a stack that is presumably big enough.  We do basic Mach
-   initialization so mig-generated stubs work, and then do an exec_startup
-   RPC on our bootstrap port, to which the exec server responds with the
-   information passed in the exec call, as well as our original bootstrap
-   port, and the base address and size of the preallocated stack.
-
-   If using cthreads, we are given a new stack by cthreads initialization and
-   deallocate the stack set up by the exec server.  On the new stack we call
-   `start1' (above) to do the rest of the startup work.  Since the stack may
-   disappear out from under us in a machine-dependent way, we use a pile of
-   static variables to communicate the information from exec_startup to start1.
-   This is unfortunate but preferable to machine-dependent frobnication to copy
-   the state from the old stack to the new one.  */
-
-#ifndef START_ARGS
-#define START_ARGS void
-#endif
-#ifdef START_MACHDEP
-START_MACHDEP
-#define _start _start0
-#endif
-
-void
-_start (START_ARGS)
-{
-  error_t err;
-  mach_port_t in_bootstrap;
-
-  /* Basic Mach initialization, must be done before RPCs can be done.  */
-  __mach_init ();
-
-  /* Run things that want to do initialization as soon as possible.  We do
-     this before exec_startup so that no out of line data arrives and
-     clutters up the address space before brk initialization.  */
-
-  RUN_HOOK (_hurd_preinit_hook, ());
-
-  if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
-				     &in_bootstrap))
-    LOSE;
-
-  if (in_bootstrap != MACH_PORT_NULL)
-    {
-      /* Call the exec server on our bootstrap port and
-	 get all our standard information from it.  */
-
-      argslen = envlen = 0;
-      _hurd_init_dtablesize = portarraysize = intarraysize = 0;
-
-      err = __exec_startup (in_bootstrap,
-			    &_hurd_stack_base, &_hurd_stack_size,
-			    &flags,
-			    &args, &argslen, &env, &envlen,
-			    &_hurd_init_dtable, &_hurd_init_dtablesize,
-			    &portarray, &portarraysize,
-			    &intarray, &intarraysize);
-      __mach_port_deallocate (__mach_task_self (), in_bootstrap);
-    }
-
-  if (err || in_bootstrap == MACH_PORT_NULL)
-    {
-      /* Either we have no bootstrap port, or the RPC to the exec server
-	 failed.  Try to snarf the args in the canonical Mach way.
-	 Hopefully either they will be on the stack as expected, or the
-	 stack will be zeros so we don't crash.  Set all our other
-	 variables to have empty information.  */
-
-      /* SNARF_ARGS (ARGC, ARGV, ENVP) snarfs the arguments and environment
-	 from the stack, assuming they were put there by the microkernel.  */
-      SNARF_ARGS (argc, argv, envp);
-
-      flags = 0;
-      args = env = NULL;
-      argslen = envlen = 0;
-      _hurd_init_dtable = NULL;
-      _hurd_init_dtablesize = 0;
-      portarray = NULL;
-      portarraysize = 0;
-      intarray = NULL;
-      intarraysize = 0;
-    }
-  else
-    argv = envp = NULL;
-
-
-  /* The user might have defined a value for this, to get more variables.
-     Otherwise it will be zero on startup.  We must make sure it is set
-     properly before before cthreads initialization, so cthreads can know
-     how much space to leave for thread variables.  */
-  if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
-    __hurd_threadvar_max = _HURD_THREADVAR_MAX;
-
-  /* Do cthreads initialization and switch to the cthread stack.  */
-
-  if (_cthread_init_routine != NULL)
-    CALL_WITH_SP (start1, (*_cthread_init_routine) ());
-  else
-    start1 ();
-
-  /* Should never get here.  */
-  LOSE;
-}
-
-
-static void
-start1 (void)
-{
-  register int envc = 0;
-
-  {
-    /* Check if the stack we are now on is different from
-       the one described by _hurd_stack_{base,size}.  */
-
-    char dummy;
-    const vm_address_t newsp = (vm_address_t) &dummy;
-
-    if (_hurd_stack_size != 0 && (newsp < _hurd_stack_base ||
-				  newsp - _hurd_stack_base > _hurd_stack_size))
-      /* The new stack pointer does not intersect with the
-	 stack the exec server set up for us, so free that stack.  */
-      __vm_deallocate (__mach_task_self (),
-		       _hurd_stack_base, _hurd_stack_size);
-  }
-
-  if (__hurd_threadvar_stack_mask == 0)
-    {
-      /* We are not using cthreads, so we will have just a single allocated
-	 area for the per-thread variables of the main user thread.  */
-      unsigned long int i;
-      __hurd_threadvar_stack_offset
-	= (unsigned long int) malloc (__hurd_threadvar_max *
-				      sizeof (unsigned long int));
-      if (__hurd_threadvar_stack_offset == 0)
-	__libc_fatal ("Can't allocate single-threaded per-thread variables.");
-      for (i = 0; i < __hurd_threadvar_max; ++i)
-	((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0;
-    }
-
-
-  /* Turn the block of null-separated strings we were passed for the
-     arguments and environment into vectors of pointers to strings.  */
-      
-  if (! argv)
-    {
-      if (args)
-	/* Count up the arguments so we can allocate ARGV.  */
-	argc = _hurd_split_args (args, argslen, NULL);
-      if (! args || argc == 0)
-	{
-	  /* No arguments passed; set argv to { NULL }.  */
-	  argc = 0;
-	  args = NULL;
-	  argv = (char **) &args;
-	}
-    }
-
-  if (! envp)
-    {
-      if (env)
-	/* Count up the environment variables so we can allocate ENVP.  */
-	envc = _hurd_split_args (env, envlen, NULL);
-      if (! env || envc == 0)
-	{
-	  /* No environment passed; set __environ to { NULL }.  */
-	  env = NULL;
-	  envp = (char **) &env;
-	}
-    }
-
-  if (! argv)
-    {
-      /* There were some arguments.
-	 Allocate space for the vectors of pointers and fill them in.  */
-      argv = __alloca ((argc + 1) * sizeof (char *));
-      _hurd_split_args (args, argslen, argv);
-    }
-  
-  if (! envp)
-    {
-      /* There was some environment.
-	 Allocate space for the vectors of pointers and fill them in.  */
-      envp = __alloca ((envc + 1) * sizeof (char *));
-      _hurd_split_args (env, envlen, envp);
-    }
-
-  __environ = envp;
-
-  if (portarray || intarray)
-    /* Initialize library data structures, start signal processing, etc.  */
-    _hurd_init (flags, argv, portarray, portarraysize, intarray, intarraysize);
-
-  /* Random library initialization.  These functions may assume that
-     _hurd_init has already run (if it is going to), and POSIX.1 facilities
-     are initialized and available.  */
-  __libc_init (argc, argv, __environ);
-
-  /* Finally, run the user program.  */
-  (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit)
-    (main (argc, argv, __environ));
-
-  /* Should never get here.  */
-  LOSE;
-}
-
-/* Split ARGSLEN bytes at ARGS into words, breaking at NUL characters.  If
-   ARGV is not a null pointer, store a pointer to the start of each word in
-   ARGV[n], and null-terminate ARGV.  Return the number of words split.  */
-
-int
-_hurd_split_args (char *args, size_t argslen, char **argv)
-{
-  char *p = args;
-  size_t n = argslen;
-  int argc = 0;
-
-  while (n > 0)
-    {
-      char *end = memchr (p, '\0', n);
-
-      if (argv)
-	argv[argc] = p;
-      ++argc;
-
-      if (end == NULL)
-	/* The last argument is unterminated.  */
-	break;
-
-      n -= end + 1 - p;
-      p = end + 1;
-    }
-
-  if (argv)
-    argv[argc] = NULL;
-  return argc;
-}