diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Versions.def | 4 | ||||
-rw-r--r-- | hurd/Versions | 7 | ||||
-rw-r--r-- | hurd/hurd.h | 6 | ||||
-rw-r--r-- | hurd/hurdlookup.c | 88 | ||||
-rw-r--r-- | hurd/report-wait.c | 122 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/intr-msg.h | 32 | ||||
-rw-r--r-- | sysdeps/mach/hurd/rename.c | 6 | ||||
-rw-r--r-- | sysdeps/mach/hurd/rmdir.c | 4 |
9 files changed, 225 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog index ac3e19525b..93cc5f24d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 1999-11-13 Roland McGrath <roland@baalperazim.frob.com> + * Versions.def (libc): Move GLIBC_2.2 dependency from GLIBC_2.1.1 to + GLIBC_2.1.3. + +1999-11-13 Roland McGrath <roland@baalperazim.frob.com> + * hurd/Versions (GLIBC_2.1.3): Define, adding directory_name_split and hurd_directory_name_split. * Versions.def (libc): Add GLIBC_2.1.3. diff --git a/Versions.def b/Versions.def index 480eef8e82..d4673915e7 100644 --- a/Versions.def +++ b/Versions.def @@ -5,7 +5,9 @@ libc { GLIBC_2.0 GLIBC_2.1 GLIBC_2.0 GLIBC_2.1.1 GLIBC_2.1 - GLIBC_2.2 GLIBC_2.1.1 + GLIBC_2.1.2 GLIBC_2.1.1 + GLIBC_2.1.3 GLIBC_2.1.2 + GLIBC_2.2 GLIBC_2.1.3 } libcrypt { GLIBC_2.0 diff --git a/hurd/Versions b/hurd/Versions index f3e311b2a9..5dcdc355d9 100644 --- a/hurd/Versions +++ b/hurd/Versions @@ -107,4 +107,11 @@ libc { # s* seteuids; } + GLIBC_2.1.3 { + # d* + directory_name_split; + + # h* + hurd_directory_name_split; + } } diff --git a/hurd/hurd.h b/hurd/hurd.h index 9ef6834776..e9c2db8152 100644 --- a/hurd/hurd.h +++ b/hurd/hurd.h @@ -180,6 +180,12 @@ extern int seteuids (int __n, const uid_t *__uidset); extern file_t __file_name_split (const char *file, char **name); extern file_t file_name_split (const char *file, char **name); +/* Split DIRECTORY into a parent directory and a name within the directory. + This is the same as file_name_split, but ignores trailing slashes. */ + +extern file_t __directory_name_split (const char *file, char **name); +extern file_t directory_name_split (const char *file, char **name); + /* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>). The file lookup uses the current root and working directory. Returns a port to the file if successful; otherwise sets `errno' diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c index 0714e4aa86..7e5f9afa99 100644 --- a/hurd/hurdlookup.c +++ b/hurd/hurdlookup.c @@ -429,6 +429,81 @@ __hurd_file_name_split (error_t (*use_init_port) } weak_alias (__hurd_file_name_split, hurd_file_name_split) +/* This is the same as hurd_file_name_split, except that it ignores + trailing slashes (so *NAME is never ""). */ +error_t +__hurd_directory_name_split (error_t (*use_init_port) + (int which, error_t (*operate) (file_t)), + file_t (*get_dtable_port) (int fd), + error_t (*lookup) + (file_t dir, char *name, int flags, mode_t mode, + retry_type *do_retry, string_t retry_name, + mach_port_t *result), + const char *file_name, + file_t *dir, char **name) +{ + error_t addref (file_t crdir) + { + *dir = crdir; + return __mach_port_mod_refs (__mach_task_self (), + crdir, MACH_PORT_RIGHT_SEND, +1); + } + + const char *lastslash = strrchr (file_name, '/'); + + if (lastslash != NULL && lastslash[1] == '\0') + { + /* Trailing slash doesn't count. Look back further. */ + + /* Back up over all trailing slashes. */ + while (lastslash > file_name && *lastslash == '/') + --lastslash; + + /* Find the last one earlier in the string, before the trailing ones. */ +#if __GLIBC__ > 2 || __GLIBC_MINOR__ >= 2 + lastslash = __memrchr (file_name, '/', lastslash - file_name); +#else + /* Keep backing up, looking for a slash. */ + do + if (lastslash == file_name) + { + /* Hit the start with no slash. */ + lastslash = NULL; + break; + } + while (*lastslash-- != '/'); +#endif + } + + if (lastslash != NULL) + { + if (lastslash == file_name) + { + /* "/foobar" => crdir + "foobar". */ + *name = (char *) file_name + 1; + return (*use_init_port) (INIT_PORT_CRDIR, &addref); + } + else + { + /* "/dir1/dir2/.../file". */ + char dirname[lastslash - file_name + 1]; + memcpy (dirname, file_name, lastslash - file_name); + dirname[lastslash - file_name] = '\0'; + *name = (char *) lastslash + 1; + return + __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup, + dirname, 0, 0, dir); + } + } + else + { + /* "foobar" => cwdir + "foobar". */ + *name = (char *) file_name; + return (*use_init_port) (INIT_PORT_CWDIR, &addref); + } +} +weak_alias (__hurd_directory_name_split, hurd_directory_name_split) + file_t __file_name_lookup (const char *file_name, int flags, mode_t mode) @@ -458,6 +533,19 @@ __file_name_split (const char *file_name, char **name) } weak_alias (__file_name_split, file_name_split) +file_t +__directory_name_split (const char *directory_name, char **name) +{ + error_t err; + file_t result; + + err = __hurd_directory_name_split (&_hurd_ports_use, &__getdport, 0, + directory_name, &result, name); + + return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; +} +weak_alias (__directory_name_split, directory_name_split) + file_t __file_name_lookup_under (file_t startdir, diff --git a/hurd/report-wait.c b/hurd/report-wait.c index e8f4f1af4a..41fdca1619 100644 --- a/hurd/report-wait.c +++ b/hurd/report-wait.c @@ -1,5 +1,5 @@ /* Report on what a thread in our task is waiting for. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999 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 @@ -26,51 +26,57 @@ #include "thread_state.h" #include "intr-msg.h" -static void -describe_number (string_t description, const char *flavor, unsigned long int i) +static char * +describe_number (string_t description, const char *flavor, long int i) { unsigned long int j; - char *p = __stpcpy (description, flavor); + char *p = flavor ? description : __stpcpy (description, flavor); + char *end; + + /* Handle sign. */ + if (i < 0) + { + i = -i; + *p++ = '-'; + } /* Allocate space for the number at the end of DESCRIPTION. */ for (j = i; j >= 10; j /= 10) p++; - p[1] = '\0'; + end = p + 1; + *end = '\0'; do { *p-- = '0' + i % 10; i /= 10; } while (i != 0); - assert (*p == '#'); + + return end; } -static void +static char * describe_port (string_t description, mach_port_t port) { int i; + if (port == MACH_PORT_NULL) + return __stpcpy (description, "(null)"); + if (port == MACH_PORT_DEAD) + return __stpcpy (description, "(dead)"); + if (port == __mach_task_self ()) - { - strcpy (description, "task-self"); - return; - } + return __stpcpy (description, "task-self"); for (i = 0; i < _hurd_nports; ++i) if (port == _hurd_ports[i].port) - { - describe_number (description, "init#", i); - return; - } + return describe_number (description, "init#", i); if (_hurd_init_dtable) { for (i = 0; i < _hurd_init_dtablesize; ++i) if (port == _hurd_init_dtable[i]) - { - describe_number (description, "fd#", i); - return; - } + return describe_number (description, "fd#", i); } else if (_hurd_dtable) { @@ -78,18 +84,12 @@ describe_port (string_t description, mach_port_t port) if (_hurd_dtable[i] == NULL) continue; else if (port == _hurd_dtable[i]->port.port) - { - describe_number (description, "fd#", i); - return; - } + return describe_number (description, "fd#", i); else if (port == _hurd_dtable[i]->ctty.port) - { - describe_number (description, "bgfd#", i); - return; - } + return describe_number (description, "bgfd#", i); } - describe_number (description, "port#", port); + return describe_number (description, "port#", port); } @@ -146,12 +146,68 @@ _S_msg_report_wait (mach_port_t msgport, thread_t thread, assert (count == MACHINE_THREAD_STATE_COUNT); if (SYSCALL_EXAMINE (&state, msgid)) { + mach_port_t send_port, rcv_port; + mach_msg_option_t option; + mach_msg_timeout_t timeout; + /* Blocked in a system call. */ - if (*msgid == -25) - /* mach_msg system call. Examine its parameters. */ - describe_port (description, MSG_EXAMINE (&state, msgid)); - else - strcpy (description, "kernel"); + 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; + } } else description[0] = '\0'; diff --git a/sysdeps/mach/hurd/i386/intr-msg.h b/sysdeps/mach/hurd/i386/intr-msg.h index a12b2f2174..d862d5842a 100644 --- a/sysdeps/mach/hurd/i386/intr-msg.h +++ b/sysdeps/mach/hurd/i386/intr-msg.h @@ -83,23 +83,35 @@ struct mach_msg_trap_args }; -static inline mach_port_t -MSG_EXAMINE (struct i386_thread_state *state, int *msgid) +static inline int +MSG_EXAMINE (struct i386_thread_state *state, int *msgid, + mach_port_t *rcv_name, mach_port_t *send_name, + mach_msg_option_t *option, mach_msg_timeout_t *timeout) { const struct mach_msg_trap_args *args = (const void *) state->uesp; mach_msg_header_t *msg; - mach_port_t send_port; if (_hurdsig_catch_memory_fault (args)) - return MACH_PORT_NULL; + return -1; msg = args->msg; + *option = args->option; + *timeout = args->timeout; + *rcv_name = args->rcv_name; _hurdsig_end_catch_fault (); - if (_hurdsig_catch_memory_fault (msg)) - return MACH_PORT_NULL; - send_port = msg->msgh_remote_port; - *msgid = msg->msgh_id; - _hurdsig_end_catch_fault (); + if (msg == 0) + { + *send_name = MACH_PORT_NULL; + *msgid = 0; + } + else + { + if (_hurdsig_catch_memory_fault (msg)) + return -1; + *send_name = msg->msgh_remote_port; + *msgid = msg->msgh_id; + _hurdsig_end_catch_fault (); + } - return send_port; + return 0; } diff --git a/sysdeps/mach/hurd/rename.c b/sysdeps/mach/hurd/rename.c index f217dedc6a..1923a44081 100644 --- a/sysdeps/mach/hurd/rename.c +++ b/sysdeps/mach/hurd/rename.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,94,96,97,99 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 @@ -29,10 +29,10 @@ rename (old, new) file_t olddir, newdir; const char *oldname, *newname; - olddir = __file_name_split (old, (char **) &oldname); + olddir = __directory_name_split (old, (char **) &oldname); if (olddir == MACH_PORT_NULL) return -1; - newdir = __file_name_split (new, (char **) &newname); + newdir = __directory_name_split (new, (char **) &newname); if (newdir == MACH_PORT_NULL) { __mach_port_deallocate (__mach_task_self (), olddir); diff --git a/sysdeps/mach/hurd/rmdir.c b/sysdeps/mach/hurd/rmdir.c index 920d698644..be9a254a30 100644 --- a/sysdeps/mach/hurd/rmdir.c +++ b/sysdeps/mach/hurd/rmdir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,94,95,97,99 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 @@ -28,7 +28,7 @@ __rmdir (file_name) { error_t err; const char *name; - file_t parent = __file_name_split (file_name, (char **) &name); + file_t parent = __directory_name_split (file_name, (char **) &name); if (parent == MACH_PORT_NULL) return -1; err = __dir_rmdir (parent, name); |