Sat May 4 05:44:25 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>

* hurd/hurd-raise.c (_hurd_raise_signal): Pass sigcode in msg_sig_post
	rpc.

	* hurd/hurdmsg.c (_S_msg_set_environment): Use argz.h functions
	instead of _hurd_split_args.
	(_S_msg_*_exec_flags): Functions removed.
	(_S_msg_startup_dosync): Stub removed.

Sat May  4 02:11:55 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>

	* sysdeps/mach/hurd/ptrace.c: Set _hurdsig_traced instead of
	EXEC_TRACED bit in _hurd_exec_flags.
	Pass sigcode arg in msg_sig_post_untraced rpc.

	* sysdeps/mach/hurd/access.c: Don't pass io port in
	auth_user_authenticate rpc.

	* posix/sched.h: Fix typos.

	* sysdeps/mach/hurd/fork.c: Use new critical section lock.
	Clear _hurdsig_traced instead of EXEC_TRACED.

	* sysdeps/stub/nanosleep.c (nanosleep): Fix typo.

	* wcsmbs/wcstol.c: Find strtol.c in ../stdlib.
	* wcsmbs/wcstof.c: Find strtod.c in ../stdlib.
	* wcsmbs/wcstod.c: Likewise.
	* wcsmbs/wcstold.c: Likewise.

	* wcsmbs/wcwidth.h: Find cname-lookup.h in ../wctype.

	* string/envz.c (envz_entry): Use const.
	(envz_get, envz_remove): Likewise.
	(envz_entry): Return char *, not const char *.

	* string/envz.h: Fix decl.

	* string/argz-create.c: Use const in prototype.
	* string/argz-next.c: Likewise.

	* sysdeps/mach/hurd/sigprocmask.c: Pass sigcode arg to msg_sig_post.
	* sysdeps/mach/hurd/i386/sigreturn.c: Likewise.
	* sysdeps/mach/hurd/sigsuspend.c: Likewise.
	* sysdeps/mach/hurd/kill.c: Likewise.

	* hurd/hurdexec.c (_hurd_exec): Use new critical section lock.
	* hurd/catch-exc.c (_S_catch_exception_raise): Likewise.
	* hurd/sigunwind.c (_hurdsig_longjmp_from_handler): Likewise.
	* hurd/thread-cancel.c (hurd_thread_cancel, hurd_check_cancel):
	Likewise.
	* sysdeps/mach/hurd/jmp-unwind.c (_longjmp_unwind): Likewise.
	* sysdeps/mach/hurd/sigaction.c: Likewise.

	* sysdeps/mach/hurd/errnos.awk: Don't use ARGV in comment; it can
	change meaninglessly.

	* hurd/hurd/signal.h (struct hurd_sigstate): Replace critical section
 	flag with a spin lock.
	(_hurd_critical_section_lock): Use spin_try_lock on that to see if we
 	get it.  No need to take SS->lock at all.
	(_hurd_critical_section_unlock): Unlock SS->critical_section_lock
	instead of clearing the old flag member.
	* hurd/hurdsig.c (_hurd_internal_post_signal): Use spin_lock_locked to
	test the critical section state.

	* hurd/hurdinit.c (_hurd_init): Set _hurdsig_traced from the intarray.

	* hurd/hurdkill.c (_hurd_sig_post): Pass 0 sigcode in msg_sig_post.

	* hurd/hurdsig.c (_hurd_internal_post_signal): Test _hurdsig_traced
 	instead of testing (_hurd_exec_flags & EXEC_TRACED).
	(_S_msg_sig_post): Take sigcode arg and pass it through.
	(_S_msg_sig_post_untraced): Likewise.
	(reauth_proc): Don't pass proc port in auth_user_authenticate.

	* hurd/setauth.c (_hurd_setauth): Don't pass object ports in
	auth_user_authenticate RPCs, just the one-off rendezvous port.
	* hurd/dtable.c (reauth_dtable): Likewise.
	* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Likewise.

	* hurd/hurdexec.c (_hurd_exec): Pass 0 flags to file_exec.
	Pass sigcode arg to msg_sig_post.

	* string/argz.h (argz_create): Use const in prototype.

	* hurd/hurdinit.c (_hurd_proc_init): Test _hurdsig_traced instead of
	testing (_hurd_exec_flags & EXEC_TRACED).
	Pass sigcode arg to msg_sig_post.

	* hurd/hurd.h: Declare _hurdsig_traced.

	* string/argz.h (__argz_next): Cast ENTRY before returning it.

	* hurd/hurd/signal.h (_hurd_critical_section_unlock): Pass sigcode arg
	to msg_sig_post.

	* hurd/path-lookup.c: New file.
	* hurd/Makefile (routines): Add path-lookup.
	* hurd/hurd/lookup.h: Declare file_name_path_scan,
	hurd_file_name_path_lookup.
	* hurd/hurd.h: Declare file_name_path_lookup.

	* sysdeps/mach/hurd/select.c: The io_select rpc no longer has a TAG_ID
	argument.  Instead, use a separate reply port for each RPC and put them
	all in a port set to wait for slow replies.
This commit is contained in:
Roland McGrath 1996-05-04 09:46:57 +00:00
parent 7a12c6bba7
commit 8f0c527e13
42 changed files with 526 additions and 306 deletions

108
ChangeLog
View File

@ -1,5 +1,113 @@
Sat May 4 05:44:25 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* hurd/hurd-raise.c (_hurd_raise_signal): Pass sigcode in msg_sig_post
rpc.
* hurd/hurdmsg.c (_S_msg_set_environment): Use argz.h functions
instead of _hurd_split_args.
(_S_msg_*_exec_flags): Functions removed.
(_S_msg_startup_dosync): Stub removed.
Sat May 4 02:11:55 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/mach/hurd/ptrace.c: Set _hurdsig_traced instead of
EXEC_TRACED bit in _hurd_exec_flags.
Pass sigcode arg in msg_sig_post_untraced rpc.
* sysdeps/mach/hurd/access.c: Don't pass io port in
auth_user_authenticate rpc.
* posix/sched.h: Fix typos.
* sysdeps/mach/hurd/fork.c: Use new critical section lock.
Clear _hurdsig_traced instead of EXEC_TRACED.
* sysdeps/stub/nanosleep.c (nanosleep): Fix typo.
* wcsmbs/wcstol.c: Find strtol.c in ../stdlib.
* wcsmbs/wcstof.c: Find strtod.c in ../stdlib.
* wcsmbs/wcstod.c: Likewise.
* wcsmbs/wcstold.c: Likewise.
* wcsmbs/wcwidth.h: Find cname-lookup.h in ../wctype.
* string/envz.c (envz_entry): Use const.
(envz_get, envz_remove): Likewise.
(envz_entry): Return char *, not const char *.
* string/envz.h: Fix decl.
* string/argz-create.c: Use const in prototype.
* string/argz-next.c: Likewise.
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/mach/hurd/sigprocmask.c: Pass sigcode arg to msg_sig_post.
* sysdeps/mach/hurd/i386/sigreturn.c: Likewise.
* sysdeps/mach/hurd/sigsuspend.c: Likewise.
* sysdeps/mach/hurd/kill.c: Likewise.
* hurd/hurdexec.c (_hurd_exec): Use new critical section lock.
* hurd/catch-exc.c (_S_catch_exception_raise): Likewise.
* hurd/sigunwind.c (_hurdsig_longjmp_from_handler): Likewise.
* hurd/thread-cancel.c (hurd_thread_cancel, hurd_check_cancel):
Likewise.
* sysdeps/mach/hurd/jmp-unwind.c (_longjmp_unwind): Likewise.
* sysdeps/mach/hurd/sigaction.c: Likewise.
* sysdeps/mach/hurd/errnos.awk: Don't use ARGV in comment; it can
change meaninglessly.
* hurd/hurd/signal.h (struct hurd_sigstate): Replace critical section
flag with a spin lock.
(_hurd_critical_section_lock): Use spin_try_lock on that to see if we
get it. No need to take SS->lock at all.
(_hurd_critical_section_unlock): Unlock SS->critical_section_lock
instead of clearing the old flag member.
* hurd/hurdsig.c (_hurd_internal_post_signal): Use spin_lock_locked to
test the critical section state.
* hurd/hurdinit.c (_hurd_init): Set _hurdsig_traced from the intarray.
* hurd/hurdkill.c (_hurd_sig_post): Pass 0 sigcode in msg_sig_post.
* hurd/hurdsig.c (_hurd_internal_post_signal): Test _hurdsig_traced
instead of testing (_hurd_exec_flags & EXEC_TRACED).
(_S_msg_sig_post): Take sigcode arg and pass it through.
(_S_msg_sig_post_untraced): Likewise.
(reauth_proc): Don't pass proc port in auth_user_authenticate.
* hurd/setauth.c (_hurd_setauth): Don't pass object ports in
auth_user_authenticate RPCs, just the one-off rendezvous port.
* hurd/dtable.c (reauth_dtable): Likewise.
* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Likewise.
* hurd/hurdexec.c (_hurd_exec): Pass 0 flags to file_exec.
Pass sigcode arg to msg_sig_post.
* string/argz.h (argz_create): Use const in prototype.
* hurd/hurdinit.c (_hurd_proc_init): Test _hurdsig_traced instead of
testing (_hurd_exec_flags & EXEC_TRACED).
Pass sigcode arg to msg_sig_post.
* hurd/hurd.h: Declare _hurdsig_traced.
* string/argz.h (__argz_next): Cast ENTRY before returning it.
* hurd/hurd/signal.h (_hurd_critical_section_unlock): Pass sigcode arg
to msg_sig_post.
* hurd/path-lookup.c: New file.
* hurd/Makefile (routines): Add path-lookup.
* hurd/hurd/lookup.h: Declare file_name_path_scan,
hurd_file_name_path_lookup.
* hurd/hurd.h: Declare file_name_path_lookup.
* sysdeps/mach/hurd/select.c: The io_select rpc no longer has a TAG_ID
argument. Instead, use a separate reply port for each RPC and put them
all in a port set to wait for slow replies.
* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in * intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in
LOCALE_ALIAS_PATH. LOCALE_ALIAS_PATH.

View File

@ -42,6 +42,7 @@ server-interfaces := hurd/msg
routines = hurdstartup hurdinit \ routines = hurdstartup hurdinit \
hurdid hurdlookup hurdpid hurdrlimit hurdprio hurdexec \ hurdid hurdlookup hurdpid hurdrlimit hurdprio hurdexec \
path-lookup \
setauth \ setauth \
pid2task task2pid \ pid2task task2pid \
getuids setuids getumask fchroot \ getuids setuids getumask fchroot \

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -64,7 +64,7 @@ _S_catch_exception_raise (mach_port_t port,
no code should do anything that can fault while holding the no code should do anything that can fault while holding the
sigstate lock. */ sigstate lock. */
ss->critical_section = 0; __spin_unlock (&ss->critical_section_lock);
ss->context = NULL; ss->context = NULL;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -242,7 +242,6 @@ reauth_dtable (void)
ref, MACH_MSG_TYPE_MAKE_SEND) && ref, MACH_MSG_TYPE_MAKE_SEND) &&
! __USEPORT (AUTH, __auth_user_authenticate ! __USEPORT (AUTH, __auth_user_authenticate
(port, (port,
d->port.port,
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
&new))) &new)))
{ {
@ -254,7 +253,6 @@ reauth_dtable (void)
ref, MACH_MSG_TYPE_MAKE_SEND) && ref, MACH_MSG_TYPE_MAKE_SEND) &&
! __USEPORT (AUTH, __auth_user_authenticate ! __USEPORT (AUTH, __auth_user_authenticate
(port, (port,
d->ctty.port,
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
&newctty))) &newctty)))
_hurd_port_set (&d->ctty, newctty); _hurd_port_set (&d->ctty, newctty);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -44,5 +44,5 @@ _hurd_raise_signal (struct hurd_sigstate *ss,
/* Send a message to the signal thread so it /* Send a message to the signal thread so it
will wake up and check for pending signals. */ will wake up and check for pending signals. */
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, signo, sigcode, __mach_task_self ());
} }

View File

@ -76,6 +76,7 @@ extern int _hurd_exec_flags; /* Flags word passed in exec_startup. */
extern struct hurd_port *_hurd_ports; extern struct hurd_port *_hurd_ports;
extern unsigned int _hurd_nports; extern unsigned int _hurd_nports;
extern volatile mode_t _hurd_umask; extern volatile mode_t _hurd_umask;
extern sigset_t _hurdsig_traced;
/* Shorthand macro for internal library code referencing _hurd_ports (see /* Shorthand macro for internal library code referencing _hurd_ports (see
<hurd/port.h>). */ <hurd/port.h>). */
@ -183,6 +184,21 @@ extern file_t file_name_lookup_under (file_t startdir, const char *file,
int flags, mode_t mode); int flags, mode_t mode);
/* Lookup FILE_NAME and return the node opened with FLAGS & MODE
(see hurd_file_name_lookup for details), but a simple file name (without
any directory prefixes) will be consecutively prefixed with the pathnames
in the `:' separated list PATH until one succeeds in a successful lookup.
If none succeed, then the first error that wasn't ENOENT is returned, or
ENOENT if no other errors were returned. If PREFIXED_NAME is non-NULL,
then if the result is looked up directly, *PREFIXED_NAME is set to NULL, and
if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
malloc'd storage containing the prefixed name. */
extern file_t file_name_path_lookup (const char *file_name, const char *path,
int flags, mode_t mode,
char **prefixed_name);
/* Open a file descriptor on a port. FLAGS are as for `open'; flags /* Open a file descriptor on a port. FLAGS are as for `open'; flags
affected by io_set_openmodes are not changed by this. If successful, affected by io_set_openmodes are not changed by this. If successful,
this consumes a user reference for PORT (which will be deallocated on this consumes a user reference for PORT (which will be deallocated on

View File

@ -1,5 +1,5 @@
/* Declarations of file name translation functions for the GNU Hurd. /* Declarations of file name translation functions for the GNU Hurd.
Copyright (C) 1995 Free Software Foundation, Inc. Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -98,4 +98,33 @@ error_t hurd_file_name_lookup_retry (error_t (*use_init_port)
file_t *result); file_t *result);
/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
NULL). Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
successive `:' separated element of PATH, returning whenever FUN returns
0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
prefixed path). If FUN never returns 0, return the first non-ENOENT
return value, or ENOENT if there is none. */
error_t file_name_path_scan (const char *file_name, const char *path,
error_t (*fun)(const char *name),
char **prefixed_name);
/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
(see hurd_file_name_lookup for details), but a simple filename (without
any directory prefixes) will be consectutively prefixed with the pathnames
in the `:' separated list PATH until one succeeds in a successful lookup.
If none succeed, then the first error that wasn't ENOENT is returned, or
ENOENT if no other errors were returned. If PREFIXED_NAME is non-NULL,
then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
malloced storage containing the prefixed name. */
error_t hurd_file_name_path_lookup (error_t (*use_init_port)
(int which,
error_t (*operate) (mach_port_t)),
file_t (*get_dtable_port) (int fd),
const char *file_name, const char *path,
int flags, mode_t mode,
file_t *result, char **prefixed_name);
#endif /* hurd/lookup.h */ #endif /* hurd/lookup.h */

View File

@ -47,9 +47,9 @@ struct hurd_signal_preempter; /* <hurd/sigpreempt.h> */
struct hurd_sigstate struct hurd_sigstate
{ {
spin_lock_t lock; /* Locks most of the rest of the structure. */ spin_lock_t critical_section_lock; /* Held if in critical section. */
int critical_section; /* Nonzero if in critical section. */ spin_lock_t lock; /* Locks most of the rest of the structure. */
thread_t thread; thread_t thread;
struct hurd_sigstate *next; /* Linked-list of thread sigstates. */ struct hurd_sigstate *next; /* Linked-list of thread sigstates. */
@ -159,27 +159,22 @@ _hurd_critical_section_lock (void)
(void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
struct hurd_sigstate *ss = *location; struct hurd_sigstate *ss = *location;
if (ss == NULL) if (ss == NULL)
{
/* The thread variable is unset; this must be the first time we've /* The thread variable is unset; this must be the first time we've
asked for it. In this case, the critical section flag cannot asked for it. In this case, the critical section flag cannot
possible already be set. Look up our sigstate structure the slow possible already be set. Look up our sigstate structure the slow
way; this locks the sigstate lock. */ way; this locks the sigstate lock. */
ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
else
__spin_lock (&ss->lock);
if (ss->critical_section)
{
/* We are already in a critical section, so do nothing. */
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
return NULL;
} }
/* Set the critical section flag so no signal handler will run. */ if (! __spin_try_lock (&ss->critical_section_lock))
ss->critical_section = 1; /* We are already in a critical section, so do nothing. */
__spin_unlock (&ss->lock); return NULL;
/* Return our sigstate pointer; this will be passed to /* With the critical section lock held no signal handler will run.
_hurd_critical_section_unlock to clear the critical section flag. */ Return our sigstate pointer; this will be passed to
_hurd_critical_section_unlock to unlock it. */
return ss; return ss;
} }
@ -191,19 +186,18 @@ _hurd_critical_section_unlock (void *our_lock)
return; return;
else else
{ {
/* It was us who acquired the critical section lock. Clear the /* It was us who acquired the critical section lock. Unlock it. */
critical section flag. */
struct hurd_sigstate *ss = our_lock; struct hurd_sigstate *ss = our_lock;
sigset_t pending; sigset_t pending;
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
ss->critical_section = 0; __spin_unlock (&ss->critical_section_lock);
pending = ss->pending & ~ss->blocked; pending = ss->pending & ~ss->blocked;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
if (pending) if (pending)
/* There are unblocked signals pending, which weren't /* There are unblocked signals pending, which weren't
delivered because we were in the critical section. delivered because we were in the critical section.
Tell the signal thread to deliver them now. */ Tell the signal thread to deliver them now. */
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
} }
} }

View File

@ -25,6 +25,7 @@ Cambridge, MA 02139, USA. */
#include <hurd.h> #include <hurd.h>
#include <hurd/fd.h> #include <hurd/fd.h>
#include <hurd/signal.h> #include <hurd/signal.h>
#include <assert.h>
#include <argz.h> #include <argz.h>
/* Overlay TASK, executing FILE with arguments ARGV and environment ENVP. /* Overlay TASK, executing FILE with arguments ARGV and environment ENVP.
@ -35,7 +36,7 @@ _hurd_exec (task_t task, file_t file,
char *const argv[], char *const envp[]) char *const argv[], char *const envp[])
{ {
error_t err; error_t err;
char *args, *env, *ap; char *args, *env;
size_t argslen, envlen; size_t argslen, envlen;
int ints[INIT_INT_MAX]; int ints[INIT_INT_MAX];
mach_port_t ports[_hurd_nports]; mach_port_t ports[_hurd_nports];
@ -44,10 +45,10 @@ _hurd_exec (task_t task, file_t file,
unsigned int dtablesize, i; unsigned int dtablesize, i;
struct hurd_port **dtable_cells; struct hurd_port **dtable_cells;
struct hurd_userlink *ulink_dtable; struct hurd_userlink *ulink_dtable;
char *const *p;
struct hurd_sigstate *ss; struct hurd_sigstate *ss;
mach_port_t *please_dealloc, *pdp; mach_port_t *please_dealloc, *pdp;
/* XXX needs to be hurdmalloc XXX */
if (err = __argz_create (argv, &args, &argslen)) if (err = __argz_create (argv, &args, &argslen))
return err; return err;
if (err = __argz_create (envp, &env, &envlen)) if (err = __argz_create (envp, &env, &envlen))
@ -89,6 +90,10 @@ _hurd_exec (task_t task, file_t file,
} }
ss = _hurd_self_sigstate (); ss = _hurd_self_sigstate ();
assert (! __spin_lock_locked (&ss->critical_section_lock));
__spin_lock (&ss->critical_section_lock);
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
ints[INIT_SIGMASK] = ss->blocked; ints[INIT_SIGMASK] = ss->blocked;
ints[INIT_SIGPENDING] = ss->pending; ints[INIT_SIGPENDING] = ss->pending;
@ -105,7 +110,6 @@ _hurd_exec (task_t task, file_t file,
critical section flag avoids anything we call trying to acquire the critical section flag avoids anything we call trying to acquire the
sigstate lock. */ sigstate lock. */
ss->critical_section = 1;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
/* Pack up the descriptor table to give the new program. */ /* Pack up the descriptor table to give the new program. */
@ -192,8 +196,7 @@ _hurd_exec (task_t task, file_t file,
*pdp++ = dtable[i]; *pdp++ = dtable[i];
} }
err = __file_exec (file, task, err = __file_exec (file, task, 0,
_hurd_exec_flags & EXEC_INHERITED,
args, argslen, env, envlen, args, argslen, env, envlen,
dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize, dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports, ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
@ -219,15 +222,7 @@ _hurd_exec (task_t task, file_t file,
__mutex_unlock (&_hurd_dtable_lock); __mutex_unlock (&_hurd_dtable_lock);
/* Safe to let signals happen now. */ /* Safe to let signals happen now. */
{ _hurd_critical_section_unlock (ss);
sigset_t pending;
__spin_lock (&ss->lock);
ss->critical_section = 0;
pending = ss->pending & ~ss->blocked;
__spin_unlock (&ss->lock);
if (pending)
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
}
outargs: outargs:
free (args); free (args);

View File

@ -30,6 +30,7 @@ int _hurd_exec_flags;
struct hurd_port *_hurd_ports; struct hurd_port *_hurd_ports;
unsigned int _hurd_nports; unsigned int _hurd_nports;
mode_t _hurd_umask; mode_t _hurd_umask;
sigset_t _hurdsig_traced;
error_t error_t
_hurd_ports_use (int which, error_t (*operate) (mach_port_t)) _hurd_ports_use (int which, error_t (*operate) (mach_port_t))
@ -78,6 +79,9 @@ _hurd_init (int flags, char **argv,
else else
_hurd_umask = CMASK; _hurd_umask = CMASK;
if (intarraysize > INIT_TRACEMASK)
_hurdsig_traced = intarray[INIT_TRACEMASK];
/* All done with init ints and ports. */ /* All done with init ints and ports. */
__vm_deallocate (__mach_task_self (), __vm_deallocate (__mach_task_self (),
(vm_address_t) intarray, (vm_address_t) intarray,
@ -147,11 +151,11 @@ _hurd_proc_init (char **argv)
here, like _hurd_pid, are already initialized. */ here, like _hurd_pid, are already initialized. */
RUN_HOOK (_hurd_proc_subinit, ()); RUN_HOOK (_hurd_proc_subinit, ());
if (_hurd_exec_flags & EXEC_TRACED) if (_hurdsig_traced)
/* This process is "traced", meaning it should stop on signals or exec. /* This process is "traced", meaning it should stop on signals or exec.
We are all set up now to handle signals. Stop ourselves, to inform We are all set up now to handle signals. Stop ourselves, to inform
our parent (presumably a debugger) that the exec has completed. */ our parent (presumably a debugger) that the exec has completed. */
__msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ()); __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
} }
/* Called when we get a message telling us to change our proc server port. */ /* Called when we get a message telling us to change our proc server port. */

View File

@ -42,7 +42,7 @@ _hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport)
(refport = arg_refport, 0), 0, (refport = arg_refport, 0), 0,
/* If no message port we cannot send signals. */ /* If no message port we cannot send signals. */
msgport == MACH_PORT_NULL ? EPERM : msgport == MACH_PORT_NULL ? EPERM :
__msg_sig_post (msgport, sig, refport)); __msg_sig_post (msgport, sig, 0, refport));
if (! err) if (! err)
delivered = 1; delivered = 1;
} }

View File

@ -100,7 +100,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
mach_port_t ref = __mach_reply_port (); mach_port_t ref = __mach_reply_port ();
error_t reauth (auth_t auth) error_t reauth (auth_t auth)
{ {
return __auth_user_authenticate (auth, unauth, ref, return __auth_user_authenticate (auth, ref,
MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND,
result); result);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <argz.h>
#define AUTHCHECK \ #define AUTHCHECK \
@ -377,57 +378,15 @@ _S_msg_set_environment (mach_port_t msgport, mach_port_t auth,
AUTHCHECK; AUTHCHECK;
envc = _hurd_split_args (data, datalen, NULL); envc = __argz_count (data, datalen);
envp = malloc ((envc + 1) * sizeof (char *)); envp = malloc ((envc + 1) * sizeof (char *));
if (envp == NULL) if (envp == NULL)
return errno; return errno;
_hurd_split_args (data, datalen, envp); __argz_extract (data, datalen, envp);
__environ = envp; /* XXX cooperate with loadenv et al */ __environ = envp; /* XXX cooperate with loadenv et al */
return 0; return 0;
} }
/* Get and frob the exec flags. */
kern_return_t
_S_msg_get_exec_flags (mach_port_t process, mach_port_t auth,
int *flags)
{
AUTHCHECK;
*flags = _hurd_exec_flags;
return 0;
}
kern_return_t
_S_msg_set_all_exec_flags (mach_port_t process, mach_port_t auth,
int flags)
{
AUTHCHECK;
_hurd_exec_flags = flags;
return 0;
}
kern_return_t
_S_msg_set_some_exec_flags (mach_port_t process, mach_port_t auth,
int flags)
{
AUTHCHECK;
_hurd_exec_flags |= flags;
return 0;
}
kern_return_t
_S_msg_clear_some_exec_flags (mach_port_t process, mach_port_t auth,
int flags)
{
AUTHCHECK;
_hurd_exec_flags &= ~flags;
return 0;
}
/* XXX */ /* XXX */
@ -445,7 +404,3 @@ _S_msg_set_dtable (mach_port_t process,
portarray_t dtable, portarray_t dtable,
mach_msg_type_number_t dtableCnt) mach_msg_type_number_t dtableCnt)
{ return EOPNOTSUPP; } { return EOPNOTSUPP; }
kern_return_t
_S_msg_startup_dosync (mach_port_t process)
{ return EOPNOTSUPP; }

View File

@ -564,7 +564,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
{ {
/* No preemption. Do normal handling. */ /* No preemption. Do normal handling. */
if (!untraced && (_hurd_exec_flags & EXEC_TRACED)) if (!untraced && __sigismember (&_hurdsig_traced, signo))
{ {
/* We are being traced. Stop to tell the debugger of the signal. */ /* We are being traced. Stop to tell the debugger of the signal. */
if (_hurd_stopped) if (_hurd_stopped)
@ -785,7 +785,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
/* The thread was in sigreturn, not in any interruptible RPC. */ /* The thread was in sigreturn, not in any interruptible RPC. */
wait_for_reply = 0; wait_for_reply = 0;
assert (! ss->critical_section); assert (! __spin_lock_locked (&ss->critical_section_lock));
} }
else else
{ {
@ -795,7 +795,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
&reply) &reply)
!= MACH_PORT_NULL); != MACH_PORT_NULL);
if (ss->critical_section) if (__spin_lock_locked (&ss->critical_section_lock))
{ {
/* The thread is in a critical section. Mark the signal as /* The thread is in a critical section. Mark the signal as
pending. When it finishes the critical section, it will pending. When it finishes the critical section, it will
@ -883,7 +883,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
thread finishes its critical section. */ thread finishes its critical section. */
inline int signals_pending (void) inline int signals_pending (void)
{ {
if (_hurd_stopped || ss->critical_section) if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
return 0; return 0;
return pending = ss->pending & ~ss->blocked; return pending = ss->pending & ~ss->blocked;
} }
@ -1057,7 +1057,7 @@ signal_allowed (int signo, mach_port_t refport)
kern_return_t kern_return_t
_S_msg_sig_post (mach_port_t me, _S_msg_sig_post (mach_port_t me,
mach_port_t reply_port, mach_msg_type_name_t reply_port_type, mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
int signo, int signo, natural_t sigcode,
mach_port_t refport) mach_port_t refport)
{ {
error_t err; error_t err;
@ -1068,7 +1068,7 @@ _S_msg_sig_post (mach_port_t me,
/* Post the signal to the designated signal-receiving thread. This will /* Post the signal to the designated signal-receiving thread. This will
reply when the signal can be considered delivered. */ reply when the signal can be considered delivered. */
_hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
signo, 0, 0, reply_port, reply_port_type, signo, sigcode, 0, reply_port, reply_port_type,
0); /* Stop if traced. */ 0); /* Stop if traced. */
return MIG_NO_REPLY; /* Already replied. */ return MIG_NO_REPLY; /* Already replied. */
@ -1081,7 +1081,7 @@ kern_return_t
_S_msg_sig_post_untraced (mach_port_t me, _S_msg_sig_post_untraced (mach_port_t me,
mach_port_t reply_port, mach_port_t reply_port,
mach_msg_type_name_t reply_port_type, mach_msg_type_name_t reply_port_type,
int signo, int signo, natural_t sigcode,
mach_port_t refport) mach_port_t refport)
{ {
error_t err; error_t err;
@ -1092,7 +1092,7 @@ _S_msg_sig_post_untraced (mach_port_t me,
/* Post the signal to the designated signal-receiving thread. This will /* Post the signal to the designated signal-receiving thread. This will
reply when the signal can be considered delivered. */ reply when the signal can be considered delivered. */
_hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
signo, 0, 0, reply_port, reply_port_type, signo, sigcode, 0, reply_port, reply_port_type,
1); /* Untraced flag. */ 1); /* Untraced flag. */
return MIG_NO_REPLY; /* Already replied. */ return MIG_NO_REPLY; /* Already replied. */
@ -1170,7 +1170,7 @@ reauth_proc (mach_port_t new)
if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC], if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
__proc_reauthenticate (port, ref, __proc_reauthenticate (port, ref,
MACH_MSG_TYPE_MAKE_SEND) || MACH_MSG_TYPE_MAKE_SEND) ||
__auth_user_authenticate (new, port, ref, __auth_user_authenticate (new, ref,
MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND,
&ignore)) &ignore))
&& ignore != MACH_PORT_NULL) && ignore != MACH_PORT_NULL)

120
hurd/path-lookup.c Normal file
View File

@ -0,0 +1,120 @@
/* Filename lookup using a search path
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
This program 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include <hurd.h>
#include <hurd/lookup.h>
/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
NULL). Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
successive `:' separated element of PATH, returning whenever FUN returns
0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
prefixed path). If FUN never returns 0, return the first non-ENOENT
return value, or ENOENT if there is none. */
error_t
file_name_path_scan (const char *file_name, const char *path,
error_t (*fun)(const char *name),
char **prefixed_name)
{
if (path == NULL || index (file_name, '/'))
{
if (prefixed_name)
*prefixed_name = 0;
return (*fun)(file_name);
}
else
{
error_t real_err = 0;
size_t file_name_len = strlen (file_name);
for (;;)
{
error_t err;
const char *next = index (path, ':') ?: path + strlen (path);
size_t pfx_len = next - path;
char pfxed_name[pfx_len + 2 + file_name_len + 1];
if (pfx_len == 0)
pfxed_name[pfx_len++] = '.';
else
bcopy (path, pfxed_name, pfx_len);
if (pfxed_name[pfx_len - 1] != '/')
pfxed_name[pfx_len++] = '/';
bcopy (file_name, pfxed_name + pfx_len, file_name_len + 1);
err = (*fun)(pfxed_name);
if (err == 0)
{
if (prefixed_name)
*prefixed_name = strdup (pfxed_name);
return 0;
}
if (!real_err && err != ENOENT)
real_err = err;
if (*next == '\0')
return real_err ?: ENOENT;
else
path = next + 1;
}
}
}
/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
(see hurd_file_name_lookup for details), but a simple filename (without
any directory prefixes) will be consectutively prefixed with the pathnames
in the `:' separated list PATH until one succeeds in a successful lookup.
If none succeed, then the first error that wasn't ENOENT is returned, or
ENOENT if no other errors were returned. If PREFIXED_NAME is non-NULL,
then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
malloced storage containing the prefixed name. */
error_t
hurd_file_name_path_lookup (error_t (*use_init_port)
(int which,
error_t (*operate) (mach_port_t)),
file_t (*get_dtable_port) (int fd),
const char *file_name, const char *path,
int flags, mode_t mode,
file_t *result, char **prefixed_name)
{
error_t lookup (const char *name)
{
return
__hurd_file_name_lookup (use_init_port, get_dtable_port,
name, flags, mode, result);
}
return file_name_path_scan (file_name, path, lookup, prefixed_name);
}
file_t
file_name_path_lookup (const char *file_name, const char *path,
int flags, mode_t mode, char **prefixed_name)
{
error_t err;
file_t result;
err = hurd_file_name_path_lookup (&_hurd_ports_use, &__getdport,
file_name, path, flags, mode,
&result, prefixed_name);
return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -73,7 +73,6 @@ _hurd_setauth (auth_t new)
! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH], ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH],
__auth_user_authenticate __auth_user_authenticate
(port, (port,
_hurd_init_dtable[d],
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
&new))) &new)))
{ {
@ -88,7 +87,7 @@ _hurd_setauth (auth_t new)
if (__USEPORT (CRDIR, if (__USEPORT (CRDIR,
! __io_reauthenticate (port, ! __io_reauthenticate (port,
ref, MACH_MSG_TYPE_MAKE_SEND) && ref, MACH_MSG_TYPE_MAKE_SEND) &&
! __auth_user_authenticate (new, port, ! __auth_user_authenticate (new,
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
&newport))) &newport)))
_hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport); _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport);
@ -98,7 +97,7 @@ _hurd_setauth (auth_t new)
if (__USEPORT (CWDIR, if (__USEPORT (CWDIR,
! __io_reauthenticate (port, ! __io_reauthenticate (port,
ref, MACH_MSG_TYPE_MAKE_SEND) && ref, MACH_MSG_TYPE_MAKE_SEND) &&
! __auth_user_authenticate (new, port, ! __auth_user_authenticate (new,
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
&newport))) &newport)))
_hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport); _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport);

View File

@ -56,7 +56,7 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val)
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
/* We should only ever be called from _longjmp_unwind (in jmp-unwind.c), /* We should only ever be called from _longjmp_unwind (in jmp-unwind.c),
which calls us inside a critical section. */ which calls us inside a critical section. */
assert (ss->critical_section); assert (__spin_lock_locked (&ss->critical_section_lock));
/* Are we on the alternate signal stack now? */ /* Are we on the alternate signal stack now? */
onstack = (ss->sigaltstack.ss_flags & SA_ONSTACK); onstack = (ss->sigaltstack.ss_flags & SA_ONSTACK);
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
@ -122,7 +122,7 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val)
having run all the unwind forms back to ENV's frame, but our SP is having run all the unwind forms back to ENV's frame, but our SP is
still inside those unwound frames. */ still inside those unwound frames. */
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
ss->critical_section = 0; __spin_unlock (&ss->critical_section_lock);
ss->blocked = ~(sigset_t) 0 & ~_SIG_CANT_MASK; ss->blocked = ~(sigset_t) 0 & ~_SIG_CANT_MASK;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);

View File

@ -1,5 +1,5 @@
/* Thread cancellation support. /* Thread cancellation support.
Copyright (C) 1995 Free Software Foundation, Inc. Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -45,9 +45,9 @@ hurd_thread_cancel (thread_t thread)
if (ss == _hurd_self_sigstate ()) if (ss == _hurd_self_sigstate ())
return EINTR; /* Bozo. */ return EINTR; /* Bozo. */
assert (! __spin_lock_locked (&ss->critical_section_lock));
__spin_lock (&ss->critical_section_lock);
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
assert (! ss->critical_section);
ss->critical_section = 1;
err = __thread_suspend (thread); err = __thread_suspend (thread);
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
@ -85,7 +85,7 @@ hurd_check_cancel (void)
int cancel; int cancel;
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
assert (! ss->critical_section); assert (! __spin_lock_locked (&ss->critical_section_lock));
cancel = ss->cancel; cancel = ss->cancel;
ss->cancel = 0; ss->cancel = 0;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);

View File

@ -33,19 +33,19 @@ __BEGIN_DECLS
/* Set scheduling parameters for a process. */ /* Set scheduling parameters for a process. */
extern int __sched_setparam __P ((__pid_t __pid, extern int __sched_setparam __P ((__pid_t __pid,
__const struct sched_param *__param)); __const struct sched_params *__param));
extern int sched_setparam __P ((__pid_t __pid, extern int sched_setparam __P ((__pid_t __pid,
__const struct sched_param *__param)); __const struct sched_params *__param));
/* Retrieve scheduling parameters for a particular process. */ /* Retrieve scheduling parameters for a particular process. */
extern int __sched_getparam __P ((__pid_t __pid, struct sched_param *__param)); extern int __sched_getparam __P ((__pid_t __pid, struct sched_params *__param));
extern int sched_getparam __P ((__pid_t __pid, struct sched_param *__param)); extern int sched_getparam __P ((__pid_t __pid, struct sched_params *__param));
/* Set scheduling algorithm and/or parameters for a process. */ /* Set scheduling algorithm and/or parameters for a process. */
extern int __sched_setscheduler __P ((__pid_t __pid, int __policy, extern int __sched_setscheduler __P ((__pid_t __pid, int __policy,
__const struct sched_param *__param)); __const struct sched_params *__param));
extern int sched_setscheduler __P ((__pid_t __pid, int __policy, extern int sched_setscheduler __P ((__pid_t __pid, int __policy,
__const struct sched_param *__param)); __const struct sched_params *__param));
/* Retrieve scheduling algorithm for a particular purpose. */ /* Retrieve scheduling algorithm for a particular purpose. */
extern int __sched_getscheduler __P ((__pid_t __pid)); extern int __sched_getscheduler __P ((__pid_t __pid));

View File

@ -26,11 +26,12 @@
ARGZ, and the total length in LEN. If a memory allocation error occurs, ARGZ, and the total length in LEN. If a memory allocation error occurs,
ENOMEM is returned, otherwise 0. */ ENOMEM is returned, otherwise 0. */
error_t error_t
__argz_create (char **argv, char **argz, size_t *len) __argz_create (char *const argv[], char **argz, size_t *len)
{ {
int argc; int argc;
size_t tlen = 0; size_t tlen = 0;
char *p, **ap; char *const *ap;
char *p;
for (argc = 0; argv[argc] != NULL; ++argc) for (argc = 0; argv[argc] != NULL; ++argc)
tlen += strlen (argv[argc]); tlen += strlen (argv[argc]);

View File

@ -28,7 +28,7 @@ __argz_next (char *argz, size_t argz_len, const char *entry)
if (entry < argz + argz_len) if (entry < argz + argz_len)
entry = strchr (entry, '\0') + 1; entry = strchr (entry, '\0') + 1;
return entry >= argz + argz_len ? NULL : entry; return entry >= argz + argz_len ? NULL : (char *) entry;
} }
else else
if (argz_len > 0) if (argz_len > 0)

View File

@ -32,47 +32,47 @@ __BEGIN_DECLS
/* Make a '\0' separated arg vector from a unix argv vector, returning it in /* Make a '\0' separated arg vector from a unix argv vector, returning it in
ARGZ, and the total length in LEN. If a memory allocation error occurs, ARGZ, and the total length in LEN. If a memory allocation error occurs,
ENOMEM is returned, otherwise 0. The result can be destroyed using free. */ ENOMEM is returned, otherwise 0. The result can be destroyed using free. */
error_t __argz_create __P ((char **__argv, char **__argz, size_t *__len)); error_t __argz_create __P ((char *const argv[], char **argz, size_t *len));
error_t argz_create __P ((char **__argv, char **__argz, size_t *__len)); error_t argz_create __P ((char *const *argv[], char **argz, size_t *len));
/* Make a '\0' separated arg vector from a SEP separated list in /* Make a '\0' separated arg vector from a SEP separated list in
STRING, returning it in ARGZ, and the total length in LEN. If a STRING, returning it in ARGZ, and the total length in LEN. If a
memory allocation error occurs, ENOMEM is returned, otherwise 0. memory allocation error occurs, ENOMEM is returned, otherwise 0.
The result can be destroyed using free. */ The result can be destroyed using free. */
error_t __argz_create_sep __P ((__const char *__string, int __sep, error_t __argz_create_sep __P ((__const char *string, int sep,
char **__argz, size_t *__len)); char **argz, size_t *len));
error_t argz_create_sep __P ((__const char *__string, int __sep, error_t argz_create_sep __P ((__const char *string, int sep,
char **__argz, size_t *__len)); char **argz, size_t *len));
/* Returns the number of strings in ARGZ. */ /* Returns the number of strings in ARGZ. */
size_t __argz_count __P ((__const char *__argz, size_t __len)); size_t __argz_count __P ((__const char *argz, size_t len));
size_t argz_count __P ((__const char *__argz, size_t __len)); size_t argz_count __P ((__const char *argz, size_t len));
/* Puts pointers to each string in ARGZ into ARGV, which must be large enough /* Puts pointers to each string in ARGZ into ARGV, which must be large enough
to hold them all. */ to hold them all. */
void __argz_extract __P ((__const char *__argz, size_t __len, char **__argv)); void __argz_extract __P ((__const char *argz, size_t len, char **argv));
void argz_extract __P ((__const char *__argz, size_t __len, char **__argv)); void argz_extract __P ((__const char *argz, size_t len, char **argv));
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
except the last into the character SEP. */ except the last into the character SEP. */
void __argz_stringify __P ((char *__argz, size_t __len, int __sep)); void __argz_stringify __P ((char *argz, size_t len, int sep));
void argz_stringify __P ((char *__argz, size_t __len, int __sep)); void argz_stringify __P ((char *argz, size_t len, int sep));
/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */ /* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
error_t __argz_append __P ((char **__argz, size_t *__argz_len, error_t __argz_append __P ((char **argz, size_t *argz_len,
__const char *__buf, size_t __buf_len)); __const char *buf, size_t buf_len));
error_t argz_append __P ((char **__argz, size_t *__argz_len, error_t argz_append __P ((char **argz, size_t *argz_len,
__const char *__buf, size_t __buf_len)); __const char *buf, size_t buf_len));
/* Append STR to the argz vector in ARGZ & ARGZ_LEN. */ /* Append STR to the argz vector in ARGZ & ARGZ_LEN. */
error_t __argz_add __P ((char **__argz, size_t *__argz_len, error_t __argz_add __P ((char **argz, size_t *argz_len,
__const char *__str)); __const char *str));
error_t argz_add __P ((char **__argz, size_t *__argz_len, error_t argz_add __P ((char **argz, size_t *argz_len,
__const char *__str)); __const char *str));
/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */ /* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */
void __argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry)); void __argz_delete __P ((char **argz, size_t *argz_len, char *entry));
void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry)); void argz_delete __P ((char **argz, size_t *argz_len, char *entry));
/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an /* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end. existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
@ -80,10 +80,10 @@ void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
in ARGZ, EINVAL is returned, else if memory can't be allocated for the new in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
ARGZ, ENOMEM is returned, else 0. */ ARGZ, ENOMEM is returned, else 0. */
error_t __argz_insert __P ((char **__argz, size_t *__argz_len, error_t __argz_insert __P ((char **argz, size_t *argz_len,
char *__before, __const char *__entry)); char *before, __const char *entry));
error_t argz_insert __P ((char **__argz, size_t *__argz_len, error_t argz_insert __P ((char **argz, size_t *argz_len,
char *__before, __const char *__entry)); char *before, __const char *entry));
/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
are no more. If entry is NULL, then the first entry is returned. This are no more. If entry is NULL, then the first entry is returned. This
@ -99,10 +99,10 @@ error_t argz_insert __P ((char **__argz, size_t *__argz_len,
for (entry = argz; entry; entry = argz_next (argz, argz_len, entry)) for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
...; ...;
*/ */
extern char *__argz_next __P ((char *__argz, size_t __argz_len, extern char *__argz_next __P ((char *argz, size_t __argz_len,
__const char *__entry)); __const char *entry));
extern char *argz_next __P ((char *__argz, size_t __argz_len, extern char *argz_next __P ((char *argz, size_t __argz_len,
__const char *__entry)); __const char *entry));
#if defined (__OPTIMIZE__) && __GNUC__ >= 2 #if defined (__OPTIMIZE__) && __GNUC__ >= 2
extern inline char * extern inline char *
@ -113,7 +113,7 @@ __argz_next (char *argz, size_t argz_len, const char *entry)
if (entry < argz + argz_len) if (entry < argz + argz_len)
entry = strchr (entry, '\0') + 1; entry = strchr (entry, '\0') + 1;
return entry >= argz + argz_len ? NULL : entry; return entry >= argz + argz_len ? NULL : (char *) entry;
} }
else else
if (argz_len > 0) if (argz_len > 0)

View File

@ -29,13 +29,13 @@
/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none. /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
If NAME contains the separator character, only the portion before it is If NAME contains the separator character, only the portion before it is
used in the comparison. */ used in the comparison. */
const char * char *
envz_entry (const char *envz, size_t envz_len, const char *name) envz_entry (const char *envz, size_t envz_len, const char *name)
{ {
while (envz_len) while (envz_len)
{ {
char *p = name; const char *p = name;
char *entry = envz; /* Start of this entry. */ const char *entry = envz; /* Start of this entry. */
/* See how far NAME and ENTRY match. */ /* See how far NAME and ENTRY match. */
while (envz_len && *p == *envz && *p && *p != SEP) while (envz_len && *p == *envz && *p && *p != SEP)
@ -43,7 +43,7 @@ envz_entry (const char *envz, size_t envz_len, const char *name)
if ((*envz == '\0' || *envz == SEP) && (*p == '\0' || *p == SEP)) if ((*envz == '\0' || *envz == SEP) && (*p == '\0' || *p == SEP))
/* Bingo! */ /* Bingo! */
return entry; return (char *) entry;
/* No match, skip to the next entry. */ /* No match, skip to the next entry. */
while (envz_len && *envz) while (envz_len && *envz)
@ -60,7 +60,7 @@ envz_entry (const char *envz, size_t envz_len, const char *name)
const char * const char *
envz_get (const char *envz, size_t envz_len, const char *name) envz_get (const char *envz, size_t envz_len, const char *name)
{ {
char *entry = envz_entry (envz, envz_len, name); const char *entry = envz_entry (envz, envz_len, name);
if (entry) if (entry)
{ {
while (*entry && *entry != SEP) while (*entry && *entry != SEP)
@ -75,7 +75,7 @@ envz_get (const char *envz, size_t envz_len, const char *name)
/* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any. */ /* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any. */
void void
envz_remove (char **envz, size_t *envz_len, char *name) envz_remove (char **envz, size_t *envz_len, const char *name)
{ {
char *entry = envz_entry (*envz, *envz_len, name); char *entry = envz_entry (*envz, *envz_len, name);
if (entry) if (entry)

View File

@ -28,7 +28,7 @@
#include <argz.h> #include <argz.h>
/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none. */ /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none. */
const char *envz_entry __P ((__const char *__envz, size_t __envz_len, char *envz_entry __P ((__const char *__envz, size_t __envz_len,
__const char *__name)); __const char *__name));
/* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0 /* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -44,7 +44,6 @@ DEFUN(__access, (file, type), CONST char *file AND int type)
err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND); err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
if (!err) if (!err)
err = __auth_user_authenticate (_hurd_id.rid_auth, err = __auth_user_authenticate (_hurd_id.rid_auth,
port,
ref, MACH_MSG_TYPE_MAKE_SEND, ref, MACH_MSG_TYPE_MAKE_SEND,
result); result);
err; err;

View File

@ -23,10 +23,7 @@
# @comment errno 123 # @comment errno 123
BEGIN { BEGIN {
printf "/* This file generated by"; print "/* This file generated by errnos.awk. */";
for (i = 0; i < ARGC; ++i)
printf " %s", ARGV[i];
printf ". */\n";
print ""; print "";
print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */"; print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
print "#ifndef _HURD_ERRNO"; print "#ifndef _HURD_ERRNO";

View File

@ -1,4 +1,4 @@
/* This file generated by gawk ../manual/errno.texi ../../mach/mach/message.h ../../mach/mach/kern_return.h ../../mach/mach/mig_errors.h ../../mach/device/device_types.h. */ /* This file generated by errnos.awk. */
/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */ /* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
#ifndef _HURD_ERRNO #ifndef _HURD_ERRNO

View File

@ -61,9 +61,7 @@ __fork (void)
struct hurd_sigstate *volatile ss; struct hurd_sigstate *volatile ss;
ss = _hurd_self_sigstate (); ss = _hurd_self_sigstate ();
__spin_lock (&ss->lock); __spin_lock (&ss->critical_section_lock);
ss->critical_section = 1;
__spin_unlock (&ss->lock);
#undef LOSE #undef LOSE
#define LOSE assert_perror (err) /* XXX */ #define LOSE assert_perror (err) /* XXX */
@ -606,7 +604,7 @@ __fork (void)
&_hurd_orphaned)); &_hurd_orphaned));
/* Forking clears the trace flag. */ /* Forking clears the trace flag. */
_hurd_exec_flags &= ~EXEC_TRACED; __sigemptyset (&_hurdsig_traced);
/* Run things that want to run in the child task to set up. */ /* Run things that want to run in the child task to set up. */
RUN_HOOK (_hurd_fork_child_hook, ()); RUN_HOOK (_hurd_fork_child_hook, ());

View File

@ -58,7 +58,7 @@ __sigreturn (struct sigcontext *scp)
arrange to have us called over again in the new reality. */ arrange to have us called over again in the new reality. */
ss->context = scp; ss->context = scp;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
/* If a pending signal was handled, sig_post never returned. /* If a pending signal was handled, sig_post never returned.
If it did return, the pending signal didn't run a handler; If it did return, the pending signal didn't run a handler;
proceed as usual. */ proceed as usual. */

View File

@ -41,14 +41,15 @@ _longjmp_unwind (jmp_buf env, int val)
/* All access to SS->active_resources must take place inside a critical /* All access to SS->active_resources must take place inside a critical
section where signal handlers cannot run. */ section where signal handlers cannot run. */
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
assert (! ss->critical_section); assert (! __spin_lock_locked (&ss->critical_section_lock));
ss->critical_section = 1; __spin_lock (&ss->critical_section_lock);
/* Remove local signal preempters being unwound past. */ /* Remove local signal preempters being unwound past. */
while (ss->preempters && while (ss->preempters &&
_JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preempters)) _JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preempters))
ss->preempters = ss->preempters->next; ss->preempters = ss->preempters->next;
__spin_unlock (&ss->critical_section_lock);
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
/* Iterate over the current thread's list of active resources. /* Iterate over the current thread's list of active resources.

View File

@ -65,7 +65,7 @@ __kill (pid_t pid, int sig)
{ {
if (msgport != MACH_PORT_NULL) if (msgport != MACH_PORT_NULL)
/* Send a signal message to his message port. */ /* Send a signal message to his message port. */
return __msg_sig_post (msgport, sig, refport); return __msg_sig_post (msgport, sig, 0, refport);
/* The process has no message port. Perhaps try direct /* The process has no message port. Perhaps try direct
frobnication of the task. */ frobnication of the task. */

View File

@ -1,5 +1,5 @@
/* Process tracing interface `ptrace' for GNU Hurd. /* Process tracing interface `ptrace' for GNU Hurd.
Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. Copyright (C) 1991, 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -93,7 +93,7 @@ ptrace (enum __ptrace_request request, ... )
{ {
case PTRACE_TRACEME: case PTRACE_TRACEME:
/* Make this process be traced. */ /* Make this process be traced. */
_hurd_exec_flags |= EXEC_TRACED; __sigfillset (&_hurdsig_traced);
__USEPORT (PROC, __proc_mark_traced (port)); __USEPORT (PROC, __proc_mark_traced (port));
break; break;
@ -144,7 +144,7 @@ ptrace (enum __ptrace_request request, ... )
/* Tell the process to take the signal (or just resume if 0). */ /* Tell the process to take the signal (or just resume if 0). */
err = HURD_MSGPORT_RPC err = HURD_MSGPORT_RPC
(__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)), (__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)),
0, 0, __msg_sig_post_untraced (msgport, data, task)); 0, 0, __msg_sig_post_untraced (msgport, data, 0, task));
} }
__mach_port_deallocate (__mach_task_self (), task); __mach_port_deallocate (__mach_task_self (), task);
return err ? __hurd_fail (err) : 0; return err ? __hurd_fail (err) : 0;
@ -178,25 +178,17 @@ ptrace (enum __ptrace_request request, ... )
err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)); err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport));
if (! err) if (! err)
{ {
err = (request == PTRACE_ATTACH ? err = __msg_set_init_int (msgport, task, INIT_TRACEMASK,
__msg_set_some_exec_flags : request == PTRACE_DETACH ? 0 :
__msg_clear_some_exec_flags) (msgport, task, EXEC_TRACED); ~(sigset_t) 0);
#ifdef notyet /* XXX */
if (! err)
/* Request (or request an end to) SIGCHLD notification
when PID stops or dies, and proc_wait working on PID. */
err = __USEPORT (PROC,
__proc_trace_pid (port, pid,
request == PTRACE_ATTACH));
#endif
if (! err) if (! err)
{ {
if (request == PTRACE_ATTACH) if (request == PTRACE_ATTACH)
/* Now stop the process. */ /* Now stop the process. */
err = __msg_sig_post (msgport, SIGSTOP, task); err = __msg_sig_post (msgport, SIGSTOP, 0, task);
else else
/* Resume the process from tracing stop. */ /* Resume the process from tracing stop. */
err = __msg_sig_post_untraced (msgport, 0, task); err = __msg_sig_post_untraced (msgport, 0, 0, task);
} }
__mach_port_deallocate (__mach_task_self (), msgport); __mach_port_deallocate (__mach_task_self (), msgport);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. /* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */
#include <hurd/fd.h> #include <hurd/fd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
/* All user select types. */ /* All user select types. */
#define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG) #define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG)
@ -41,12 +42,8 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
fd_set *exceptfds AND struct timeval *timeout) fd_set *exceptfds AND struct timeval *timeout)
{ {
int i; int i;
mach_port_t port; mach_port_t portset;
int got; int got;
int *types;
struct hurd_userlink *ulink;
mach_port_t *ports;
struct hurd_fd **cells;
error_t err; error_t err;
fd_set rfds, wfds, xfds; fd_set rfds, wfds, xfds;
int firstfd, lastfd; int firstfd, lastfd;
@ -54,6 +51,14 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
(timeout->tv_sec * 1000 + (timeout->tv_sec * 1000 +
timeout->tv_usec / 1000) : timeout->tv_usec / 1000) :
0); 0);
struct
{
struct hurd_userlink ulink;
struct hurd_fd *cell;
mach_port_t io_port;
int type;
mach_port_t reply_port;
} d[nfds];
/* Use local copies so we can't crash from user bogosity. */ /* Use local copies so we can't crash from user bogosity. */
if (readfds == NULL) if (readfds == NULL)
@ -76,10 +81,6 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
nfds = _hurd_dtablesize; nfds = _hurd_dtablesize;
/* Collect the ports for interesting FDs. */ /* Collect the ports for interesting FDs. */
cells = __alloca (nfds * sizeof (*cells));
ports = __alloca (nfds * sizeof (*ports));
types = __alloca (nfds * sizeof (*types));
ulink = __alloca (nfds * sizeof (*ulink));
firstfd = lastfd = -1; firstfd = lastfd = -1;
for (i = 0; i < nfds; ++i) for (i = 0; i < nfds; ++i)
{ {
@ -90,16 +91,16 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
type |= SELECT_WRITE; type |= SELECT_WRITE;
if (exceptfds != NULL && FD_ISSET (i, &xfds)) if (exceptfds != NULL && FD_ISSET (i, &xfds))
type |= SELECT_URG; type |= SELECT_URG;
types[i] = type; d[i].type = type;
if (type) if (type)
{ {
cells[i] = _hurd_dtable[i]; d[i].cell = _hurd_dtable[i];
ports[i] = _hurd_port_get (&cells[i]->port, &ulink[i]); d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
if (ports[i] == MACH_PORT_NULL) if (d[i].io_port == MACH_PORT_NULL)
{ {
/* If one descriptor is bogus, we fail completely. */ /* If one descriptor is bogus, we fail completely. */
while (i-- > 0) while (i-- > 0)
_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]); _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
errno = EBADF; errno = EBADF;
break; break;
} }
@ -115,58 +116,63 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
if (i < nfds) if (i < nfds)
return -1; return -1;
/* Get a port to receive the io_select_reply messages on. */
port = __mach_reply_port ();
/* Send them all io_select request messages. */ /* Send them all io_select request messages. */
got = 0;
err = 0; err = 0;
got = 0;
portset = MACH_PORT_NULL;
for (i = firstfd; i <= lastfd; ++i) for (i = firstfd; i <= lastfd; ++i)
if (types[i]) if (d[i].type)
{ {
if (!err) int type = d[i].type;
{ d[i].reply_port = __mach_reply_port ();
int tag = i; err = __io_select (d[i].io_port, d[i].reply_port,
int type = types[i];
err = __io_select (ports[i], port,
/* Poll for each but the last. */ /* Poll for each but the last. */
(i == lastfd && got == 0) ? to : 0, (i == lastfd && got == 0) ? to : 0,
&type, &tag); &type);
switch (err) switch (err)
{ {
case MACH_RCV_TIMED_OUT: case MACH_RCV_TIMED_OUT:
/* No immediate response. This is normal. */ /* No immediate response. This is normal. */
err = 0; err = 0;
break; if (got == 0)
case 0:
/* We got an answer. This is not necessarily the answer to
the query we sent just now. It may correspond to any
prior query which timed out before its answer arrived. */
if (tag < 0 || tag > i || (type & SELECT_ALL) == 0)
/* This is not a proper answer to any query we have yet
made. */
err = EGRATUITOUS;
else
{ {
/* Some port is ready. TAG tells us which. */ /* We will wait again for a reply later. */
types[tag] &= type; if (portset == MACH_PORT_NULL)
types[tag] |= SELECT_RETURNED; /* Create the portset to receive all the replies on. */
++got; err = __mach_port_allocate (__mach_task_self (),
MACH_PORT_RIGHT_PORT_SET,
&portset);
if (! err)
/* Put this reply port in the port set. */
__mach_port_move_member (__mach_task_self (),
d[i].reply_port, portset);
} }
break; break;
default: default:
/* Any other error kills us. /* No other error should happen. Callers of select don't
But we must continue to loop to free the ports. */ expect to see errors, so we simulate readiness of the erring
object and the next call hopefully will get the error again. */
type = SELECT_ALL;
/* FALLTHROUGH */
case 0:
/* We got an answer. */
if ((type & SELECT_ALL) == 0)
/* Bogus answer; treat like an error, as a fake positive. */
type = SELECT_ALL;
/* This port is already ready already. */
d[i].type &= type;
d[i].type |= SELECT_RETURNED;
++got;
break; break;
} }
} _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);
} }
/* Now wait for reply messages. */ /* Now wait for reply messages. */
if (!err && got == 0 && port != MACH_PORT_NULL) if (!err && got == 0)
{ {
/* Now wait for io_select_reply messages on PORT, /* Now wait for io_select_reply messages on PORT,
timing out as appropriate. */ timing out as appropriate. */
@ -187,15 +193,13 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
error_t err; error_t err;
mach_msg_type_t result_type; mach_msg_type_t result_type;
int result; int result;
mach_msg_type_t tag_type;
int tag;
} success; } success;
} msg; } msg;
mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT); mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
error_t msgerr; error_t msgerr;
while ((msgerr = __mach_msg (&msg.head, while ((msgerr = __mach_msg (&msg.head,
MACH_RCV_MSG | options, MACH_RCV_MSG | options,
0, sizeof msg, port, to, 0, sizeof msg, portset, to,
MACH_PORT_NULL)) == MACH_MSG_SUCCESS) MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
{ {
/* We got a message. Decode it. */ /* We got a message. Decode it. */
@ -209,34 +213,45 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
{ {
/* This is a properly formatted message so far. /* This is a properly formatted message so far.
See if it is a success or a failure. */ See if it is a success or a failure. */
if (msg.error.err) if (msg.error.err == EINTR &&
msg.head.msgh_size == sizeof msg.error)
{ {
err = msg.error.err; /* EINTR response; poll for further responses
if (msg.head.msgh_size != sizeof msg.error) and then return quickly. */
__mach_msg_destroy (&msg); err = EINTR;
goto poll;
} }
else if (msg.head.msgh_size != sizeof msg.success || if (msg.error.err ||
*(int *) &msg.success.tag_type != *(int *) &inttype || msg.head.msgh_size != sizeof msg.success ||
*(int *) &msg.success.result_type != *(int *) &inttype) *(int *) &msg.success.result_type != *(int *) &inttype ||
__mach_msg_destroy (&msg); (msg.success.result & SELECT_ALL) == 0)
else if ((msg.success.result & SELECT_ALL) == 0 ||
msg.success.tag < firstfd || msg.success.tag > lastfd)
err = EGRATUITOUS;
else
{ {
/* This is a winning io_select_reply message! /* Error or bogus reply. Simulate readiness. */
Record the readiness it indicates and send a reply. */ __mach_msg_destroy (&msg);
types[msg.success.tag] &= msg.success.result; msg.success.result = SELECT_ALL;
types[msg.success.tag] |= SELECT_RETURNED; }
/* Look up the respondant's reply port and record its
readiness. */
{
int had = got;
for (i = firstfd; i <= lastfd; ++i)
if (d[i].type && d[i].reply_port == msg.head.msgh_local_port)
{
d[i].type &= msg.success.result;
d[i].type |= SELECT_RETURNED;
++got; ++got;
} }
assert (got > had);
}
} }
if (msg.head.msgh_remote_port != MACH_PORT_NULL) if (msg.head.msgh_remote_port != MACH_PORT_NULL)
__mach_port_deallocate (__mach_task_self (), __mach_port_deallocate (__mach_task_self (),
msg.head.msgh_remote_port); msg.head.msgh_remote_port);
if (got || err == EINTR) if (got)
poll:
{ {
/* Poll for another message. */ /* Poll for another message. */
to = 0; to = 0;
@ -252,19 +267,17 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
message waiting. */ message waiting. */
err = 0; err = 0;
if (got && err == EINTR) if (got)
/* Some calls were interrupted, but at least one descriptor /* At least one descriptor is known to be ready now, so we will
is known to be ready now, so we will return success. */ return success. */
err = 0; err = 0;
} }
if (port != MACH_PORT_NULL) for (i = firstfd; i <= lastfd; ++i)
/* We must destroy the port if we made some select requests if (d[i].type)
that might send notification on that port after we no longer care. __mach_port_destroy (__mach_task_self (), d[i].reply_port);
If the port were reused, that notification could confuse the next if (portset != MACH_PORT_NULL)
select call to use the port. The notification might be valid, __mach_port_destroy (__mach_task_self (), portset);
but the descriptor may have changed to a different server. */
__mach_port_destroy (__mach_task_self (), port);
if (err) if (err)
return __hurd_fail (err); return __hurd_fail (err);
@ -277,7 +290,7 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
ones are initially set. */ ones are initially set. */
for (i = firstfd; i <= lastfd; ++i) for (i = firstfd; i <= lastfd; ++i)
{ {
int type = types[i]; int type = d[i].type;
if ((type & SELECT_RETURNED) == 0) if ((type & SELECT_RETURNED) == 0)
type = 0; type = 0;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -47,6 +47,7 @@ DEFUN(__sigaction, (sig, act, oact),
ss = _hurd_self_sigstate (); ss = _hurd_self_sigstate ();
__spin_lock (&ss->critical_section_lock);
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
old = ss->actions[sig]; old = ss->actions[sig];
if (act != NULL) if (act != NULL)
@ -55,7 +56,6 @@ DEFUN(__sigaction, (sig, act, oact),
if (act != NULL && sig == SIGCHLD && if (act != NULL && sig == SIGCHLD &&
(a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP)) (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
{ {
ss->critical_section = 1;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
/* Inform the proc server whether or not it should send us SIGCHLD for /* Inform the proc server whether or not it should send us SIGCHLD for
@ -65,16 +65,16 @@ DEFUN(__sigaction, (sig, act, oact),
__proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP))); __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
__spin_lock (&ss->lock); __spin_lock (&ss->lock);
ss->critical_section = 0;
pending = ss->pending & ~ss->blocked; pending = ss->pending & ~ss->blocked;
} }
else else
pending = 0; pending = 0;
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
__spin_unlock (&ss->critical_section_lock);
if (pending) if (pending)
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
if (oact != NULL) if (oact != NULL)
*oact = old; *oact = old;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -79,7 +79,7 @@ DEFUN(__sigprocmask, (how, set, oset),
if (pending) if (pending)
/* Send a message to the signal thread so it /* Send a message to the signal thread so it
will wake up and check for pending signals. */ will wake up and check for pending signals. */
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -57,7 +57,7 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set)
if (pending) if (pending)
/* Tell the signal thread to check for pending signals. */ /* Tell the signal thread to check for pending signals. */
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
/* Wait for the signal thread's message. */ /* Wait for the signal thread's message. */
__mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait, __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
@ -71,7 +71,7 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set)
if (pending) if (pending)
/* Tell the signal thread to check for pending signals. */ /* Tell the signal thread to check for pending signals. */
__msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
/* We've been interrupted! And a good thing, too. /* We've been interrupted! And a good thing, too.
Otherwise we'd never return. Otherwise we'd never return.

View File

@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
/* Pause execution for a number of nanoseconds. */ /* Pause execution for a number of nanoseconds. */
int int
nanosleep (const struct timespec *requested_time, struct time_spec *remaining) nanosleep (const struct timespec *requested_time, struct timespec *remaining)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;

View File

@ -22,4 +22,4 @@ Boston, MA 02111-1307, USA. */
#define USE_WIDE_CHAR 1 #define USE_WIDE_CHAR 1
#include "strtod.c" #include "../stdlib/strtod.c"

View File

@ -28,4 +28,4 @@ Boston, MA 02111-1307, USA. */
#define FLOAT_HUGE_VAL HUGE_VALf #define FLOAT_HUGE_VAL HUGE_VALf
#define USE_WIDE_CHAR 1 #define USE_WIDE_CHAR 1
#include "strtod.c" #include "../stdlib/strtod.c"

View File

@ -19,4 +19,4 @@ Boston, MA 02111-1307, USA. */
#define USE_WIDE_CHAR 1 #define USE_WIDE_CHAR 1
#include "strtol.c" #include "../stdlib/strtol.c"

View File

@ -28,4 +28,4 @@ Boston, MA 02111-1307, USA. */
#define FLOAT_HUGE_VAL HUGE_VALl #define FLOAT_HUGE_VAL HUGE_VALl
#define USE_WIDE_CHAR 1 #define USE_WIDE_CHAR 1
#include "strtod.c" #include "../stdlib/strtod.c"

View File

@ -1,7 +1,7 @@
/* Internal header containing implementation of wcwidth() function. /* Internal header containing implementation of wcwidth() function.
Copyright (C) 1996 Free Software Foundation, Inc. Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edi>, 1996. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
The GNU C Library is free software; you can redistribute it and/or 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 modify it under the terms of the GNU Library General Public License as
@ -19,7 +19,7 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include <wchar.h> #include <wchar.h>
#include "cname-lookup.h" #include "../wctype/cname-lookup.h"
/* Array containing width information. */ /* Array containing width information. */
extern unsigned char *__ctype_width; extern unsigned char *__ctype_width;