fix scanf %c conversion wrongly storing a terminating null byte
[oweals/musl.git] / src / stdio / tempnam.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdint.h>
5 #include <unistd.h>
6 #include <time.h>
7 #include "libc.h"
8 #include "atomic.h"
9
10 #define MAXTRIES 100
11
12 char *tempnam(const char *dir, const char *pfx)
13 {
14         static int index;
15         char *s;
16         struct timespec ts;
17         int pid = getpid();
18         size_t l;
19         int n;
20         int try=0;
21
22         if (!dir) dir = P_tmpdir;
23         if (!pfx) pfx = "temp";
24
25         if (access(dir, R_OK|W_OK|X_OK) != 0)
26                 return NULL;
27
28         l = strlen(dir) + 1 + strlen(pfx) + 3*(sizeof(int)*3+2) + 1;
29         s = malloc(l);
30         if (!s) return s;
31
32         do {
33                 clock_gettime(CLOCK_REALTIME, &ts);
34                 n = ts.tv_nsec ^ (uintptr_t)&s ^ (uintptr_t)s;
35                 snprintf(s, l, "%s/%s-%d-%d-%x", dir, pfx, pid, a_fetch_add(&index, 1), n);
36         } while (!access(s, F_OK) && try++<MAXTRIES);
37         if (try>=MAXTRIES) {
38                 free(s);
39                 return 0;
40         }
41         return s;
42 }