diff options
Diffstat (limited to 'sysdeps/mach/hurd/opendir.c')
-rw-r--r-- | sysdeps/mach/hurd/opendir.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c index 23e04ede0e..a1ff947f06 100644 --- a/sysdeps/mach/hurd/opendir.c +++ b/sysdeps/mach/hurd/opendir.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1993,1994,1995,1996,1997,1998,2001,2003,2005,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1993,94,95,96,97,98,2001,2003 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 @@ -33,29 +32,62 @@ #include "dirstream.h" -/* Open a directory stream on a file descriptor in Hurd internal form. - We do no checking here on the descriptor. */ +/* Open a directory stream on NAME. */ DIR * -_hurd_fd_opendir (struct hurd_fd *d) +__opendir (const char *name) { DIR *dirp; + int fd; + struct hurd_fd *d; - if (d == NULL) + if (name[0] == '\0') { - errno = EBADF; + /* POSIX.1-1990 says an empty name gets ENOENT; + but `open' might like it fine. */ + __set_errno (ENOENT); return NULL; } + { + /* Append trailing slash to directory name to force ENOTDIR + if it's not a directory. + + We open using the O_NONBLOCK flag so that a nondirectory with + blocking behavior (FIFO or device) gets ENOTDIR immediately + rather than waiting for the special file's open wakeup predicate. */ + + size_t len = strlen (name); + if (name[len - 1] == '/') + fd = __open (name, O_RDONLY | O_NONBLOCK); + else + { + char n[len + 2]; + memcpy (n, name, len); + n[len] = '/'; + n[len + 1] = '\0'; + fd = __open (n, O_RDONLY | O_NONBLOCK); + } + } + if (fd < 0) + return NULL; + dirp = (DIR *) malloc (sizeof (DIR)); if (dirp == NULL) - return NULL; + { + __close (fd); + return NULL; + } + + /* Extract the pointer to the descriptor structure. */ + __mutex_lock (&_hurd_dtable_lock); + d = dirp->__fd = _hurd_dtable[fd]; + __mutex_unlock (&_hurd_dtable_lock); /* Set the descriptor to close on exec. */ __spin_lock (&d->port.lock); d->flags |= FD_CLOEXEC; __spin_unlock (&d->port.lock); - dirp->__fd = d; dirp->__data = dirp->__ptr = NULL; dirp->__entry_data = dirp->__entry_ptr = 0; dirp->__allocation = 0; @@ -65,29 +97,4 @@ _hurd_fd_opendir (struct hurd_fd *d) return dirp; } - - -/* Open a directory stream on NAME. */ -DIR * -__opendir (const char *name) -{ - if (name[0] == '\0') - { - /* POSIX.1-1990 says an empty name gets ENOENT; - but `open' might like it fine. */ - __set_errno (ENOENT); - return NULL; - } - - int fd = __open (name, O_RDONLY | O_NONBLOCK | O_DIRECTORY); - if (fd < 0) - return NULL; - - /* Extract the pointer to the descriptor structure. */ - DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd)); - if (dirp == NULL) - __close (fd); - - return dirp; -} weak_alias (__opendir, opendir) |