| #include <stdio.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <sys/stat.h> |
| #include <limits.h> |
| #include <string.h> |
| #include "syscall.h" |
| |
| #define MAXTRIES 100 |
| |
| char* __randname(char*); |
| |
| char* tempnam(const char* dir, const char* pfx) { |
| char s[PATH_MAX]; |
| size_t l, dl, pl; |
| int try |
| ; |
| int r; |
| |
| if (!dir) |
| dir = P_tmpdir; |
| if (!pfx) |
| pfx = "temp"; |
| |
| dl = strlen(dir); |
| pl = strlen(pfx); |
| l = dl + 1 + pl + 1 + 6; |
| |
| if (l >= PATH_MAX) { |
| errno = ENAMETOOLONG; |
| return 0; |
| } |
| |
| memcpy(s, dir, dl); |
| s[dl] = '/'; |
| memcpy(s + dl + 1, pfx, pl); |
| s[dl + 1 + pl] = '_'; |
| s[l] = 0; |
| |
| for (try = 0; try < MAXTRIES; try ++) { |
| __randname(s + l - 6); |
| #ifdef SYS_lstat |
| r = __syscall(SYS_lstat, s, &(struct stat){0}); |
| #else |
| r = __syscall(SYS_fstatat, AT_FDCWD, s, &(struct stat){0}, |
| AT_SYMLINK_NOFOLLOW); |
| #endif |
| if (r == -ENOENT) |
| return strdup(s); |
| } |
| return 0; |
| } |