/* * Copyright (C) 2006-2009 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file file_write.c simple output plugin for testing purposes */ #include #include #include "para.h" #include "list.h" #include "sched.h" #include "ggo.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_write_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_write_open(struct writer_node *wn) { struct private_file_write_data *pfwd = para_calloc( sizeof(struct private_file_write_data)); 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); if (!conf->filename_given) free(filename); if (pfwd->fd >= 0) return 1; free(pfwd); return -E_FW_OPEN; } static int file_write_pre_select(struct sched *s, struct writer_node *wn) { struct private_file_write_data *pfwd = wn->private_data; 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_write_post_select(struct sched *s, struct writer_node *wn) { struct private_file_write_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->bufp + wn->written, *wng->loaded - wn->written); if (ret < 0) return -E_FW_WRITE; wn->written += ret; return 1; } static void file_write_close(struct writer_node *wn) { struct private_file_write_data *pfwd = wn->private_data; close(pfwd->fd); free(pfwd); } __malloc static void *file_write_parse_config(const char *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_write_init(struct writer *w) { struct file_write_args_info dummy; file_cmdline_parser_init(&dummy); w->open = file_write_open; w->pre_select = file_write_pre_select; w->post_select = file_write_post_select; w->parse_config = file_write_parse_config; w->close = file_write_close; w->shutdown = NULL; /* nothing to do */ w->help = (struct ggo_help) { .short_help = file_write_args_info_help, .detailed_help = file_write_args_info_detailed_help }; file_cmdline_parser_free(&dummy); }