]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - hurd/dtable.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / hurd / dtable.c
index 3e785a9710e13f36c18869c10ca000cec0c8b675..ca2b35981abde0e8b9a0ca4afe944de18c794082 100644 (file)
@@ -1,22 +1,20 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+/* Copyright (C) 1991-2015 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 free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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.
+   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
+   Lesser 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.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
-#include <ansidecl.h>
 #include <hurd.h>
 #include <hurd/term.h>
 #include <hurd/fd.h>
@@ -41,7 +39,7 @@ DEFINE_HOOK (_hurd_fd_subinit, (void));
 static void
 init_dtable (void)
 {
-  register size_t i;
+  int i;
 
   __mutex_init (&_hurd_dtable_lock);
 
@@ -55,7 +53,7 @@ init_dtable (void)
     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
 
   /* Initialize the descriptor table.  */
-  for (i = 0; i < _hurd_init_dtablesize; ++i)
+  for (i = 0; (unsigned int) i < _hurd_init_dtablesize; ++i)
     {
       if (_hurd_init_dtable[i] == MACH_PORT_NULL)
        /* An unused descriptor is marked by a null pointer.  */
@@ -108,18 +106,35 @@ text_set_element (_hurd_subinit, init_dtable);
 static file_t
 get_dtable_port (int fd)
 {
+  struct hurd_fd *d = _hurd_fd_get (fd);
   file_t dport;
-  int err = HURD_DPORT_USE (fd, __mach_port_mod_refs (__mach_task_self (),
-                                                     (dport = port),
-                                                     MACH_PORT_RIGHT_SEND,
-                                                     1));
-  if (err)
-    {
-      errno = err;
-      return MACH_PORT_NULL;
-    }
-  else
-    return dport;
+
+  if (!d)
+    return __hurd_fail (EBADF), MACH_PORT_NULL;
+
+  HURD_CRITICAL_BEGIN;
+
+  dport = HURD_PORT_USE (&d->port,
+                        ({
+                          error_t err;
+                          mach_port_t outport;
+                          err = __mach_port_mod_refs (__mach_task_self (),
+                                                      port,
+                                                      MACH_PORT_RIGHT_SEND,
+                                                      1);
+                          if (err)
+                            {
+                              errno = err;
+                              outport = MACH_PORT_NULL;
+                            }
+                          else
+                            outport = port;
+                          outport;
+                        }));
+
+  HURD_CRITICAL_END;
+
+  return dport;
 }
 
 file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;
@@ -173,36 +188,50 @@ static void
 ctty_new_pgrp (void)
 {
   int i;
-  
+
   HURD_CRITICAL_BEGIN;
   __mutex_lock (&_hurd_dtable_lock);
 
-  for (i = 0; i < _hurd_dtablesize; ++i)
+  if (__USEPORT (CTTYID, port == MACH_PORT_NULL))
     {
-      struct hurd_fd *const d = _hurd_dtable[i];
-      struct hurd_userlink ulink, ctty_ulink;
-      io_t port, ctty;
-
-      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 != MACH_PORT_NULL)
-       {
-         /* 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_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
-           new = MACH_PORT_NULL;
-         _hurd_port_set (&d->ctty, new);
-       }
-
-      _hurd_port_free (&d->port, &ulink, port);
-      _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
+      /* We have no controlling terminal.  If we haven't had one recently,
+        but our pgrp is being pointlessly diddled anyway, then we will
+        have nothing to do in the loop below because no fd will have a
+        ctty port at all.
+
+        More likely, a setsid call is responsible both for the change
+        in pgrp and for clearing the cttyid port.  In that case, setsid
+        held the dtable lock while updating the dtable to clear all the
+        ctty ports, and ergo must have finished doing so before we run here.
+        So we can be sure, again, that the loop below has no work to do.  */
     }
+  else
+    for (i = 0; i < _hurd_dtablesize; ++i)
+      {
+       struct hurd_fd *const d = _hurd_dtable[i];
+       struct hurd_userlink ulink, ctty_ulink;
+       io_t port, ctty;
+
+       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 != MACH_PORT_NULL)
+         {
+           /* 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_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
+             new = MACH_PORT_NULL;
+           _hurd_port_set (&d->ctty, new);
+         }
+
+       _hurd_port_free (&d->port, &ulink, port);
+       _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
+      }
 
   __mutex_unlock (&_hurd_dtable_lock);
   HURD_CRITICAL_END;
@@ -226,7 +255,7 @@ reauth_dtable (void)
     {
       struct hurd_fd *const d = _hurd_dtable[i];
       mach_port_t new, newctty, ref;
-      
+
       if (d == NULL)
        /* Nothing to do for an unused descriptor cell.  */
        continue;
@@ -235,14 +264,13 @@ reauth_dtable (void)
 
       /* Take the descriptor cell's lock.  */
       __spin_lock (&d->port.lock);
-      
+
       /* Reauthenticate the descriptor's port.  */
       if (d->port.port != MACH_PORT_NULL &&
          ! __io_reauthenticate (d->port.port,
                                 ref, MACH_MSG_TYPE_MAKE_SEND) &&
          ! __USEPORT (AUTH, __auth_user_authenticate
                       (port,
-                       d->port.port,
                        ref, MACH_MSG_TYPE_MAKE_SEND,
                        &new)))
        {
@@ -254,7 +282,6 @@ reauth_dtable (void)
                                     ref, MACH_MSG_TYPE_MAKE_SEND) &&
              ! __USEPORT (AUTH, __auth_user_authenticate
                           (port,
-                           d->ctty.port,
                            ref, MACH_MSG_TYPE_MAKE_SEND,
                            &newctty)))
            _hurd_port_set (&d->ctty, newctty);