diff options
| -rw-r--r-- | src/stdio/tempnam.c | 55 | ||||
| -rw-r--r-- | src/stdio/tmpfile.c | 8 | ||||
| -rw-r--r-- | src/stdio/tmpnam.c | 40 | 
3 files changed, 48 insertions, 55 deletions
| diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c index f73ca9f9..9bf8c727 100644 --- a/src/stdio/tempnam.c +++ b/src/stdio/tempnam.c @@ -1,42 +1,43 @@  #include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <limits.h>  #include <string.h> -#include <stdlib.h> -#include <stdint.h> -#include <unistd.h> -#include <time.h> -#include "libc.h" -#include "atomic.h" +#include "syscall.h"  #define MAXTRIES 100 +char *__randname(char *); +  char *tempnam(const char *dir, const char *pfx)  { -	static int index; -	char *s; -	struct timespec ts; -	int pid = getpid(); -	size_t l; -	int n; -	int try=0; +	char s[PATH_MAX]; +	size_t l, dl, pl; +	int try; +	int r;  	if (!dir) dir = P_tmpdir;  	if (!pfx) pfx = "temp"; -	if (access(dir, R_OK|W_OK|X_OK) != 0) -		return NULL; - -	l = strlen(dir) + 1 + strlen(pfx) + 3*(sizeof(int)*3+2) + 1; -	s = malloc(l); -	if (!s) return s; +	dl = strlen(dir); +	pl = strlen(pfx); +	l = dl + 1 + pl + 1 + 6; -	do { -		clock_gettime(CLOCK_REALTIME, &ts); -		n = ts.tv_nsec ^ (uintptr_t)&s ^ (uintptr_t)s; -		snprintf(s, l, "%s/%s-%d-%d-%x", dir, pfx, pid, a_fetch_add(&index, 1), n); -	} while (!access(s, F_OK) && try++<MAXTRIES); -	if (try>=MAXTRIES) { -		free(s); +	if (l >= PATH_MAX) { +		errno = ENAMETOOLONG;  		return 0;  	} -	return s; + +	memcpy(s, dir, dl); +	s[dl] = '/'; +	memcpy(s+dl+1, pfx, pl); +	s[dl+1+pl] = '_'; + +	for (try=0; try<MAXTRIES; try++) { +		__randname(s+l-6); +		r = __syscall(SYS_lstat, s, &(struct stat){0}); +		if (r == -ENOENT) return strdup(s); +	} +	return 0;  } diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c index b0d0ba07..c8569948 100644 --- a/src/stdio/tmpfile.c +++ b/src/stdio/tmpfile.c @@ -1,19 +1,19 @@  #include <stdio.h>  #include <fcntl.h> -#include <unistd.h>  #include "stdio_impl.h"  #define MAXTRIES 100 +char *__randname(char *); +  FILE *tmpfile(void)  { -	char buf[L_tmpnam], *s; +	char s[] = "/tmp/tmpfile_XXXXXX";  	int fd;  	FILE *f;  	int try;  	for (try=0; try<MAXTRIES; try++) { -		s = tmpnam(buf); -		if (!s) return 0; +		__randname(s+13);  		fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);  		if (fd >= 0) {  			f = __fdopen(fd, "w+"); diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c index 2bd72b3b..92f699c2 100644 --- a/src/stdio/tmpnam.c +++ b/src/stdio/tmpnam.c @@ -1,31 +1,23 @@  #include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <unistd.h> -#include <time.h> -#include "libc.h" +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h>  #include "syscall.h" -#include "atomic.h"  #define MAXTRIES 100 -char *tmpnam(char *s) -{ -	static int index; -	static char s2[L_tmpnam]; -	struct timespec ts; -	int try = 0; -	unsigned n; - -	if (!s) s = s2; +char *__randname(char *); -	if (__syscall(SYS_access, P_tmpdir, R_OK|W_OK|X_OK) != 0) -		return NULL; - -	do { -		__syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts, 0); -		n = ts.tv_nsec ^ (uintptr_t)&s ^ (uintptr_t)s; -		snprintf(s, L_tmpnam, "/tmp/t%x-%x", a_fetch_add(&index, 1), n); -	} while (!__syscall(SYS_access, s, F_OK) && try++<MAXTRIES); -	return try>=MAXTRIES ? 0 : s; +char *tmpnam(char *buf) +{ +	static char internal[L_tmpnam]; +	char s[] = "/tmp/tmpnam_XXXXXX"; +	int try; +	int r; +	for (try=0; try<MAXTRIES; try++) { +		__randname(s+12); +		r = __syscall(SYS_lstat, s, &(struct stat){0}); +		if (r == -ENOENT) return strcpy(buf ? buf : internal, s); +	} +	return 0;  } | 
