-#include <reader.h>
-#include <command.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void*
-reader_start_routine(void* p);
-
-reader_t
-reader_new(command_t command)
+/*\r
+ * src/reader.c - type representing a stdout reader.\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 reader type.\r
+ *\r
+ */ \r
+ \r
+#include <unit.h>\r
+#include <reader.h>\r
+#include <command.h>\r
+ \r\rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
+\r\r\rstatic void *\r reader_start_routine(void *p);
+\r\rreader_t \r reader_new(command_t command) \r
{
- reader_t reader = xbt_new0(s_reader_t, 1);
-
- reader->thread = NULL;
- reader->command = command;
- reader->broken_pipe = 0;
- reader->failed = 0;
- reader->done = 0;
-
- reader->started = xbt_os_sem_init(0);
-
- return reader;
-}
+ \rreader_t reader;
+ \r\r
+ /* TODO : check the parameter */ \r
+ \rreader = xbt_new0(s_reader_t, 1);
+ \r\rreader->thread = NULL;
+ \rreader->command = command;
+ \rreader->broken_pipe = 0;
+ \rreader->failed = 0;
+ \rreader->done = 0;
+ \r\rreader->started = xbt_os_sem_init(0);
+ \r\rreturn reader;
+\r}
-void
-reader_free(reader_t* reader)
+\r\rint \r reader_free(reader_t * ptr) \r
{
- free(*reader);
- *reader = NULL;
-}
+ \rif ((*ptr)->started)
+ \rxbt_os_sem_destroy((*ptr)->started);
+ \r\rfree(*ptr);
+ \r\r*ptr = NULL;
+ \r\rreturn 0;
+\r}
-void
-reader_read(reader_t reader)
+\r\rvoid \r reader_read(reader_t reader) \r
{
- reader->thread = xbt_os_thread_create("", reader_start_routine, reader);
-}
+ \rreader->thread = xbt_os_thread_create("", reader_start_routine, reader);
+\r} \r\r
-#ifdef WIN32
-static void*
-reader_start_routine(void* p)
+#ifdef _XBT_WIN32\r
+static void *\r reader_start_routine(void *p) \r
{
- reader_t reader = (reader_t)p;
- command_t command = reader->command;
-
- xbt_strbuff_t output = command->output;
- HANDLE stdout_fd = command->stdout_fd;
-
- DWORD number_of_bytes_to_read = 4096;
- DWORD number_of_bytes_readed;
-
- char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
-
- while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && !reader->broken_pipe)
- {
- if(!ReadFile(reader->command->stdout_fd, buffer, number_of_bytes_to_read, &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
- {
- if(GetLastError() == ERROR_BROKEN_PIPE)
- reader->broken_pipe = 1;
- else
- reader->failed = 1;
- }
- else
- {
- if(number_of_bytes_readed > 0)
- {
- buffer[number_of_bytes_readed]='\0';
- xbt_strbuff_append(output,buffer);
- }
- else
- {
- xbt_os_thread_yield();
- }
- }
- }
-
- free(buffer);
+ \rreader_t reader = (reader_t) p;
+ \rcommand_t command = reader->command;
+ \r\rxbt_strbuff_t output = command->output;
+ \rHANDLE stdout_fd = command->stdout_fd;
+ \r\rDWORD number_of_bytes_to_read = 1024; /*command->context->output->used; */
+ \rDWORD number_of_bytes_readed = 0;
+ \r\rchar *buffer =
+ (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
+ \rchar *clean =
+ (char *) calloc(number_of_bytes_to_read + 1, sizeof(char));
+ \rsize_t i, j;
+ \r\rxbt_os_sem_release(reader->started);
+ \r\rwhile (!command->failed && !command->interrupted
+ && !command->successeded && !reader->failed
+ && !reader->broken_pipe)
+ \r {
+ \rif (!ReadFile
+ (stdout_fd, buffer, number_of_bytes_to_read,
+ &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))
+ \r {
+ \rif (GetLastError() == ERROR_BROKEN_PIPE)
+ \rreader->broken_pipe = 1;
+ \r
+ else
+ \rreader->failed = 1;
+ \r\r}
+ \r
+ else
+ \r {
+ \rif (number_of_bytes_readed > 0)
+ \r {
+ \rfor (i = 0, j = 0; i < number_of_bytes_readed; i++)
+ \rif ((buffer[i]) != '\r')
+ \rclean[j++] = buffer[i];
+ \r\rxbt_strbuff_append(output, clean);
+ \r\rmemset(buffer, 0, 1024);
+ \rmemset(clean, 0, 1024);
+ \r}
+ \r
+ else
+ \r {
+ \rxbt_os_thread_yield();
+ \r}
+ \r}
+ \r}
+ \r\rfree(clean);
+ \rfree(buffer);
+ \r\rxbt_strbuff_chomp(command->output);
+ \rxbt_strbuff_trim(command->output);
+ \r\rreader->done = 1;
+ \r\rif (command->failed)
+ \r {
+ \rif (command->reason == csr_write_failure)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before write failure",
+ command->context->pos);
+ \r}
+ \r
+ else if (command->reason == csr_write_pipe_broken)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before broken pipe", command->context->pos);
+ \r}
+ \r}
+ \r
+ else if (command->interrupted)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before interruption", command->context->pos);
+ \r}
+ \r
+ else if (reader->failed && !command->failed && !command->interrupted
+ && !command->successeded)
+ \r {
+ \rERROR2("[%s] Error while reading output of child `%s'",
+ command->context->pos, command->context->command_line);
+ \r\rif (command->output->used)
+ \rINFO2("[%s] Output on read failure:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before read failure", command->context->pos);
+ \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+ \rcommand_kill(command);
+ \rcommand_handle_failure(command, csr_read_failure);
+ \r}
+ \r\r\r\rreturn NULL;
+\r}
- if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
- {
- command_kill(command);
- exit_code = EREAD;
- command_handle_failure(command, csr_read_failure);
- }
-
- return NULL;
-}
-#else
-static void*
-reader_start_routine(void* p)
+\r\r
+#else /* \r */
+static void *\r reader_start_routine(void *p) \r
{
- reader_t reader = (reader_t)p;
- command_t command = reader->command;
- xbt_strbuff_t output = command->output;
- int stdout_fd = command->stdout_fd;
- int number_of_bytes_readed;
- int number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;
-
- char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));
- xbt_os_sem_release(reader->started);
-
- do
- {
- number_of_bytes_readed = read(stdout_fd, buffer, number_of_bytes_to_read);
-
- if(number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN)
- {
- reader->failed = 1;
- }
-
- if(number_of_bytes_readed > 0)
- {
- buffer[number_of_bytes_readed]='\0';
- xbt_strbuff_append(output,buffer);
- }
- else
- {
- usleep(100);
- }
-
- }while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && (number_of_bytes_readed != 0 /* end of file <-> normal exit */));
-
- free(buffer);
-
- if(reader->failed && !command->failed && !command->interrupted && !command->successeded)
- {
- command_kill(command);
- exit_code = EREAD;
- command_handle_failure(command, csr_read_failure);
- }
-
- reader->done = 1;
-
- return NULL;
-}
-#endif
+ \rreader_t reader = (reader_t) p;
+ \rcommand_t command = reader->command;
+ \rxbt_strbuff_t output = command->output;
+ \rint stdout_fd = command->stdout_fd;
+ \rint number_of_bytes_readed;
+ \rint number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;
+ \r\rint total = 0;
+ \r\rchar *buffer = (char *) calloc(number_of_bytes_to_read, sizeof(char));
+ \rxbt_os_sem_release(reader->started);
+ \r\r
+ do
+ \r {
+ \rnumber_of_bytes_readed =
+ read(stdout_fd, buffer, number_of_bytes_to_read);
+ \r\rif (number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN)
+ \r {
+ \rreader->failed = 1;
+ \r}
+ \r\rif (number_of_bytes_readed > 0)
+ \r {
+ \rbuffer[number_of_bytes_readed] = '\0';
+ \rxbt_strbuff_append(output, buffer);
+ \rtotal += total;
+ \r}
+ \r
+ else
+ \r {
+ \rxbt_os_thread_yield();
+ \r}
+ \r\r} while (!command->failed && !command->interrupted
+ && !command->successeded && !reader->failed
+ && (number_of_bytes_readed !=
+ 0 /* end of file <-> normal exit */ ));
+ \r\rfree(buffer);
+ \r\rif (close(command->stdout_fd) < 0)
+ \r {
+ \r
+ /* TODO */ \r
+ }
+ \r
+ else
+ \rcommand->stdout_fd = INDEFINITE_FD;
+ \r\rxbt_strbuff_chomp(command->output);
+ \rxbt_strbuff_trim(command->output);
+ \r\rreader->done = 1;
+ \r\rif (command->failed)
+ \r {
+ \rif (command->reason == csr_write_failure)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on write failure:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before write failur",
+ command->context->pos);
+ \r}
+ \r
+ else if (command->reason == csr_write_pipe_broken)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on broken pipe:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before broken pipe", command->context->pos);
+ \r}
+ \r}
+ \r
+ else if (command->interrupted)
+ \r {
+ \rif (command->output->used)
+ \rINFO2("[%s] Output on interruption:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before interruption", command->context->pos);
+ \r}
+ \r
+ else if (reader->failed && !command->failed && !command->interrupted
+ && !command->successeded)
+ \r {
+ \rERROR2("[%s] Error while reading output of child `%s'",
+ command->context->pos, command->context->command_line);
+ \r\rif (command->output->used)
+ \rINFO2("[%s] Output on read failure:\n%s", command->context->pos,
+ command->output->data);
+ \r
+ else
+ \rINFO1("[%s] No output before read failure", command->context->pos);
+ \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+ \rcommand_kill(command);
+ \rcommand_handle_failure(command, csr_read_failure);
+ \r}
+ \r\r\rreturn NULL;
+\r}
-void
-reader_wait(reader_t reader)
+\r
+#endif /* \r */
+\rvoid \r reader_wait(reader_t reader) \r
{
- xbt_os_thread_join(reader->thread, NULL);
-}
+ \rxbt_os_thread_join(reader->thread, NULL);
+\r} \r