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 <stdio.h> |
||||
|
#include <fcntl.h> |
||||
|
#include <errno.h> |
||||
|
#include <sys/stat.h> |
||||
|
#include <limits.h> |
||||
#include <string.h> |
#include <string.h> |
||||
#include <stdlib.h> |
#include "syscall.h" |
||||
#include <stdint.h> |
|
||||
#include <unistd.h> |
|
||||
#include <time.h> |
|
||||
#include "libc.h" |
|
||||
#include "atomic.h" |
|
||||
|
|
||||
#define MAXTRIES 100 |
#define MAXTRIES 100 |
||||
|
|
||||
|
char *__randname(char *); |
||||
|
|
||||
char *tempnam(const char *dir, const char *pfx) |
char *tempnam(const char *dir, const char *pfx) |
||||
{ |
{ |
||||
static int index; |
char s[PATH_MAX]; |
||||
char *s; |
size_t l, dl, pl; |
||||
struct timespec ts; |
int try; |
||||
int pid = getpid(); |
int r; |
||||
size_t l; |
|
||||
int n; |
|
||||
int try=0; |
|
||||
|
|
||||
if (!dir) dir = P_tmpdir; |
if (!dir) dir = P_tmpdir; |
||||
if (!pfx) pfx = "temp"; |
if (!pfx) pfx = "temp"; |
||||
|
|
||||
if (access(dir, R_OK|W_OK|X_OK) != 0) |
dl = strlen(dir); |
||||
return NULL; |
pl = strlen(pfx); |
||||
|
l = dl + 1 + pl + 1 + 6; |
||||
l = strlen(dir) + 1 + strlen(pfx) + 3*(sizeof(int)*3+2) + 1; |
|
||||
s = malloc(l); |
|
||||
if (!s) return s; |
|
||||
|
|
||||
do { |
if (l >= PATH_MAX) { |
||||
clock_gettime(CLOCK_REALTIME, &ts); |
errno = ENAMETOOLONG; |
||||
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); |
|
||||
return 0; |
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 <stdio.h> |
||||
#include <stdlib.h> |
#include <fcntl.h> |
||||
#include <stdint.h> |
#include <errno.h> |
||||
#include <unistd.h> |
#include <sys/stat.h> |
||||
#include <time.h> |
|
||||
#include "libc.h" |
|
||||
#include "syscall.h" |
#include "syscall.h" |
||||
#include "atomic.h" |
|
||||
|
|
||||
#define MAXTRIES 100 |
#define MAXTRIES 100 |
||||
|
|
||||
char *tmpnam(char *s) |
char *__randname(char *); |
||||
{ |
|
||||
static int index; |
|
||||
static char s2[L_tmpnam]; |
|
||||
struct timespec ts; |
|
||||
int try = 0; |
|
||||
unsigned n; |
|
||||
|
|
||||
if (!s) s = s2; |
|
||||
|
|
||||
if (__syscall(SYS_access, P_tmpdir, R_OK|W_OK|X_OK) != 0) |
char *tmpnam(char *buf) |
||||
return NULL; |
{ |
||||
|
static char internal[L_tmpnam]; |
||||
do { |
char s[] = "/tmp/tmpnam_XXXXXX"; |
||||
__syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts, 0); |
int try; |
||||
n = ts.tv_nsec ^ (uintptr_t)&s ^ (uintptr_t)s; |
int r; |
||||
snprintf(s, L_tmpnam, "/tmp/t%x-%x", a_fetch_add(&index, 1), n); |
for (try=0; try<MAXTRIES; try++) { |
||||
} while (!__syscall(SYS_access, s, F_OK) && try++<MAXTRIES); |
__randname(s+12); |
||||
return try>=MAXTRIES ? 0 : s; |
r = __syscall(SYS_lstat, s, &(struct stat){0}); |
||||
|
if (r == -ENOENT) return strcpy(buf ? buf : internal, s); |
||||
|
} |
||||
|
return 0; |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue