2 * UCW Library -- Temporary Fastbufs
4 * (c) 2002--2007 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
12 #include "ucw/fastbuf.h"
13 #include "ucw/threads.h"
17 #include <sys/fcntl.h>
22 static char *temp_prefix;
23 static int public_dir = 1;
25 static struct cf_section temp_config = {
27 CF_STRING("Prefix", &temp_prefix),
28 CF_INT("PublicDir", &public_dir),
33 static void CONSTRUCTOR temp_global_init(void)
35 cf_declare_section("Tempfiles", &temp_config, 0);
39 temp_file_name(char *name_buf, int *open_flags)
47 char *env = getenv("TMPDIR");
50 prefix = xmalloc(strlen(env) + 6);
51 sprintf(prefix, "%s/temp", env);
60 if (gettimeofday(&tv, NULL))
61 die("Could not generate temp file name: %m");
62 sprintf(name_buf, "%s-%u", prefix, (uns) tv.tv_usec);
68 struct ucwlib_context *ctx = ucwlib_thread_context();
69 int cnt = ++ctx->temp_counter;
71 if (ctx->thread_id == pid)
72 sprintf(name_buf, "%s%d-%d", temp_prefix, pid, cnt);
74 sprintf(name_buf, "%s%d-%d-%d", temp_prefix, pid, ctx->thread_id, cnt);
83 bopen_tmp_file(struct fb_params *params)
85 char name[TEMP_FILE_NAME_LEN];
86 int fd = open_tmp(name, O_RDWR | O_CREAT | O_TRUNC, 0600);
87 struct fastbuf *fb = bopen_fd_name(fd, params, name);
88 bconfig(fb, BCONFIG_IS_TEMP_FILE, 1);
93 open_tmp(char *name_buf, int open_flags, int mode)
95 int create_flags, fd, retry = 10;
98 temp_file_name(name_buf, &create_flags);
99 fd = open(name_buf, open_flags | create_flags, mode);
101 while (fd < 0 && errno == EEXIST && retry --);
103 die("Unable to create temp file %s: %m", name_buf);
108 bopen_tmp(uns buflen)
110 return bopen_tmp_file(&(struct fb_params){ .type = FB_STD, .buffer_size = buflen });
113 void bfix_tmp_file(struct fastbuf *fb, const char *name)
115 int was_temp = bconfig(fb, BCONFIG_IS_TEMP_FILE, 0);
116 ASSERT(was_temp == 1);
117 if (rename(fb->name, name))
118 die("Cannot rename %s to %s: %m", fb->name, name);
124 #include "ucw/getopt.h"
126 int main(int argc, char **argv)
129 if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0)
130 die("Hey, whaddya want?");
132 struct fastbuf *f = bopen_tmp(65536);
133 bputsn(f, "Hello, world!");