1996-02-08 10:00:34 +00:00
|
|
|
/* Report on what a thread in our task is waiting for.
|
1999-11-13 23:52:38 +00:00
|
|
|
Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
|
1997-02-15 04:31:36 +00:00
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 04:58:11 +00:00
|
|
|
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.
|
1997-02-15 04:31:36 +00:00
|
|
|
|
|
|
|
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
|
2001-07-06 04:58:11 +00:00
|
|
|
Lesser General Public License for more details.
|
1997-02-15 04:31:36 +00:00
|
|
|
|
2001-07-06 04:58:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with the GNU C Library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
02111-1307 USA. */
|
1996-02-08 10:00:34 +00:00
|
|
|
|
|
|
|
#include <hurd.h>
|
|
|
|
#include <hurd/signal.h>
|
|
|
|
#include <hurd/fd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <hurd/msg_server.h>
|
|
|
|
#include "thread_state.h"
|
|
|
|
#include "intr-msg.h"
|
|
|
|
|
1999-11-13 23:52:38 +00:00
|
|
|
static char *
|
|
|
|
describe_number (string_t description, const char *flavor, long int i)
|
1996-02-08 10:00:34 +00:00
|
|
|
{
|
1996-07-19 17:18:51 +00:00
|
|
|
unsigned long int j;
|
1999-11-13 23:52:38 +00:00
|
|
|
char *p = flavor ? description : __stpcpy (description, flavor);
|
|
|
|
char *end;
|
|
|
|
|
|
|
|
/* Handle sign. */
|
|
|
|
if (i < 0)
|
|
|
|
{
|
|
|
|
i = -i;
|
|
|
|
*p++ = '-';
|
|
|
|
}
|
1996-05-01 01:01:48 +00:00
|
|
|
|
|
|
|
/* Allocate space for the number at the end of DESCRIPTION. */
|
|
|
|
for (j = i; j >= 10; j /= 10)
|
|
|
|
p++;
|
1999-11-13 23:52:38 +00:00
|
|
|
end = p + 1;
|
|
|
|
*end = '\0';
|
1996-05-01 01:01:48 +00:00
|
|
|
|
1996-02-08 10:00:34 +00:00
|
|
|
do
|
|
|
|
{
|
1996-05-01 01:01:48 +00:00
|
|
|
*p-- = '0' + i % 10;
|
1996-02-08 10:00:34 +00:00
|
|
|
i /= 10;
|
|
|
|
} while (i != 0);
|
1999-11-13 23:52:38 +00:00
|
|
|
|
|
|
|
return end;
|
1996-02-08 10:00:34 +00:00
|
|
|
}
|
|
|
|
|
1999-11-13 23:52:38 +00:00
|
|
|
static char *
|
1996-02-08 10:00:34 +00:00
|
|
|
describe_port (string_t description, mach_port_t port)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
1999-11-13 23:52:38 +00:00
|
|
|
if (port == MACH_PORT_NULL)
|
|
|
|
return __stpcpy (description, "(null)");
|
|
|
|
if (port == MACH_PORT_DEAD)
|
|
|
|
return __stpcpy (description, "(dead)");
|
|
|
|
|
1996-02-08 10:00:34 +00:00
|
|
|
if (port == __mach_task_self ())
|
1999-11-13 23:52:38 +00:00
|
|
|
return __stpcpy (description, "task-self");
|
1996-02-08 10:00:34 +00:00
|
|
|
|
|
|
|
for (i = 0; i < _hurd_nports; ++i)
|
|
|
|
if (port == _hurd_ports[i].port)
|
1999-11-13 23:52:38 +00:00
|
|
|
return describe_number (description, "init#", i);
|
1996-02-08 10:00:34 +00:00
|
|
|
|
|
|
|
if (_hurd_init_dtable)
|
|
|
|
{
|
|
|
|
for (i = 0; i < _hurd_init_dtablesize; ++i)
|
|
|
|
if (port == _hurd_init_dtable[i])
|
1999-11-13 23:52:38 +00:00
|
|
|
return describe_number (description, "fd#", i);
|
1996-02-08 10:00:34 +00:00
|
|
|
}
|
|
|
|
else if (_hurd_dtable)
|
|
|
|
{
|
|
|
|
for (i = 0; i < _hurd_dtablesize; ++i)
|
|
|
|
if (_hurd_dtable[i] == NULL)
|
|
|
|
continue;
|
|
|
|
else if (port == _hurd_dtable[i]->port.port)
|
1999-11-13 23:52:38 +00:00
|
|
|
return describe_number (description, "fd#", i);
|
1996-02-08 10:00:34 +00:00
|
|
|
else if (port == _hurd_dtable[i]->ctty.port)
|
1999-11-13 23:52:38 +00:00
|
|
|
return describe_number (description, "bgfd#", i);
|
1996-02-08 10:00:34 +00:00
|
|
|
}
|
|
|
|
|
1999-11-13 23:52:38 +00:00
|
|
|
return describe_number (description, "port#", port);
|
1996-02-08 10:00:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-02-23 22:09:31 +00:00
|
|
|
/* We want _HURD_ITIMER_THREAD, but don't want to link in the itimer code
|
|
|
|
unnecessarily. */
|
|
|
|
#if 0 /* libc.so.0.0 needs this defined, so make it a weak alias for now. */
|
|
|
|
extern thread_t _hurd_itimer_thread; /* XXX */
|
|
|
|
weak_extern (_hurd_itimer_thread)
|
|
|
|
#else
|
|
|
|
static thread_t default_hurd_itimer_thread;
|
|
|
|
weak_alias (default_hurd_itimer_thread, _hurd_itimer_thread)
|
|
|
|
#endif
|
1996-05-29 17:50:37 +00:00
|
|
|
|
1996-02-08 10:00:34 +00:00
|
|
|
kern_return_t
|
|
|
|
_S_msg_report_wait (mach_port_t msgport, thread_t thread,
|
|
|
|
string_t description, int *msgid)
|
|
|
|
{
|
|
|
|
*msgid = 0;
|
|
|
|
|
|
|
|
if (thread == _hurd_msgport_thread)
|
|
|
|
/* Cute. */
|
|
|
|
strcpy (description, "msgport");
|
1999-11-18 Roland McGrath <roland@baalperazim.frob.com>
* hurd/hurdsig.c (_hurdsig_init): If __hurd_threadvar_stack_mask is
nonzero, use cthread_fork to create the signal thread.
* hurd/msgportdemux.c (_hurd_msgport_receive): Initialize
_hurd_msgport_thread here (to self).
* sysdeps/mach/hurd/fork.c (__fork): When __hurd_sigthread_stack_end
is zero, instead compute child signal thread's starting SP from parent
signal thread's current SP and the threadvar_stack variables.
* hurd/Versions (GLIBC_2.1.3): Add cthread_fork, cthread_detach.
These are now referenced weakly by _hurdsig_init.
* hurd/report-wait.c (_S_msg_report_wait): Fix typo:
&_hurd_itimer_thread not &_hurd_msgport_thread.
1999-10-01 Roland McGrath <roland@baalperazim.frob.com>
* hurd/hurdfchdir.c (_hurd_change_directory_port_from_fd): Rewrite
without HURD_DPORT_USE to clean up warnings.
* hurd/dtable.c (get_dtable_port): Likewise.
* hurd/hurdioctl.c (rectty_dtable): Renamed to install_ctty.
(install_ctty): Do the changing of the cttyid port cell here, inside
the critical section while we holding the dtable lock.
(_hurd_setcttyid, tiocsctty, tiocnotty): Use that instead of changing
the port cell and calling rectty_dtable.
(_hurd_locked_install_cttyid): New function, split out of install_ctty.
(install_ctty): Use it inside a critical section, with the lock held.
* sysdeps/mach/hurd/setsid.c (__setsid): Use
_hurd_locked_install_cttyid to effect the cttyid and dtable changes
after proc_setsid, having held the dtable lock throughout.
* hurd/dtable.c (ctty_new_pgrp): With the dtable lock held, check the
cttyid port for null and bail out early if so. The dtable lock
serializes us after any cttyid change and its associated dtable update.
1999-12-03 05:01:23 +00:00
|
|
|
else if (&_hurd_itimer_thread && thread == _hurd_itimer_thread)
|
1996-05-29 17:50:37 +00:00
|
|
|
strcpy (description, "itimer");
|
1996-02-08 10:00:34 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Make sure this is really one of our threads. */
|
|
|
|
|
|
|
|
struct hurd_sigstate *ss;
|
|
|
|
|
|
|
|
__mutex_lock (&_hurd_siglock);
|
|
|
|
for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
|
|
|
|
if (ss->thread == thread)
|
|
|
|
break;
|
|
|
|
__mutex_unlock (&_hurd_siglock);
|
|
|
|
if (ss == NULL)
|
|
|
|
/* To hell with you. */
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
if (ss->suspended != MACH_PORT_NULL)
|
|
|
|
strcpy (description, "sigsuspend");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Examine the thread's state to see if it is blocked in an RPC. */
|
|
|
|
|
|
|
|
struct machine_thread_state state;
|
|
|
|
mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
|
|
|
|
error_t err;
|
|
|
|
|
|
|
|
err = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
|
|
|
|
(integer_t *) &state, &count);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
assert (count == MACHINE_THREAD_STATE_COUNT);
|
|
|
|
if (SYSCALL_EXAMINE (&state, msgid))
|
|
|
|
{
|
1999-11-13 23:52:38 +00:00
|
|
|
mach_port_t send_port, rcv_port;
|
|
|
|
mach_msg_option_t option;
|
|
|
|
mach_msg_timeout_t timeout;
|
|
|
|
|
1996-02-08 10:00:34 +00:00
|
|
|
/* Blocked in a system call. */
|
1999-11-13 23:52:38 +00:00
|
|
|
if (*msgid == -25
|
|
|
|
/* mach_msg system call. Examine its parameters. */
|
|
|
|
&& MSG_EXAMINE (&state, msgid, &send_port, &rcv_port,
|
|
|
|
&option, &timeout) == 0)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
if (send_port != MACH_PORT_NULL && *msgid != 0)
|
|
|
|
{
|
|
|
|
/* For the normal case of RPCs, we consider the
|
|
|
|
destination port to be the interesting thing
|
|
|
|
whether we are in fact sending or receiving at the
|
|
|
|
moment. That tells us who we are waiting for the
|
|
|
|
reply from. */
|
|
|
|
if (send_port == ss->intr_port)
|
|
|
|
{
|
|
|
|
/* This is a Hurd interruptible RPC.
|
|
|
|
Mark it by surrounding the port description
|
|
|
|
string with [...] brackets. */
|
|
|
|
description[0] = '[';
|
|
|
|
p = describe_port (description + 1, send_port);
|
|
|
|
*p++ = ']';
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
(void) describe_port (description, send_port);
|
|
|
|
}
|
|
|
|
else if (rcv_port != MACH_PORT_NULL)
|
|
|
|
{
|
|
|
|
/* This system call had no send port, but had a
|
|
|
|
receive port. The msgid we extracted is then just
|
|
|
|
some garbage or perhaps the msgid of the last
|
|
|
|
message this thread received, but it's not a
|
|
|
|
helpful thing to return. */
|
|
|
|
strcpy (describe_port (description, rcv_port), ":rcv");
|
|
|
|
*msgid = 0;
|
|
|
|
}
|
|
|
|
else if ((option & (MACH_RCV_MSG|MACH_RCV_TIMEOUT))
|
|
|
|
== (MACH_RCV_MSG|MACH_RCV_TIMEOUT))
|
|
|
|
{
|
|
|
|
/* A receive with no valid port can be used for a
|
|
|
|
pure timeout. Report the timeout value (counted
|
|
|
|
in milliseconds); note this is the original total
|
|
|
|
time, not the time remaining. */
|
|
|
|
strcpy (describe_number (description, 0, timeout), "ms");
|
|
|
|
*msgid = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy (description, "mach_msg");
|
|
|
|
*msgid = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* Some other system call. */
|
|
|
|
{
|
|
|
|
(void) describe_number (description, "syscall#", *msgid);
|
|
|
|
*msgid = 0;
|
|
|
|
}
|
1996-02-08 10:00:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
description[0] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__mach_port_deallocate (__mach_task_self (), thread);
|
|
|
|
return 0;
|
|
|
|
}
|
Tue May 7 19:00:01 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* string/argz-extract.c: Remove const from decl.
* string/argz.h: Here too.
* Makeconfig (version.mk): Fix regexp in sed cmd.
Depend on $(..)Makeconfig.
* GMP code updated from gmp-2.0 release.
* stdlib/Makefile (mpn-routines): Removed add_1, added inlines.
* sysdeps/generic/add_1.c: File removed.
* stdlib/strtod.c: mp_limb is now mp_limb_t.
* stdlib/fpioconst.c, stdlib/fpioconst.h: Likewise.
* stdio-common/_itoa.c: Likewise.
* stdio-common/printf_fp.c: Likewise.
Don't include ansidecl.h.
* sysdeps/mach/hurd/getcwd.c: Use io_identity instead of io_stat.
* shlib-versions: New file.
* Makerules (soversions.mk): New target, include file generated from
shlib-versions. Moved shared library rules before installation rules.
Rewrote shared library installation rules for versioned libraries.
* math/Makefile (libm.so-version): Variable removed.
* sysdeps/mach/hurd/i386/exc2signal.c: Use struct hurd_signal_detail.
* hurd/report-wait.c (_S_msg_describe_ports): New function.
* configure.in: Add AC_PROG_LN_S check.
* config.make.in (LN_S): New variable.
Sun May 5 03:10:44 1996 Ulrich Drepper <drepper@cygnus.com>
* misc/efgcvt_r.c (ecvt_r): Work aroung gcc bug. gcc does
not know about weak aliases now and optimizes necessary `if'
statement away.
* posix/unistd.h: Add swapoff prototype.
* sysdeps/generic/confname.h: Add even more POSIX.4 symbols.
* sysdeps/posix/fpathconf.c (__fpathconf): Get information
for _PC_PATH_MAX from fstatfs function if available.
* sysdeps/posix/sysconf.c: Add code to handle _SC_AIO_LISTIO_MAX,
_SC_AIO_MAX, _SC_AIO_PRIO_DELTA_MAX, _SC_DELAYTIMER_MAX,
_SC_MQ_OPEN_MAX, _SC_MQ_PRIO_MAX, _SC_RTSIG_MAX,
_SC_SEM_NSEMS_MAX, _SC_SEM_VALUE_MAX, _SC_SIGQUEUE_MAX, and
_SC_TIMER_MAX.
* sysdeps/unix/sysv/sysv4/sysconf.c: Ditto.
* sysdeps/stub/swapoff.c: New file. Stub version for swapoff
function.
* sysdeps/unix/syscalls.list: Add swapoff.
* sysdeps/unix/sysv/linux/Dist: Add sys/acct.h.
* sysdeps/unix/sysv/linux/Makefile [$(subdir) == misc]
(sysdep_routines): Add mount, umount, llseek, setfsgid, setfsuid,
sysinfo, and uselib.
(headers): Add sys/sysinfo.h.
* sysdeps/unix/sysv/linux/gethostid.c: Prevent warning.
* sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) == misc]
(sysdep_routines): Add ioperm, iopl, and vm86.
(headers): Add sys/perm.h and sys/vm86.h.
* sysdeps/unix/sysv/linux/i386/sys/perm.h: New file. Contains
prototypes for iopl and ioperm.
* sysdeps/unix/sysv/linux/i386/sys/vm86.h: New file. Contains
prototype for vm86.
* sysdeps/unix/sysv/linux/i386/syscalls.list: New file. Add
vm86 system call.
* sysdeps/unix/sysv/linux/sys/acct.h: New file. Contains
prototypes for acct function.
* sysdeps/unix/sysv/linux/sys/socket.h: Provide real header
file with prototypes.
* sysdeps/unix/sysv/linux/sys/sysinfo.h: New file. Contains
prototype for sysinfo function.
* sysdeps/unix/sysv/linux/syscalls.list: Add flock, ioperm, iopl,
llseek, setfsgid, setfsuid, sysinfo, and uselib.
* sysdeps/unix/sysv/linux/sysconf.c: Instead of duplicating
posix/sysconf.c now only handle cases different to that
implementation.
Tue May 7 15:08:19 1996 Miles Bader <miles@gnu.ai.mit.edu>
* stdio/linewrap.c (__line_wrap_output): Renamed from lwoutput
(all references changed). Now exported.
* stdio/linewrap.c (struct data): Type deleted (moved to linewrap.h).
(wrap_stream, unwrap_stream, lwclose, lwfileno, lwoutput,
line_wrap_stream, line_unwrap_stream): Use struct line_wrap_data
instead of struct data.
(lwoutput, line_wrap_stream, line_unwrap_stream): Rename various
occurences of `wrap' and `wrapmargin' to `wmargin'.
(line_wrapped, line_wrap_lmargin, line_wrap_set_lmargin,
line_wrap_rmargin, line_wrap_set_rmargin, line_wrap_wmargin,
line_wrap_set_wmargin, line_wrap_point): New functions.
* stdio/linewrap.h: New file.
* stdio/Makefile (headers): Add linewrap.h.
Tue May 7 14:19:12 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/Makefile: File removed.
* stdio/stdio.h: Remove line_wrap_stream, line_unwap_stream decls.
* sysdeps/unix/sysv/linux/schedbits.h: New file.
Tue May 7 13:47:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
* stdio/linewrap.c (struct data): Make margin fields not-pointers.
(lwoutput): Adjust uses acordingly.
* sysdeps/mach/hurd/fdatasync.c: New file.
* sysdeps/mach/hurd/fsync.c: Pass new flag to file_sync.
* sysdeps/mach/hurd/xmknod.c: Pass new flag to dir_link.
* sysdeps/mach/hurd/symlink.c: Likewise.
* sysdeps/mach/hurd/link.c: Likewise.
* sysdeps/mach/hurd/bind.c: Likewise.
* hurd/hurdsig.c (write_corefile): Likewise.
* hurd/hurdsig.c (write_corefile): Pass cttyid port to crash server.
* sysdeps/mach/hurd/fpathconf.c: RPC takes int pointer, not long int.
* sysdeps/mach/hurd/_exit.c (_hurd_exit): Pass sigcode arg to
proc_mark_exit.
* sysdeps/mach/hurd/dl-sysdep.c (_exit): Likewise.
* sysdeps/mach/hurd/wait4.c: Pass sigcode arg to proc_wait.
* sysdeps/mach/hurd/rename.c: Pass new flag to dir_rename.
* hurd/hurdfault.c (_hurdsig_fault_catch_exception_raise): Use struct
hurd_signal_detail.
* hurd/catch-exc.c (_S_catch_exception_raise): Likewise.
* hurd/hurd-raise.c (_hurd_raise_signal): Likewise.
* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
Likewise.
* sysdeps/mach/hurd/setitimer.c (restart_itimer): Likewise.
* hurd/hurd/signal.h: Fix _hurd_exception2signal prototype.
* hurd/hurdsig.c (write_corefile): Take const struct
hurd_signal_detail * arg. Pass all details to crash_dump_task.
(_hurd_internal_post_signal): Pass DETAIL to write_corefile.
(_hurd_internal_post_signal: suspend): Pass code and error to
proc_mark_stop.
* hurd/hurdprio.c (_hurd_priority_which_map): Pass flags arg to
proc_getprocinfo by reference.
1996-05-08 02:07:47 +00:00
|
|
|
|
|
|
|
kern_return_t
|
|
|
|
_S_msg_describe_ports (mach_port_t msgport, mach_port_t refport,
|
|
|
|
mach_port_t *ports, mach_msg_type_number_t nports,
|
|
|
|
char **desc, mach_msg_type_number_t *desclen)
|
|
|
|
{
|
|
|
|
char *p, *end;
|
|
|
|
|
|
|
|
if (__USEPORT (AUTH, msgport != port))
|
|
|
|
return EPERM;
|
|
|
|
|
|
|
|
end = *desc + *desclen;
|
|
|
|
p = *desc;
|
|
|
|
while (nports-- > 0)
|
|
|
|
{
|
|
|
|
char this[200];
|
|
|
|
describe_port (this, *ports++);
|
|
|
|
p = __stpncpy (p, this, end - p);
|
|
|
|
if (p == end && p[-1] != '\0')
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
*desclen = p - *desc;
|
|
|
|
return 0;
|
|
|
|
}
|