fix scanf %c conversion wrongly storing a terminating null byte
[oweals/musl.git] / src / stdio / tmpnam.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <unistd.h>
5 #include <time.h>
6 #include "libc.h"
7 #include "syscall.h"
8 #include "atomic.h"
9
10 #define MAXTRIES 100
11
12 char *tmpnam(char *s)
13 {
14         static int index;
15         static char s2[L_tmpnam];
16         struct timespec ts;
17         int try = 0;
18         unsigned n;
19
20         if (!s) s = s2;
21
22         if (__syscall(SYS_access, P_tmpdir, R_OK|W_OK|X_OK) != 0)
23                 return NULL;
24
25         do {
26                 __syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts, 0);
27                 n = ts.tv_nsec ^ (uintptr_t)&s ^ (uintptr_t)s;
28                 snprintf(s, L_tmpnam, "/tmp/t%x-%x", a_fetch_add(&index, 1), n);
29         } while (!__syscall(SYS_access, s, F_OK) && try++<MAXTRIES);
30         return try>=MAXTRIES ? 0 : s;
31 }