Revision | 638a23483b40c5b606ee323e6612e7e454e5154b (tree) |
---|---|
Zeit | 2014-12-16 01:53:06 |
Autor | Anthony G. Basile <blueness@gent...> |
Commiter | Bernhard Reutner-Fischer |
mkostemp: fix implementation
mkostemp(char *template, int flags) generates a unique temporary
filename from a template. The flags parameter accepts three of
the same flags as open(2): O_APPEND, O_CLOEXEC, and O_SYNC. The
current implementation of mkostemp(3) does not respect the flags
and in fact confuses the flags with the file mode which should
always be S_IRUSR | S_IWUSR. This patch corrects this issue.
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
@@ -308,7 +308,7 @@ gaih_local(const char *name, const struct gaih_service *service, | ||
308 | 308 | char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path; |
309 | 309 | |
310 | 310 | if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0 |
311 | - || __gen_tempname(buf, __GT_NOCREATE, 0) != 0 | |
311 | + || __gen_tempname(buf, __GT_NOCREATE, 0, 0) != 0 | |
312 | 312 | ) { |
313 | 313 | return -EAI_SYSTEM; |
314 | 314 | } |
@@ -177,7 +177,7 @@ static void brain_damaged_fillrand(unsigned char *buf, unsigned int len) | ||
177 | 177 | __GT_DIR: create a directory with given mode. |
178 | 178 | |
179 | 179 | */ |
180 | -int attribute_hidden __gen_tempname (char *tmpl, int kind, mode_t mode) | |
180 | +int attribute_hidden __gen_tempname (char *tmpl, int kind, int flags, mode_t mode) | |
181 | 181 | { |
182 | 182 | char *XXXXXX; |
183 | 183 | unsigned int i; |
@@ -219,11 +219,11 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind, mode_t mode) | ||
219 | 219 | fd = 0; |
220 | 220 | } |
221 | 221 | case __GT_FILE: |
222 | - fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, mode); | |
222 | + fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode); | |
223 | 223 | break; |
224 | 224 | #if defined __UCLIBC_HAS_LFS__ |
225 | 225 | case __GT_BIGFILE: |
226 | - fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, mode); | |
226 | + fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode); | |
227 | 227 | break; |
228 | 228 | #endif |
229 | 229 | case __GT_DIR: |
@@ -10,7 +10,7 @@ extern int ___path_search (char *tmpl, size_t tmpl_len, const char *dir, | ||
10 | 10 | const char *pfx /*, int try_tmpdir */) attribute_hidden; |
11 | 11 | #define __path_search(tmpl, tmpl_len, dir, pfx, try_tmpdir) ___path_search(tmpl, tmpl_len, dir, pfx) |
12 | 12 | |
13 | -extern int __gen_tempname (char *__tmpl, int __kind, mode_t mode) attribute_hidden; | |
13 | +extern int __gen_tempname (char *__tmpl, int __kind, int flags, mode_t mode) attribute_hidden; | |
14 | 14 | |
15 | 15 | /* The __kind argument to __gen_tempname may be one of: */ |
16 | 16 | #define __GT_FILE 0 /* create a file */ |
@@ -35,7 +35,7 @@ tempnam (const char *dir, const char *pfx) | ||
35 | 35 | if (__path_search (buf, FILENAME_MAX, dir, pfx, 1)) |
36 | 36 | return NULL; |
37 | 37 | |
38 | - if (__gen_tempname (buf, __GT_NOCREATE, 0)) | |
38 | + if (__gen_tempname (buf, __GT_NOCREATE, 0, 0)) | |
39 | 39 | return NULL; |
40 | 40 | |
41 | 41 | return strdup (buf); |
@@ -35,7 +35,7 @@ FILE * tmpfile (void) | ||
35 | 35 | |
36 | 36 | if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) |
37 | 37 | return NULL; |
38 | - fd = __gen_tempname (buf, __GT_FILE, S_IRUSR | S_IWUSR); | |
38 | + fd = __gen_tempname (buf, __GT_FILE, 0, S_IRUSR | S_IWUSR); | |
39 | 39 | if (fd < 0) |
40 | 40 | return NULL; |
41 | 41 |
@@ -40,7 +40,7 @@ tmpnam (char *s) | ||
40 | 40 | 0)) |
41 | 41 | return NULL; |
42 | 42 | |
43 | - if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0), 0)) | |
43 | + if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0, 0), 0)) | |
44 | 44 | return NULL; |
45 | 45 | |
46 | 46 | if (s == NULL) |
@@ -27,7 +27,7 @@ char * tmpnam_r (char *s) | ||
27 | 27 | |
28 | 28 | if (__path_search (s, L_tmpnam, NULL, NULL, 0)) |
29 | 29 | return NULL; |
30 | - if (__gen_tempname (s, __GT_NOCREATE, 0)) | |
30 | + if (__gen_tempname (s, __GT_NOCREATE, 0, 0)) | |
31 | 31 | return NULL; |
32 | 32 | |
33 | 33 | return s; |
@@ -29,7 +29,7 @@ | ||
29 | 29 | (This function comes from OpenBSD.) */ |
30 | 30 | char * mkdtemp (char *template) |
31 | 31 | { |
32 | - if (__gen_tempname (template, __GT_DIR, S_IRUSR | S_IWUSR | S_IXUSR)) | |
32 | + if (__gen_tempname (template, __GT_DIR, 0, S_IRUSR | S_IWUSR | S_IXUSR)) | |
33 | 33 | return NULL; |
34 | 34 | else |
35 | 35 | return template; |
@@ -17,6 +17,7 @@ | ||
17 | 17 | |
18 | 18 | #include <stdio.h> |
19 | 19 | #include <stdlib.h> |
20 | +#include <fcntl.h> | |
20 | 21 | #include "../misc/internals/tempname.h" |
21 | 22 | |
22 | 23 | /* Generate a unique temporary file name from TEMPLATE. |
@@ -26,5 +27,6 @@ | ||
26 | 27 | int |
27 | 28 | mkostemp (char *template, int flags) |
28 | 29 | { |
29 | - return __gen_tempname (template, __GT_FILE, flags); | |
30 | + flags -= flags & O_ACCMODE; /* Remove O_RDONLY, O_WRONLY, and O_RDWR. */ | |
31 | + return __gen_tempname (template, __GT_FILE, flags, S_IRUSR | S_IWUSR); | |
30 | 32 | } |
@@ -27,5 +27,5 @@ | ||
27 | 27 | int |
28 | 28 | mkostemp64 (char *template, int flags) |
29 | 29 | { |
30 | - return __gen_tempname (template, __GT_BIGFILE, flags | O_LARGEFILE); | |
30 | + return __gen_tempname (template, __GT_BIGFILE, flags | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IXUSR); | |
31 | 31 | } |
@@ -26,5 +26,5 @@ | ||
26 | 26 | Then open the file and return a fd. */ |
27 | 27 | int mkstemp (char *template) |
28 | 28 | { |
29 | - return __gen_tempname (template, __GT_FILE, S_IRUSR | S_IWUSR); | |
29 | + return __gen_tempname (template, __GT_FILE, 0, S_IRUSR | S_IWUSR); | |
30 | 30 | } |
@@ -26,5 +26,5 @@ | ||
26 | 26 | Then open the file and return a fd. */ |
27 | 27 | int mkstemp64 (char *template) |
28 | 28 | { |
29 | - return __gen_tempname (template, __GT_BIGFILE, S_IRUSR | S_IWUSR); | |
29 | + return __gen_tempname (template, __GT_BIGFILE, 0, S_IRUSR | S_IWUSR); | |
30 | 30 | } |
@@ -24,7 +24,7 @@ | ||
24 | 24 | * they are replaced with a string that makes the filename unique. */ |
25 | 25 | char *mktemp(char *template) |
26 | 26 | { |
27 | - if (__gen_tempname (template, __GT_NOCREATE, 0) < 0) | |
27 | + if (__gen_tempname (template, __GT_NOCREATE, 0, 0) < 0) | |
28 | 28 | /* We return the null string if we can't find a unique file name. */ |
29 | 29 | template[0] = '\0'; |
30 | 30 |
@@ -336,7 +336,7 @@ sem_open (const char *name, int oflag, ...) | ||
336 | 336 | mempcpy (mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen), |
337 | 337 | "XXXXXX", 7); |
338 | 338 | |
339 | - fd = __gen_tempname (tmpfname, __GT_FILE, mode); | |
339 | + fd = __gen_tempname (tmpfname, __GT_FILE, 0, mode); | |
340 | 340 | if (fd == -1) |
341 | 341 | return SEM_FAILED; |
342 | 342 |
@@ -274,6 +274,8 @@ stdlib/testarc4random | ||
274 | 274 | stdlib/testatexit |
275 | 275 | stdlib/test-canon |
276 | 276 | stdlib/test-canon2 |
277 | +stdlib/test-mkostemp-O_CLOEXEC | |
278 | +stdlib/test-mkostemp-child | |
277 | 279 | stdlib/teston_exit |
278 | 280 | stdlib/teststrtol |
279 | 281 | stdlib/teststrtoq |
@@ -0,0 +1,45 @@ | ||
1 | +#define _XOPEN_SOURCE_EXTENDED | |
2 | +#include <stdio.h> | |
3 | +#include <stdlib.h> | |
4 | +#include <string.h> | |
5 | +#include <unistd.h> | |
6 | +#include <sys/types.h> | |
7 | +#include <sys/stat.h> | |
8 | +#include <fcntl.h> | |
9 | +#include <sys/wait.h> | |
10 | +#include <errno.h> | |
11 | + | |
12 | +#if !defined __ARCH_USE_MMU__ | |
13 | +# define fork vfork | |
14 | +#endif | |
15 | + | |
16 | +int main(int argc, char *argv[]) { | |
17 | + int fd, status; | |
18 | + char buff[5]; | |
19 | + char template[] = "/tmp/test-mkostemp.XXXXXX"; | |
20 | + | |
21 | + fd = mkostemp(template, O_CLOEXEC); | |
22 | + unlink(template); | |
23 | + | |
24 | + snprintf(buff, 5, "%d", fd); | |
25 | + | |
26 | + if(!fork()) | |
27 | + if(execl("./test-mkostemp-child", "test-mkostemp-child", buff, NULL) == -1) | |
28 | + exit(EXIT_FAILURE); | |
29 | + | |
30 | + wait(&status); | |
31 | + | |
32 | + memset(buff, 0, 5); | |
33 | + lseek(fd, 0, SEEK_SET); | |
34 | + errno = 0; | |
35 | + if(read(fd, buff, 5) == -1) | |
36 | + exit(EXIT_FAILURE); | |
37 | + | |
38 | + if(!strncmp(buff, "test", 5)) | |
39 | + exit(EXIT_FAILURE); | |
40 | + else | |
41 | + exit(EXIT_SUCCESS); | |
42 | + | |
43 | + close(fd); | |
44 | + exit(EXIT_SUCCESS); | |
45 | +} |
@@ -0,0 +1,22 @@ | ||
1 | +#include <stdio.h> | |
2 | +#include <stdlib.h> | |
3 | +#include <unistd.h> | |
4 | + | |
5 | +int main(int argc, char *argv[]) { | |
6 | + int fd; | |
7 | + | |
8 | + /* This file gets built and run as a test, but its | |
9 | + * really just a helper for test-mkostemp-O_CLOEXEC.c. | |
10 | + * So, we'll always return succcess. | |
11 | + */ | |
12 | + if(argc != 2) | |
13 | + exit(EXIT_SUCCESS); | |
14 | + | |
15 | + sscanf(argv[1], "%d", &fd); | |
16 | + | |
17 | + if(write(fd, "test\0", 5) == -1) | |
18 | + ; /* Don't Panic! Failure is okay here. */ | |
19 | + | |
20 | + close(fd); | |
21 | + exit(EXIT_SUCCESS); | |
22 | +} |