Formerly ../hurd/alloc-fd.c.~6~
[kopensolaris-gnu/glibc.git] / hurd / dtable.c
index 3f0f482..301513b 100644 (file)
@@ -19,6 +19,7 @@ Cambridge, MA 02139, USA.  */
 #include <ansidecl.h>
 #include <hurd.h>
 #include <hurd/term.h>
+#include <hurd/fd.h>
 #include <gnu-stabs.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -29,9 +30,9 @@ Cambridge, MA 02139, USA.  */
 #ifdef noteven
 struct mutex _hurd_dtable_lock;
 #endif
-struct _hurd_dtable _hurd_dtable;
+struct hurd_dtable _hurd_dtable;
 int _hurd_dtable_rlimit;
-int *_hurd_dtable_user_dealloc;
+struct hurd_userlink *_hurd_dtable_users;
 
 const struct _hurd_dtable_resizes _hurd_dtable_resizes;
 
@@ -42,12 +43,13 @@ static void
 init_dtable (void)
 {
   register size_t i;
+  struct hurd_fd **dt;
 
 #ifdef noteven
   __mutex_init (&_hurd_dtable_lock);
 #endif
 
-  _hurd_dtable_user_dealloc = NULL;
+  _hurd_dtable_users = NULL;
 
   /* The initial size of the descriptor table is that of the passed-in
      table, rounded up to a multiple of FOPEN_MAX descriptors.  */
@@ -55,18 +57,32 @@ init_dtable (void)
     = (_hurd_init_dtablesize + FOPEN_MAX - 1) / FOPEN_MAX * FOPEN_MAX;
   _hurd_dtable_rlimit = _hurd_dtable.size;
 
-  _hurd_dtable.d = malloc (_hurd_dtable.size * sizeof (*_hurd_dtable.d));
-  if (_hurd_dtable.d == NULL)
+  /* Allocate the vector of pointers.  */
+  dt = _hurd_dtable.d = malloc (_hurd_dtable.size * sizeof (*_hurd_dtable.d));
+  if (dt == NULL)
     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
 
+  /* Initialize the descriptor table.  */
   for (i = 0; i < _hurd_init_dtablesize; ++i)
     {
-      struct _hurd_fd *const d = &_hurd_dtable.d[i];
-
-      _hurd_port_init (&d->port, MACH_PORT_NULL);
-      _hurd_port_init (&d->ctty, MACH_PORT_NULL);
-
-      _hurd_port2fd (d, _hurd_init_dtable[i], 0);
+      if (_hurd_init_dtable[i] == MACH_PORT_NULL)
+       /* An unused descriptor is marked by a null pointer.  */
+       dt[i] = NULL;
+      else
+       {
+         /* Allocate a new file descriptor structure.  */
+         struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
+         if (new == NULL)
+           __libc_fatal ("hurd: Can't allocate initial file descriptors\n");
+
+         /* Initialize the port cells.  */
+         _hurd_port_init (&new->port, MACH_PORT_NULL);
+         _hurd_port_init (&new->ctty, MACH_PORT_NULL);
+
+         /* Install the port in the descriptor.
+            This sets up all the ctty magic.  */
+         _hurd_port2fd (new, _hurd_init_dtable[i], 0);
+       }
     }
 
   /* Clear out the initial descriptor table.
@@ -79,119 +95,13 @@ init_dtable (void)
 
   /* Initialize the remaining empty slots in the table.  */
   for (; i < _hurd_dtable.size; ++i)
-    {
-      _hurd_port_init (&_hurd_dtable.d[i].port, MACH_PORT_NULL);
-      _hurd_port_init (&_hurd_dtable.d[i].ctty, MACH_PORT_NULL);
-      _hurd_dtable.d[i].flags = 0;
-    }
+    dt[i] = NULL;
 }
 
 text_set_element (__libc_subinit, init_dtable);
-\f
-/* Allocate a new file descriptor and install PORT in it.  FLAGS are as for
-   `open'; only O_IGNORE_CTTY is meaningful, but all are saved.
-
-   If the descriptor table is full, set errno, and return -1.
-   If DEALLOC is nonzero, deallocate PORT first.  */
-int
-_hurd_intern_fd (io_t port, int flags, int dealloc)
-{
-  int fd;
-  struct _hurd_fd *d = _hurd_alloc_fd (&fd, 0);
-
-  if (d == NULL)
-    {
-      if (dealloc)
-       __mach_port_deallocate (__mach_task_self (), port);
-      return -1;
-    }
-
-  _hurd_port2fd (d, port, flags);
-  __spin_unlock (&d->port.lock);
-  return fd;
-}
-
-/* Allocate a new file descriptor and return it, locked.
-   If the table is full, set errno and return NULL.  */
-struct _hurd_fd *
-_hurd_alloc_fd (int *fd, const int first_fd)
-{
-  int i;
-
-  __mutex_lock (&hurd_dtable_lock);
-
-  for (i = first_fd; i < _hurd_dtable.size; ++i)
-    {
-      struct _hurd_fd *d = &_hurd_dtable.d[i];
-      __spin_lock (&d->port.lock);
-      if (d->port.port == MACH_PORT_NULL)
-       {
-         __mutex_unlock (&hurd_dtable_lock);
-         if (fd != NULL)
-           *fd = i;
-         return d;
-       }
-      else
-       __spin_unlock (&d->port.lock);
-    }
 
-  __mutex_unlock (&hurd_dtable_lock);
-
-  errno = EMFILE;
-  return NULL;
-}
-
-\f
-void
-_hurd_port2fd (struct _hurd_fd *d, io_t port, int flags)
-{
-  io_t ctty;
-  mach_port_t cttyid;
-  int is_ctty = !(flags & O_IGNORE_CTTY) && ! __term_getctty (port, &cttyid);
-
-  if (is_ctty)
-    {
-      /* This port is capable of being a controlling tty.
-        Is it ours?  */
-      is_ctty &= __USEPORT (CTTYID, port == cttyid);
-      __mach_port_deallocate (__mach_task_self (), cttyid);
-#if 0
-      struct _hurd_port *const id = &_hurd_ports[INIT_PORT_CTTYID];
-      __spin_lock (&id->lock);
-      if (id->port == MACH_PORT_NULL)
-       /* We have no controlling tty, so make this one it.  */
-       _hurd_port_locked_set (id, cttyid);
-      else
-       {
-         if (cttyid != id->port)
-           /* We have a controlling tty and this is not it.  */
-           is_ctty = 0;
-         /* Either we don't want CTTYID, or ID->port already is it.
-            So we don't need to change ID->port, and we
-            can release the reference to CTTYID.  */
-         __spin_unlock (&id->lock);
-         __mach_port_deallocate (__mach_task_self (), cttyid);
-       }
-#endif
-    }
-
-  if (is_ctty && ! __term_become_ctty (port, _hurd_pid, _hurd_pgrp,
-                                      _hurd_msgport, &ctty))
-    {
-      /* Operations on CTTY return EBACKGROUND when we are not a
-        foreground user of the tty.  */
-      d->port.port = ctty;
-      ctty = port;
-    }
-  else
-    /* XXX if IS_CTTY, then this port is our ctty, but we are
-       not doing ctty style i/o because term_become_ctty barfed.
-       What to do?  */
-    /* No ctty magic happening here.  */
-    ctty = MACH_PORT_NULL;
-
-  _hurd_port_set (&d->ctty, ctty);
-}
+/* XXX when the linker supports it, the following functions should all be
+   elsewhere and just have text_set_elements here.  */
 \f
 /* Called by `getdport' to do its work.  */
 
@@ -215,6 +125,7 @@ get_dtable_port (int fd)
 
 text_set_element (_hurd_getdport_fn, get_dtable_port);
 \f
+#if 0
 /* Called on fork to install the dtable in NEWTASK.
    The dtable lock is held.  */
 
@@ -228,7 +139,7 @@ fork_dtable (task_t newtask)
 
   for (i = 0; !err && i < _hurd_dtable.size; ++i)
     {
-      struct _hurd_port_userlink ulink, ctty_ulink;
+      struct hurd_userlink ulink, ctty_ulink;
       io_t port = _hurd_port_get (&_hurd_dtable.d[i].port, &ulink);
       io_t ctty = _hurd_port_get (&_hurd_dtable.d[i].ctty, &ctty_ulink);
 
@@ -250,6 +161,7 @@ fork_dtable (task_t newtask)
 
 text_set_element (_hurd_fork_hook, fork_dtable);
 text_set_element (_hurd_fork_locks, _hurd_dtable_lock);
+#endif
 \f
 /* Called to reauthenticate the dtable when the auth port changes.  */
 
@@ -262,9 +174,13 @@ reauth_dtable (void)
 
   for (i = 0; i < _hurd_dtable.size; ++i)
     {
-      struct _hurd_fd *const d = &_hurd_dtable.d[i];
+      struct hurd_fd *const d = _hurd_dtable.d[i];
       mach_port_t new, newctty;
       
+      if (d == NULL)
+       /* Nothing to do for an unused descriptor cell.  */
+       continue;
+
       /* Take the descriptor cell's lock.  */
       __spin_lock (&d->port.lock);
       
@@ -307,9 +223,13 @@ rectty_dtable (mach_port_t cttyid)
 
   for (i = 0; i < _hurd_dtable.size; ++i)
     {
-      struct _hurd_fd *const d = &_hurd_dtable.d[i];
+      struct hurd_fd *const d = _hurd_dtable.d[i];
       mach_port_t newctty;
 
+      if (d == NULL)
+       /* Nothing to do for an unused descriptor cell.  */
+       continue;
+
       if (cttyid == MACH_PORT_NULL)
        /* We now have no controlling tty at all.  */
        newctty = MACH_PORT_NULL;
@@ -377,13 +297,12 @@ tiocsctty (int fd,
 }
 _HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY);
 
-#ifdef TIOCNOCTTY
 /* Dissociate from the controlling terminal.  */
 
 static int
-tiocnoctty (int fd,
-           int request,        /* Always TIOCNOCTTY.  */
-           void *arg)          /* Not used.  */
+tiocnotty (int fd,
+          int request,         /* Always TIOCNOTTY.  */
+          void *arg)           /* Not used.  */
 {
   /* XXX should verify that FD is ctty and return EINVAL? */
 
@@ -397,6 +316,5 @@ tiocnoctty (int fd,
   return 0;
 }
 _HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY);
-#endif
 
 #endif