Mercurial > hg > octave-kai > gnulib-hg
annotate lib/chdir-safer.c @ 17160:72f4bab621be
fts: introduce FTS_VERBATIM
This gives clients the option to disable stripping of trailing slashes
from input path names during fts_open initialization.
The recent change v0.0-7611-g3a9002d that made fts_open strip trailing
slashes from input path names had a negative impact on findutils that
relies on the old fts_open behavior to implement POSIX requirement that
each path operand of the find utility shall be evaluated unaltered as it
was provided, including all trailing slash characters.
* lib/fts_.h (FTS_VERBATIM): New bit flag.
(FTS_OPTIONMASK, FTS_NAMEONLY, FTS_STOP): Adjust.
* lib/fts.c (fts_open): Honor it.
author | Dmitry V. Levin <ldv@altlinux.org> |
---|---|
date | Sun, 18 Nov 2012 04:40:18 +0400 |
parents | 8250f2777afc |
children | e542fd46ad6f |
rev | line source |
---|---|
6527 | 1 /* much like chdir(2), but safer |
2 | |
16201
8250f2777afc
maint: update all copyright year number ranges
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
3 Copyright (C) 2005-2006, 2008-2012 Free Software Foundation, Inc. |
6527 | 4 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
6527 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
8 (at your option) any later version. |
6527 | 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 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
6527 | 17 |
18 /* written by Jim Meyering */ | |
19 | |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
7225
diff
changeset
|
20 #include <config.h> |
6527 | 21 |
22 #include "chdir-safer.h" | |
23 | |
24 #include <stdbool.h> | |
25 #include <fcntl.h> | |
26 #include <errno.h> | |
27 #include <unistd.h> | |
28 #include <sys/types.h> | |
29 #include <sys/stat.h> | |
6912 | 30 #include "same-inode.h" |
6527 | 31 |
11941 | 32 #ifndef HAVE_READLINK |
33 # define HAVE_READLINK 0 | |
10052
cfa44ca8e7ba
Avoid compile failure on systems without ELOOP (like mingw).
Jim Meyering <meyering@redhat.com>
parents:
9309
diff
changeset
|
34 #endif |
cfa44ca8e7ba
Avoid compile failure on systems without ELOOP (like mingw).
Jim Meyering <meyering@redhat.com>
parents:
9309
diff
changeset
|
35 |
6527 | 36 /* Like chdir, but fail if DIR is a symbolic link to a directory (or |
13616
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
37 similar funny business). This avoids a minor race condition |
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
38 between when a directory is created or statted and when the process |
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
39 chdirs into it. |
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
40 |
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
41 On older systems lacking full support for O_SEARCH, this function |
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
42 can also fail if DIR is not readable. */ |
6527 | 43 int |
44 chdir_no_follow (char const *dir) | |
45 { | |
46 int result = 0; | |
47 int saved_errno; | |
48 int fd = open (dir, | |
13616
acc972b5da60
fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
49 O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK); |
6527 | 50 if (fd < 0) |
51 return -1; | |
52 | |
53 /* If open follows symlinks, lstat DIR and fstat FD to ensure that | |
54 they are the same file; if they are different files, set errno to | |
55 ELOOP (the same value that open uses for symlinks with | |
10054
9612e33b3129
Make chdir-safer.c more efficient on a system with no symlinks.
Jim Meyering <meyering@redhat.com>
parents:
10053
diff
changeset
|
56 O_NOFOLLOW) so the caller can report a failure. |
11941 | 57 Skip this check if HAVE_READLINK == 0, which should be the case |
10054
9612e33b3129
Make chdir-safer.c more efficient on a system with no symlinks.
Jim Meyering <meyering@redhat.com>
parents:
10053
diff
changeset
|
58 on any system that lacks symlink support. */ |
11941 | 59 if (HAVE_READLINK && ! HAVE_WORKING_O_NOFOLLOW) |
6527 | 60 { |
61 struct stat sb1; | |
62 result = lstat (dir, &sb1); | |
63 if (result == 0) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
64 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
65 struct stat sb2; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
66 result = fstat (fd, &sb2); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
67 if (result == 0 && ! SAME_INODE (sb1, sb2)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
68 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
69 errno = ELOOP; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
70 result = -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
71 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11941
diff
changeset
|
72 } |
6527 | 73 } |
74 | |
75 if (result == 0) | |
76 result = fchdir (fd); | |
77 | |
78 saved_errno = errno; | |
79 close (fd); | |
80 errno = saved_errno; | |
81 return result; | |
82 } |