2 * src/reader.c - type representing a stdout reader.
\r
4 * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved.
\r
6 * This program is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the license (GNU LGPL) which comes with this package.
\r
10 * This file contains all the definitions of the functions related with
\r
11 * the tesh reader type.
\r
17 #include <command.h>
\r
18 \r\rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
19 \r\r\rstatic void *
\r reader_start_routine(void *p);
20 \r\rreader_t
\r reader_new(command_t command)
\r
24 /* TODO : check the parameter */
\r
25 \rreader = xbt_new0(s_reader_t, 1);
26 \r\rreader->thread = NULL;
27 \rreader->command = command;
28 \rreader->broken_pipe = 0;
31 \r\rreader->started = xbt_os_sem_init(0);
35 \r\rint
\r reader_free(reader_t * ptr)
\r
37 \rif ((*ptr)->started)
38 \rxbt_os_sem_destroy((*ptr)->started);
44 \r\rvoid
\r reader_read(reader_t reader)
\r
46 \rreader->thread = xbt_os_thread_create("", reader_start_routine, reader);
50 static void *
\r reader_start_routine(void *p)
\r
52 \rreader_t reader = (reader_t) p;
53 \rcommand_t command = reader->command;
54 \r\rxbt_strbuff_t output = command->output;
55 \rHANDLE stdout_fd = command->stdout_fd;
56 \r\rDWORD number_of_bytes_to_read = 1024; /*command->context->output->used; */
57 \rDWORD number_of_bytes_readed = 0;
59 (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
61 (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
63 \r\rxbt_os_sem_release(reader->started);
64 \r\rwhile (!command->failed && !command->interrupted
65 && !command->successeded && !reader->failed
66 && !reader->broken_pipe)
69 (stdout_fd, buffer, number_of_bytes_to_read,
70 &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
72 \rif (GetLastError() == ERROR_BROKEN_PIPE)
73 \rreader->broken_pipe = 1;
81 \rif (number_of_bytes_readed > 0)
83 \rfor (i = 0, j = 0; i < number_of_bytes_readed; i++)
84 \rif ((buffer[i]) != '\r')
85 \rclean[j++] = buffer[i];
86 \r\rxbt_strbuff_append(output, clean);
87 \r\rmemset(buffer, 0, 1024);
88 \rmemset(clean, 0, 1024);
93 \rxbt_os_thread_yield();
99 \r\rxbt_strbuff_chomp(command->output);
100 \rxbt_strbuff_trim(command->output);
101 \r\rreader->done = 1;
102 \r\rif (command->failed)
104 \rif (command->reason == csr_write_failure)
106 \rif (command->output->used)
107 \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
108 command->output->data);
111 \rINFO1("[%s] No output before write failure",
112 command->context->pos);
115 else if (command->reason == csr_write_pipe_broken)
117 \rif (command->output->used)
118 \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
119 command->output->data);
122 \rINFO1("[%s] No output before broken pipe", command->context->pos);
126 else if (command->interrupted)
128 \rif (command->output->used)
129 \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
130 command->output->data);
133 \rINFO1("[%s] No output before interruption", command->context->pos);
136 else if (reader->failed && !command->failed && !command->interrupted
137 && !command->successeded)
139 \rERROR2("[%s] Error while reading output of child `%s'",
140 command->context->pos, command->context->command_line);
141 \r\rif (command->output->used)
142 \rINFO2("[%s] Output on read failure:\n%s", command->context->pos,
143 command->output->data);
146 \rINFO1("[%s] No output before read failure", command->context->pos);
147 \r\runit_set_error(command->unit, errno, 0, command->context->pos);
148 \rcommand_kill(command);
149 \rcommand_handle_failure(command, csr_read_failure);
156 static void *
\r reader_start_routine(void *p)
\r
158 \rreader_t reader = (reader_t) p;
159 \rcommand_t command = reader->command;
160 \rxbt_strbuff_t output = command->output;
161 \rint stdout_fd = command->stdout_fd;
162 \rint number_of_bytes_readed;
163 \rint number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;
165 \r\rchar *buffer = (char *) calloc(number_of_bytes_to_read, sizeof(char));
166 \rxbt_os_sem_release(reader->started);
170 \rnumber_of_bytes_readed =
171 read(stdout_fd, buffer, number_of_bytes_to_read);
172 \r\rif (number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN)
174 \rreader->failed = 1;
176 \r\rif (number_of_bytes_readed > 0)
178 \rbuffer[number_of_bytes_readed] = '\0';
179 \rxbt_strbuff_append(output, buffer);
185 \rxbt_os_thread_yield();
187 \r\r} while (!command->failed && !command->interrupted
188 && !command->successeded && !reader->failed
189 && (number_of_bytes_readed !=
190 0 /* end of file <-> normal exit */ ));
192 \r\rif (close(command->stdout_fd) < 0)
199 \rcommand->stdout_fd = INDEFINITE_FD;
200 \r\rxbt_strbuff_chomp(command->output);
201 \rxbt_strbuff_trim(command->output);
202 \r\rreader->done = 1;
203 \r\rif (command->failed)
205 \rif (command->reason == csr_write_failure)
207 \rif (command->output->used)
208 \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
209 command->output->data);
212 \rINFO1("[%s] No output before write failur",
213 command->context->pos);
216 else if (command->reason == csr_write_pipe_broken)
218 \rif (command->output->used)
219 \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
220 command->output->data);
223 \rINFO1("[%s] No output before broken pipe", command->context->pos);
227 else if (command->interrupted)
229 \rif (command->output->used)
230 \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
231 command->output->data);
234 \rINFO1("[%s] No output before interruption", command->context->pos);
237 else if (reader->failed && !command->failed && !command->interrupted
238 && !command->successeded)
240 \rERROR2("[%s] Error while reading output of child `%s'",
241 command->context->pos, command->context->command_line);
242 \r\rif (command->output->used)
243 \rINFO2("[%s] Output on read failure:\n%s", command->context->pos,
244 command->output->data);
247 \rINFO1("[%s] No output before read failure", command->context->pos);
248 \r\runit_set_error(command->unit, errno, 0, command->context->pos);
249 \rcommand_kill(command);
250 \rcommand_handle_failure(command, csr_read_failure);
257 \rvoid
\r reader_wait(reader_t reader)
\r
259 \rxbt_os_thread_join(reader->thread, NULL);