annotate lib/unlink.c @ 14379:2330aac2ae54

maint: adjust cpp indentation to reflect nesting depth I.e., in a block of code that begins with an unnested "#if", put one space between the "#" in column 1 and following token. For example, -#include <sys/vfs.h> +# include <sys/vfs.h> Do this only in .c files that are part of a module I maintain. * lib/linkat.c: Filter through cppi. * lib/nanosleep.c: Likewise. * lib/openat.c: Likewise. * lib/openat-die.c: Likewise. * lib/dup3.c: Likewise. * lib/fchownat.c: Likewise. * lib/flock.c: Likewise. * lib/fsync.c: Likewise. * lib/fts.c: Likewise. * lib/getpass.c: Likewise. * lib/gettimeofday.c: Likewise. * lib/userspec.c: Likewise. * Makefile (sc_cpp_indent_check): New rule, to check this.
author Jim Meyering <meyering@redhat.com>
date Sun, 20 Feb 2011 23:02:43 +0100
parents 97fc9a21a8fb
children 9f47f8c334f2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12040
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
1 /* Work around unlink bugs.
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
2
14079
97fc9a21a8fb maint: update almost all copyright ranges to include 2011
Jim Meyering <meyering@redhat.com>
parents: 13016
diff changeset
3 Copyright (C) 2009-2011 Free Software Foundation, Inc.
12040
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
4
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
8 (at your option) any later version.
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
9
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
13 GNU General Public License for more details.
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
14
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
17
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
18 #include <config.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
19
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
20 #include <unistd.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
21
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
22 #include <errno.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
23 #include <stdlib.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
24 #include <string.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
25 #include <sys/stat.h>
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
26
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
27 #undef unlink
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
28
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
29 /* Remove file NAME.
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
30 Return 0 if successful, -1 if not. */
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
31
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
32 int
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
33 rpl_unlink (char const *name)
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
34 {
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
35 /* Work around Solaris 9 bug where unlink("file/") succeeds. */
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
36 size_t len = strlen (name);
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
37 int result = 0;
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
38 if (len && ISSLASH (name[len - 1]))
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
39 {
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
40 /* We can't unlink(2) something if it doesn't exist. If it does
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
41 exist, then it resolved to a directory, due to the trailing
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
42 slash, and POSIX requires that the unlink attempt to remove
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
43 that directory (which would leave the symlink dangling).
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
44 Unfortunately, Solaris 9 is one of the platforms where the
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
45 root user can unlink directories, and we don't want to
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
46 cripple this behavior on real directories, even if it is
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
47 seldom needed (at any rate, it's nicer to let coreutils'
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
48 unlink(1) give the correct errno for non-root users). But we
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
49 don't know whether name was an actual directory, or a symlink
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
50 to a directory; and due to the bug of ignoring trailing
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
51 slash, Solaris 9 would end up successfully unlinking the
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
52 symlink instead of the directory. Technically, we could use
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
53 realpath to find the canonical directory name to attempt
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
54 deletion on. But that is a lot of work for a corner case; so
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
55 we instead just use an lstat on the shortened name, and
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
56 reject symlinks with trailing slashes. The root user of
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
57 unlink(1) will just have to live with the rule that they
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
58 can't delete a directory via a symlink. */
12040
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
59 struct stat st;
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
60 result = lstat (name, &st);
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
61 if (result == 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
62 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
63 /* Trailing NUL will overwrite the trailing slash. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
64 char *short_name = malloc (len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
65 if (!short_name)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
66 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
67 errno = EPERM;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
68 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
69 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
70 memcpy (short_name, name, len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
71 while (len && ISSLASH (short_name[len - 1]))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
72 short_name[--len] = '\0';
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
73 if (len && (lstat (short_name, &st) || S_ISLNK (st.st_mode)))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
74 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
75 free (short_name);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
76 errno = EPERM;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
77 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
78 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
79 free (short_name);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12040
diff changeset
80 }
12040
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
81 }
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
82 if (!result)
13016
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
83 {
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
84 #if UNLINK_PARENT_BUG
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
85 if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.'
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
86 && (len == 2 || ISSLASH (name[len - 3])))
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
87 {
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
88 errno = EISDIR; /* could also use EPERM */
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
89 return -1;
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
90 }
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
91 #endif
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
92 result = unlink (name);
e627775450ed Work around unlink() bug on MacOS X 10.5.6.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
93 }
12040
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
94 return result;
e8108d5c7ca7 unlink: new module, for Solaris 9 bug
Eric Blake <ebb9@byu.net>
parents:
diff changeset
95 }