Logo AND Algorithmique Numérique Distribuée

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