1 /* Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 /** \file file_write.c simple output plugin for testing purposes */
9 #include "write_cmd.lsg.h"
13 #include "buffer_tree.h"
19 /** Data specific to the file writer. */
20 struct private_file_write_data {
21 /** The file descriptor of the output file. */
26 * Get a random filename.
28 * This is by no means a secure way to create temporary files in a hostile
29 * directory like \p /tmp. However, we use it only for creating temp files in
30 * ~/.paraslash, for which it is OK. Result must be freed by the caller.
32 __must_check __malloc static char *random_filename(void)
34 srandom(clock_get_realtime(NULL)->tv_usec);
35 return make_message("%s/%08ld", get_confdir(), para_random(99999999));
38 static int prepare_output_file(struct writer_node *wn)
40 const unsigned flags = O_WRONLY | O_CREAT, mode = S_IRUSR | S_IWUSR;
42 struct private_file_write_data *pfwd;
45 if (WRITE_CMD_OPT_GIVEN(FILE, FILENAME, wn->lpr)) {
46 const char *path = WRITE_CMD_OPT_STRING_VAL(FILE, FILENAME,
48 ret = para_open(path, flags, mode);
50 char *path = random_filename();
51 ret = para_open(path, flags, mode);
57 ret = mark_fd_blocking(fd);
62 pfwd = wn->private_data = zalloc(sizeof(*pfwd));
67 static void file_write_pre_monitor(struct sched *s, void *context)
69 struct writer_node *wn = context;
70 struct private_file_write_data *pfwd = wn->private_data;
71 int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
76 return sched_min_delay(s);
77 sched_monitor_writefd(pfwd->fd, s);
80 static void file_write_close(struct writer_node *wn)
82 struct private_file_write_data *pfwd = wn->private_data;
90 static int file_write_post_monitor(__a_unused struct sched *s, void *context)
92 struct writer_node *wn = context;
93 struct private_file_write_data *pfwd = wn->private_data;
94 struct btr_node *btrn = wn->btrn;
99 ret = task_get_notification(wn->task);
102 ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF);
106 ret = prepare_output_file(wn);
109 if (!sched_write_ok(pfwd->fd, s))
111 bytes = btr_next_buffer(btrn, &buf);
113 //PARA_INFO_LOG("writing %zu\n", bytes);
114 ret = xwrite(pfwd->fd, buf, bytes);
117 btr_consume(btrn, ret);
120 btr_remove_node(&wn->btrn);
124 /** the init function of the file writer */
125 struct writer lsg_write_cmd_com_file_user_data = {
126 .pre_monitor = file_write_pre_monitor,
127 .post_monitor = file_write_post_monitor,
128 .close = file_write_close,