Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Indent the rest of the code (examples, buildtools, doc...) except for examples/SMPI...
[simgrid.git] / tools / tesh2 / src / reader.c
1 /*\r
2  * src/reader.c - type representing a stdout reader.\r
3  *\r
4  * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. \r
5  *\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
8  *\r
9  * Purpose:\r
10  *              This file contains all the definitions of the functions related with\r
11  *              the tesh reader type.\r
12  *\r
13  */  \r
14     \r
15 #include <unit.h>\r
16 #include <reader.h>\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
21 {
22   \rreader_t reader;
23   \r\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;
29   \rreader->failed = 0;
30   \rreader->done = 0;
31   \r\rreader->started = xbt_os_sem_init(0);
32   \r\rreturn reader;
33 \r}
34
35 \r\rint \r reader_free(reader_t * ptr) \r
36 {
37   \rif ((*ptr)->started)
38     \rxbt_os_sem_destroy((*ptr)->started);
39   \r\rfree(*ptr);
40   \r\r*ptr = NULL;
41   \r\rreturn 0;
42 \r}
43
44 \r\rvoid \r reader_read(reader_t reader) \r
45 {
46   \rreader->thread = xbt_os_thread_create("", reader_start_routine, reader);
47 \r\r\r
48
49 #ifdef _XBT_WIN32\r
50 static void *\r reader_start_routine(void *p) \r
51 {
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;
58   \r\rchar *buffer =
59       (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
60   \rchar *clean =
61       (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
62   \rsize_t i, j;
63   \r\rxbt_os_sem_release(reader->started);
64   \r\rwhile (!command->failed && !command->interrupted
65            && !command->successeded && !reader->failed
66            && !reader->broken_pipe)
67     \r {
68     \rif (!ReadFile
69          (stdout_fd, buffer, number_of_bytes_to_read,
70           &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
71       \r {
72       \rif (GetLastError() == ERROR_BROKEN_PIPE)
73         \rreader->broken_pipe = 1;
74       \r
75       else
76         \rreader->failed = 1;
77       \r\r}
78     \r
79     else
80       \r {
81       \rif (number_of_bytes_readed > 0)
82         \r {
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);
89         \r}
90       \r
91       else
92         \r {
93         \rxbt_os_thread_yield();
94         \r}
95       \r}
96     \r}
97   \r\rfree(clean);
98   \rfree(buffer);
99   \r\rxbt_strbuff_chomp(command->output);
100   \rxbt_strbuff_trim(command->output);
101   \r\rreader->done = 1;
102   \r\rif (command->failed)
103     \r {
104     \rif (command->reason == csr_write_failure)
105       \r {
106       \rif (command->output->used)
107         \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
108                command->output->data);
109       \r
110       else
111         \rINFO1("[%s] No output before write failure",
112                command->context->pos);
113       \r}
114     \r
115     else if (command->reason == csr_write_pipe_broken)
116       \r {
117       \rif (command->output->used)
118         \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
119                command->output->data);
120       \r
121       else
122         \rINFO1("[%s] No output before broken pipe", command->context->pos);
123       \r}
124     \r}
125   \r
126   else if (command->interrupted)
127     \r {
128     \rif (command->output->used)
129       \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
130              command->output->data);
131     \r
132     else
133       \rINFO1("[%s] No output before interruption", command->context->pos);
134     \r}
135   \r
136   else if (reader->failed && !command->failed && !command->interrupted
137            && !command->successeded)
138     \r {
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);
144     \r
145     else
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);
150     \r}
151   \r\r\r\rreturn NULL;
152 \r}
153
154 \r\r
155 #else   /* \r */
156 static void *\r reader_start_routine(void *p) \r
157 {
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;
164   \r\rint total = 0;
165   \r\rchar *buffer = (char *) calloc(number_of_bytes_to_read, sizeof(char));
166   \rxbt_os_sem_release(reader->started);
167   \r\r
168   do
169     \r {
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)
173       \r {
174       \rreader->failed = 1;
175       \r}
176     \r\rif (number_of_bytes_readed > 0)
177       \r {
178       \rbuffer[number_of_bytes_readed] = '\0';
179       \rxbt_strbuff_append(output, buffer);
180       \rtotal += total;
181       \r}
182     \r
183     else
184       \r {
185       \rxbt_os_thread_yield();
186       \r}
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 */ ));
191   \r\rfree(buffer);
192   \r\rif (close(command->stdout_fd) < 0)
193     \r {
194     \r
195         /* TODO */ \r
196     }
197   \r
198   else
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)
204     \r {
205     \rif (command->reason == csr_write_failure)
206       \r {
207       \rif (command->output->used)
208         \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
209                command->output->data);
210       \r
211       else
212         \rINFO1("[%s] No output before write failur",
213                command->context->pos);
214       \r}
215     \r
216     else if (command->reason == csr_write_pipe_broken)
217       \r {
218       \rif (command->output->used)
219         \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
220                command->output->data);
221       \r
222       else
223         \rINFO1("[%s] No output before broken pipe", command->context->pos);
224       \r}
225     \r}
226   \r
227   else if (command->interrupted)
228     \r {
229     \rif (command->output->used)
230       \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
231              command->output->data);
232     \r
233     else
234       \rINFO1("[%s] No output before interruption", command->context->pos);
235     \r}
236   \r
237   else if (reader->failed && !command->failed && !command->interrupted
238            && !command->successeded)
239     \r {
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);
245     \r
246     else
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);
251     \r}
252   \r\r\rreturn NULL;
253 \r}
254
255 \r
256 #endif  /* \r */
257 \rvoid \r reader_wait(reader_t reader) \r
258 {
259   \rxbt_os_thread_join(reader->thread, NULL);
260 \r\r