#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;
-int check_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 *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);
+ 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)
-{
- struct private_file_writer_data *pfwd = wn->private_data;
- int ret = write(pfwd->fd, data, nbytes);
- if (ret < 0)
- ret = -E_FW_WRITE;
- return ret;
-}
-
-static void file_writer_pre_select(struct sched *s, struct task *t)
+static int file_writer_pre_select(struct sched *s, struct writer_node *wn)
{
- 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;
+ return -E_FW_NO_FILE;
if (!*wng->loaded)
- return;
- t->ret = 1;
+ return 1;
para_fd_set(pfwd->fd, &s->wfds, &s->max_fileno);
pfwd->check_fd = 1;
+ return 1;
}
-static void file_writer_post_select(struct sched *s, struct task *t)
+static int file_writer_post_select(struct sched *s, struct writer_node *wn)
{
- struct writer_node *wn = t->private_data;
struct private_file_writer_data *pfwd = wn->private_data;
struct writer_node_group *wng = wn->wng;
+ int ret;
- t->ret = 0;
if (!pfwd->check_fd)
- return;
- if (!*wng->loaded)
- return;
+ return 1;
+ if (*wng->loaded <= wn->written)
+ return 1;
if (!FD_ISSET(pfwd->fd, &s->wfds))
- return;
+ return 1;
// 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;
+ ret = write(pfwd->fd, wng->buf + wn->written,
+ *wng->loaded - wn->written);
+ if (ret < 0)
+ return -E_FW_WRITE;
+ wn->written += ret;
+ return 1;
}
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 */
}