Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/unlink-directory.c @ 9532:00cd9aacd03c HEAD
Updated copyright notices to include year 2010.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 25 Jan 2010 01:18:58 +0200 |
parents | 58630516a9d4 |
children |
rev | line source |
---|---|
9532
00cd9aacd03c
Updated copyright notices to include year 2010.
Timo Sirainen <tss@iki.fi>
parents:
9374
diff
changeset
|
1 /* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */ |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
2 |
0 | 3 /* |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
4 There's a bit tricky race condition with recursive deletion. |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
5 Suppose this happens: |
0 | 6 |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
7 lstat(dir, ..) -> OK, it's a directory |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
8 // attacker deletes dir, replaces it with symlink to / |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
9 opendir(dir) -> it actually opens / |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
10 |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
11 Most portable solution is to lstat() the dir, chdir() there, then check |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
12 that "." points to same device/inode as we originally lstat()ed. This |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
13 assumes that the device has usable inodes, most should except for some NFS |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
14 implementations. |
0 | 15 |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
16 Filesystems may also reassign a deleted inode to another file |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
17 immediately after it's deleted. That in theory makes it possible to exploit |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
18 this race to delete the new directory. However, the new inode is quite |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
19 unlikely to be any important directory, and attacker is quite unlikely to |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
20 find out which directory even got the inode. Maybe with some setuid program |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
21 or daemon interaction something could come out of it though. |
0 | 22 |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
23 Another less portable solution is to fchdir(open(dir, O_NOFOLLOW)). |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
24 This should be completely safe. |
0 | 25 |
1741
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
26 The actual file deletion also has to be done relative to current |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
27 directory, to make sure that the whole directory structure isn't replaced |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
28 with another one while we're deleting it. Going back to parent directory |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
29 isn't too easy either - safest (and easiest) way again is to open() the |
9df02b1533b3
Removed most of the license comments from src/lib/*.c. It's just fine to
Timo Sirainen <tss@iki.fi>
parents:
1453
diff
changeset
|
30 directory and fchdir() back there. |
0 | 31 */ |
32 | |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
33 #define _GNU_SOURCE /* for O_NOFOLLOW with Linux */ |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
34 |
0 | 35 #include "lib.h" |
4011
323c09be5f00
Moved dupliated close_save_errno() code to public close_keep_errno() function.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3863
diff
changeset
|
36 #include "close-keep-errno.h" |
0 | 37 #include "unlink-directory.h" |
38 | |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
39 #include <fcntl.h> |
0 | 40 #include <unistd.h> |
41 #include <dirent.h> | |
42 #include <sys/stat.h> | |
43 | |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
44 static int unlink_directory_r(const char *dir) |
0 | 45 { |
46 DIR *dirp; | |
47 struct dirent *d; | |
48 struct stat st; | |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
49 int dir_fd, old_errno; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
50 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
51 #ifdef O_NOFOLLOW |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
52 dir_fd = open(dir, O_RDONLY | O_NOFOLLOW); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
53 if (dir_fd == -1) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
54 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
55 #else |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
56 struct stat st2; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
57 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
58 if (lstat(dir, &st) < 0) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
59 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
60 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
61 if (!S_ISDIR(st.st_mode)) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
62 errno = ENOTDIR; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
63 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
64 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
65 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
66 dir_fd = open(dir, O_RDONLY); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
67 if (dir_fd == -1) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
68 return -1; |
0 | 69 |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
70 if (fstat(dir_fd, &st2) < 0) { |
4011
323c09be5f00
Moved dupliated close_save_errno() code to public close_keep_errno() function.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3863
diff
changeset
|
71 close_keep_errno(dir_fd); |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
72 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
73 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
74 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
75 if (st.st_ino != st2.st_ino || |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
76 !CMP_DEV_T(st.st_dev, st2.st_dev)) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
77 /* directory was just replaced with something else. */ |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
78 (void)close(dir_fd); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
79 errno = ENOTDIR; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
80 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
81 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
82 #endif |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
83 if (fchdir(dir_fd) < 0) { |
4011
323c09be5f00
Moved dupliated close_save_errno() code to public close_keep_errno() function.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3863
diff
changeset
|
84 close_keep_errno(dir_fd); |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
85 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
86 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
87 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
88 dirp = opendir("."); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
89 if (dirp == NULL) { |
4011
323c09be5f00
Moved dupliated close_save_errno() code to public close_keep_errno() function.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
3863
diff
changeset
|
90 close_keep_errno(dir_fd); |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
91 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
92 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
93 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
94 errno = 0; |
0 | 95 while ((d = readdir(dirp)) != NULL) { |
96 if (d->d_name[0] == '.' && | |
97 (d->d_name[1] == '\0' || | |
98 (d->d_name[1] == '.' && d->d_name[2] == '\0'))) { | |
99 /* skip . and .. */ | |
100 continue; | |
101 } | |
102 | |
1453 | 103 if (unlink(d->d_name) < 0 && errno != ENOENT) { |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
104 old_errno = errno; |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
105 |
1453 | 106 if (lstat(d->d_name, &st) < 0) { |
107 if (errno != ENOENT) | |
108 break; | |
109 errno = 0; | |
110 } else if (S_ISDIR(st.st_mode)) { | |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
111 if (unlink_directory_r(d->d_name) < 0) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
112 if (errno != ENOENT) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
113 break; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
114 errno = 0; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
115 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
116 if (fchdir(dir_fd) < 0) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
117 break; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
118 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
119 if (rmdir(d->d_name) < 0) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
120 if (errno != ENOENT) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
121 break; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
122 errno = 0; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
123 } |
0 | 124 } else { |
1453 | 125 /* so it wasn't a directory */ |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
126 errno = old_errno; |
9374
58630516a9d4
unlink_directory(): Log if unlink()ing some file fails.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
127 i_error("unlink(%s/%s) failed: %m", |
58630516a9d4
unlink_directory(): Log if unlink()ing some file fails.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
128 dir, d->d_name); |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
129 break; |
0 | 130 } |
131 } | |
132 } | |
1452
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
133 old_errno = errno; |
0 | 134 |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
135 (void)close(dir_fd); |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
817
diff
changeset
|
136 if (closedir(dirp) < 0) |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
817
diff
changeset
|
137 return -1; |
0 | 138 |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
139 if (old_errno != 0) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
140 errno = old_errno; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
141 return -1; |
822
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
817
diff
changeset
|
142 } |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
817
diff
changeset
|
143 |
5101f8bf2368
If used base/login directories exist already, make sure they're with correct
Timo Sirainen <tss@iki.fi>
parents:
817
diff
changeset
|
144 return 0; |
0 | 145 } |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
146 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
147 int unlink_directory(const char *dir, bool unlink_dir) |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
148 { |
1452
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
149 int fd, ret, old_errno; |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
150 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
151 fd = open(".", O_RDONLY); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
152 if (fd == -1) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
153 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
154 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
155 ret = unlink_directory_r(dir); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
156 if (ret < 0 && errno == ENOENT) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
157 ret = 0; |
1452
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
158 old_errno = errno; |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
159 |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
160 if (fchdir(fd) < 0) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
161 i_fatal("unlink_directory(%s): " |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
162 "Can't fchdir() back to our original dir: %m", dir); |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
163 } |
1249 | 164 (void)close(fd); |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
165 |
1452
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
166 if (ret < 0) { |
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
167 errno = old_errno; |
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
168 return -1; |
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
169 } |
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
170 |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
171 if (unlink_dir) { |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
172 if (rmdir(dir) < 0 && errno != ENOENT) |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
173 return -1; |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
174 } |
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
175 |
1452
22495f001acc
Returned errno was often wrong.
Timo Sirainen <tss@iki.fi>
parents:
1249
diff
changeset
|
176 return 0; |
1243
478471737964
unlink_directory() is now (hopefully) race-condition free.
Timo Sirainen <tss@iki.fi>
parents:
822
diff
changeset
|
177 } |