2 * src/writer.c - type representing a stdin writer.
\r
4 * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved.
\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
10 * This file contains all the definitions of the functions related with
\r
11 * the tesh writer type.
\r
16 #include <command.h>
\r
18 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
\r
21 writer_start_routine(void* p);
\r
24 writer_new(command_t command)
\r
27 /* TODO : check the parameter */
\r
29 writer = xbt_new0(s_writer_t, 1);
\r
31 writer->thread = NULL;
\r
32 writer->command = command;
\r
33 writer->written = xbt_os_sem_init(0);
\r
34 writer->can_write = xbt_os_sem_init(0);
\r
42 writer_free(writer_t* ptr)
\r
44 /* TODO : check the parameter */
\r
46 /*xbt_os_sem_destroy((*writer)->started);
\r
47 xbt_os_sem_destroy((*writer)->can_write);*/
\r
56 writer_write(writer_t writer)
\r
58 writer->thread = xbt_os_thread_create("", writer_start_routine, writer);
\r
63 writer_start_routine(void* p)
\r
65 writer_t writer = (writer_t)p;
\r
66 command_t command = writer->command;
\r
68 char* input = (char*)(command->context->input->data);
\r
70 DWORD number_of_bytes_to_write = command->context->input->used;
\r
71 DWORD number_of_bytes_written = 0;
\r
73 while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)
\r
75 if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))
\r
77 if(GetLastError() == ERROR_NO_DATA)
\r
78 writer->broken_pipe = 1;
\r
85 input += number_of_bytes_written;
\r
86 number_of_bytes_to_write -= number_of_bytes_written;
\r
90 command->context->input->data[0]='\0';
\r
91 command->context->input->used=0;
\r
93 if(writer->failed && !command->successeded && !command->failed && !command->interrupted)
\r
95 error_register("Write failure", errno, command->context->command_line, command->unit->fstream->name);
\r
96 command_handle_failure(command, csr_write_failure);
\r
98 /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
\r
100 command_kill(command);
\r
101 command_handle_failure(command, csr_write_pipe_broken);
\r
104 CloseHandle(command->stdin_fd);
\r
105 command->stdin_fd = INDEFINITE_FD;
\r
111 writer_start_routine(void* p)
\r
113 writer_t writer = (writer_t)p;
\r
114 command_t command = writer->command;
\r
115 int number_of_bytes_to_write = command->context->input->used;
\r
116 char* input = (char*)(command->context->input->data);
\r
120 while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)
\r
122 got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;
\r
123 got = write(writer->command->stdin_fd, input, got );
\r
130 else if(EAGAIN == errno)
\r
131 {/* the pipe is full */
\r
134 xbt_os_sem_release(writer->written);
\r
136 xbt_os_thread_yield();
\r
141 else if(EPIPE == errno)
\r
143 writer->broken_pipe = 1;
\r
148 writer->failed = 1;
\r
154 number_of_bytes_to_write -= got;
\r
158 xbt_os_thread_yield();
\r
163 xbt_os_sem_release(writer->written);
\r
166 if(close(command->stdin_fd) < 0)
\r
171 command->stdin_fd = INDEFINITE_FD;
\r
173 command->context->input->data[0]='\0';
\r
174 command->context->input->used=0;
\r
176 if(writer->failed && !command->successeded && !command->failed && !command->interrupted)
\r
178 command_kill(command);
\r
179 error_register("Write failure", errno, command->context->command_line, command->unit->fstream->name);
\r
180 command_handle_failure(command, csr_write_failure);
\r
182 else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
\r
184 error_register("write() function failed", errno, command->context->command_line, command->unit->fstream->name);
\r
185 command_kill(command);
\r
186 command_handle_failure(command, csr_write_pipe_broken);
\r
197 writer_wait(writer_t writer)
\r
199 xbt_os_thread_join(writer->thread, NULL);
\r