2 * Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file file_write.c simple output plugin for testing purposes */
10 #include <sys/types.h>
13 #include "write_cmd.lsg.h"
17 #include "buffer_tree.h"
23 /** Data specific to the file writer. */
24 struct private_file_write_data {
25 /** The file descriptor of the output file. */
30 * Get a random filename.
32 * This is by no means a secure way to create temporary files in a hostile
33 * directory like \p /tmp. However, we use it only for creating temp files in
34 * ~/.paraslash, for which it is OK. Result must be freed by the caller.
36 __must_check __malloc static char *random_filename(void)
38 char *result, *home = para_homedir();
40 srandom(clock_get_realtime(NULL)->tv_usec);
41 result = make_message("%s/.paraslash/%08ld", home,
42 para_random(99999999));
47 static int prepare_output_file(struct writer_node *wn)
49 const unsigned flags = O_WRONLY | O_CREAT, mode = S_IRUSR | S_IWUSR;
51 struct private_file_write_data *pfwd;
54 if (WRITE_CMD_OPT_GIVEN(FILE, FILENAME, wn->lpr)) {
55 const char *path = WRITE_CMD_OPT_STRING_VAL(FILE, FILENAME,
57 ret = para_open(path, flags, mode);
59 char *path = random_filename();
60 ret = para_open(path, flags, mode);
66 ret = mark_fd_blocking(fd);
71 pfwd = wn->private_data = para_calloc(sizeof(*pfwd));
76 static void file_write_pre_select(struct sched *s, void *context)
78 struct writer_node *wn = context;
79 struct private_file_write_data *pfwd = wn->private_data;
80 int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
85 return sched_min_delay(s);
86 para_fd_set(pfwd->fd, &s->wfds, &s->max_fileno);
89 static void file_write_close(struct writer_node *wn)
91 struct private_file_write_data *pfwd = wn->private_data;
99 static int file_write_post_select(__a_unused struct sched *s, void *context)
101 struct writer_node *wn = context;
102 struct private_file_write_data *pfwd = wn->private_data;
103 struct btr_node *btrn = wn->btrn;
108 ret = task_get_notification(wn->task);
111 ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF);
115 ret = prepare_output_file(wn);
118 if (!FD_ISSET(pfwd->fd, &s->wfds))
120 bytes = btr_next_buffer(btrn, &buf);
122 //PARA_INFO_LOG("writing %zu\n", bytes);
123 ret = xwrite(pfwd->fd, buf, bytes);
126 btr_consume(btrn, ret);
129 btr_remove_node(&wn->btrn);
133 /** the init function of the file writer */
134 struct writer lsg_write_cmd_com_file_user_data = {
135 .pre_select = file_write_pre_select,
136 .post_select = file_write_post_select,
137 .close = file_write_close,