diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-03-29 08:34:47 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-03-29 08:34:47 -0400 | 
| commit | 507a9fa6ff9948eb7d858467b7be2cb1dcf15d03 (patch) | |
| tree | 90d5e4f8977942072e5a418dbc7ea5bbc8cd72be | |
| parent | 9646e4d024c05332c9653419abd6c41fdd48a33b (diff) | |
| download | musl-507a9fa6ff9948eb7d858467b7be2cb1dcf15d03.tar.gz | |
fix tmpnam to generate better names, not depend on non-ISO-C symbols
| -rw-r--r-- | src/stdio/tmpnam.c | 42 | 
1 files changed, 17 insertions, 25 deletions
| diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c index 14d59220..6099b74b 100644 --- a/src/stdio/tmpnam.c +++ b/src/stdio/tmpnam.c @@ -1,38 +1,30 @@  #include <stdio.h>  #include <stdlib.h> -#include <string.h> -#include <limits.h>  #include <unistd.h> +#include <time.h>  #include "libc.h" +#include "syscall.h" +#include "atomic.h" + +#define MAXTRIES 100  char *tmpnam(char *s)  { -	static int lock;  	static int index; -	static char *s2; -	int pid = getpid(); -	char *dir = getenv("TMPDIR"); - -	if (!s) { -		if (!s2) s2 = malloc(L_tmpnam); -		s = s2; -	} +	static char s2[L_tmpnam]; +	struct timespec ts; +	int try = 0; +	unsigned n; -	/* this interface is insecure anyway but at least we can try.. */ -	if (!dir || strlen(dir) > L_tmpnam-32) -		dir = P_tmpdir; +	if (!s) s = s2; -	if (access(dir, R_OK|W_OK|X_OK) != 0) +	if (__syscall(SYS_access, P_tmpdir, R_OK|W_OK|X_OK) != 0)  		return NULL; -	LOCK(&lock); -	for (index++; index < TMP_MAX; index++) { -		snprintf(s, L_tmpnam, "%s/temp%d-%d", dir, pid, index); -		if (access(s, F_OK) != 0) { -			UNLOCK(&lock); -			return s; -		} -	} -	UNLOCK(&lock); -	return NULL; +	do { +		__syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts, 0); +		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;  } | 
