Mercurial > hg > octave-kai > gnulib-hg
annotate lib/chdir-safer.c @ 9309:bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 07 Oct 2007 19:14:58 +0200 |
parents | 8a1a9361108c |
children | cfa44ca8e7ba |
rev | line source |
---|---|
6527 | 1 /* much like chdir(2), but safer |
2 | |
3 Copyright (C) 2005, 2006 Free Software Foundation, Inc. | |
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 |
32 /* Like chdir, but fail if DIR is a symbolic link to a directory (or | |
33 similar funny business), or if DIR is not readable. This avoids a | |
34 minor race condition between when a directory is created or statted | |
35 and when the process chdirs into it. */ | |
36 int | |
37 chdir_no_follow (char const *dir) | |
38 { | |
39 int result = 0; | |
40 int saved_errno; | |
41 int fd = open (dir, | |
42 O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK); | |
43 if (fd < 0) | |
44 return -1; | |
45 | |
46 /* If open follows symlinks, lstat DIR and fstat FD to ensure that | |
47 they are the same file; if they are different files, set errno to | |
48 ELOOP (the same value that open uses for symlinks with | |
49 O_NOFOLLOW) so the caller can report a failure. */ | |
50 if (! O_NOFOLLOW) | |
51 { | |
52 struct stat sb1; | |
53 result = lstat (dir, &sb1); | |
54 if (result == 0) | |
55 { | |
56 struct stat sb2; | |
57 result = fstat (fd, &sb2); | |
58 if (result == 0 && ! SAME_INODE (sb1, sb2)) | |
59 { | |
60 errno = ELOOP; | |
61 result = -1; | |
62 } | |
63 } | |
64 } | |
65 | |
66 if (result == 0) | |
67 result = fchdir (fd); | |
68 | |
69 saved_errno = errno; | |
70 close (fd); | |
71 errno = saved_errno; | |
72 return result; | |
73 } |