X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=file_writer.c;h=e90647d230cf7f3f797f648892fa0530198941ab;hp=dabe92ce37fb941909a3286fe0575ef9e23e260d;hb=db02b614d1231685e64b27b4838c7cd699e51790;hpb=abc1c0b936dfe3eeaf73560be9e6e276d2993ef3 diff --git a/file_writer.c b/file_writer.c index dabe92ce..e90647d2 100644 --- a/file_writer.c +++ b/file_writer.c @@ -19,38 +19,80 @@ /** \file file_writer.c simple output plugin for testing purposes */ #include "para.h" +#include "list.h" +#include "sched.h" #include "write.h" #include "string.h" +#include "fd.h" +#include "file_write.cmdline.h" #include "error.h" +/** data specific to the file writer */ struct private_file_writer_data { + /** the file descriptor of the output file */ int fd; + /** non-zero if \a fd was added to the write fd set */ + int check_fd; }; -static int file_writer_open(struct writer_node *w) + +static int file_writer_open(struct writer_node *wn) { struct private_file_writer_data *pfwd = para_calloc( sizeof(struct private_file_writer_data)); - char *tmp = para_tmpname(), *home = para_homedir(), - *filename = make_message("%s/.paraslash/%s", home, tmp); - - free(home); - free(tmp); - w->private_data = pfwd; + struct file_write_args_info *conf = wn->conf; + char *filename; + if (conf->filename_given) + filename = conf->filename_arg; + else { + char *tmp = para_tmpname(), *home = para_homedir(); + filename = make_message("%s/.paraslash/%s", home, tmp); + free(home); + free(tmp); + } + wn->private_data = pfwd; pfwd->fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - free(filename); + if (!conf->filename_given) + free(filename); if (pfwd->fd >= 0) return 8192; free(pfwd); return -E_FW_OPEN; } -static int file_writer_write(char *data, size_t nbytes, struct writer_node *wn) +static int file_writer_pre_select(struct sched *s, struct writer_node *wn) { struct private_file_writer_data *pfwd = wn->private_data; - int ret = write(pfwd->fd, data, nbytes); + struct writer_node_group *wng = wn->wng; + + pfwd->check_fd = 0; + if (pfwd->fd <= 0) + return -E_FW_NO_FILE; + if (!*wng->loaded) + return 1; + para_fd_set(pfwd->fd, &s->wfds, &s->max_fileno); + pfwd->check_fd = 1; + return 1; +} + +static int file_writer_post_select(struct sched *s, struct writer_node *wn) +{ + struct private_file_writer_data *pfwd = wn->private_data; + struct writer_node_group *wng = wn->wng; + int ret; + + if (!pfwd->check_fd) + return 1; + if (*wng->loaded <= wn->written) + return 1; + if (!FD_ISSET(pfwd->fd, &s->wfds)) + return 1; +// PARA_INFO_LOG("writing %zd\n", *wng->loaded); + ret = write(pfwd->fd, wng->buf + wn->written, + *wng->loaded - wn->written); if (ret < 0) - ret = -E_FW_WRITE; - return ret; + return -E_FW_WRITE; + wn->written += ret; + return 1; } static void file_writer_close(struct writer_node *wn) @@ -60,10 +102,26 @@ static void file_writer_close(struct writer_node *wn) free(pfwd); } +__malloc void *file_writer_parse_config(char *options) +{ + PARA_INFO_LOG("options: %s\n", options); + struct file_write_args_info *conf + = para_calloc(sizeof(struct file_write_args_info)); + int ret = file_cmdline_parser_string(options, conf, "file_write"); + PARA_INFO_LOG("conf->filename_given: %d\n", conf->filename_given); + if (!ret) + return conf; + free(conf); + return NULL; +} + +/** the init function of the file writer */ void file_writer_init(struct writer *w) { w->open = file_writer_open; - w->write = file_writer_write; + w->pre_select = file_writer_pre_select; + w->post_select = file_writer_post_select; + w->parse_config = file_writer_parse_config; w->close = file_writer_close; w->shutdown = NULL; /* nothing to do */ }