X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=file_writer.c;h=9145ef9fb7ae24432e7e975af0601e965691e398;hp=a7a765e1175c6379e1881973faa9553255a3cd40;hb=633f7c0f0194cd8ec3a478d820f55dd6a752d915;hpb=0f8ed21f8532a276d4f24b01638fd303fd57f0ed diff --git a/file_writer.c b/file_writer.c index a7a765e1..9145ef9f 100644 --- a/file_writer.c +++ b/file_writer.c @@ -19,28 +19,40 @@ /** \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; + /** 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); @@ -56,6 +68,44 @@ static int file_writer_write(char *data, size_t nbytes, struct writer_node *wn) return ret; } +static void file_writer_pre_select(struct sched *s, struct task *t) +{ + struct writer_node *wn = t->private_data; + struct private_file_writer_data *pfwd = wn->private_data; + struct writer_node_group *wng = wn->wng; + +// PARA_INFO_LOG("task %p check_fd: %d\n", t, pfwd->check_fd); + pfwd->check_fd = 0; + t->ret = -E_FW_NO_FILE; + if (pfwd->fd <= 0) + return; + t->ret = 0; + if (!*wng->loaded) + return; + t->ret = 1; + para_fd_set(pfwd->fd, &s->wfds, &s->max_fileno); + pfwd->check_fd = 1; +} + +static void file_writer_post_select(struct sched *s, struct task *t) +{ + struct writer_node *wn = t->private_data; + struct private_file_writer_data *pfwd = wn->private_data; + struct writer_node_group *wng = wn->wng; + + t->ret = 0; + if (!pfwd->check_fd) + return; + if (!*wng->loaded) + return; + if (!FD_ISSET(pfwd->fd, &s->wfds)) + return; +// PARA_INFO_LOG("writing %zd\n", *wng->loaded); + t->ret = write(pfwd->fd, wng->buf, *wng->loaded); + if (t->ret < 0) + t->ret = -E_FW_WRITE; +} + static void file_writer_close(struct writer_node *wn) { struct private_file_writer_data *pfwd = wn->private_data; @@ -63,11 +113,27 @@ 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 */ }