Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Delete unused -fprofile-arcs flags.
[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
19 \r
20 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
21 \r
22 \r
23 static void*\r
24 reader_start_routine(void* p);\r
25 \r
26 reader_t\r
27 reader_new(command_t command)\r
28 {\r
29         reader_t reader;\r
30         \r
31         /* TODO : check the parameter */\r
32         \r
33         reader = xbt_new0(s_reader_t, 1);\r
34         \r
35         reader->thread = NULL;\r
36         reader->command = command;\r
37         reader->broken_pipe = 0;\r
38         reader->failed = 0;\r
39         reader->done = 0;\r
40         \r
41         reader->started = xbt_os_sem_init(0);\r
42         \r
43         return reader;\r
44 }\r
45 \r
46 int\r
47 reader_free(reader_t* ptr)\r
48 {\r
49         if((*ptr)->started)\r
50                 xbt_os_sem_destroy((*ptr)->started);\r
51         \r
52         free(*ptr);\r
53         \r
54         *ptr = NULL;\r
55         \r
56         return 0;\r
57 }\r
58 \r
59 void\r
60 reader_read(reader_t reader)\r
61 {\r
62         reader->thread = xbt_os_thread_create("", reader_start_routine, reader);\r
63 }\r
64 \r
65 #ifdef WIN32\r
66 static void*\r
67 reader_start_routine(void* p)\r
68 {\r
69         reader_t reader = (reader_t)p;\r
70         command_t command = reader->command;\r
71         \r
72         xbt_strbuff_t output = command->output;\r
73         HANDLE stdout_fd = command->stdout_fd;\r
74         \r
75         DWORD number_of_bytes_to_read = 1024; /*command->context->output->used;*/\r
76         DWORD number_of_bytes_readed = 0;\r
77         \r
78         char* buffer = (char*)calloc(number_of_bytes_to_read + 1,sizeof(char));\r
79         char* clean = (char*)calloc(number_of_bytes_to_read + 1,sizeof(char));\r
80         size_t i, j;\r
81 \r
82         xbt_os_sem_release(reader->started);\r
83 \r
84         while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && !reader->broken_pipe)\r
85         {\r
86                 if(!ReadFile(stdout_fd, buffer, number_of_bytes_to_read, &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))\r
87                 {\r
88                         if(GetLastError() == ERROR_BROKEN_PIPE)\r
89                                 reader->broken_pipe = 1;\r
90                         else\r
91                         reader->failed = 1;\r
92                                 \r
93                 }\r
94                 else\r
95                 {\r
96                         if(number_of_bytes_readed > 0) \r
97                         {\r
98                                 for(i= 0, j= 0; i < number_of_bytes_readed; i++)\r
99                                         if((buffer[i]) != '\r')\r
100                                                 clean[j++] = buffer[i];\r
101 \r
102                                 xbt_strbuff_append(output,clean);\r
103 \r
104                                 memset(buffer, 0, 1024);\r
105                                 memset(clean, 0, 1024);\r
106                         } \r
107                         else \r
108                         {\r
109                                 xbt_os_thread_yield();\r
110                         }\r
111                 }\r
112         }\r
113 \r
114         free(clean);\r
115         free(buffer);\r
116 \r
117         xbt_strbuff_chomp(command->output);\r
118         xbt_strbuff_trim(command->output);\r
119 \r
120         reader->done = 1;\r
121         \r
122         if(command->failed)\r
123         {\r
124                 if(command->reason == csr_write_failure)\r
125                 {\r
126                         if(command->output->used)\r
127                                 INFO2("[%s] Output on write failure:\n%s",command->context->pos, command->output->data);\r
128                         else\r
129                                 INFO1("[%s] No output before write failure",command->context->pos);\r
130                 }\r
131                 else if(command->reason == csr_write_pipe_broken)\r
132                 {\r
133                         if(command->output->used)\r
134                                 INFO2("[%s] Output on broken pipe:\n%s",command->context->pos, command->output->data);\r
135                         else\r
136                                 INFO1("[%s] No output before broken pipe",command->context->pos);\r
137                 }\r
138         }\r
139         else if(command->interrupted)\r
140         {\r
141                 if(command->output->used)\r
142                         INFO2("[%s] Output on interruption:\n%s",command->context->pos, command->output->data);\r
143                 else\r
144                         INFO1("[%s] No output before interruption",command->context->pos);\r
145         }\r
146         else if(reader->failed && !command->failed && !command->interrupted && !command->successeded)\r
147         {\r
148                 ERROR2("[%s] Error while reading output of child `%s'", command->context->pos, command->context->command_line);\r
149                 \r
150                 if(command->output->used)\r
151                         INFO2("[%s] Output on read failure:\n%s",command->context->pos, command->output->data);\r
152                 else\r
153                         INFO1("[%s] No output before read failure",command->context->pos);\r
154                 \r
155                 unit_set_error(command->unit, errno, 0, command->context->pos);\r
156                 command_kill(command);\r
157                 command_handle_failure(command, csr_read_failure);\r
158         }\r
159 \r
160         \r
161         \r
162         return NULL;\r
163 }\r
164 \r
165 #else\r
166 static void*\r
167 reader_start_routine(void* p) \r
168 {\r
169         reader_t reader = (reader_t)p;\r
170         command_t command = reader->command;\r
171         xbt_strbuff_t output = command->output;\r
172         int stdout_fd = command->stdout_fd;\r
173         int number_of_bytes_readed;\r
174         int number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;\r
175 \r
176         int total = 0;\r
177                 \r
178         char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));\r
179         xbt_os_sem_release(reader->started);\r
180         \r
181         do \r
182         {\r
183                 number_of_bytes_readed = read(stdout_fd, buffer, number_of_bytes_to_read);\r
184                 \r
185                 if(number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN) \r
186                 {\r
187                         reader->failed = 1;\r
188                 }\r
189                 \r
190                 if(number_of_bytes_readed > 0) \r
191                 {\r
192                         buffer[number_of_bytes_readed]='\0';\r
193                         xbt_strbuff_append(output,buffer);\r
194                         total += total;\r
195                 } \r
196                 else \r
197                 {\r
198                         xbt_os_thread_yield();\r
199                 }\r
200         \r
201         }while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && (number_of_bytes_readed != 0 /* end of file <-> normal exit */));\r
202         \r
203         free(buffer);\r
204         \r
205         if(close(command->stdout_fd) < 0)\r
206         {\r
207                 /* TODO */\r
208         }\r
209         else\r
210                 command->stdout_fd = INDEFINITE_FD;\r
211         \r
212         xbt_strbuff_chomp(command->output);\r
213         xbt_strbuff_trim(command->output);\r
214 \r
215         reader->done = 1;\r
216 \r
217         if(command->failed)\r
218         {\r
219                 if(command->reason == csr_write_failure)\r
220                 {\r
221                         if(command->output->used)\r
222                                 INFO2("[%s] Output on write failure:\n%s",command->context->pos, command->output->data);\r
223                         else\r
224                                 INFO1("[%s] No output before write failur",command->context->pos);\r
225                 }\r
226                 else if(command->reason == csr_write_pipe_broken)\r
227                 {\r
228                         if(command->output->used)\r
229                                 INFO2("[%s] Output on broken pipe:\n%s",command->context->pos, command->output->data);\r
230                         else\r
231                                 INFO1("[%s] No output before broken pipe",command->context->pos);\r
232                 }\r
233         }\r
234         else if(command->interrupted)\r
235         {\r
236                 if(command->output->used)\r
237                         INFO2("[%s] Output on interruption:\n%s",command->context->pos, command->output->data);\r
238                 else\r
239                         INFO1("[%s] No output before interruption",command->context->pos);\r
240         }\r
241         else if(reader->failed && !command->failed && !command->interrupted && !command->successeded)\r
242         {\r
243                 ERROR2("[%s] Error while reading output of child `%s'", command->context->pos, command->context->command_line);\r
244                 \r
245                 if(command->output->used)\r
246                         INFO2("[%s] Output on read failure:\n%s",command->context->pos, command->output->data);\r
247                 else\r
248                         INFO1("[%s] No output before read failure",command->context->pos);\r
249                 \r
250                 unit_set_error(command->unit, errno, 0, command->context->pos);\r
251                 command_kill(command);\r
252                 command_handle_failure(command, csr_read_failure);\r
253         }\r
254         \r
255         \r
256         return NULL;\r
257\r
258 #endif\r
259 \r
260 void\r
261 reader_wait(reader_t reader)\r
262 {\r
263         xbt_os_thread_join(reader->thread, NULL);\r
264 }\r