Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
some new files used to check Tesh
[simgrid.git] / tools / tesh2 / src / writer.c
index c3ba975..bb9b445 100644 (file)
-#include <writer.h>
-#include <command.h>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
-
-static void*
-writer_start_routine(void* p);
-
-writer_t
-writer_new(command_t command)
-{
-       writer_t writer = xbt_new0(s_writer_t, 1);
-
-       writer->thread = NULL;
-       writer->command = command;
-       writer->written = xbt_os_sem_init(0);
-       writer->can_write = xbt_os_sem_init(0);
-       
-       writer->done = 0;
-
-       return writer;
-}
-
-void
-writer_free(writer_t* writer)
-{
-       
-       /*xbt_os_sem_destroy((*writer)->started);
-       xbt_os_sem_destroy((*writer)->can_write);*/
-       
-       free(*writer);
-       *writer = NULL;
-}
-
-void
-writer_write(writer_t writer)
-{
-       writer->thread = xbt_os_thread_create("", writer_start_routine, writer);
-}
-
-#ifdef WIN32
-static void*
-writer_start_routine(void* p)
-{
-       writer_t writer = (writer_t)p;
-       command_t command = writer->command;
-       
-       char* input = (char*)(command->context->input->data);
-       
-       DWORD number_of_bytes_to_write = command->context->input->used;
-       DWORD number_of_bytes_written = 0;
-
-       
-       while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)
-       {
-               if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))
-               {
-                       if(GetLastError() ==  ERROR_NO_DATA)
-                               writer->broken_pipe = 1;
-                       else
-                       writer->failed = 1;
-                               
-               }
-               else
-               {
-                       input += number_of_bytes_written;
-                       number_of_bytes_to_write -= number_of_bytes_written;
-               }
-       }
-       
-       command->context->input->data[0]='\0';
-       command->context->input->used=0;
-       
-       if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               exit_code = EWRITE;
-               command_handle_failure(command, csr_write_failure);
-       }
-       /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               command_handle_failure(command, csr_write_pipe_broken);
-       }*/
-       
-
-       return NULL;
-}
-#else
-/*static void* 
-writer_start_routine(void* p) 
-{
-       writer_t writer = (writer_t)p;
-       command_t command = writer->command;
-       int number_of_bytes_written = 0;
-       int number_of_bytes_to_write = command->context->input->used;
-       char* input = (char*)(command->context->input->data);
-       int got;
-       
-       xbt_os_sem_release(writer->started);
-       
-       
-       
-       while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && (number_of_bytes_written < number_of_bytes_to_write))
-       {
-               got = write(writer->command->stdin_fd, input + number_of_bytes_written, number_of_bytes_to_write - number_of_bytes_written);
-               
-               if(got > 0)
-                       number_of_bytes_written += got;
-               
-               if(got < 0) 
-               {
-                       if(errno == EPIPE) 
-                       {
-                               writer->broken_pipe = 1;
-                       } 
-                       else if(errno != EINTR && errno != EAGAIN && errno != EPIPE) 
-                       {
-                               writer->failed = 1;
-                       }
-               }
-       
-               if(got <= 0)
-                       usleep(100);
-       }
-       
-       command->context->input->data[0]='\0';
-       command->context->input->used=0;
-       
-       if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               exit_code = EWRITE;
-               command_handle_failure(command, csr_write_failure);
-       }
-       else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               exit_code = EWRITEPIPE;
-               command_handle_failure(command, csr_write_pipe_broken);
-       }
-       
-       
-       close(command->stdin_fd);
-       command->stdin_fd = INDEFINITE_FD;
-       
-       return NULL;
-}*/
-
-static void* 
-writer_start_routine(void* p) 
-{
-       writer_t writer = (writer_t)p;
-       command_t command = writer->command;
-       int number_of_bytes_to_write = command->context->input->used;
-       char* input = (char*)(command->context->input->data);
-       int got;
-       int released = 0;
-       
-       
-       xbt_os_sem_acquire(writer->can_write);
-       
-       
-       while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)
-       {
-               got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;
-               got = write(writer->command->stdin_fd, input, got );
-               
-               if(got < 0) 
-               {
-                       if(EINTR == errno)
-                               continue;
-                               
-                       else if(EAGAIN == errno)
-                       {/* the pipe is full */
-                               if(!released)
-                               {
-                                       xbt_os_sem_release(writer->written);
-                                       released = 1;
-                               }
-                               
-                               continue;
-                       }
-                       else if(EPIPE == errno) 
-                       {
-                               writer->broken_pipe = 1;
-                               break;
-                       } 
-                       else
-                       {
-                               writer->failed = 1;
-                               break;
-                       }
-                       
-               }
-               
-               number_of_bytes_to_write -= got;
-               input += got;
-               
-               if(got == 0)
-                       xbt_os_thread_yield();
-               
-       }
-       
-       if(!released)
-       {
-               xbt_os_sem_release(writer->written);
-               released = 1;
-       }
-       
-
-       close(command->stdin_fd);
-       command->stdin_fd = INDEFINITE_FD;
-       
-       command->context->input->data[0]='\0';
-       command->context->input->used=0;
-       
-       if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               exit_code = EWRITE;
-               command_handle_failure(command, csr_write_failure);
-       }
-       else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)
-       {
-               command_kill(command);
-               exit_code = EWRITEPIPE;
-               command_handle_failure(command, csr_write_pipe_broken);
-       }
-       
-       writer->done = 1;
-       
-       return NULL;
-       
-}
-
-#endif
-void
-writer_wait(writer_t writer)
-{
-       xbt_os_thread_join(writer->thread, 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
+\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