#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <errno.h>
-static char *temp_prefix = "/tmp/temp";
+static char *temp_prefix;
+static int public_dir = 1;
static struct cf_section temp_config = {
CF_ITEMS {
CF_STRING("Prefix", &temp_prefix),
+ CF_INT("PublicDir", &public_dir),
CF_END
}
};
}
void
-temp_file_name(char *buf)
+temp_file_name(char *name_buf, int *open_flags)
{
- struct ucwlib_context *ctx = ucwlib_thread_context();
- int cnt = ++ctx->temp_counter;
- int pid = getpid();
- if (ctx->thread_id == pid)
- sprintf(buf, "%s%d-%d", temp_prefix, pid, cnt);
+ char *prefix;
+ int free_prefix = 0;
+ if (temp_prefix)
+ prefix = temp_prefix;
else
- sprintf(buf, "%s%d-%d-%d", temp_prefix, pid, ctx->thread_id, cnt);
+ {
+ char *env = getenv("TMPDIR");
+ if (env)
+ {
+ prefix = xmalloc(strlen(env) + 6);
+ sprintf(prefix, "%s/temp", env);
+ free_prefix = 1;
+ }
+ else
+ prefix = "/tmp/temp";
+ }
+ if (public_dir)
+ {
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL))
+ die("Could not generate temp file name: %m");
+ sprintf(name_buf, "%s-%u", prefix, (uns) tv.tv_usec);
+ if (open_flags)
+ *open_flags = O_EXCL;
+ }
+ else
+ {
+ struct ucwlib_context *ctx = ucwlib_thread_context();
+ int cnt = ++ctx->temp_counter;
+ int pid = getpid();
+ if (ctx->thread_id == pid)
+ sprintf(name_buf, "%s%d-%d", temp_prefix, pid, cnt);
+ else
+ sprintf(name_buf, "%s%d-%d-%d", temp_prefix, pid, ctx->thread_id, cnt);
+ if (open_flags)
+ *open_flags = 0;
+ }
+ if (free_prefix)
+ xfree(prefix);
}
struct fastbuf *
bopen_tmp_file(struct fb_params *params)
{
char name[TEMP_FILE_NAME_LEN];
- temp_file_name(name);
- struct fastbuf *fb = bopen_file(name, O_RDWR | O_CREAT | O_TRUNC, params);
+ int fd = open_tmp(name, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ struct fastbuf *fb = bopen_fd_name(fd, params, name);
bconfig(fb, BCONFIG_IS_TEMP_FILE, 1);
return fb;
}
+int
+open_tmp(char *name_buf, int open_flags, int mode)
+{
+ int create_flags, fd, retry = 10;
+ do
+ {
+ temp_file_name(name_buf, &create_flags);
+ fd = open(name_buf, open_flags | create_flags, mode);
+ }
+ while (fd < 0 && errno == EEXIST && retry --);
+ if (fd < 0)
+ die("Unable to create temp file %s: %m", name_buf);
+ return fd;
+}
+
struct fastbuf *
bopen_tmp(uns buflen)
{