diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-03-29 09:00:22 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-03-29 09:00:22 -0400 | 
| commit | 8250742b90b8b54e642fa9201bf0cf8b7c27bbb8 (patch) | |
| tree | a12ed40d599ed320b5a9c669bddafe3905e48edd | |
| parent | a88edbec15abe3c8e08d5065d8bea399898e757c (diff) | |
| download | musl-8250742b90b8b54e642fa9201bf0cf8b7c27bbb8.tar.gz | |
fix tempnam name generation, and a small bug in tmpnam on retry limit
| -rw-r--r-- | src/stdio/tempnam.c | 39 | ||||
| -rw-r--r-- | src/stdio/tmpnam.c | 2 | 
2 files changed, 20 insertions, 21 deletions
| diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c index 2cbcb864..dc4f2bad 100644 --- a/src/stdio/tempnam.c +++ b/src/stdio/tempnam.c @@ -1,19 +1,22 @@  #include <stdio.h>  #include <string.h>  #include <stdlib.h> -#include <fcntl.h>  #include <unistd.h> -#include <limits.h> -#include <errno.h> +#include <time.h>  #include "libc.h" +#include "atomic.h" + +#define MAXTRIES 100  char *tempnam(const char *dir, const char *pfx)  { -	static int lock;  	static int index;  	char *s; +	struct timespec ts;  	int pid = getpid(); -	int l; +	size_t l; +	int n; +	int try=0;  	if (!dir) dir = P_tmpdir;  	if (!pfx) pfx = "temp"; @@ -21,22 +24,18 @@ char *tempnam(const char *dir, const char *pfx)  	if (access(dir, R_OK|W_OK|X_OK) != 0)  		return NULL; -	l = strlen(dir) + 1 + strlen(pfx) + 2 + sizeof(int)*3*2 + 1; +	l = strlen(dir) + 1 + strlen(pfx) + 3*(sizeof(int)*3+2) + 1;  	s = malloc(l); -	if (!s) { -		errno = ENOMEM; -		return NULL; -	} +	if (!s) return s; -	LOCK(&lock); -	for (; index < TMP_MAX; index++) { -		snprintf(s, l, "%s/%s-%d-%d", dir, pfx, pid, index); -		if (access(s, F_OK) != 0) { -			UNLOCK(&lock); -			return s; -		} +	do { +		clock_gettime(CLOCK_REALTIME, &ts); +		n = ts.tv_nsec ^ (unsigned)&s ^ (unsigned)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); +		return 0;  	} -	UNLOCK(&lock); -	free(s); -	return NULL;	 +	return s;  } diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c index 6099b74b..010cf039 100644 --- a/src/stdio/tmpnam.c +++ b/src/stdio/tmpnam.c @@ -26,5 +26,5 @@ char *tmpnam(char *s)  		n = ts.tv_nsec ^ (unsigned)&s ^ (unsigned)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; +	return try>=MAXTRIES ? 0 : s;  } | 
