Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Define correctly variables for windows.
[simgrid.git] / tools / tesh2 / src / reader.c
index 4b962a7..6aa254a 100644 (file)
-#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)
-{
-       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;
-}
-
-void
-reader_free(reader_t* reader)
-{
-       free(*reader);
-       *reader = NULL;
-}
-
-void
-reader_read(reader_t reader)
-{
-       reader->thread = xbt_os_thread_create("", reader_start_routine, reader);
-}
-
-#ifdef WIN32
-static void*
-reader_start_routine(void* p)
-{
-       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);
-
-       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) 
-{
-       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
-
-void
-reader_wait(reader_t reader)
-{
-       xbt_os_thread_join(reader->thread, NULL);
-}
+/*\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
+\r
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
+\r
+\r
+static void*\r
+reader_start_routine(void* p);\r
+\r
+reader_t\r
+reader_new(command_t command)\r
+{\r
+       reader_t reader;\r
+       \r
+       /* TODO : check the parameter */\r
+       \r
+       reader = xbt_new0(s_reader_t, 1);\r
+       \r
+       reader->thread = NULL;\r
+       reader->command = command;\r
+       reader->broken_pipe = 0;\r
+       reader->failed = 0;\r
+       reader->done = 0;\r
+       \r
+       reader->started = xbt_os_sem_init(0);\r
+       \r
+       return reader;\r
+}\r
+\r
+int\r
+reader_free(reader_t* ptr)\r
+{\r
+       if((*ptr)->started)\r
+               xbt_os_sem_destroy((*ptr)->started);\r
+       \r
+       free(*ptr);\r
+       \r
+       *ptr = NULL;\r
+       \r
+       return 0;\r
+}\r
+\r
+void\r
+reader_read(reader_t reader)\r
+{\r
+       reader->thread = xbt_os_thread_create("", reader_start_routine, reader);\r
+}\r
+\r
+#ifdef _XBT_WIN32\r
+static void*\r
+reader_start_routine(void* p)\r
+{\r
+       reader_t reader = (reader_t)p;\r
+       command_t command = reader->command;\r
+       \r
+       xbt_strbuff_t output = command->output;\r
+       HANDLE stdout_fd = command->stdout_fd;\r
+       \r
+       DWORD number_of_bytes_to_read = 1024; /*command->context->output->used;*/\r
+       DWORD number_of_bytes_readed = 0;\r
+       \r
+       char* buffer = (char*)calloc(number_of_bytes_to_read + 1,sizeof(char));\r
+       char* clean = (char*)calloc(number_of_bytes_to_read + 1,sizeof(char));\r
+       size_t i, j;\r
+\r
+       xbt_os_sem_release(reader->started);\r
+\r
+       while(!command->failed && !command->interrupted && !command->successeded && !reader->failed && !reader->broken_pipe)\r
+       {\r
+               if(!ReadFile(stdout_fd, buffer, number_of_bytes_to_read, &number_of_bytes_readed, NULL) || (0 == number_of_bytes_readed))\r
+               {\r
+                       if(GetLastError() == ERROR_BROKEN_PIPE)\r
+                               reader->broken_pipe = 1;\r
+                       else\r
+                       reader->failed = 1;\r
+                               \r
+               }\r
+               else\r
+               {\r
+                       if(number_of_bytes_readed > 0) \r
+                       {\r
+                               for(i= 0, j= 0; i < number_of_bytes_readed; i++)\r
+                                       if((buffer[i]) != '\r')\r
+                                               clean[j++] = buffer[i];\r
+\r
+                               xbt_strbuff_append(output,clean);\r
+\r
+                               memset(buffer, 0, 1024);\r
+                               memset(clean, 0, 1024);\r
+                       } \r
+                       else \r
+                       {\r
+                               xbt_os_thread_yield();\r
+                       }\r
+               }\r
+       }\r
+\r
+       free(clean);\r
+       free(buffer);\r
+\r
+       xbt_strbuff_chomp(command->output);\r
+       xbt_strbuff_trim(command->output);\r
+\r
+       reader->done = 1;\r
+       \r
+       if(command->failed)\r
+       {\r
+               if(command->reason == csr_write_failure)\r
+               {\r
+                       if(command->output->used)\r
+                               INFO2("[%s] Output on write failure:\n%s",command->context->pos, command->output->data);\r
+                       else\r
+                               INFO1("[%s] No output before write failure",command->context->pos);\r
+               }\r
+               else if(command->reason == csr_write_pipe_broken)\r
+               {\r
+                       if(command->output->used)\r
+                               INFO2("[%s] Output on broken pipe:\n%s",command->context->pos, command->output->data);\r
+                       else\r
+                               INFO1("[%s] No output before broken pipe",command->context->pos);\r
+               }\r
+       }\r
+       else if(command->interrupted)\r
+       {\r
+               if(command->output->used)\r
+                       INFO2("[%s] Output on interruption:\n%s",command->context->pos, command->output->data);\r
+               else\r
+                       INFO1("[%s] No output before interruption",command->context->pos);\r
+       }\r
+       else if(reader->failed && !command->failed && !command->interrupted && !command->successeded)\r
+       {\r
+               ERROR2("[%s] Error while reading output of child `%s'", command->context->pos, command->context->command_line);\r
+               \r
+               if(command->output->used)\r
+                       INFO2("[%s] Output on read failure:\n%s",command->context->pos, command->output->data);\r
+               else\r
+                       INFO1("[%s] No output before read failure",command->context->pos);\r
+               \r
+               unit_set_error(command->unit, errno, 0, command->context->pos);\r
+               command_kill(command);\r
+               command_handle_failure(command, csr_read_failure);\r
+       }\r
+\r
+       \r
+       \r
+       return NULL;\r
+}\r
+\r
+#else\r
+static void*\r
+reader_start_routine(void* p) \r
+{\r
+       reader_t reader = (reader_t)p;\r
+       command_t command = reader->command;\r
+       xbt_strbuff_t output = command->output;\r
+       int stdout_fd = command->stdout_fd;\r
+       int number_of_bytes_readed;\r
+       int number_of_bytes_to_read = (1024 > SSIZE_MAX) ? SSIZE_MAX : 1024;\r
+\r
+       int total = 0;\r
+               \r
+       char* buffer = (char*)calloc(number_of_bytes_to_read,sizeof(char));\r
+       xbt_os_sem_release(reader->started);\r
+       \r
+       do \r
+       {\r
+               number_of_bytes_readed = read(stdout_fd, buffer, number_of_bytes_to_read);\r
+               \r
+               if(number_of_bytes_readed < 0 && errno != EINTR && errno != EAGAIN) \r
+               {\r
+                       reader->failed = 1;\r
+               }\r
+               \r
+               if(number_of_bytes_readed > 0) \r
+               {\r
+                       buffer[number_of_bytes_readed]='\0';\r
+                       xbt_strbuff_append(output,buffer);\r
+                       total += total;\r
+               } \r
+               else \r
+               {\r
+                       xbt_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
+       \r
+       free(buffer);\r
+       \r
+       if(close(command->stdout_fd) < 0)\r
+       {\r
+               /* TODO */\r
+       }\r
+       else\r
+               command->stdout_fd = INDEFINITE_FD;\r
+       \r
+       xbt_strbuff_chomp(command->output);\r
+       xbt_strbuff_trim(command->output);\r
+\r
+       reader->done = 1;\r
+\r
+       if(command->failed)\r
+       {\r
+               if(command->reason == csr_write_failure)\r
+               {\r
+                       if(command->output->used)\r
+                               INFO2("[%s] Output on write failure:\n%s",command->context->pos, command->output->data);\r
+                       else\r
+                               INFO1("[%s] No output before write failur",command->context->pos);\r
+               }\r
+               else if(command->reason == csr_write_pipe_broken)\r
+               {\r
+                       if(command->output->used)\r
+                               INFO2("[%s] Output on broken pipe:\n%s",command->context->pos, command->output->data);\r
+                       else\r
+                               INFO1("[%s] No output before broken pipe",command->context->pos);\r
+               }\r
+       }\r
+       else if(command->interrupted)\r
+       {\r
+               if(command->output->used)\r
+                       INFO2("[%s] Output on interruption:\n%s",command->context->pos, command->output->data);\r
+               else\r
+                       INFO1("[%s] No output before interruption",command->context->pos);\r
+       }\r
+       else if(reader->failed && !command->failed && !command->interrupted && !command->successeded)\r
+       {\r
+               ERROR2("[%s] Error while reading output of child `%s'", command->context->pos, command->context->command_line);\r
+               \r
+               if(command->output->used)\r
+                       INFO2("[%s] Output on read failure:\n%s",command->context->pos, command->output->data);\r
+               else\r
+                       INFO1("[%s] No output before read failure",command->context->pos);\r
+               \r
+               unit_set_error(command->unit, errno, 0, command->context->pos);\r
+               command_kill(command);\r
+               command_handle_failure(command, csr_read_failure);\r
+       }\r
+       \r
+       \r
+       return NULL;\r
+} \r
+#endif\r
+\r
+void\r
+reader_wait(reader_t reader)\r
+{\r
+       xbt_os_thread_join(reader->thread, NULL);\r
+}\r