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 char *result
, *home
= para_homedir();
36 srandom(clock_get_realtime(NULL
)->tv_usec
);
37 result
= make_message("%s/.paraslash/%08ld", home
,
38 para_random(99999999));
43 static int prepare_output_file(struct writer_node
*wn
)
45 const unsigned flags
= O_WRONLY
| O_CREAT
, mode
= S_IRUSR
| S_IWUSR
;
47 struct private_file_write_data
*pfwd
;
50 if (WRITE_CMD_OPT_GIVEN(FILE, FILENAME
, wn
->lpr
)) {
51 const char *path
= WRITE_CMD_OPT_STRING_VAL(FILE, FILENAME
,
53 ret
= para_open(path
, flags
, mode
);
55 char *path
= random_filename();
56 ret
= para_open(path
, flags
, mode
);
62 ret
= mark_fd_blocking(fd
);
67 pfwd
= wn
->private_data
= para_calloc(sizeof(*pfwd
));
72 static void file_write_pre_select(struct sched
*s
, void *context
)
74 struct writer_node
*wn
= context
;
75 struct private_file_write_data
*pfwd
= wn
->private_data
;
76 int ret
= btr_node_status(wn
->btrn
, wn
->min_iqs
, BTR_NT_LEAF
);
81 return sched_min_delay(s
);
82 para_fd_set(pfwd
->fd
, &s
->wfds
, &s
->max_fileno
);
85 static void file_write_close(struct writer_node
*wn
)
87 struct private_file_write_data
*pfwd
= wn
->private_data
;
95 static int file_write_post_select(__a_unused
struct sched
*s
, void *context
)
97 struct writer_node
*wn
= context
;
98 struct private_file_write_data
*pfwd
= wn
->private_data
;
99 struct btr_node
*btrn
= wn
->btrn
;
104 ret
= task_get_notification(wn
->task
);
107 ret
= btr_node_status(btrn
, wn
->min_iqs
, BTR_NT_LEAF
);
111 ret
= prepare_output_file(wn
);
114 if (!FD_ISSET(pfwd
->fd
, &s
->wfds
))
116 bytes
= btr_next_buffer(btrn
, &buf
);
118 //PARA_INFO_LOG("writing %zu\n", bytes);
119 ret
= xwrite(pfwd
->fd
, buf
, bytes
);
122 btr_consume(btrn
, ret
);
125 btr_remove_node(&wn
->btrn
);
129 /** the init function of the file writer */
130 struct writer lsg_write_cmd_com_file_user_data
= {
131 .pre_select
= file_write_pre_select
,
132 .post_select
= file_write_post_select
,
133 .close
= file_write_close
,