/* * Copyright (C) 2006-2009 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file stdout.c Functions that deal with writing to stdout. */ #include /* readdir() */ #include #include "para.h" #include "string.h" #include "list.h" #include "sched.h" #include "fd.h" #include "error.h" #include "stdout.h" /** * The pre_select function of the stdout task. * * \param s The scheduler this task was registered to. * \param t The task structure of the stdout task. * * This function is always successful. If there is data available in the input * buffer, it adds \p STDOUT_FILENO to the write fd set of \a s. */ static void stdout_pre_select(struct sched *s, struct task *t) { struct stdout_task *sot = container_of(t, struct stdout_task, task); t->error = 0; sot->check_fd = 0; if (!*sot->loaded) { if (*sot->input_error < 0) { t->error = *sot->input_error; s->timeout.tv_sec = 0; s->timeout.tv_usec = 1; } return; } sot->check_fd = 1; para_fd_set(STDOUT_FILENO, &s->wfds, &s->max_fileno); } /** * The post select function of the stdout task. * * \param s The scheduler this task was registered to. * \param t The task structure of the stdout task. * * This function checks if \p STDOUT_FILENO was included by in the write fd set * of \a s during the previous pre_select call. If yes, and \p STDOUT_FILENO * appeears to be writable, the data loaded in the input buffer is written to * stdout. */ static void stdout_post_select(struct sched *s, struct task *t) { struct stdout_task *sot = container_of(t, struct stdout_task, task); ssize_t ret; t->error = 0; if (!sot->check_fd) { if (!*sot->loaded && *sot->input_error < 0) t->error = *sot->input_error; return; } if (!FD_ISSET(STDOUT_FILENO, &s->wfds)) return; ret = write(STDOUT_FILENO, *sot->bufp, *sot->loaded); if (ret < 0) { t->error = -ERRNO_TO_PARA_ERROR(errno); return; } *sot->loaded -= ret; if (*sot->loaded) memmove(*sot->bufp, *sot->bufp + ret, *sot->loaded); } /** * Initialize a stdout task structure with default values. * * \param sot The stdout task structure. * * This fills in the pre/post select function poinzters of the task structure * given by \a sot. */ void stdout_set_defaults(struct stdout_task *sot) { int ret; sot->task.pre_select = stdout_pre_select; sot->task.post_select = stdout_post_select; sprintf(sot->task.status, "stdout writer"); ret = mark_fd_nonblocking(STDOUT_FILENO); if (ret >= 0) return; PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(EXIT_FAILURE); }