mirror of https://git.musl-libc.org/git/musl
Browse Source
these all now use the shared __randname function internally, rather than duplicating logic for producing a random name. incorrect usage of the access syscall (which works with real uid/gid, not effective) has been removed, along with unnecessary heavy dependencies like snprintf.master
3 changed files with 48 additions and 55 deletions
@ -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; |
|||
} |
|||
|
|||
@ -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; |
|||
} |
|||
|
|||
Loading…
Reference in new issue