aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2001-06-17 21:09:28 +0000
committerRoland McGrath <roland@gnu.org>2001-06-17 21:09:28 +0000
commit5fe915ee12806a1cb6a5ece20746a4f080de0a65 (patch)
tree35dcf389db65c96eae7fddeed1d38a70552df573 /sysdeps
parent21bc421fb026fe05ecf80882d7698020ad0e336c (diff)
downloadglibc-5fe915ee12806a1cb6a5ece20746a4f080de0a65.tar
glibc-5fe915ee12806a1cb6a5ece20746a4f080de0a65.tar.gz
glibc-5fe915ee12806a1cb6a5ece20746a4f080de0a65.tar.bz2
glibc-5fe915ee12806a1cb6a5ece20746a4f080de0a65.zip
* hurd/Makefile (routines): Add lookup-retry.
* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Broken out ... * hurd/lookup-retry.c: ... into here, new file. * sysdeps/mach/hurd/dl-sysdep.c (open_file): Call that instead using of duplicate code here. * hurd/hurdexec.c (_hurd_exec): Be robust for DTABLESIZE==0. * posix/regex.c: Avoid an access violation if malloc fails.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c251
1 files changed, 36 insertions, 215 deletions
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index 8bcce13588..d30717b197 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -29,8 +29,7 @@
#include <sysdep.h>
#include <mach/mig_support.h>
#include "hurdstartup.h"
-#include <mach/host_info.h>
-#include <stdio-common/_itoa.h>
+#include <hurd/lookup.h>
#include <hurd/auth.h>
#include <hurd/term.h>
#include <stdarg.h>
@@ -266,20 +265,37 @@ _dl_sysdep_start_cleanup (void)
dynamic linker re-relocates itself to be user-visible (for -ldl),
it will get the user's definition (i.e. usually libc's). */
-/* Open FILE_NAME and return a Hurd I/O for it in *PORT, or
- return an error. If STAT is non-zero, stat the file into that stat buffer. */
+/* Open FILE_NAME and return a Hurd I/O for it in *PORT, or return an
+ error. If STAT is non-zero, stat the file into that stat buffer. */
static error_t
-open_file (const char *file_name, int mode,
+open_file (const char *file_name, int flags,
mach_port_t *port, struct stat *stat)
{
enum retry_type doretry;
char retryname[1024]; /* XXX string_t LOSES! */
- file_t startdir, newpt, fileport;
- int dealloc_dir;
- int nloops;
+ file_t startdir;
error_t err;
- assert (!(mode & ~O_READ));
+ error_t use_init_port (int which, error_t (*operate) (file_t))
+ {
+ return (which < _dl_hurd_data->portarraysize
+ ? ((*operate) (_dl_hurd_data->portarray[which]))
+ : EGRATUITOUS);
+ }
+ file_t get_dtable_port (int fd)
+ {
+ if ((unsigned int) fd < _dl_hurd_data->dtablesize
+ && _dl_hurd_data->dtable[fd] != MACH_PORT_NULL)
+ {
+ __mach_port_mod_refs (__mach_task_self (), _dl_hurd_data->dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ return _dl_hurd_data->dtable[fd];
+ }
+ errno = EBADF;
+ return MACH_PORT_NULL;
+ }
+
+ assert (!(flags & ~O_READ));
startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
INIT_PORT_CRDIR : INIT_PORT_CWDIR];
@@ -287,216 +303,21 @@ open_file (const char *file_name, int mode,
while (file_name[0] == '/')
file_name++;
- if (err = __dir_lookup (startdir, (char *)file_name, mode, 0,
- &doretry, retryname, &fileport))
- return err;
+ err = __dir_lookup (startdir, (char *)file_name, O_RDONLY, 0,
+ &doretry, retryname, port);
- dealloc_dir = 0;
- nloops = 0;
-
- while (1)
+ if (!err)
+ err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port,
+ __dir_lookup, doretry, retryname,
+ O_RDONLY, 0, port);
+ if (!err && stat)
{
- if (dealloc_dir)
- __mach_port_deallocate (__mach_task_self (), startdir);
+ err = __io_stat (*port, stat);
if (err)
- return err;
-
- switch (doretry)
- {
- case FS_RETRY_REAUTH:
- {
- mach_port_t ref = __mach_reply_port ();
- err = __io_reauthenticate (fileport, ref, MACH_MSG_TYPE_MAKE_SEND);
- if (! err)
- err = __auth_user_authenticate
- (_dl_hurd_data->portarray[INIT_PORT_AUTH],
- ref, MACH_MSG_TYPE_MAKE_SEND,
- &newpt);
- __mach_port_destroy (__mach_task_self (), ref);
- }
- __mach_port_deallocate (__mach_task_self (), fileport);
- if (err)
- return err;
- fileport = newpt;
- /* Fall through. */
-
- case FS_RETRY_NORMAL:
-#ifdef SYMLOOP_MAX
- if (nloops++ >= SYMLOOP_MAX)
- return ELOOP;
-#endif
-
- /* An empty RETRYNAME indicates we have the final port. */
- if (retryname[0] == '\0')
- {
- dealloc_dir = 1;
- opened:
- /* We have the file open. Now map it. */
- if (stat)
- err = __io_stat (fileport, stat);
-
- if (err)
- {
- if (dealloc_dir)
- __mach_port_deallocate (__mach_task_self (), fileport);
- }
- else
- {
- if (!dealloc_dir)
- __mach_port_mod_refs (__mach_task_self (), fileport,
- MACH_PORT_RIGHT_SEND, 1);
- *port = fileport;
- }
-
- return err;
- }
-
- startdir = fileport;
- dealloc_dir = 1;
- file_name = retryname;
- break;
-
- case FS_RETRY_MAGICAL:
- switch (retryname[0])
- {
- case '/':
- startdir = _dl_hurd_data->portarray[INIT_PORT_CRDIR];
- dealloc_dir = 0;
- if (fileport != MACH_PORT_NULL)
- __mach_port_deallocate (__mach_task_self (), fileport);
- file_name = &retryname[1];
- break;
-
- case 'f':
- if (retryname[1] == 'd' && retryname[2] == '/' &&
- isdigit (retryname[3]))
- {
- /* We can't use strtol for the decoding here
- because it brings in hairy locale bloat. */
- char *p;
- int fd = 0;
- for (p = &retryname[3]; isdigit (*p); ++p)
- fd = (fd * 10) + (*p - '0');
- /* Check for excess text after the number. A slash is
- valid; it ends the component. Anything else does not
- name a numeric file descriptor. */
- if (*p != '/' && *p != '\0')
- return ENOENT;
- if (fd < 0 || fd >= _dl_hurd_data->dtablesize ||
- _dl_hurd_data->dtable[fd] == MACH_PORT_NULL)
- /* If the name was a proper number, but the file
- descriptor does not exist, we return EBADF instead
- of ENOENT. */
- return EBADF;
- fileport = _dl_hurd_data->dtable[fd];
- if (*p == '\0')
- {
- /* This descriptor is the file port we want. */
- dealloc_dir = 0;
- goto opened;
- }
- else
- {
- /* Do a normal retry on the remaining components. */
- startdir = fileport;
- dealloc_dir = 1;
- file_name = p + 1; /* Skip the slash. */
- break;
- }
- }
- else
- goto bad_magic;
- break;
-
- case 'm':
- if (retryname[1] == 'a' && retryname[2] == 'c' &&
- retryname[3] == 'h' && retryname[4] == 't' &&
- retryname[5] == 'y' && retryname[6] == 'p' &&
- retryname[7] == 'e')
- {
- error_t err;
- struct host_basic_info hostinfo;
- mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT;
- char *p;
- if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
- (natural_t *) &hostinfo,
- &hostinfocnt))
- return err;
- if (hostinfocnt != HOST_BASIC_INFO_COUNT)
- return EGRATUITOUS;
- p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0);
- *--p = '/';
- p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0);
- if (p < retryname)
- abort (); /* XXX write this right if this ever happens */
- if (p > retryname)
- strcpy (retryname, p);
- startdir = fileport;
- dealloc_dir = 1;
- }
- else
- goto bad_magic;
- break;
-
- case 't':
- if (retryname[1] == 't' && retryname[2] == 'y')
- switch (retryname[3])
- {
- error_t opentty (file_t *result)
- {
- error_t err;
- file_t unauth;
- err = __termctty_open_terminal
- (_dl_hurd_data->portarray[INIT_PORT_CTTYID],
- mode, &unauth);
- if (! err)
- {
- mach_port_t ref = __mach_reply_port ();
- err = __io_reauthenticate
- (unauth, ref, MACH_MSG_TYPE_MAKE_SEND);
- if (! err)
- err = __auth_user_authenticate
- (_dl_hurd_data->portarray[INIT_PORT_AUTH],
- ref, MACH_MSG_TYPE_MAKE_SEND,
- result);
- __mach_port_deallocate (__mach_task_self (),
- unauth);
- __mach_port_destroy (__mach_task_self (), ref);
- }
- return err;
- }
-
- case '\0':
- if (err = opentty (&fileport))
- return err;
- dealloc_dir = 1;
- goto opened;
- case '/':
- if (err = opentty (&startdir))
- return err;
- dealloc_dir = 1;
- strcpy (retryname, &retryname[4]);
- break;
- default:
- goto bad_magic;
- }
- else
- goto bad_magic;
- break;
-
- default:
- bad_magic:
- return EGRATUITOUS;
- }
- break;
-
- default:
- return EGRATUITOUS;
- }
-
- err = __dir_lookup (startdir, (char *)file_name, mode, 0,
- &doretry, retryname, &fileport);
+ __mach_port_deallocate (__mach_task_self (), *port);
}
+
+ return err;
}
int weak_function