diff options
author | Kim Kibum <kb0929.kim@samsung.com> | 2012-05-21 17:40:28 +0900 |
---|---|---|
committer | Kim Kibum <kb0929.kim@samsung.com> | 2012-05-21 17:40:28 +0900 |
commit | 5fab833656f8722f000d40da4733c164690a18df (patch) | |
tree | 06c6b7063a663592937cbcd47dd400ac931e0490 /gnu/stat.c | |
parent | 43e15e32d26b017f436da3dd40334b4df292e5a5 (diff) | |
download | cpio-5fab833656f8722f000d40da4733c164690a18df.tar.gz cpio-5fab833656f8722f000d40da4733c164690a18df.tar.bz2 cpio-5fab833656f8722f000d40da4733c164690a18df.zip |
Upload Tizen:Base source
Diffstat (limited to 'gnu/stat.c')
-rw-r--r-- | gnu/stat.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/gnu/stat.c b/gnu/stat.c new file mode 100644 index 0000000..8db01a4 --- /dev/null +++ b/gnu/stat.c @@ -0,0 +1,106 @@ +/* -*- buffer-read-only: t -*- vi: set ro: */ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Work around platform bugs in stat. + Copyright (C) 2009, 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* written by Eric Blake */ + +#include <config.h> + +/* Get the original definition of stat. It might be defined as a macro. */ +#define __need_system_sys_stat_h +#include <sys/types.h> +#include <sys/stat.h> +#undef __need_system_sys_stat_h + +static inline int +orig_stat (const char *filename, struct stat *buf) +{ + return stat (filename, buf); +} + +/* Specification. */ +#include <sys/stat.h> + +#include <errno.h> +#include <limits.h> +#include <stdbool.h> +#include <string.h> + +/* Store information about NAME into ST. Work around bugs with + trailing slashes. Mingw has other bugs (such as st_ino always + being 0 on success) which this wrapper does not work around. But + at least this implementation provides the ability to emulate fchdir + correctly. */ + +int +rpl_stat (char const *name, struct stat *st) +{ + int result = orig_stat (name, st); +#if REPLACE_FUNC_STAT_FILE + /* Solaris 9 mistakenly succeeds when given a non-directory with a + trailing slash. */ + if (result == 0 && !S_ISDIR (st->st_mode)) + { + size_t len = strlen (name); + if (ISSLASH (name[len - 1])) + { + errno = ENOTDIR; + return -1; + } + } +#endif /* REPLACE_FUNC_STAT_FILE */ +#if REPLACE_FUNC_STAT_DIR + if (result == -1 && errno == ENOENT) + { + /* Due to mingw's oddities, there are some directories (like + c:\) where stat() only succeeds with a trailing slash, and + other directories (like c:\windows) where stat() only + succeeds without a trailing slash. But we want the two to be + synonymous, since chdir() manages either style. Likewise, Mingw also + reports ENOENT for names longer than PATH_MAX, when we want + ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR. + Fortunately, mingw PATH_MAX is small enough for stack + allocation. */ + char fixed_name[PATH_MAX + 1] = {0}; + size_t len = strlen (name); + bool check_dir = false; + if (PATH_MAX <= len) + errno = ENAMETOOLONG; + else if (len) + { + strcpy (fixed_name, name); + if (ISSLASH (fixed_name[len - 1])) + { + check_dir = true; + while (len && ISSLASH (fixed_name[len - 1])) + fixed_name[--len] = '\0'; + if (!len) + fixed_name[0] = '/'; + } + else + fixed_name[len++] = '/'; + result = orig_stat (fixed_name, st); + if (result == 0 && check_dir && !S_ISDIR (st->st_mode)) + { + result = -1; + errno = ENOTDIR; + } + } + } +#endif /* REPLACE_FUNC_STAT_DIR */ + return result; +} |