Formerly ../hurd/dtable.c.~28~
authorroland <roland>
Fri, 25 Mar 1994 05:08:11 +0000 (05:08 +0000)
committerroland <roland>
Fri, 25 Mar 1994 05:08:11 +0000 (05:08 +0000)
hurd/dtable.c

index 4d67480..a158b5e 100644 (file)
@@ -125,12 +125,15 @@ get_dtable_port (int fd)
 /* text_set_element (_hurd_getdport_fn, get_dtable_port); */
 file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;        /* XXX */
 \f
-#if 0
-/* Called on fork to install the dtable in NEWTASK.
-   The dtable lock is held.  */
+/* Called on fork to install the dtable in NEWTASK.  The dtable lock is
+   held now and was taken before the child was created, copying our memory.
+   Insert send rights for all of the normal io ports for fds, with the same
+   names they have in our task.  We trust that none of the ports in the
+   dtable were be changed while we have been holding the lock, so the port
+   names copied by the child are still valid in our task.  */
 
 static error_t
-fork_dtable (task_t newtask)
+fork_parent_dtable (task_t newtask)
 {
   error_t err;
   int i;
@@ -140,28 +143,102 @@ fork_dtable (task_t newtask)
   for (i = 0; !err && i < _hurd_dtable.size; ++i)
     {
       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);
+      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);
 
-      if (port != MACH_PORT_NULL)
-       err = __mach_port_insert_right (newtask, port, port,
-                                       MACH_MSG_TYPE_COPY_SEND);
-      if (!err && ctty != MACH_PORT_NULL)
+      /* If there is a ctty-special port (it will be in PORT),
+        insert only the normal io port.  The child will get a fresh
+        ctty-special port.  */
+      if (ctty != MACH_PORT_NULL)
        err = __mach_port_insert_right (newtask, ctty, ctty,
                                        MACH_MSG_TYPE_COPY_SEND);
+      else if (port != MACH_PORT_NULL)
+       /* There is no ctty-special port; PORT is the normal io port.  */
+       err = __mach_port_insert_right (newtask, port, port,
+                                       MACH_MSG_TYPE_COPY_SEND);
 
       _hurd_port_free (&_hurd_dtable.d[i].port, &ulink, port);
       _hurd_port_free (&_hurd_dtable.d[i].ctty, &ctty_ulink, ctty);
+    }
+  return err;
+}
+
+/* We are in the child fork; the dtable lock is still held.
+   The parent has inserted send rights for all the normal io ports,
+   but we must recover ctty-special ports for ourselves.  */
+static error_t
+fork_child_dtable (void)
+{
+  error_t err;
+  int i;
+
+  err = 0;
+
+  for (i = 0; !err && i < _hurd_dtable.size; ++i)
+    {
+      struct hurd_fd *d = _hurd_dtable.d[i];
+
+      d->port.userlink = d->ctty.userlink = NULL;
+
+      if (d->ctty.port)
+       /* There was a ctty-special port in the parent.
+          We need to get one for ourselves too.  */
+         err = __term_become_ctty (d->ctty.port,
+                                   /* XXX no guarantee that init_pids hook
+                                      has been run BEFORE this one! */
+                                   _hurd_pid, _hurd_pgrp, _hurd_msgport,
+                                   &d->port.port);
 
       /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
     }
-  __mutex_unlock (&_hurd_dtable_lock);
   return err;
 }
 
-text_set_element (_hurd_fork_hook, fork_dtable);
 text_set_element (_hurd_fork_locks, _hurd_dtable_lock);
-#endif
+text_set_element (_hurd_fork_setup_hook, fork_parent_dtable);
+text_set_element (_hurd_fork_child_hook, fork_child_dtable);
+\f
+/* Called when our process group has changed.  */
+
+static void
+ctty_new_pgrp (void)
+{
+  int i;
+  
+  __mutex_lock (&_hurd_dtable_lock);
+
+  for (i = 0; i < _hurd_dtable.size; ++i)
+    {
+      struct hurd_fd *const d = _hurd_dtable.d[i];
+      struct hurd_userlink ulink, ctty_ulink;
+      io_t port, ctty;
+      mach_port_t newctty;
+
+      if (d == NULL)
+       /* Nothing to do for an unused descriptor cell.  */
+       continue;
+
+      port = _hurd_port_get (&d->port, &ulink);
+      ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
+
+      if (ctty)
+       {
+         /* This fd has a ctty-special port.  We need a new one, to tell
+             the io server of our different process group.  */
+         io_t new;
+         if (! __term_become_ctty (ctty, _hurd_pid, _hurd_pgrp, _hurd_msgport,
+                                   &new))
+           _hurd_port_set (&d->port, new);
+       }
+
+      _hurd_port_free (&d->port, &ulink, port);
+      _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
+    }
+
+  __mutex_unlock (&_hurd_dtable_lock);
+}
+
+text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);
 \f
 /* Called to reauthenticate the dtable when the auth port changes.  */
 
@@ -214,6 +291,9 @@ reauth_dtable (void)
 
 text_set_element (_hurd_reauth_hook, reauth_dtable);
 \f
+\f
+#if 0
+
 #include <hurd/signal.h>
 
 static void
@@ -263,8 +343,6 @@ rectty_dtable (mach_port_t cttyid)
 
   __mutex_unlock (&_hurd_dtable_lock);
 }
-\f
-#if 0
 
 #include <sys/ioctl.h>