Logo AND Algorithmique Numérique Distribuée

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