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>
|
1998-10-20 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/i386/setresuid.c (__setresuid): Fix
|
* sysdeps/unix/sysv/linux/i386/setresuid.c (__setresuid): Fix
|
||||||
|
@ -29,9 +29,40 @@
|
|||||||
|
|
||||||
#include <dirstream.h>
|
#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.
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
#ifndef O_DIRECTORY
|
static void
|
||||||
# define O_DIRECTORY 0
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -53,18 +84,28 @@ __opendir (const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We first have to check whether the name is for a directory. We
|
#ifdef O_DIRECTORY
|
||||||
cannot do this after the open() call since the open/close operation
|
/* Test whether O_DIRECTORY works. */
|
||||||
performed on, say, a tape device might have undesirable effects. */
|
if (o_directory_works == -1)
|
||||||
if (__stat (name, &statbuf) < 0)
|
tryopen_o_directory ();
|
||||||
return NULL;
|
|
||||||
if (! S_ISDIR (statbuf.st_mode))
|
/* We can skip the expensive `stat' call if O_DIRECTORY works. */
|
||||||
|
if (o_directory_works == 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
__set_errno (ENOTDIR);
|
/* We first have to check whether the name is for a directory. We
|
||||||
return NULL;
|
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)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user