micro-utils/src/mktemp.c

99 lines
1.6 KiB
C
Raw Normal View History

2024-07-01 10:23:00 +00:00
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "make_path.h"
2024-07-09 12:43:55 +00:00
static int make_temp_dir(char *tmp) {
2024-07-01 10:23:00 +00:00
if (!mkdtemp(tmp)) {
if (errno == EINVAL)
fprintf(stderr, "mktemp: template does not end in exactly 'XXXXX': %s\n", tmp);
else
fprintf(stderr, "mktemp: %s\n", strerror(errno));
return 1;
}
return 0;
}
2024-07-09 12:43:55 +00:00
static int get_suffix(const char *str) {
2024-07-01 10:23:00 +00:00
size_t len = strlen(str);
for (size_t i = len - 1; i > 0; i--)
if (str[i] == 'X')
return len - i - 1;
return 0;
}
2024-07-09 12:43:55 +00:00
static int make_temp_file(char *tmp) {
2024-07-01 10:23:00 +00:00
if (!strstr(tmp, "XXXXXX")) {
fprintf(stderr, "mktemp: too few X's in template: %s\n", tmp);
return 1;
}
int fd = mkstemps(tmp, get_suffix(tmp));
if (fd < 0) {
fprintf(stderr, "mktemp: %s\n", strerror(errno));
return 1;
}
close(fd);
return 0;
}
int main(int argc, char **argv) {
unsigned int d_flag = 0;
char *path = NULL;
int opt;
while ((opt = getopt(argc, argv, "dp:")) != -1) {
switch (opt) {
case 'd':
d_flag = 1;
break;
case 'p':
path = optarg;
break;
default:
2024-07-03 14:22:50 +00:00
puts("mktemp [dp] [file]\n\t-d Dir\n\t-p Base dir");
2024-07-01 10:23:00 +00:00
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0 && path == NULL) {
path = getenv("TMPDIR");
if (!path || path[0] == '\0')
path = "/tmp/";
}
char *x = mu_make_path("mktemp", path, (argc == 0) ? "tmp.XXXXXX" : argv[0]);
if (x == NULL)
return 1;
if (d_flag) {
if (make_temp_dir(x)) {
free(x);
return 1;
}
}
else {
if (make_temp_file(x)) {
free(x);
return 1;
}
}
puts(x);
free(x);
return 0;
}