-/* 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>
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;
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;