Imported Upstream version 1.4.15
This commit is contained in:
parent
882cdeecca
commit
047baae1ca
386 changed files with 60019 additions and 38317 deletions
74
gl/open.c
74
gl/open.c
|
@ -1,5 +1,5 @@
|
|||
/* Open a descriptor to a file.
|
||||
Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -38,6 +38,11 @@ orig_open (const char *filename, int flags, mode_t mode)
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef REPLACE_OPEN_DIRECTORY
|
||||
# define REPLACE_OPEN_DIRECTORY 0
|
||||
#endif
|
||||
|
||||
int
|
||||
open (const char *filename, int flags, ...)
|
||||
|
@ -51,12 +56,9 @@ open (const char *filename, int flags, ...)
|
|||
va_list arg;
|
||||
va_start (arg, flags);
|
||||
|
||||
/* If mode_t is narrower than int, use the promoted type (int),
|
||||
not mode_t. Use sizeof to guess whether mode_t is narrower;
|
||||
we don't know of any practical counterexamples. */
|
||||
mode = (sizeof (mode_t) < sizeof (int)
|
||||
? va_arg (arg, int)
|
||||
: va_arg (arg, mode_t));
|
||||
/* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4
|
||||
creates crashing code when 'mode_t' is smaller than 'int'. */
|
||||
mode = va_arg (arg, PROMOTED_MODE_T);
|
||||
|
||||
va_end (arg);
|
||||
}
|
||||
|
@ -92,15 +94,38 @@ open (const char *filename, int flags, ...)
|
|||
{
|
||||
size_t len = strlen (filename);
|
||||
if (len > 0 && filename[len - 1] == '/')
|
||||
{
|
||||
errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fd = orig_open (filename, flags, mode);
|
||||
|
||||
#if REPLACE_FCHDIR
|
||||
/* Implementing fchdir and fdopendir requires the ability to open a
|
||||
directory file descriptor. If open doesn't support that (as on
|
||||
mingw), we use a dummy file that behaves the same as directories
|
||||
on Linux (ie. always reports EOF on attempts to read()), and
|
||||
override fstat() in fchdir.c to hide the fact that we have a
|
||||
dummy. */
|
||||
if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES
|
||||
&& (flags & O_ACCMODE) == O_RDONLY)
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
/* Maximum recursion depth of 1. */
|
||||
fd = open ("/dev/null", flags, mode);
|
||||
if (0 <= fd)
|
||||
fd = _gl_register_fd (fd, filename);
|
||||
}
|
||||
else
|
||||
errno = EACCES;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPEN_TRAILING_SLASH_BUG
|
||||
/* If the filename ends in a slash and fd does not refer to a directory,
|
||||
then fail.
|
||||
|
@ -116,24 +141,25 @@ open (const char *filename, int flags, ...)
|
|||
with ENOTDIR. */
|
||||
if (fd >= 0)
|
||||
{
|
||||
/* We know len is positive, since open did not fail with ENOENT. */
|
||||
size_t len = strlen (filename);
|
||||
if (len > 0 && filename[len - 1] == '/')
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (filename[len - 1] == '/')
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
close (fd);
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
close (fd);
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FCHDIR_REPLACEMENT
|
||||
if (fd >= 0)
|
||||
_gl_register_fd (fd, filename);
|
||||
#if REPLACE_FCHDIR
|
||||
if (!REPLACE_OPEN_DIRECTORY && 0 <= fd)
|
||||
fd = _gl_register_fd (fd, filename);
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue