Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
tesh version 2
[simgrid.git] / tools / tesh2 / src / reader.c
1 #include <reader.h>
2 #include <command.h>
3
4 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
5
6 static void*
7 reader_start_routine(void* p);
8
9 reader_t
10 reader_new(command_t command)
11 {
12         reader_t reader = xbt_new0(s_reader_t, 1);
13         
14         reader->thread = NULL;
15         reader->command = command;
16         reader->broken_pipe = 0;
17         reader->failed = 0;
18         
19         reader->started = xbt_os_sem_init(0);
20         
21         return reader;
22 }
23
24 void
25 reader_free(reader_t* reader)
26 {
27         free(*reader);
28         *reader = NULL;
29 }
30
31 void
32 reader_read(reader_t reader)
33 {
34         reader->thread = xbt_os_thread_create("", reader_start_routine, reader);
35 }
36
37 #ifdef WIN32
38 static void*
39 reader_start_routine(void* p)
40 {
41         reader_t reader = (reader_t)p;
42         command_t command = reader->command;
43         
44         xbt_strbuff_t output = command->output;
45         HANDLE stdout_fd = command->stdout_fd;
46         
47         DWORD number_of_bytes_to_read = 4096;
48         DWORD number_of_bytes_readed;
49         
50         char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
51         
52         while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && !reader->broken_pipe)
53         {
54                 if(!ReadFile(reader->command->stdout_fd, buffer, number_of_bytes_to_read, &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
55                 {
56                         if(GetLastError() == ERROR_BROKEN_PIPE)
57                                 reader->broken_pipe = 1;
58                         else
59                         reader->failed = 1;
60                 }
61                 else
62                 {
63                         if(number_of_bytes_readed > 0) 
64                         {
65                                 buffer[number_of_bytes_readed]='\0';
66                                 xbt_strbuff_append(output,buffer);
67                         } 
68                         else 
69                         {
70                                 xbt_os_thread_yield();
71                         }
72                 }
73         }
74         
75         free(buffer);
76
77         if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
78         {
79                 command_kill(command);
80                 exit_code = EREAD;
81                 command_handle_failure(command, csr_read_failure);
82         }
83         
84         return NULL;
85 }
86 #else
87 static void*
88 reader_start_routine(void* p) 
89 {
90         reader_t reader = (reader_t)p;
91         command_t command = reader->command;
92         xbt_strbuff_t output = command->output;
93         int stdout_fd = command->stdout_fd;
94         int number_of_bytes_readed;
95         int number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;
96                 
97         char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
98         xbt_os_sem_release(reader->started);
99         
100         do 
101         {
102                 number_of_bytes_readed = read(stdout_fd, buffer, number_of_bytes_to_read);
103                 
104                 if(number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN) 
105                 {
106                         reader->failed = 1;
107                 }
108                 
109                 if(number_of_bytes_readed > 0) 
110                 {
111                         buffer[number_of_bytes_readed]='\0';
112                         xbt_strbuff_append(output,buffer);
113                 } 
114                 else 
115                 {
116                         usleep(100);
117                 }
118         
119         }while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && (number_of_bytes_readed != 0 /* end of file <-> normal exit */));
120         
121         free(buffer);
122
123         if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
124         {
125                 command_kill(command);
126                 exit_code = EREAD;
127                 command_handle_failure(command, csr_read_failure);
128         }
129         
130         reader->broken_pipe = 1;
131         
132         /*printf("the reader of the command %p is ended\n",command);*/
133         
134         return NULL;
135
136 #endif
137
138 void
139 reader_wait(reader_t reader)
140 {
141         xbt_os_thread_join(reader->thread, NULL);
142 }