Hash :
d4c637e5
Author :
Date :
2020-08-15T16:54:17
Support compiling without -loldnames on native Windows. * m4/gnulib-common.m4 (GL_MDA_DEFINES, _GL_MDA_DEFINES): New macros. * m4/chown.m4 (AC_FUNC_CHOWN): In the test programs, use GL_MDA_DEFINES. (gl_FUNC_CHOWN, gl_FUNC_CHOWN_FOLLOWS_SYMLINK): Likewise. * m4/dup.m4 (gl_FUNC_DUP): Likewise. * m4/dup2.m4 (gl_FUNC_DUP2): Likewise. * m4/fchdir.m4 (gl_FUNC_FCHDIR): Likewise. * m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Likewise. * m4/fchownat.m4 (gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG): Likewise. * m4/fcntl-o.m4 (gl_FCNTL_O_FLAGS): Likewise. * m4/fcntl.m4 (gl_FUNC_FCNTL): Likewise. * m4/fdopen.m4 (gl_FUNC_FDOPEN): Likewise. * m4/fdopendir.m4 (gl_FUNC_FDOPENDIR): Likewise. * m4/fflush.m4 (gl_FUNC_FFLUSH_STDIN): Likewise. * m4/fopen.m4 (gl_FUNC_FOPEN_GNU): Likewise. * m4/freopen.m4 (gl_FUNC_FREOPEN): Likewise. * m4/futimens.m4 (gl_FUNC_FUTIMENS): Likewise. * m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Likewise. * m4/getcwd-path-max.m4 (gl_FUNC_GETCWD_PATH_MAX): Likewise. * m4/getcwd.m4 (gl_FUNC_GETCWD_NULL, gl_FUNC_GETCWD_SIGNATURE): Likewise. * m4/getdtablesize.m4 (gl_FUNC_GETDTABLESIZE): Likewise. * m4/linkat.m4 (gl_FUNC_LINKAT): Likewise. * m4/lseek.m4 (gl_FUNC_LSEEK): Likewise. * m4/mkdir.m4 (gl_FUNC_MKDIR): Likewise. * m4/mkstemp.m4 (gl_FUNC_MKSTEMP): Likewise. * m4/mktime.m4 (gl_FUNC_MKTIME_WORKS): Likewise. * m4/open-slash.m4 (gl_OPEN_TRAILING_SLASH_BUG): Likewise. * m4/poll.m4 (gl_FUNC_POLL): Likewise. * m4/posix_spawn.m4 (gl_POSIX_SPAWN_WORKS): Likewise. * m4/pread.m4 (gl_FUNC_PREAD): Likewise. * m4/pselect.m4 (gl_FUNC_PSELECT): Likewise. * m4/pthread_sigmask.m4 (gl_FUNC_PTHREAD_SIGMASK): Likewise. * m4/ptsname_r.m4 (gl_PREREQ_PTSNAME_R): Likewise. * m4/putenv.m4 (gl_FUNC_PUTENV): Likewise. * m4/pwrite.m4 (gl_FUNC_PWRITE): Likewise. * m4/rename.m4 (gl_FUNC_RENAME): Likewise. * m4/rmdir-errno.m4 (gl_FUNC_RMDIR_NOTEMPTY): Likewise. * m4/rmdir.m4 (gl_FUNC_RMDIR): Likewise. * m4/select.m4 (gl_FUNC_SELECT): Likewise. * m4/setenv.m4 (gl_FUNC_UNSETENV): Likewise. * m4/strncat.m4 (gl_FUNC_STRNCAT): Likewise. * m4/ttyname_r.m4 (gl_FUNC_TTYNAME_R): Likewise. * m4/unlink-busy.m4 (gl_FUNC_UNLINK_BUSY_TEXT): Likewise. * m4/unlink.m4 (gl_FUNC_UNLINK): Likewise. * m4/utimens.m4 (gl_UTIMENS): Likewise. * m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise. * m4/utimes.m4 (gl_FUNC_UTIMES): Likewise. * m4/canonicalize.m4 (gl_CANONICALIZE_LGPL): On native Windows, don't test for getcwd. * m4/utime.m4 (gl_FUNC_UTIME): On native Windows, don't test for utime. * m4/wcsdup.m4 (gl_FUNC_WCSDUP): To test for wcsdup, use a test program with GL_MDA_DEFINES. * lib/c++defs.h (_GL_CXXALIAS_MDA): New macro. * lib/fcntl.in.h (creat, open): On native Windows, use the underscore- prefixed symbol. * lib/search.in.h (lfind, lsearch): Likewise. * lib/stdio.in.h (fcloseall, fdopen, fileno, getw, putw, tempnam): Likewise. * lib/stdlib.in.h (ecvt, fcvt, gcvt, mktemp, putenv): Likewise. * lib/string.in.h (memccpy, strdup): Likewise. * lib/sys_stat.in.h (chmod, umask): Likewise. * lib/time.in.h (tzset): Likewise. * lib/unistd.in.h (access, chdir, close, dup, dup2, execl, execle, execlp, execv, execve, execvp, execvpe, getcwd, getpid, isatty, lseek, read, rmdir, swab, unlink, write): Likewise. * lib/utime.in.h (utime): Likewise. * lib/wchar.in.h (wcsdup): Likewise. * lib/math.in.h (j0, j1, jn, y0, y1, yn): Likewise. (isfinite, isinf, isnan, signbit): On native Windows, don't define as an rpl_-prefixed macro. * lib/canonicalize-lgpl.c (__getcwd): On native Windows, use _getcwd. * lib/close.c (close_nothrow): On native Windows, use _close. * lib/creat.c (orig_creat): On native Windows, use _creat. * lib/dup.c (dup_nothrow): On native Windows, use _dup. * lib/dup2.c (dup2_nothrow): Use _dup2. * lib/fdopen.c (fdopen_nothrow): On native Windows, use _fdopen. * lib/getcwd-lgpl.c: On native Windows, use _getcwd. * lib/getcwd.c (getcwd_nothrow): Use _getcwd also on mingw. * lib/open.c (orig_open): On native Windows, use _open. * lib/read.c (read_nothrow): Use _read. * lib/rmdir.c: On native Windows, use _rmdir. * lib/unlink.c: On native Windows, use _unlink. * lib/write.c (write_nothrow): Use _write. * lib/sys_select.in.h (close): With clang, don't attach a warning on an undefined symbol. * lib/sys_socket.in.h (close): Likewise. * lib/sys_time.in.h (close): Likewise. * tests/test-spawn-pipe-child.c: On native Windows, use _fdopen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/* Work around unlink bugs.
Copyright (C) 2009-2020 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 <https://www.gnu.org/licenses/>. */
#include <config.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "filename.h"
#undef unlink
#if defined _WIN32 && !defined __CYGWIN__
# define unlink _unlink
#endif
/* Remove file NAME.
Return 0 if successful, -1 if not. */
int
rpl_unlink (char const *name)
{
/* Work around Solaris 9 bug where unlink("file/") succeeds. */
size_t len = strlen (name);
int result = 0;
if (len && ISSLASH (name[len - 1]))
{
/* We can't unlink(2) something if it doesn't exist. If it does
exist, then it resolved to a directory, due to the trailing
slash, and POSIX requires that the unlink attempt to remove
that directory (which would leave the symlink dangling).
Unfortunately, Solaris 9 is one of the platforms where the
root user can unlink directories, and we don't want to
cripple this behavior on real directories, even if it is
seldom needed (at any rate, it's nicer to let coreutils'
unlink(1) give the correct errno for non-root users). But we
don't know whether name was an actual directory, or a symlink
to a directory; and due to the bug of ignoring trailing
slash, Solaris 9 would end up successfully unlinking the
symlink instead of the directory. Technically, we could use
realpath to find the canonical directory name to attempt
deletion on. But that is a lot of work for a corner case; so
we instead just use an lstat on the shortened name, and
reject symlinks with trailing slashes. The root user of
unlink(1) will just have to live with the rule that they
can't delete a directory via a symlink. */
struct stat st;
result = lstat (name, &st);
if (result == 0)
{
/* Trailing NUL will overwrite the trailing slash. */
char *short_name = malloc (len);
if (!short_name)
return -1;
memcpy (short_name, name, len);
while (len && ISSLASH (short_name[len - 1]))
short_name[--len] = '\0';
if (len && (lstat (short_name, &st) || S_ISLNK (st.st_mode)))
{
free (short_name);
errno = EPERM;
return -1;
}
free (short_name);
}
}
if (!result)
{
#if UNLINK_PARENT_BUG
if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.'
&& (len == 2 || ISSLASH (name[len - 3])))
{
errno = EISDIR; /* could also use EPERM */
return -1;
}
#endif
result = unlink (name);
}
return result;
}