mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-17 13:00:43 +08:00
Update.
1998-10-18 Zack Weinberg <zack@rabi.phys.columbia.edu> * sysdeps/unix/opendir.c: Check at runtime for kernel support for O_DIRECTORY.
This commit is contained in:
parent
9cdc774d05
commit
413bb8ca87
@ -1,3 +1,8 @@
|
||||
1998-10-18 Zack Weinberg <zack@rabi.phys.columbia.edu>
|
||||
|
||||
* sysdeps/unix/opendir.c: Check at runtime for kernel support for
|
||||
O_DIRECTORY.
|
||||
|
||||
1998-10-20 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/setresuid.c (__setresuid): Fix
|
||||
|
@ -29,9 +29,40 @@
|
||||
|
||||
#include <dirstream.h>
|
||||
|
||||
/* opendir() must not accidentally open something other than a directory.
|
||||
Some OS's have kernel support for that, some don't. In the worst
|
||||
case we have to stat() before the open() AND fstat() after.
|
||||
|
||||
#ifndef O_DIRECTORY
|
||||
# define O_DIRECTORY 0
|
||||
We have to test at runtime for kernel support since libc may have
|
||||
been compiled with different headers to the kernel it's running on.
|
||||
This test can't be done reliably in the general case. We'll use
|
||||
/dev/null, which if it's not a device lots of stuff will break, as
|
||||
a guinea pig. It may be missing in chroot environments, so we
|
||||
make sure to fail safe. */
|
||||
#ifdef O_DIRECTORY
|
||||
static int o_directory_works = -1;
|
||||
|
||||
static void
|
||||
tryopen_o_directory (void)
|
||||
{
|
||||
int serrno = errno;
|
||||
int x = __open ("/dev/null", O_RDONLY|O_NDELAY|O_DIRECTORY);
|
||||
|
||||
if (x >= 0)
|
||||
{
|
||||
__close (x);
|
||||
o_directory_works = 0;
|
||||
}
|
||||
else if (errno != ENOTDIR)
|
||||
o_directory_works = 0;
|
||||
else
|
||||
o_directory_works = 1;
|
||||
|
||||
__set_errno (serrno);
|
||||
}
|
||||
# define EXTRA_FLAGS O_DIRECTORY
|
||||
#else
|
||||
# define EXTRA_FLAGS 0
|
||||
#endif
|
||||
|
||||
|
||||
@ -53,18 +84,28 @@ __opendir (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We first have to check whether the name is for a directory. We
|
||||
cannot do this after the open() call since the open/close operation
|
||||
performed on, say, a tape device might have undesirable effects. */
|
||||
if (__stat (name, &statbuf) < 0)
|
||||
return NULL;
|
||||
if (! S_ISDIR (statbuf.st_mode))
|
||||
#ifdef O_DIRECTORY
|
||||
/* Test whether O_DIRECTORY works. */
|
||||
if (o_directory_works == -1)
|
||||
tryopen_o_directory ();
|
||||
|
||||
/* We can skip the expensive `stat' call if O_DIRECTORY works. */
|
||||
if (o_directory_works == 0)
|
||||
#endif
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return NULL;
|
||||
/* We first have to check whether the name is for a directory. We
|
||||
cannot do this after the open() call since the open/close operation
|
||||
performed on, say, a tape device might have undesirable effects. */
|
||||
if (__stat (name, &statbuf) < 0)
|
||||
return NULL;
|
||||
if (! S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fd = __open (name, O_RDONLY|O_NDELAY|O_DIRECTORY);
|
||||
fd = __open (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user