Commit MetaInfo

Revision638a23483b40c5b606ee323e6612e7e454e5154b (tree)
Time2014-12-16 01:53:06
AuthorAnthony G. Basile <blueness@gent...>
CommiterBernhard Reutner-Fischer

Log Message

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>

Change Summary

Incremental Difference

--- a/libc/inet/getaddrinfo.c
+++ b/libc/inet/getaddrinfo.c
@@ -308,7 +308,7 @@ gaih_local(const char *name, const struct gaih_service *service,
308308 char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path;
309309
310310 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
312312 ) {
313313 return -EAI_SYSTEM;
314314 }
--- a/libc/misc/internals/tempname.c
+++ b/libc/misc/internals/tempname.c
@@ -177,7 +177,7 @@ static void brain_damaged_fillrand(unsigned char *buf, unsigned int len)
177177 __GT_DIR: create a directory with given mode.
178178
179179 */
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)
181181 {
182182 char *XXXXXX;
183183 unsigned int i;
@@ -219,11 +219,11 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind, mode_t mode)
219219 fd = 0;
220220 }
221221 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);
223223 break;
224224 #if defined __UCLIBC_HAS_LFS__
225225 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);
227227 break;
228228 #endif
229229 case __GT_DIR:
--- a/libc/misc/internals/tempname.h
+++ b/libc/misc/internals/tempname.h
@@ -10,7 +10,7 @@ extern int ___path_search (char *tmpl, size_t tmpl_len, const char *dir,
1010 const char *pfx /*, int try_tmpdir */) attribute_hidden;
1111 #define __path_search(tmpl, tmpl_len, dir, pfx, try_tmpdir) ___path_search(tmpl, tmpl_len, dir, pfx)
1212
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;
1414
1515 /* The __kind argument to __gen_tempname may be one of: */
1616 #define __GT_FILE 0 /* create a file */
--- a/libc/stdio/tempnam.c
+++ b/libc/stdio/tempnam.c
@@ -35,7 +35,7 @@ tempnam (const char *dir, const char *pfx)
3535 if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
3636 return NULL;
3737
38- if (__gen_tempname (buf, __GT_NOCREATE, 0))
38+ if (__gen_tempname (buf, __GT_NOCREATE, 0, 0))
3939 return NULL;
4040
4141 return strdup (buf);
--- a/libc/stdio/tmpfile.c
+++ b/libc/stdio/tmpfile.c
@@ -35,7 +35,7 @@ FILE * tmpfile (void)
3535
3636 if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
3737 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);
3939 if (fd < 0)
4040 return NULL;
4141
--- a/libc/stdio/tmpnam.c
+++ b/libc/stdio/tmpnam.c
@@ -40,7 +40,7 @@ tmpnam (char *s)
4040 0))
4141 return NULL;
4242
43- if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0), 0))
43+ if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0, 0), 0))
4444 return NULL;
4545
4646 if (s == NULL)
--- a/libc/stdio/tmpnam_r.c
+++ b/libc/stdio/tmpnam_r.c
@@ -27,7 +27,7 @@ char * tmpnam_r (char *s)
2727
2828 if (__path_search (s, L_tmpnam, NULL, NULL, 0))
2929 return NULL;
30- if (__gen_tempname (s, __GT_NOCREATE, 0))
30+ if (__gen_tempname (s, __GT_NOCREATE, 0, 0))
3131 return NULL;
3232
3333 return s;
--- a/libc/stdlib/mkdtemp.c
+++ b/libc/stdlib/mkdtemp.c
@@ -29,7 +29,7 @@
2929 (This function comes from OpenBSD.) */
3030 char * mkdtemp (char *template)
3131 {
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))
3333 return NULL;
3434 else
3535 return template;
--- a/libc/stdlib/mkostemp.c
+++ b/libc/stdlib/mkostemp.c
@@ -17,6 +17,7 @@
1717
1818 #include <stdio.h>
1919 #include <stdlib.h>
20+#include <fcntl.h>
2021 #include "../misc/internals/tempname.h"
2122
2223 /* Generate a unique temporary file name from TEMPLATE.
@@ -26,5 +27,6 @@
2627 int
2728 mkostemp (char *template, int flags)
2829 {
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);
3032 }
--- a/libc/stdlib/mkostemp64.c
+++ b/libc/stdlib/mkostemp64.c
@@ -27,5 +27,5 @@
2727 int
2828 mkostemp64 (char *template, int flags)
2929 {
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);
3131 }
--- a/libc/stdlib/mkstemp.c
+++ b/libc/stdlib/mkstemp.c
@@ -26,5 +26,5 @@
2626 Then open the file and return a fd. */
2727 int mkstemp (char *template)
2828 {
29- return __gen_tempname (template, __GT_FILE, S_IRUSR | S_IWUSR);
29+ return __gen_tempname (template, __GT_FILE, 0, S_IRUSR | S_IWUSR);
3030 }
--- a/libc/stdlib/mkstemp64.c
+++ b/libc/stdlib/mkstemp64.c
@@ -26,5 +26,5 @@
2626 Then open the file and return a fd. */
2727 int mkstemp64 (char *template)
2828 {
29- return __gen_tempname (template, __GT_BIGFILE, S_IRUSR | S_IWUSR);
29+ return __gen_tempname (template, __GT_BIGFILE, 0, S_IRUSR | S_IWUSR);
3030 }
--- a/libc/stdlib/mktemp.c
+++ b/libc/stdlib/mktemp.c
@@ -24,7 +24,7 @@
2424 * they are replaced with a string that makes the filename unique. */
2525 char *mktemp(char *template)
2626 {
27- if (__gen_tempname (template, __GT_NOCREATE, 0) < 0)
27+ if (__gen_tempname (template, __GT_NOCREATE, 0, 0) < 0)
2828 /* We return the null string if we can't find a unique file name. */
2929 template[0] = '\0';
3030
--- a/libpthread/nptl/sem_open.c
+++ b/libpthread/nptl/sem_open.c
@@ -336,7 +336,7 @@ sem_open (const char *name, int oflag, ...)
336336 mempcpy (mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen),
337337 "XXXXXX", 7);
338338
339- fd = __gen_tempname (tmpfname, __GT_FILE, mode);
339+ fd = __gen_tempname (tmpfname, __GT_FILE, 0, mode);
340340 if (fd == -1)
341341 return SEM_FAILED;
342342
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -274,6 +274,8 @@ stdlib/testarc4random
274274 stdlib/testatexit
275275 stdlib/test-canon
276276 stdlib/test-canon2
277+stdlib/test-mkostemp-O_CLOEXEC
278+stdlib/test-mkostemp-child
277279 stdlib/teston_exit
278280 stdlib/teststrtol
279281 stdlib/teststrtoq
--- /dev/null
+++ b/test/stdlib/test-mkostemp-O_CLOEXEC.c
@@ -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+}
--- /dev/null
+++ b/test/stdlib/test-mkostemp-child.c
@@ -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+}
Show on old repository browser