2 * Copyright (C) 2006-2009 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file stdout.c Functions that deal with writing to stdout. */
9 #include <dirent.h> /* readdir() */
19 #include "buffer_tree.h"
22 * The pre_select function of the stdout task.
24 * \param s The scheduler this task was registered to.
25 * \param t The task structure of the stdout task.
27 * This function is always successful. If there is data available in the input
28 * buffer, it adds \p STDOUT_FILENO to the write fd set of \a s.
30 static void stdout_pre_select(struct sched
*s
, struct task
*t
)
32 struct stdout_task
*sot
= container_of(t
, struct stdout_task
, task
);
37 if (*sot
->input_error
< 0) {
38 t
->error
= *sot
->input_error
;
39 s
->timeout
.tv_sec
= 0;
40 s
->timeout
.tv_usec
= 1;
45 para_fd_set(STDOUT_FILENO
, &s
->wfds
, &s
->max_fileno
);
48 static void stdout_pre_select_btr(struct sched
*s
, struct task
*t
)
50 struct stdout_task
*sot
= container_of(t
, struct stdout_task
, task
);
51 size_t sz
= btr_get_input_queue_size(sot
->btrn
);
56 if (btr_no_parent(sot
->btrn
)) {
58 btr_del_node(sot
->btrn
);
59 s
->timeout
.tv_sec
= 0;
60 s
->timeout
.tv_usec
= 1;
65 para_fd_set(STDOUT_FILENO
, &s
->wfds
, &s
->max_fileno
);
69 * The post select function of the stdout task.
71 * \param s The scheduler this task was registered to.
72 * \param t The task structure of the stdout task.
74 * This function checks if \p STDOUT_FILENO was included by in the write fd set
75 * of \a s during the previous pre_select call. If yes, and \p STDOUT_FILENO
76 * appeears to be writable, the data loaded in the input buffer is written to
79 static void stdout_post_select(struct sched
*s
, struct task
*t
)
81 struct stdout_task
*sot
= container_of(t
, struct stdout_task
, task
);
86 if (!*sot
->loaded
&& *sot
->input_error
< 0)
87 t
->error
= *sot
->input_error
;
90 if (!FD_ISSET(STDOUT_FILENO
, &s
->wfds
))
92 ret
= write(STDOUT_FILENO
, *sot
->bufp
, *sot
->loaded
);
94 t
->error
= -ERRNO_TO_PARA_ERROR(errno
);
99 memmove(*sot
->bufp
, *sot
->bufp
+ ret
, *sot
->loaded
);
102 static void stdout_post_select_btr(struct sched
*s
, struct task
*t
)
104 struct stdout_task
*sot
= container_of(t
, struct stdout_task
, task
);
106 size_t sz
= btr_get_input_queue_size(sot
->btrn
);
107 bool orphan
= btr_no_parent(sot
->btrn
);
111 if (!sot
->check_fd
) {
112 if (sz
== 0 && orphan
) {
113 t
->error
= -E_ORPHAN
;
118 if (!FD_ISSET(STDOUT_FILENO
, &s
->wfds
))
120 sz
= btr_next_buffer(sot
->btrn
, &buf
);
123 ret
= write(STDOUT_FILENO
, buf
, sz
);
125 t
->error
= -ERRNO_TO_PARA_ERROR(errno
);
128 btr_consume(sot
->btrn
, ret
);
131 btr_del_node(sot
->btrn
);
134 * Initialize a stdout task structure with default values.
136 * \param sot The stdout task structure.
138 * This fills in the pre/post select function poinzters of the task structure
141 void stdout_set_defaults(struct stdout_task
*sot
)
146 sot
->task
.pre_select
= stdout_pre_select_btr
;
147 sot
->task
.post_select
= stdout_post_select_btr
;
149 sot
->task
.pre_select
= stdout_pre_select
;
150 sot
->task
.post_select
= stdout_post_select
;
152 sprintf(sot
->task
.status
, "stdout writer");
153 ret
= mark_fd_nonblocking(STDOUT_FILENO
);
156 PARA_EMERG_LOG("%s\n", para_strerror(-ret
));