Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
97aa2dcc1e0309b8ac75f5993f7030bc6441a52e
[simgrid.git] / tools / tesh2 / src / writer.c
1 #include <writer.h>
2 #include <command.h>
3
4 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
5
6 static void*
7 writer_start_routine(void* p);
8
9 writer_t
10 writer_new(command_t command)
11 {
12         writer_t writer = xbt_new0(s_writer_t, 1);
13
14         writer->thread = NULL;
15         writer->command = command;
16         writer->started = xbt_os_sem_init(0);
17
18         return writer;
19 }
20
21 void
22 writer_free(writer_t* writer)
23 {
24         free(*writer);
25         *writer = NULL;
26 }
27
28 void
29 writer_write(writer_t writer)
30 {
31         writer->thread = xbt_os_thread_create("", writer_start_routine, writer);
32 }
33
34 #ifdef WIN32
35 static void*
36 writer_start_routine(void* p)
37 {
38         writer_t writer = (writer_t)p;
39         command_t command = writer->command;
40         
41         char* input = (char*)(command->context->input->data);
42         
43         DWORD number_of_bytes_to_write = command->context->input->used;
44         DWORD number_of_bytes_written = 0;
45
46         
47         while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)
48         {
49                 if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))
50                 {
51                         if(GetLastError() ==  ERROR_NO_DATA)
52                                 writer->broken_pipe = 1;
53                         else
54                         writer->failed = 1;
55                                 
56                 }
57                 else
58                 {
59                         input += number_of_bytes_written;
60                         number_of_bytes_to_write -= number_of_bytes_written;
61                 }
62         }
63         
64         command->context->input->data[0]='\0';
65         command->context->input->used=0;
66         
67         if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
68         {
69                 command_kill(command);
70                 exit_code = EWRITE;
71                 command_handle_failure(command, csr_write_failure);
72         }
73         /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
74         {
75                 command_kill(command);
76                 command_handle_failure(command, csr_write_pipe_broken);
77         }*/
78         
79
80         return NULL;
81 }
82 #else
83 /*static void* 
84 writer_start_routine(void* p) 
85 {
86         writer_t writer = (writer_t)p;
87         command_t command = writer->command;
88         int number_of_bytes_written = 0;
89         int number_of_bytes_to_write = command->context->input->used;
90         char* input = (char*)(command->context->input->data);
91         int got;
92         
93         xbt_os_sem_release(writer->started);
94         
95         
96         
97         while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && (number_of_bytes_written < number_of_bytes_to_write))
98         {
99                 got = write(writer->command->stdin_fd, input + number_of_bytes_written, number_of_bytes_to_write - number_of_bytes_written);
100                 
101                 if(got > 0)
102                         number_of_bytes_written += got;
103                 
104                 if(got < 0) 
105                 {
106                         if(errno == EPIPE) 
107                         {
108                                 writer->broken_pipe = 1;
109                         } 
110                         else if(errno != EINTR && errno != EAGAIN && errno != EPIPE) 
111                         {
112                                 writer->failed = 1;
113                         }
114                 }
115         
116                 if(got <= 0)
117                         usleep(100);
118         }
119         
120         command->context->input->data[0]='\0';
121         command->context->input->used=0;
122         
123         if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
124         {
125                 command_kill(command);
126                 exit_code = EWRITE;
127                 command_handle_failure(command, csr_write_failure);
128         }
129         else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
130         {
131                 command_kill(command);
132                 exit_code = EWRITEPIPE;
133                 command_handle_failure(command, csr_write_pipe_broken);
134         }
135         
136         
137         close(command->stdin_fd);
138         command->stdin_fd = INDEFINITE_FD;
139         
140         return NULL;
141 }*/
142
143 static void* 
144 writer_start_routine(void* p) 
145 {
146         writer_t writer = (writer_t)p;
147         command_t command = writer->command;
148         long number_of_bytes_to_write = command->context->input->used;
149         char* input = (char*)(command->context->input->data);
150         int got;
151         
152         xbt_os_sem_release(writer->started);
153         
154         while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)
155         {
156                 got = number_of_bytes_to_write > SSIZE_MAX ? SSIZE_MAX : number_of_bytes_to_write;
157                 got = write( writer->command->stdin_fd, input, got );
158                         
159                 if(got < 0) 
160                 {
161                         if(EINTR == errno || EAGAIN == errno)
162                         {
163                                 continue;
164                         }
165                         else if(EPIPE == errno) 
166                         {
167                                 writer->broken_pipe = 1;
168                                 break;
169                         } 
170                         else
171                         {
172                                 writer->failed = 1;
173                                 break;
174                         }
175                         
176                 }
177                 
178                 number_of_bytes_to_write -= got;
179                 input += got;
180                 
181                 if(got == 0)
182                         usleep(100);
183         }
184         
185         command->context->input->data[0]='\0';
186         command->context->input->used=0;
187         
188         if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
189         {
190                 command_kill(command);
191                 exit_code = EWRITE;
192                 command_handle_failure(command, csr_write_failure);
193         }
194         else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
195         {
196                 command_kill(command);
197                 exit_code = EWRITEPIPE;
198                 command_handle_failure(command, csr_write_pipe_broken);
199         }
200         
201         
202         close(command->stdin_fd);
203         command->stdin_fd = INDEFINITE_FD;
204         
205         return NULL;
206         
207 }
208
209 #endif
210 void
211 writer_wait(writer_t writer)
212 {
213         xbt_os_thread_join(writer->thread, NULL);
214
215 }