* This file contains all the definitions of the functions related with\r
* the tesh writer type.\r
*\r
- */\r
- \r
+ */ \r
+ \r
#include <writer.h>\r
#include <command.h>\r
#include <unit.h>\r
-\r
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
-\r
-static void*\r
-writer_start_routine(void* p);\r
-\r
-writer_t\r
-writer_new(command_t command)\r
-{\r
- writer_t writer;\r
- /* TODO : check the parameter */\r
- \r
- writer = xbt_new0(s_writer_t, 1);\r
-\r
- writer->thread = NULL;\r
- writer->command = command;\r
- writer->written = xbt_os_sem_init(0);\r
- writer->can_write = xbt_os_sem_init(0);\r
- \r
- writer->done = 0;\r
-\r
- return writer;\r
-}\r
-\r
-int\r
-writer_free(writer_t* ptr)\r
-{\r
-\r
- if((*ptr)->written)\r
- xbt_os_sem_destroy((*ptr)->written);\r
- \r
- if((*ptr)->can_write)\r
- xbt_os_sem_destroy((*ptr)->can_write);\r
- \r
- free(*ptr);\r
-\r
- *ptr = NULL;\r
- \r
- return 0;\r
-}\r
-\r
-void\r
-writer_write(writer_t writer)\r
-{\r
- writer->thread = xbt_os_thread_create("", writer_start_routine, writer);\r
-}\r
-\r
-#ifdef WIN32\r
-static void*\r
-writer_start_routine(void* p)\r
-{\r
- writer_t writer = (writer_t)p;\r
- command_t command = writer->command;\r
- \r
- char* input = (char*)(command->context->input->data);\r
- \r
- DWORD number_of_bytes_to_write = command->context->input->used;\r
- DWORD number_of_bytes_written = 0;\r
-\r
- while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)\r
- {\r
- if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))\r
- {\r
- if(GetLastError() == ERROR_NO_DATA)\r
- writer->broken_pipe = 1;\r
- else\r
- writer->failed = 1;\r
- \r
- }\r
- else\r
- {\r
- input += number_of_bytes_written;\r
- number_of_bytes_to_write -= number_of_bytes_written;\r
- }\r
- }\r
- \r
- command->context->input->data[0]='\0';\r
- command->context->input->used=0;\r
- \r
- if(writer->failed && !command->successeded && !command->failed && !command->interrupted)\r
- {\r
- ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
- unit_set_error(command->unit, (int)GetLastError(), 0);\r
- command_handle_failure(command, csr_write_failure);\r
- }\r
- /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
- {\r
-\r
- ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
- unit_set_error(command->unit, (int)GetLastError(), 0);\r
- command_kill(command);\r
- command_handle_failure(command, csr_write_pipe_broken);\r
- }*/\r
- \r
- CloseHandle(command->stdin_fd);\r
- command->stdin_fd = INDEFINITE_FD;\r
-\r
- return NULL;\r
-}\r
-#else\r
-static void* \r
-writer_start_routine(void* p) \r
-{\r
- writer_t writer = (writer_t)p;\r
- command_t command = writer->command;\r
- int number_of_bytes_to_write = command->context->input->used;\r
- char* input = (char*)(command->context->input->data);\r
- int got;\r
- int released = 0;\r
- \r
- while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)\r
- {\r
- got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;\r
- got = write(writer->command->stdin_fd, input, got );\r
- \r
- if(got < 0) \r
- {\r
- if(EINTR == errno)\r
- continue;\r
- \r
- else if(EAGAIN == errno)\r
- {/* the pipe is full */\r
- if(!released)\r
- {\r
- xbt_os_sem_release(writer->written);\r
- released = 1;\r
- xbt_os_thread_yield();\r
- }\r
- \r
- continue;\r
- }\r
- else if(EPIPE == errno) \r
- {\r
- writer->broken_pipe = 1;\r
- break;\r
- } \r
- else\r
- {\r
- writer->failed = 1;\r
- break;\r
- }\r
- \r
- }\r
- \r
- number_of_bytes_to_write -= got;\r
- input += got;\r
- \r
- if(got == 0)\r
- xbt_os_thread_yield();\r
- \r
- }\r
- \r
- if(!released)\r
- xbt_os_sem_release(writer->written);\r
- \r
- \r
- if(close(command->stdin_fd) < 0)\r
- {\r
- /* TODO */\r
- }\r
- else\r
- command->stdin_fd = INDEFINITE_FD;\r
- \r
- command->context->input->data[0]='\0';\r
- command->context->input->used=0;\r
- \r
- if(writer->failed && !command->successeded && !command->failed && !command->interrupted)\r
- {\r
- command_kill(command);\r
- ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
- \r
- unit_set_error(command->unit, errno, 0);\r
- command_handle_failure(command, csr_write_failure);\r
- }\r
- else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
- {\r
- ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
-\r
- unit_set_error(command->unit, errno, 0);\r
- command_kill(command);\r
- command_handle_failure(command, csr_write_pipe_broken);\r
- }\r
- \r
- writer->done = 1;\r
- \r
- return NULL;\r
- \r
-}\r
-\r
-#endif\r
-void\r
-writer_wait(writer_t writer)\r
-{\r
- xbt_os_thread_join(writer->thread, NULL);\r
-\r
-}\r
+ \rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
+\r\rstatic void *\r writer_start_routine(void *p);
+\r\rwriter_t \r writer_new(command_t command) \r
+{
+ \rwriter_t writer;
+ \r
+ /* TODO : check the parameter */ \r
+ \rwriter = xbt_new0(s_writer_t, 1);
+ \r\rwriter->thread = NULL;
+ \rwriter->command = command;
+ \rwriter->written = xbt_os_sem_init(0);
+ \rwriter->can_write = xbt_os_sem_init(0);
+ \r\rwriter->done = 0;
+ \r\rreturn writer;
+\r}
+
+\r\rint \r writer_free(writer_t * ptr) \r
+{
+ \r\rif ((*ptr)->written)
+ \rxbt_os_sem_destroy((*ptr)->written);
+ \r\rif ((*ptr)->can_write)
+ \rxbt_os_sem_destroy((*ptr)->can_write);
+ \r\rfree(*ptr);
+ \r\r*ptr = NULL;
+ \r\rreturn 0;
+\r}
+
+\r\rvoid \r writer_write(writer_t writer) \r
+{
+ \rwriter->thread = xbt_os_thread_create("", writer_start_routine, writer);
+\r} \r\r
+
+#ifdef _XBT_WIN32\r
+static void *\r writer_start_routine(void *p) \r
+{
+ \rwriter_t writer = (writer_t) p;
+ \rcommand_t command = writer->command;
+ \r\rchar *input = (char *) (command->context->input->data);
+ \r\rDWORD number_of_bytes_to_write = command->context->input->used;
+ \rDWORD number_of_bytes_written = 0;
+ \r\rxbt_os_sem_release(writer->written);
+ \r\rwhile (!command->failed && !command->interrupted
+ && !command->successeded && !writer->failed
+ && !writer->broken_pipe && number_of_bytes_to_write)
+ \r {
+ \rif (!WriteFile
+ (writer->command->stdin_fd, input, number_of_bytes_to_write,
+ &number_of_bytes_written, NULL))
+ \r {
+ \rif (GetLastError() == ERROR_NO_DATA)
+ \rwriter->broken_pipe = 1;
+ \r
+ else
+ \rwriter->failed = 1;
+ \r\r}
+ \r
+ else
+ \r {
+ \rinput += number_of_bytes_written;
+ \rnumber_of_bytes_to_write -= number_of_bytes_written;
+ \r}
+ \r}
+ \r\rcommand->context->input->data[0] = '\0';
+ \rcommand->context->input->used = 0;
+ \r\rif (writer->failed && !command->successeded && !command->failed
+ && !command->interrupted)
+ \r {
+ \rERROR2("[%s] Error while writing input to child `%s'",
+ command->context->pos, command->context->command_line);
+ \runit_set_error(command->unit, (int) GetLastError(), 0,
+ command->context->pos);
+ \rcommand_handle_failure(command, csr_write_failure);
+ \r}
+ \r
+ /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
+ {\r
+ \r
+ ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
+ unit_set_error(command->unit, (int)GetLastError(), 0);\r
+ command_kill(command);\r
+ command_handle_failure(command, csr_write_pipe_broken);\r
+ } */ \r
+ \rCloseHandle(command->stdin_fd);
+ \rcommand->stdin_fd = INDEFINITE_FD;
+ \r\rreturn NULL;
+\r}
+
+\r
+#else /* \r */
+static void *\r writer_start_routine(void *p) \r
+{
+ \rwriter_t writer = (writer_t) p;
+ \rcommand_t command = writer->command;
+ \rint number_of_bytes_to_write = command->context->input->used;
+ \rchar *input = (char *) (command->context->input->data);
+ \rint got;
+ \rint released = 0;
+ \r\rwhile (!command->failed && !command->interrupted
+ && !command->successeded && number_of_bytes_to_write > 0)
+ \r {
+ \rgot =
+ number_of_bytes_to_write >
+ PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;
+ \rgot = write(writer->command->stdin_fd, input, got);
+ \r\rif (got < 0)
+ \r {
+ \rif (EINTR == errno)
+ \rcontinue;
+ \r\r
+ else if (EAGAIN == errno)
+ \r { /* the pipe is full */
+ \rif (!released)
+ \r {
+ \rxbt_os_sem_release(writer->written);
+ \rreleased = 1;
+ \rxbt_os_thread_yield();
+ \r}
+ \r\rcontinue;
+ \r}
+ \r
+ else if (EPIPE == errno)
+ \r {
+ \rwriter->broken_pipe = 1;
+ \rbreak;
+ \r}
+ \r
+ else
+ \r {
+ \rwriter->failed = 1;
+ \rbreak;
+ \r}
+ \r\r}
+ \r\rnumber_of_bytes_to_write -= got;
+ \rinput += got;
+ \r\rif (got == 0)
+ \rxbt_os_thread_yield();
+ \r\r}
+ \r\rif (!released)
+ \rxbt_os_sem_release(writer->written);
+ \r\r\rif (close(command->stdin_fd) < 0)
+ \r {
+ \r
+ /* TODO */ \r
+ }
+ \r
+ else
+ \rcommand->stdin_fd = INDEFINITE_FD;
+ \r\rcommand->context->input->data[0] = '\0';
+ \rcommand->context->input->used = 0;
+ \r\rif (writer->failed && !command->successeded && !command->failed
+ && !command->interrupted)
+ \r {
+ \rcommand_kill(command);
+ \rERROR2("[%s] Error while writing input to child `%s'",
+ command->context->pos, command->context->command_line);
+ \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+ \rcommand_handle_failure(command, csr_write_failure);
+ \r}
+ \r
+ else if (writer->broken_pipe && !command->successeded && !command->failed
+ && !command->interrupted)
+ \r {
+ \rERROR2("[%s] Pipe broken while writing input to child `%s'",
+ command->context->pos, command->context->command_line);
+ \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+ \rcommand_kill(command);
+ \rcommand_handle_failure(command, csr_write_pipe_broken);
+ \r}
+ \r\rwriter->done = 1;
+ \r\rreturn NULL;
+\r\r}
+
+\r\r
+#endif /* \r */
+void \r writer_wait(writer_t writer) \r
+{
+ \rxbt_os_thread_join(writer->thread, NULL);
+\r\r} \r