+++ /dev/null
-/*\r
- * src/writer.c - type representing a stdin writer.\r
- *\r
- * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. \r
- *\r
- * This program is free software; you can redistribute it and/or modify it \r
- * under the terms of the license (GNU LGPL) which comes with this package.\r
- *\r
- * Purpose:\r
- * This file contains all the definitions of the functions related with\r
- * the tesh writer type.\r
- *\r
- */ \r
- \r
-#include <writer.h>\r
-#include <command.h>\r
-#include <unit.h>\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