diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile.in | 30 | ||||
| -rw-r--r-- | lib/dosname.h | 53 | ||||
| -rw-r--r-- | lib/gnulib.mk | 45 | ||||
| -rw-r--r-- | lib/lstat.c | 91 | ||||
| -rw-r--r-- | lib/readlink.c | 74 | ||||
| -rw-r--r-- | lib/stat.c | 105 | ||||
| -rw-r--r-- | lib/symlink.c | 57 |
7 files changed, 443 insertions, 12 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in index 7135d3ebbf9..04ee541a09c 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | # the same distribution terms as the rest of that program. | 24 | # the same distribution terms as the rest of that program. |
| 25 | # | 25 | # |
| 26 | # Generated by gnulib-tool. | 26 | # Generated by gnulib-tool. |
| 27 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value mktime strftime sys_stat | 27 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value lstat mktime readlink strftime symlink sys_stat |
| 28 | 28 | ||
| 29 | VPATH = @srcdir@ | 29 | VPATH = @srcdir@ |
| 30 | pkgdatadir = $(datadir)/@PACKAGE@ | 30 | pkgdatadir = $(datadir)/@PACKAGE@ |
| @@ -55,11 +55,13 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ | |||
| 55 | $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gl-comp.m4 \ | 55 | $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gl-comp.m4 \ |
| 56 | $(top_srcdir)/m4/gnulib-common.m4 \ | 56 | $(top_srcdir)/m4/gnulib-common.m4 \ |
| 57 | $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/longlong.m4 \ | 57 | $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/longlong.m4 \ |
| 58 | $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/mktime.m4 \ | 58 | $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/md5.m4 \ |
| 59 | $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/st_dm_mode.m4 \ | 59 | $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/multiarch.m4 \ |
| 60 | $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ | 60 | $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/st_dm_mode.m4 \ |
| 61 | $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdlib_h.m4 \ | 61 | $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdbool.m4 \ |
| 62 | $(top_srcdir)/m4/strftime.m4 $(top_srcdir)/m4/sys_stat_h.m4 \ | 62 | $(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdint.m4 \ |
| 63 | $(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strftime.m4 \ | ||
| 64 | $(top_srcdir)/m4/symlink.m4 $(top_srcdir)/m4/sys_stat_h.m4 \ | ||
| 63 | $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ | 65 | $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ |
| 64 | $(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd_h.m4 \ | 66 | $(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd_h.m4 \ |
| 65 | $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/configure.in | 67 | $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/configure.in |
| @@ -602,10 +604,11 @@ BUILT_SOURCES = arg-nonnull.h c++defs.h $(GETOPT_H) $(STDBOOL_H) \ | |||
| 602 | $(STDDEF_H) $(STDINT_H) stdlib.h sys/stat.h time.h unistd.h \ | 604 | $(STDDEF_H) $(STDINT_H) stdlib.h sys/stat.h time.h unistd.h \ |
| 603 | warn-on-use.h | 605 | warn-on-use.h |
| 604 | EXTRA_DIST = $(top_srcdir)/./arg-nonnull.h $(top_srcdir)/./c++defs.h \ | 606 | EXTRA_DIST = $(top_srcdir)/./arg-nonnull.h $(top_srcdir)/./c++defs.h \ |
| 605 | md5.c md5.h ftoastr.c ftoastr.h filemode.c filemode.h \ | 607 | md5.c md5.h dosname.h ftoastr.c ftoastr.h filemode.c \ |
| 606 | getloadavg.c getopt.c getopt.in.h getopt1.c getopt_int.h \ | 608 | filemode.h getloadavg.c getopt.c getopt.in.h getopt1.c \ |
| 607 | intprops.h mktime-internal.h mktime.c stdbool.in.h stddef.in.h \ | 609 | getopt_int.h intprops.h lstat.c mktime-internal.h mktime.c \ |
| 608 | stdint.in.h stdlib.in.h strftime.c strftime.h sys_stat.in.h \ | 610 | readlink.c stat.c stdbool.in.h stddef.in.h stdint.in.h \ |
| 611 | stdlib.in.h strftime.c strftime.h symlink.c sys_stat.in.h \ | ||
| 609 | time.in.h time_r.c unistd.in.h $(top_srcdir)/./warn-on-use.h | 612 | time.in.h time_r.c unistd.in.h $(top_srcdir)/./warn-on-use.h |
| 610 | MOSTLYCLEANDIRS = sys | 613 | MOSTLYCLEANDIRS = sys |
| 611 | MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \ | 614 | MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \ |
| @@ -619,7 +622,8 @@ libgnu_a_SOURCES = dtoastr.c gettext.h ignore-value.h | |||
| 619 | libgnu_a_LIBADD = $(gl_LIBOBJS) | 622 | libgnu_a_LIBADD = $(gl_LIBOBJS) |
| 620 | libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) | 623 | libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) |
| 621 | EXTRA_libgnu_a_SOURCES = md5.c ftoastr.c filemode.c getloadavg.c \ | 624 | EXTRA_libgnu_a_SOURCES = md5.c ftoastr.c filemode.c getloadavg.c \ |
| 622 | getopt.c getopt1.c mktime.c strftime.c time_r.c | 625 | getopt.c getopt1.c lstat.c mktime.c readlink.c stat.c \ |
| 626 | strftime.c symlink.c time_r.c | ||
| 623 | ARG_NONNULL_H = arg-nonnull.h | 627 | ARG_NONNULL_H = arg-nonnull.h |
| 624 | CXXDEFS_H = c++defs.h | 628 | CXXDEFS_H = c++defs.h |
| 625 | WARN_ON_USE_H = warn-on-use.h | 629 | WARN_ON_USE_H = warn-on-use.h |
| @@ -678,9 +682,13 @@ distclean-compile: | |||
| 678 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@ | 682 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@ |
| 679 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ | 683 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ |
| 680 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ | 684 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ |
| 685 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@ | ||
| 681 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ | 686 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ |
| 682 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ | 687 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ |
| 688 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@ | ||
| 689 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@ | ||
| 683 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strftime.Po@am__quote@ | 690 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strftime.Po@am__quote@ |
| 691 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@ | ||
| 684 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ | 692 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ |
| 685 | 693 | ||
| 686 | .c.o: | 694 | .c.o: |
diff --git a/lib/dosname.h b/lib/dosname.h new file mode 100644 index 00000000000..acdd03b156e --- /dev/null +++ b/lib/dosname.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* File names on MS-DOS/Windows systems. | ||
| 2 | |||
| 3 | Copyright (C) 2000-2001, 2004-2006, 2009-2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | |||
| 18 | From Paul Eggert and Jim Meyering. */ | ||
| 19 | |||
| 20 | #ifndef _DOSNAME_H | ||
| 21 | #define _DOSNAME_H | ||
| 22 | |||
| 23 | #if (defined _WIN32 || defined __WIN32__ || \ | ||
| 24 | defined __MSDOS__ || defined __CYGWIN__ || \ | ||
| 25 | defined __EMX__ || defined __DJGPP__) | ||
| 26 | /* This internal macro assumes ASCII, but all hosts that support drive | ||
| 27 | letters use ASCII. */ | ||
| 28 | # define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ | ||
| 29 | <= 'z' - 'a') | ||
| 30 | # define FILE_SYSTEM_PREFIX_LEN(Filename) \ | ||
| 31 | (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) | ||
| 32 | # ifndef __CYGWIN__ | ||
| 33 | # define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 | ||
| 34 | # endif | ||
| 35 | # define ISSLASH(C) ((C) == '/' || (C) == '\\') | ||
| 36 | #else | ||
| 37 | # define FILE_SYSTEM_PREFIX_LEN(Filename) 0 | ||
| 38 | # define ISSLASH(C) ((C) == '/') | ||
| 39 | #endif | ||
| 40 | |||
| 41 | #ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE | ||
| 42 | # define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE | ||
| 46 | # define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) | ||
| 47 | # else | ||
| 48 | # define IS_ABSOLUTE_FILE_NAME(F) \ | ||
| 49 | (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) | ||
| 50 | #endif | ||
| 51 | #define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) | ||
| 52 | |||
| 53 | #endif /* DOSNAME_H_ */ | ||
diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 53cc3815254..b5fd4a358db 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | # the same distribution terms as the rest of that program. | 9 | # the same distribution terms as the rest of that program. |
| 10 | # | 10 | # |
| 11 | # Generated by gnulib-tool. | 11 | # Generated by gnulib-tool. |
| 12 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value mktime strftime sys_stat | 12 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value lstat mktime readlink strftime symlink sys_stat |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | MOSTLYCLEANFILES += core *.stackdump | 15 | MOSTLYCLEANFILES += core *.stackdump |
| @@ -78,6 +78,13 @@ EXTRA_libgnu_a_SOURCES += md5.c | |||
| 78 | 78 | ||
| 79 | ## end gnulib module crypto/md5 | 79 | ## end gnulib module crypto/md5 |
| 80 | 80 | ||
| 81 | ## begin gnulib module dosname | ||
| 82 | |||
| 83 | |||
| 84 | EXTRA_DIST += dosname.h | ||
| 85 | |||
| 86 | ## end gnulib module dosname | ||
| 87 | |||
| 81 | ## begin gnulib module dtoastr | 88 | ## begin gnulib module dtoastr |
| 82 | 89 | ||
| 83 | libgnu_a_SOURCES += dtoastr.c | 90 | libgnu_a_SOURCES += dtoastr.c |
| @@ -151,6 +158,15 @@ EXTRA_DIST += intprops.h | |||
| 151 | 158 | ||
| 152 | ## end gnulib module intprops | 159 | ## end gnulib module intprops |
| 153 | 160 | ||
| 161 | ## begin gnulib module lstat | ||
| 162 | |||
| 163 | |||
| 164 | EXTRA_DIST += lstat.c | ||
| 165 | |||
| 166 | EXTRA_libgnu_a_SOURCES += lstat.c | ||
| 167 | |||
| 168 | ## end gnulib module lstat | ||
| 169 | |||
| 154 | ## begin gnulib module mktime | 170 | ## begin gnulib module mktime |
| 155 | 171 | ||
| 156 | 172 | ||
| @@ -160,6 +176,24 @@ EXTRA_libgnu_a_SOURCES += mktime.c | |||
| 160 | 176 | ||
| 161 | ## end gnulib module mktime | 177 | ## end gnulib module mktime |
| 162 | 178 | ||
| 179 | ## begin gnulib module readlink | ||
| 180 | |||
| 181 | |||
| 182 | EXTRA_DIST += readlink.c | ||
| 183 | |||
| 184 | EXTRA_libgnu_a_SOURCES += readlink.c | ||
| 185 | |||
| 186 | ## end gnulib module readlink | ||
| 187 | |||
| 188 | ## begin gnulib module stat | ||
| 189 | |||
| 190 | |||
| 191 | EXTRA_DIST += stat.c | ||
| 192 | |||
| 193 | EXTRA_libgnu_a_SOURCES += stat.c | ||
| 194 | |||
| 195 | ## end gnulib module stat | ||
| 196 | |||
| 163 | ## begin gnulib module stdbool | 197 | ## begin gnulib module stdbool |
| 164 | 198 | ||
| 165 | BUILT_SOURCES += $(STDBOOL_H) | 199 | BUILT_SOURCES += $(STDBOOL_H) |
| @@ -344,6 +378,15 @@ EXTRA_libgnu_a_SOURCES += strftime.c | |||
| 344 | 378 | ||
| 345 | ## end gnulib module strftime | 379 | ## end gnulib module strftime |
| 346 | 380 | ||
| 381 | ## begin gnulib module symlink | ||
| 382 | |||
| 383 | |||
| 384 | EXTRA_DIST += symlink.c | ||
| 385 | |||
| 386 | EXTRA_libgnu_a_SOURCES += symlink.c | ||
| 387 | |||
| 388 | ## end gnulib module symlink | ||
| 389 | |||
| 347 | ## begin gnulib module sys_stat | 390 | ## begin gnulib module sys_stat |
| 348 | 391 | ||
| 349 | BUILT_SOURCES += sys/stat.h | 392 | BUILT_SOURCES += sys/stat.h |
diff --git a/lib/lstat.c b/lib/lstat.c new file mode 100644 index 00000000000..b26065ede28 --- /dev/null +++ b/lib/lstat.c | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* Work around a bug of lstat on some systems | ||
| 2 | |||
| 3 | Copyright (C) 1997-2006, 2008-2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* written by Jim Meyering */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #if !HAVE_LSTAT | ||
| 23 | /* On systems that lack symlinks, our replacement <sys/stat.h> already | ||
| 24 | defined lstat as stat, so there is nothing further to do other than | ||
| 25 | avoid an empty file. */ | ||
| 26 | typedef int dummy; | ||
| 27 | #else /* HAVE_LSTAT */ | ||
| 28 | |||
| 29 | /* Get the original definition of lstat. It might be defined as a macro. */ | ||
| 30 | # define __need_system_sys_stat_h | ||
| 31 | # include <sys/types.h> | ||
| 32 | # include <sys/stat.h> | ||
| 33 | # undef __need_system_sys_stat_h | ||
| 34 | |||
| 35 | static inline int | ||
| 36 | orig_lstat (const char *filename, struct stat *buf) | ||
| 37 | { | ||
| 38 | return lstat (filename, buf); | ||
| 39 | } | ||
| 40 | |||
| 41 | /* Specification. */ | ||
| 42 | # include <sys/stat.h> | ||
| 43 | |||
| 44 | # include <string.h> | ||
| 45 | # include <errno.h> | ||
| 46 | |||
| 47 | /* lstat works differently on Linux and Solaris systems. POSIX (see | ||
| 48 | `pathname resolution' in the glossary) requires that programs like | ||
| 49 | `ls' take into consideration the fact that FILE has a trailing slash | ||
| 50 | when FILE is a symbolic link. On Linux and Solaris 10 systems, the | ||
| 51 | lstat function already has the desired semantics (in treating | ||
| 52 | `lstat ("symlink/", sbuf)' just like `lstat ("symlink/.", sbuf)', | ||
| 53 | but on Solaris 9 and earlier it does not. | ||
| 54 | |||
| 55 | If FILE has a trailing slash and specifies a symbolic link, | ||
| 56 | then use stat() to get more info on the referent of FILE. | ||
| 57 | If the referent is a non-directory, then set errno to ENOTDIR | ||
| 58 | and return -1. Otherwise, return stat's result. */ | ||
| 59 | |||
| 60 | int | ||
| 61 | rpl_lstat (const char *file, struct stat *sbuf) | ||
| 62 | { | ||
| 63 | size_t len; | ||
| 64 | int lstat_result = orig_lstat (file, sbuf); | ||
| 65 | |||
| 66 | if (lstat_result != 0) | ||
| 67 | return lstat_result; | ||
| 68 | |||
| 69 | /* This replacement file can blindly check against '/' rather than | ||
| 70 | using the ISSLASH macro, because all platforms with '\\' either | ||
| 71 | lack symlinks (mingw) or have working lstat (cygwin) and thus do | ||
| 72 | not compile this file. 0 len should have already been filtered | ||
| 73 | out above, with a failure return of ENOENT. */ | ||
| 74 | len = strlen (file); | ||
| 75 | if (file[len - 1] != '/' || S_ISDIR (sbuf->st_mode)) | ||
| 76 | return 0; | ||
| 77 | |||
| 78 | /* At this point, a trailing slash is only permitted on | ||
| 79 | symlink-to-dir; but it should have found information on the | ||
| 80 | directory, not the symlink. Call stat() to get info about the | ||
| 81 | link's referent. Our replacement stat guarantees valid results, | ||
| 82 | even if the symlink is not pointing to a directory. */ | ||
| 83 | if (!S_ISLNK (sbuf->st_mode)) | ||
| 84 | { | ||
| 85 | errno = ENOTDIR; | ||
| 86 | return -1; | ||
| 87 | } | ||
| 88 | return stat (file, sbuf); | ||
| 89 | } | ||
| 90 | |||
| 91 | #endif /* HAVE_LSTAT */ | ||
diff --git a/lib/readlink.c b/lib/readlink.c new file mode 100644 index 00000000000..35d045b9a12 --- /dev/null +++ b/lib/readlink.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* Stub for readlink(). | ||
| 2 | Copyright (C) 2003-2007, 2009-2011 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include <unistd.h> | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | #include <string.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | |||
| 26 | #if !HAVE_READLINK | ||
| 27 | |||
| 28 | /* readlink() substitute for systems that don't have a readlink() function, | ||
| 29 | such as DJGPP 2.03 and mingw32. */ | ||
| 30 | |||
| 31 | ssize_t | ||
| 32 | readlink (const char *name, char *buf _GL_UNUSED, | ||
| 33 | size_t bufsize _GL_UNUSED) | ||
| 34 | { | ||
| 35 | struct stat statbuf; | ||
| 36 | |||
| 37 | /* In general we should use lstat() here, not stat(). But on platforms | ||
| 38 | without symbolic links, lstat() - if it exists - would be equivalent to | ||
| 39 | stat(), therefore we can use stat(). This saves us a configure check. */ | ||
| 40 | if (stat (name, &statbuf) >= 0) | ||
| 41 | errno = EINVAL; | ||
| 42 | return -1; | ||
| 43 | } | ||
| 44 | |||
| 45 | #else /* HAVE_READLINK */ | ||
| 46 | |||
| 47 | # undef readlink | ||
| 48 | |||
| 49 | /* readlink() wrapper that uses correct types, for systems like cygwin | ||
| 50 | 1.5.x where readlink returns int, and which rejects trailing slash, | ||
| 51 | for Solaris 9. */ | ||
| 52 | |||
| 53 | ssize_t | ||
| 54 | rpl_readlink (const char *name, char *buf, size_t bufsize) | ||
| 55 | { | ||
| 56 | # if READLINK_TRAILING_SLASH_BUG | ||
| 57 | size_t len = strlen (name); | ||
| 58 | if (len && name[len - 1] == '/') | ||
| 59 | { | ||
| 60 | /* Even if name without the slash is a symlink to a directory, | ||
| 61 | both lstat() and stat() must resolve the trailing slash to | ||
| 62 | the directory rather than the symlink. We can therefore | ||
| 63 | safely use stat() to distinguish between EINVAL and | ||
| 64 | ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat(). */ | ||
| 65 | struct stat st; | ||
| 66 | if (stat (name, &st) == 0) | ||
| 67 | errno = EINVAL; | ||
| 68 | return -1; | ||
| 69 | } | ||
| 70 | # endif /* READLINK_TRAILING_SLASH_BUG */ | ||
| 71 | return readlink (name, buf, bufsize); | ||
| 72 | } | ||
| 73 | |||
| 74 | #endif /* HAVE_READLINK */ | ||
diff --git a/lib/stat.c b/lib/stat.c new file mode 100644 index 00000000000..cbc9100fd4d --- /dev/null +++ b/lib/stat.c | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* Work around platform bugs in stat. | ||
| 2 | Copyright (C) 2009-2011 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* written by Eric Blake */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | /* Get the original definition of stat. It might be defined as a macro. */ | ||
| 22 | #define __need_system_sys_stat_h | ||
| 23 | #include <sys/types.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | #undef __need_system_sys_stat_h | ||
| 26 | |||
| 27 | static inline int | ||
| 28 | orig_stat (const char *filename, struct stat *buf) | ||
| 29 | { | ||
| 30 | return stat (filename, buf); | ||
| 31 | } | ||
| 32 | |||
| 33 | /* Specification. */ | ||
| 34 | #include <sys/stat.h> | ||
| 35 | |||
| 36 | #include <errno.h> | ||
| 37 | #include <limits.h> | ||
| 38 | #include <stdbool.h> | ||
| 39 | #include <string.h> | ||
| 40 | #include "dosname.h" | ||
| 41 | |||
| 42 | /* Store information about NAME into ST. Work around bugs with | ||
| 43 | trailing slashes. Mingw has other bugs (such as st_ino always | ||
| 44 | being 0 on success) which this wrapper does not work around. But | ||
| 45 | at least this implementation provides the ability to emulate fchdir | ||
| 46 | correctly. */ | ||
| 47 | |||
| 48 | int | ||
| 49 | rpl_stat (char const *name, struct stat *st) | ||
| 50 | { | ||
| 51 | int result = orig_stat (name, st); | ||
| 52 | #if REPLACE_FUNC_STAT_FILE | ||
| 53 | /* Solaris 9 mistakenly succeeds when given a non-directory with a | ||
| 54 | trailing slash. */ | ||
| 55 | if (result == 0 && !S_ISDIR (st->st_mode)) | ||
| 56 | { | ||
| 57 | size_t len = strlen (name); | ||
| 58 | if (ISSLASH (name[len - 1])) | ||
| 59 | { | ||
| 60 | errno = ENOTDIR; | ||
| 61 | return -1; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | #endif /* REPLACE_FUNC_STAT_FILE */ | ||
| 65 | #if REPLACE_FUNC_STAT_DIR | ||
| 66 | if (result == -1 && errno == ENOENT) | ||
| 67 | { | ||
| 68 | /* Due to mingw's oddities, there are some directories (like | ||
| 69 | c:\) where stat() only succeeds with a trailing slash, and | ||
| 70 | other directories (like c:\windows) where stat() only | ||
| 71 | succeeds without a trailing slash. But we want the two to be | ||
| 72 | synonymous, since chdir() manages either style. Likewise, Mingw also | ||
| 73 | reports ENOENT for names longer than PATH_MAX, when we want | ||
| 74 | ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR. | ||
| 75 | Fortunately, mingw PATH_MAX is small enough for stack | ||
| 76 | allocation. */ | ||
| 77 | char fixed_name[PATH_MAX + 1] = {0}; | ||
| 78 | size_t len = strlen (name); | ||
| 79 | bool check_dir = false; | ||
| 80 | if (PATH_MAX <= len) | ||
| 81 | errno = ENAMETOOLONG; | ||
| 82 | else if (len) | ||
| 83 | { | ||
| 84 | strcpy (fixed_name, name); | ||
| 85 | if (ISSLASH (fixed_name[len - 1])) | ||
| 86 | { | ||
| 87 | check_dir = true; | ||
| 88 | while (len && ISSLASH (fixed_name[len - 1])) | ||
| 89 | fixed_name[--len] = '\0'; | ||
| 90 | if (!len) | ||
| 91 | fixed_name[0] = '/'; | ||
| 92 | } | ||
| 93 | else | ||
| 94 | fixed_name[len++] = '/'; | ||
| 95 | result = orig_stat (fixed_name, st); | ||
| 96 | if (result == 0 && check_dir && !S_ISDIR (st->st_mode)) | ||
| 97 | { | ||
| 98 | result = -1; | ||
| 99 | errno = ENOTDIR; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | #endif /* REPLACE_FUNC_STAT_DIR */ | ||
| 104 | return result; | ||
| 105 | } | ||
diff --git a/lib/symlink.c b/lib/symlink.c new file mode 100644 index 00000000000..2896cc9655b --- /dev/null +++ b/lib/symlink.c | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* Stub for symlink(). | ||
| 2 | Copyright (C) 2009-2011 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include <unistd.h> | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | #include <string.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | |||
| 26 | |||
| 27 | #if HAVE_SYMLINK | ||
| 28 | |||
| 29 | # undef symlink | ||
| 30 | |||
| 31 | /* Create a symlink, but reject trailing slash. */ | ||
| 32 | int | ||
| 33 | rpl_symlink (char const *contents, char const *name) | ||
| 34 | { | ||
| 35 | size_t len = strlen (name); | ||
| 36 | if (len && name[len - 1] == '/') | ||
| 37 | { | ||
| 38 | struct stat st; | ||
| 39 | if (lstat (name, &st) == 0) | ||
| 40 | errno = EEXIST; | ||
| 41 | return -1; | ||
| 42 | } | ||
| 43 | return symlink (contents, name); | ||
| 44 | } | ||
| 45 | |||
| 46 | #else /* !HAVE_SYMLINK */ | ||
| 47 | |||
| 48 | /* The system does not support symlinks. */ | ||
| 49 | int | ||
| 50 | symlink (char const *contents _GL_UNUSED, | ||
| 51 | char const *name _GL_UNUSED) | ||
| 52 | { | ||
| 53 | errno = ENOSYS; | ||
| 54 | return -1; | ||
| 55 | } | ||
| 56 | |||
| 57 | #endif /* !HAVE_SYMLINK */ | ||