]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - hurd/dtable.c
Fix BZ #21654 - grp-merge.c alignment
[thirdparty/glibc.git] / hurd / dtable.c
index 30f6a5ee822f21da7f4803506171ea486381b868..46bad42c3cc8e2bf5e9f3f835b65176902fab322 100644 (file)
@@ -1,20 +1,19 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2017 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.
+   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.
+   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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, 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 <hurd.h>
 #include <hurd/term.h>
@@ -107,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;
@@ -176,32 +192,46 @@ ctty_new_pgrp (void)
   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;