Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Indent the rest of the code (examples, buildtools, doc...) except for examples/SMPI...
[simgrid.git] / tools / tesh2 / src / command.c
index 677979f..d43adf1 100644 (file)
  *             This file contains all the definitions of the functions related with\r
  *             the tesh command type.\r
  *\r
- */\r
+ */  \r
 #include <unit.h>\r
 #include <command.h>\r
 #include <context.h>\r
 #include <writer.h>\r
 #include <reader.h>\r
 #include <timer.h>\r
-\r
+    \r
 #ifndef _XBT_WIN32\r
 #include <sys/types.h>\r
 #include <sys/wait.h>\r
 #include <sys/stat.h>\r
 #include <unistd.h>\r
-#else\r
-char *\r
-tow32cmd(const char* cmd)\r
-{\r
-       static char w32cmd[PATH_MAX + 1] = {0};\r
-       char cmd_buf[PATH_MAX + 1] = {0};\r
-    size_t i,j, len;\r
-\r
-    if(!cmd)\r
-    {\r
-       errno = EINVAL;\r
-               return NULL;\r
-       }\r
-\r
-       /* TODO : if ~*/\r
-       if(cmd[0] != '.')\r
-       {\r
-               strcpy(w32cmd, cmd);\r
-               return w32cmd;\r
-       }\r
-\r
-       i = j = 0;\r
-       len = strlen(cmd);\r
-\r
-       while(i < len)\r
-       {\r
-               if(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '>')\r
-                       cmd_buf[j++] = cmd[i];\r
-               else\r
-                       break;\r
-\r
-               i++;\r
-       }\r
-\r
-   _fullpath(w32cmd, cmd_buf, sizeof(w32cmd));\r
-\r
-   if(!strstr(w32cmd, ".exe"))\r
-               strcat(w32cmd, ".exe ");\r
-\r
-   strcat(w32cmd, cmd + i);\r
-\r
-\r
-   /*printf("w32cmd : %s", w32cmd);*/\r
-\r
-   return w32cmd;\r
-}\r
-#endif\r
-\r
+#else   /* \r */
+char *\r tow32cmd(const char *cmd) \r
+{
+  \rstatic char w32cmd[PATH_MAX + 1] = { 0 };
+  \rchar cmd_buf[PATH_MAX + 1] = { 0 };
+  \rsize_t i, j, len;
+  \r\rif (!cmd)
+    \r {
+    \rerrno = EINVAL;
+    \rreturn NULL;
+    \r}
+  \r\r
+      /* TODO : if ~ */ \r
+      if (cmd[0] != '.')
+    \r {
+    \rstrcpy(w32cmd, cmd);
+    \rreturn w32cmd;
+    \r}
+  \r\ri = j = 0;
+  \rlen = strlen(cmd);
+  \r\rwhile (i < len)
+    \r {
+    \rif (cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '>')
+      \rcmd_buf[j++] = cmd[i];
+    \r
+    else
+      \rbreak;
+    \r\ri++;
+    \r}
+  \r\r_fullpath(w32cmd, cmd_buf, sizeof(w32cmd));
+  \r\rif (!strstr(w32cmd, ".exe"))
+    \rstrcat(w32cmd, ".exe ");
+  \r\rstrcat(w32cmd, cmd + i);
+  \r\r\r
+      /*printf("w32cmd : %s", w32cmd); */ \r
+      \rreturn w32cmd;
+\r}
+
+\r
+#endif  /* \r */
+    \r
 #include <com.h>\r
-\r
+    \r
 #include <xsignal.h>\r
-\r
+    \r
 #include <is_cmd.h>\r
-\r
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
-\r
-static void*\r
-command_start(void* p);\r
-\r
-\r
-command_t\r
-command_new(unit_t unit, context_t context, xbt_os_mutex_t mutex)\r
-{\r
-       command_t command;\r
-\r
-       command = xbt_new0(s_command_t, 1);\r
-\r
-       /* get the context of the execution of the command */\r
-       if(!(command->context = context_dup(context)))\r
-       {\r
-               free(command);\r
-               return NULL;\r
-       }\r
-\r
-       /* the exit code of the command is indefinite */\r
-       command->exit_code = INDEFINITE;\r
-\r
-       /* the signal of the command is indefinite */\r
-       command->signal = INDEFINITE_SIGNAL;\r
-\r
-       command->failed = 0;\r
-       command->interrupted = 0;\r
-\r
-       /* the mutex used to safetly access to the command unit properties */\r
-       command->mutex = mutex;\r
-\r
-       command->output = xbt_strbuff_new();\r
-\r
-       command->pid = INDEFINITE_PID;\r
-\r
-       command->stat_val = -1;\r
-\r
-       /* set the unit of the command */\r
-       command->root = unit->root ? unit->root : unit;\r
-       command->unit = unit;\r
-\r
-       /* all the commands are runned in a thread */\r
-       command->thread = NULL;\r
-\r
-       command->successeded = 0;\r
-\r
-       command->reader = reader_new(command);\r
-\r
-       if(context->input->used)\r
-               command->writer = writer_new(command);\r
-       else\r
-               command->writer = NULL;\r
-\r
-       if(context->timeout != INDEFINITE)\r
-               command->timer = timer_new(command);\r
-       else\r
-               command->timer = NULL;\r
-\r
-       command->status = cs_initialized;\r
-       command->reason = csr_unknown;\r
-\r
-       command->stdin_fd = INDEFINITE_FD;\r
-       command->stdout_fd = INDEFINITE_FD;\r
-\r
-\r
-       /* register the command */\r
-       xbt_os_mutex_acquire(mutex);\r
-\r
-       xbt_dynar_push(unit->commands, &command);\r
-       command->root->cmd_nb++;\r
-       xbt_os_mutex_release(mutex);\r
-\r
-       #ifndef _XBT_WIN32\r
-       command->killed = 0;\r
-       command->execlp_errno = 0;\r
-       #endif\r
-\r
-\r
-       return command;\r
-}\r
-\r
-int\r
-command_run(command_t command)\r
-{\r
-       if(!silent_flag && !interrupted)\r
-               INFO2("[%s] %s",command->context->pos, command->context->command_line);\r
-\r
-       if(!just_print_flag)\r
-       {\r
-               if(!interrupted)\r
-               {\r
-                       /* start the command in a thread*/\r
-                       if(command->context->async)\r
-                       {\r
-                               command->thread = xbt_os_thread_create("", command_start, command);\r
-\r
-                       }\r
-                       else\r
-                       {\r
-                               /* start the command in the main thread */\r
-                               command_start(command);\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       command_interrupt(command);\r
-               }\r
-\r
-\r
-       }\r
-\r
-       return 0;\r
-\r
-}\r
-\r
-static void*\r
-command_start(void* p)\r
-{\r
-       command_t command = (command_t)p;\r
-       unit_t root = command->root;\r
-\r
-       /* the command is started */\r
-       command->status = cs_started;\r
-\r
-       /* increment the number of started commands of the unit */\r
-       xbt_os_mutex_acquire(command->mutex);\r
-       (root->started_cmd_nb)++;\r
-       xbt_os_mutex_release(command->mutex);\r
-\r
-       /* execute the command of the test */\r
-\r
-       #ifndef _XBT_WIN32\r
-       command_exec(command, command->context->command_line);\r
-       #else\r
-       /* play the translated command line on Windows */\r
-       command_exec(command, command->context->t_command_line);\r
-       #endif\r
-\r
-       if(cs_in_progress == command->status)\r
-       {\r
-               /* wait the process if it is in progress */\r
-               command_wait(command);\r
-\r
-               if(cs_failed != command->status && cs_interrupted != command->status)\r
-                       command_check(command);\r
-       }\r
-\r
-       xbt_os_mutex_acquire(command->mutex);\r
-\r
-       /* if it's the last command of the root unit */\r
-       if(!root->interrupted && root->parsed && (root->started_cmd_nb == (root->failed_cmd_nb + root->interrupted_cmd_nb + root->successeded_cmd_nb)))\r
-       {\r
-               /* first release the mutex */\r
-               root->released = 1;\r
-               xbt_os_mutex_release(command->mutex);\r
-               /* the last command release the unit */\r
-               xbt_os_sem_release(root->sem);\r
-       }\r
-       else\r
-               xbt_os_mutex_release(command->mutex);\r
-\r
-\r
-       /* wait the end of the timer, the reader and the writer */\r
-       if(command->timer && command->timer->thread)\r
-               timer_wait(command->timer);\r
-\r
-       /* wait the end of the writer */\r
-       if(command->writer && command->writer->thread)\r
-               writer_wait(command->writer);\r
-\r
-       /* wait the end of the reader */\r
-       if(command->reader && command->reader->thread)\r
-               reader_wait(command->reader);\r
-\r
-\r
-\r
-       return NULL;\r
-}\r
-\r
+    \rXBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
+\r\rstatic void *\r command_start(void *p);
+\r\r\rcommand_t \r
+command_new(unit_t unit, context_t context, xbt_os_mutex_t mutex) \r
+{
+  \rcommand_t command;
+  \r\rcommand = xbt_new0(s_command_t, 1);
+  \r\r
+      /* get the context of the execution of the command */ \r
+      if (!(command->context = context_dup(context)))
+    \r {
+    \rfree(command);
+    \rreturn NULL;
+    \r}
+  \r\r
+      /* the exit code of the command is indefinite */ \r
+      command->exit_code = INDEFINITE;
+  \r\r
+      /* the signal of the command is indefinite */ \r
+      command->signal = INDEFINITE_SIGNAL;
+  \r\rcommand->failed = 0;
+  \rcommand->interrupted = 0;
+  \r\r
+      /* the mutex used to safetly access to the command unit properties */ \r
+      command->mutex = mutex;
+  \r\rcommand->output = xbt_strbuff_new();
+  \r\rcommand->pid = INDEFINITE_PID;
+  \r\rcommand->stat_val = -1;
+  \r\r
+      /* set the unit of the command */ \r
+      command->root = unit->root ? unit->root : unit;
+  \rcommand->unit = unit;
+  \r\r
+      /* all the commands are runned in a thread */ \r
+      command->thread = NULL;
+  \r\rcommand->successeded = 0;
+  \r\rcommand->reader = reader_new(command);
+  \r\rif (context->input->used)
+    \rcommand->writer = writer_new(command);
+  \r
+  else
+    \rcommand->writer = NULL;
+  \r\rif (context->timeout != INDEFINITE)
+    \rcommand->timer = timer_new(command);
+  \r
+  else
+    \rcommand->timer = NULL;
+  \r\rcommand->status = cs_initialized;
+  \rcommand->reason = csr_unknown;
+  \r\rcommand->stdin_fd = INDEFINITE_FD;
+  \rcommand->stdout_fd = INDEFINITE_FD;
+  \r\r\r
+      /* register the command */ \r
+      xbt_os_mutex_acquire(mutex);
+  \r\rxbt_dynar_push(unit->commands, &command);
+  \rcommand->root->cmd_nb++;
+  \rxbt_os_mutex_release(mutex);
+  \r\r
+#ifndef _XBT_WIN32\r
+      command->killed = 0;
+  \rcommand->execlp_errno = 0;
+  \r
+#endif  /* \r */
+      \r\rreturn command;
+\r}
+
+\r\rint \r command_run(command_t command) \r
+{
+  \rif (!silent_flag && !interrupted)
+    \rINFO2("[%s] %s", command->context->pos,
+           command->context->command_line);
+  \r\rif (!just_print_flag)
+    \r {
+    \rif (!interrupted)
+      \r {
+      \r
+          /* start the command in a thread */ \r
+          if (command->context->async)
+        \r {
+        \rcommand->thread =
+            xbt_os_thread_create("", command_start, command);
+        \r\r}
+      \r
+      else
+        \r {
+        \r
+            /* start the command in the main thread */ \r
+            command_start(command);
+        \r}
+      \r}
+    \r
+    else
+      \r {
+      \rcommand_interrupt(command);
+      \r}
+    \r\r\r}
+  \r\rreturn 0;
+\r\r}
+
+\r\rstatic void *\r command_start(void *p) \r
+{
+  \rcommand_t command = (command_t) p;
+  \runit_t root = command->root;
+  \r\r
+      /* the command is started */ \r
+      command->status = cs_started;
+  \r\r
+      /* increment the number of started commands of the unit */ \r
+      xbt_os_mutex_acquire(command->mutex);
+  \r(root->started_cmd_nb)++;
+  \rxbt_os_mutex_release(command->mutex);
+  \r\r
+      /* execute the command of the test */ \r
+      \r
+#ifndef _XBT_WIN32\r
+      command_exec(command, command->context->command_line);
+  \r
+#else   /* \r */
+      /* play the translated command line on Windows */ \r
+      command_exec(command, command->context->t_command_line);
+  \r
+#endif  /* \r */
+      \rif (cs_in_progress == command->status)
+    \r {
+    \r
+        /* wait the process if it is in progress */ \r
+        command_wait(command);
+    \r\rif (cs_failed != command->status
+          && cs_interrupted != command->status)
+      \rcommand_check(command);
+    \r}
+  \r\rxbt_os_mutex_acquire(command->mutex);
+  \r\r
+      /* if it's the last command of the root unit */ \r
+      if (!root->interrupted && root->parsed
+          && (root->started_cmd_nb ==
+              (root->failed_cmd_nb + root->interrupted_cmd_nb +
+               root->successeded_cmd_nb)))
+    \r {
+    \r
+        /* first release the mutex */ \r
+        root->released = 1;
+    \rxbt_os_mutex_release(command->mutex);
+    \r
+        /* the last command release the unit */ \r
+        xbt_os_sem_release(root->sem);
+    \r}
+  \r
+  else
+    \rxbt_os_mutex_release(command->mutex);
+  \r\r\r
+      /* wait the end of the timer, the reader and the writer */ \r
+      if (command->timer && command->timer->thread)
+    \rtimer_wait(command->timer);
+  \r\r
+      /* wait the end of the writer */ \r
+      if (command->writer && command->writer->thread)
+    \rwriter_wait(command->writer);
+  \r\r
+      /* wait the end of the reader */ \r
+      if (command->reader && command->reader->thread)
+    \rreader_wait(command->reader);
+  \r\r\r\rreturn NULL;
+\r}
+
+\r\r
 #ifdef _XBT_WIN32\r
-\r
+    \r
 #ifndef BUFSIZE\r
 #define BUFSIZE        4096\r
-#endif\r
-void\r
-command_exec(command_t command, const char* command_line)\r
-{\r
-\r
-       STARTUPINFO si = {0};                                   /* contains the informations about the child process windows*/\r
-       PROCESS_INFORMATION pi = {0};                   /* contains child process informations                                          */\r
-       SECURITY_ATTRIBUTES sa = {0};                   /* contains the security descriptor for the pipe handles        */\r
-       HANDLE child_stdin_handle[2] = {NULL};  /* child_stdin_handle[1]        <-> stdout of the child process */\r
-       HANDLE child_stdout_handle[2] = {NULL}; /* child_stdout_handle[0]       <-> stdin of the child process  */\r
-       HANDLE child_stderr = NULL;\r
-\r
-\r
-       sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
-    sa.lpSecurityDescriptor = NULL;                    /* use default security for the pipe handles                            */\r
-\r
-       sa.bInheritHandle = TRUE;                               /* the pipe handles can be inherited                                            */\r
-\r
-       if(!CreatePipe(&(child_stdin_handle[0]),&(child_stdin_handle[1]),&sa,0))\r
-    {\r
-               ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               command->failed = 1;\r
-               command->status = cs_failed;\r
-\r
-               return;\r
-    }\r
-\r
-\r
-       if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[1]),GetCurrentProcess(),&(child_stderr),0,TRUE,DUPLICATE_SAME_ACCESS))\r
-    {\r
-               ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               CloseHandle(child_stdin_handle[0]);\r
-               CloseHandle(child_stdin_handle[1]);\r
-\r
-               command->failed = 1;\r
-               command->status = cs_failed;\r
-\r
-               return;\r
-    }\r
-\r
-       if(!CreatePipe(&(child_stdout_handle[0]),&(child_stdout_handle[1]),&sa,0))\r
-    {\r
-               ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               CloseHandle(child_stdout_handle[0]);\r
-               CloseHandle(child_stdout_handle[1]);\r
-               CloseHandle(child_stdin_handle[0]);\r
-               CloseHandle(child_stdin_handle[1]);\r
-\r
-               command->failed = 1;\r
-               command->status = cs_failed;\r
-\r
-               return;\r
-    }\r
-\r
-       /* Read handle for read operations on the child std output. */\r
-       if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[0]),GetCurrentProcess(),&(command->stdout_fd),0,FALSE, DUPLICATE_SAME_ACCESS))\r
-    {\r
-               CloseHandle(child_stdout_handle[0]);\r
-               CloseHandle(child_stdout_handle[1]);\r
-               CloseHandle(child_stdin_handle[0]);\r
-               CloseHandle(child_stdin_handle[1]);\r
-\r
-               command->failed = 1;\r
-               command->status = cs_failed;\r
-\r
-               ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               return;\r
-       }\r
-\r
-\r
-       /* Write handle for write operations on the child std input. */\r
-       if(!DuplicateHandle(GetCurrentProcess(),(child_stdout_handle[1]),GetCurrentProcess(),&(command->stdin_fd), 0,FALSE,DUPLICATE_SAME_ACCESS))\r
-    {\r
-               CloseHandle(child_stdout_handle[0]);\r
-               CloseHandle(child_stdout_handle[1]);\r
-               CloseHandle(child_stdin_handle[0]);\r
-               CloseHandle(child_stdin_handle[1]);\r
-\r
-               command->failed = 1;\r
-               command->status = cs_failed;\r
-\r
-               ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               return;\r
-    }\r
-\r
-       CloseHandle(child_stdin_handle[0]);\r
-       CloseHandle(child_stdout_handle[1]);\r
-\r
-\r
-       if(command->timer)\r
-       {\r
-               /* launch the timer */\r
-               timer_time(command->timer);\r
-       }\r
-\r
-       if(command->reader)\r
-       {\r
-               /* launch the reader */\r
-               reader_read(command->reader);\r
-       }\r
-\r
-\r
-       if(command->writer)\r
-       {\r
-               /* launch the writer */\r
-               writer_write(command->writer);\r
-       }\r
-\r
-       /* if there is a reader wait for its starting */\r
-       if(command->reader)\r
-               xbt_os_sem_acquire(command->reader->started);\r
-\r
-       /* if there is a reader wait for its ending */\r
-       if(command->writer)\r
-               xbt_os_sem_acquire(command->writer->written);\r
-\r
-       /* if there is a reader wait for its starting */\r
-       if(command->timer)\r
-               xbt_os_sem_acquire(command->timer->started);\r
-\r
-    si.cb = sizeof(STARTUPINFO);\r
-\r
-       si.dwFlags |= STARTF_USESTDHANDLES;\r
-       si.hStdOutput = child_stdin_handle[1];\r
-       si.hStdInput  = child_stdout_handle[0];\r
-       si.hStdError  = child_stderr;\r
-\r
-       /* launch the process */\r
-       if(!CreateProcess(\r
-                                               NULL,\r
-                                               tow32cmd(command_line),\r
-                                               NULL,\r
-                                               NULL,\r
-                                               TRUE,\r
-                                               CREATE_NO_WINDOW,\r
-                                               NULL,\r
-                                               NULL,\r
-                                               &si,\r
-                                               &pi)\r
-       )\r
-       {\r
-\r
-               if(ERROR_FILE_NOT_FOUND == GetLastError())\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(ECMDNOTFOUND, 1));\r
-                       unit_set_error(command->unit, ECMDNOTFOUND, 1, command->context->pos);\r
-                       command_handle_failure(command, csr_command_not_found);\r
-               }\r
-               else\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));\r
-\r
-                       unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-                       command_handle_failure(command, csr_create_process_function_failure);\r
-               }\r
-\r
-    }\r
-       else\r
-       {\r
-               /* the command is running */\r
-               command->status = cs_in_progress;\r
-\r
-               /* save the pid of the command */\r
-               command->pid = pi.hProcess;\r
-\r
-               /* close non used thread handle */\r
-               CloseHandle(pi.hThread);\r
-\r
-       }\r
-\r
-\r
-       /* close non used handles */\r
-       CloseHandle(child_stdin_handle[1]);\r
-    CloseHandle(child_stdout_handle[0]);\r
-       CloseHandle(child_stderr);\r
-\r
-\r
-}\r
-#else\r
-void\r
-command_exec(command_t command, const char* command_line)\r
-{\r
-       int child_stdin_fd[2] ;\r
-       int child_stdout_fd[2];\r
-\r
-       #ifdef __CHKCMD\r
-       int rv = is_cmd(command->unit->runner->path, command->unit->runner->builtin, command_line);\r
-\r
-       if(rv != 0)\r
-       {\r
-\r
-               if(rv == EINVAL)\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(rv, 0));\r
-                       unit_set_error(command->unit, rv, 0, command->context->pos);\r
-               }\r
-               else\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(rv, 1));\r
-                       unit_set_error(command->unit, rv, 1, command->context->pos);\r
-               }\r
-\r
-               command_handle_failure(command, csr_command_not_found);\r
-\r
-               return;\r
-       }\r
-\r
-       #endif\r
-\r
-\r
-       if(command->writer)\r
-       {\r
-               if(pipe(child_stdin_fd))\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-\r
-                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-\r
-                       command_handle_failure(command, csr_pipe_function_failed);\r
-\r
-\r
-\r
-                       return;\r
-               }\r
-       }\r
-\r
-       if(command->reader)\r
-       {\r
-               if(pipe(child_stdout_fd))\r
-               {\r
-                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-\r
-                       if(command->writer)\r
-                       {\r
-                               close(child_stdin_fd[0]);\r
-                               close(child_stdin_fd[1]);\r
-                       }\r
-\r
-                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-\r
-                       command_handle_failure(command, csr_pipe_function_failed);\r
-\r
-                       return;\r
-               }\r
-       }\r
-\r
-       if(command->writer)\r
-       {\r
-               if(fcntl(child_stdin_fd[1], F_SETFL, fcntl(child_stdin_fd[1], F_GETFL) | O_NONBLOCK) < 0)\r
-               {\r
-\r
-                       ERROR3("[%s] `%s'  : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-\r
-                       close(child_stdin_fd[0]);\r
-                       close(child_stdin_fd[1]);\r
-\r
-                       if(command->reader)\r
-                       {\r
-                               close(child_stdout_fd[0]);\r
-                               close(child_stdout_fd[1]);\r
-                       }\r
-\r
-                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-\r
-                       command_handle_failure(command, csr_fcntl_function_failed);\r
-\r
-                       return;\r
-               }\r
-       }\r
-\r
-       /* to write to the child stdin */\r
-       command->stdin_fd = child_stdin_fd[1];\r
-\r
-       /* to read from the child stdout */\r
-       command->stdout_fd = child_stdout_fd[0];\r
-\r
-       /* launch the reader if any*/\r
-       if(command->reader)\r
-               reader_read(command->reader);\r
-\r
-    /* launch the writer if any */\r
-       if(command->writer)\r
-               writer_write(command->writer);\r
-\r
-       /* launch the timer if any */\r
-       if(command->timer)\r
-               timer_time(command->timer);\r
-\r
-       /* if there is a reader wait for its starting */\r
-       if(command->reader)\r
-               xbt_os_sem_acquire(command->reader->started);\r
-\r
-       /* if there is a reader wait for its ending */\r
-       if(command->writer)\r
-               xbt_os_sem_acquire(command->writer->written);\r
-\r
-       /* if there is a reader wait for its starting */\r
-       if(command->timer)\r
-               xbt_os_sem_acquire(command->timer->started);\r
-\r
-       /* update the state of the command, assume it is in progress */\r
-       command->status = cs_in_progress;\r
-\r
-       command->pid= fork();\r
-\r
-       if(command->pid < 0)\r
-       {/* error */\r
-               if(command->writer)\r
-               {\r
-                       close(child_stdin_fd[0]);\r
-                       close(child_stdin_fd[1]);\r
-               }\r
-\r
-               if(command->reader)\r
-               {\r
-                       close(child_stdout_fd[0]);\r
-                       close(child_stdout_fd[1]);\r
-               }\r
-\r
-               ERROR2("[%s] Cannot fork the command `%s'", command->context->pos, command->context->command_line);\r
-               unit_set_error(command->unit, errno, 0, command->context->pos);\r
-               command_handle_failure(command,csr_fork_function_failure);\r
-       }\r
-       else\r
-       {\r
-               if(command->pid)\r
-               {/* father */\r
-\r
-                       /* close unused file descriptors */\r
-                       if(command->writer)\r
-                               close(child_stdin_fd[0]);\r
-\r
-                       if(command->reader)\r
-                               close(child_stdout_fd[1]);\r
-               }\r
-               else\r
-               {/* child */\r
-\r
-                       /* close unused file descriptors */\r
-                       if(command->writer)\r
-                               close(child_stdin_fd[1]);\r
-\r
-                       if(command->reader)\r
-                               close(child_stdout_fd[0]);\r
-\r
-                       if(command->writer)\r
-                       {\r
-                               /* redirect stdin to child_stdin_fd[0] (now fgets(), getchar() ... read from the pipe */\r
-                               if(dup2(child_stdin_fd[0],STDIN_FILENO) < 0)\r
-                               {\r
-                                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-                                       command->unit->exit_code = errno;\r
-\r
-                                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-                                       command_handle_failure(command,csr_dup2_function_failure);\r
-                               }\r
-\r
-                               /* close the unused file descriptor  */\r
-                               close(child_stdin_fd[0]);\r
-                       }\r
-\r
-                       if(command->reader)\r
-                       {\r
-\r
-                               /* redirect stdout and stderr to child_stdout_fd[1] (now printf(), perror()... write to the pipe */\r
-                               if(dup2(child_stdout_fd[1],STDOUT_FILENO) < 0)\r
-                               {\r
-                                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-\r
-                                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-                                       command_handle_failure(command, csr_dup2_function_failure);\r
-                               }\r
-\r
-                               if(dup2(child_stdout_fd[1], STDERR_FILENO) < 0)\r
-                               {\r
-                                       ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));\r
-                                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-                                       command_handle_failure(command, csr_dup2_function_failure);\r
-                               }\r
-\r
-                               /* close the unused file descriptor  */\r
-                               close(child_stdout_fd[1]);\r
-                       }\r
-\r
-                       /* launch the command */\r
-                       if(execlp("/bin/sh", "sh", "-c", command->context->command_line, NULL) < 0)\r
-                               command->execlp_errno = errno;\r
-               }\r
-       }\r
-}\r
-#endif\r
-\r
+#endif  /* \r */
+void \r command_exec(command_t command, const char *command_line) \r
+{
+  \r\rSTARTUPINFO si = {
+  0};                           /* contains the informations about the child process windows */
+  \rPROCESS_INFORMATION pi = {
+  0};                           /* contains child process informations                                          */
+  \rSECURITY_ATTRIBUTES sa = {
+  0};                           /* contains the security descriptor for the pipe handles        */
+  \rHANDLE child_stdin_handle[2] = {
+  NULL};                        /* child_stdin_handle[1]        <-> stdout of the child process */
+  \rHANDLE child_stdout_handle[2] = {
+  NULL};                        /* child_stdout_handle[0]       <-> stdin of the child process  */
+  \rHANDLE child_stderr = NULL;
+  \r\r\rsa.nLength = sizeof(SECURITY_ATTRIBUTES);
+  \rsa.lpSecurityDescriptor = NULL;      /* use default security for the pipe handles                            */
+  \r\rsa.bInheritHandle = TRUE;   /* the pipe handles can be inherited                                            */
+  \r\rif (!CreatePipe
+        (&(child_stdin_handle[0]), &(child_stdin_handle[1]), &sa, 0))
+    \r {
+    \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+            command->context->command_line,
+            error_to_string((int) GetLastError(), 0));
+    \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                     command->context->pos);
+    \r\rcommand->failed = 1;
+    \rcommand->status = cs_failed;
+    \r\rreturn;
+    \r}
+  \r\r\rif (!DuplicateHandle
+         (GetCurrentProcess(), (child_stdin_handle[1]),
+          GetCurrentProcess(), &(child_stderr), 0, TRUE,
+          DUPLICATE_SAME_ACCESS))
+    \r {
+    \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+            command->context->command_line,
+            error_to_string((int) GetLastError(), 0));
+    \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                     command->context->pos);
+    \r\rCloseHandle(child_stdin_handle[0]);
+    \rCloseHandle(child_stdin_handle[1]);
+    \r\rcommand->failed = 1;
+    \rcommand->status = cs_failed;
+    \r\rreturn;
+    \r}
+  \r\rif (!CreatePipe
+        (&(child_stdout_handle[0]), &(child_stdout_handle[1]), &sa, 0))
+    \r {
+    \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+            command->context->command_line,
+            error_to_string((int) GetLastError(), 0));
+    \runit_set_error(command->unit, (int) GetLastError(), 0,
+                    command->context->pos);
+    \r\rCloseHandle(child_stdout_handle[0]);
+    \rCloseHandle(child_stdout_handle[1]);
+    \rCloseHandle(child_stdin_handle[0]);
+    \rCloseHandle(child_stdin_handle[1]);
+    \r\rcommand->failed = 1;
+    \rcommand->status = cs_failed;
+    \r\rreturn;
+    \r}
+  \r\r
+      /* Read handle for read operations on the child std output. */ \r
+      if (!DuplicateHandle
+          (GetCurrentProcess(), (child_stdin_handle[0]),
+           GetCurrentProcess(), &(command->stdout_fd), 0, FALSE,
+           DUPLICATE_SAME_ACCESS))
+    \r {
+    \rCloseHandle(child_stdout_handle[0]);
+    \rCloseHandle(child_stdout_handle[1]);
+    \rCloseHandle(child_stdin_handle[0]);
+    \rCloseHandle(child_stdin_handle[1]);
+    \r\rcommand->failed = 1;
+    \rcommand->status = cs_failed;
+    \r\rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+             command->context->command_line,
+             error_to_string((int) GetLastError(), 0));
+    \runit_set_error(command->unit, (int) GetLastError(), 0,
+                    command->context->pos);
+    \r\rreturn;
+    \r}
+  \r\r\r
+      /* Write handle for write operations on the child std input. */ \r
+      if (!DuplicateHandle
+          (GetCurrentProcess(), (child_stdout_handle[1]),
+           GetCurrentProcess(), &(command->stdin_fd), 0, FALSE,
+           DUPLICATE_SAME_ACCESS))
+    \r {
+    \rCloseHandle(child_stdout_handle[0]);
+    \rCloseHandle(child_stdout_handle[1]);
+    \rCloseHandle(child_stdin_handle[0]);
+    \rCloseHandle(child_stdin_handle[1]);
+    \r\rcommand->failed = 1;
+    \rcommand->status = cs_failed;
+    \r\rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+             command->context->command_line,
+             error_to_string((int) GetLastError(), 0));
+    \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                     command->context->pos);
+    \r\rreturn;
+    \r}
+  \r\rCloseHandle(child_stdin_handle[0]);
+  \rCloseHandle(child_stdout_handle[1]);
+  \r\r\rif (command->timer)
+    \r {
+    \r
+        /* launch the timer */ \r
+        timer_time(command->timer);
+    \r}
+  \r\rif (command->reader)
+    \r {
+    \r
+        /* launch the reader */ \r
+        reader_read(command->reader);
+    \r}
+  \r\r\rif (command->writer)
+    \r {
+    \r
+        /* launch the writer */ \r
+        writer_write(command->writer);
+    \r}
+  \r\r
+      /* if there is a reader wait for its starting */ \r
+      if (command->reader)
+    \rxbt_os_sem_acquire(command->reader->started);
+  \r\r
+      /* if there is a reader wait for its ending */ \r
+      if (command->writer)
+    \rxbt_os_sem_acquire(command->writer->written);
+  \r\r
+      /* if there is a reader wait for its starting */ \r
+      if (command->timer)
+    \rxbt_os_sem_acquire(command->timer->started);
+  \r\rsi.cb = sizeof(STARTUPINFO);
+  \r\rsi.dwFlags |= STARTF_USESTDHANDLES;
+  \rsi.hStdOutput = child_stdin_handle[1];
+  \rsi.hStdInput = child_stdout_handle[0];
+  \rsi.hStdError = child_stderr;
+  \r\r
+      /* launch the process */ \r
+      if (!CreateProcess
+          (\rNULL, \rtow32cmd(command_line), \rNULL, \rNULL, \rTRUE,
+           \rCREATE_NO_WINDOW, \rNULL, \rNULL, \r&si, \r&pi) \r)
+    \r {
+    \r\rif (ERROR_FILE_NOT_FOUND == GetLastError())
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line, error_to_string(ECMDNOTFOUND,
+                                                              1));
+      \runit_set_error(command->unit, ECMDNOTFOUND, 1,
+                      command->context->pos);
+      \rcommand_handle_failure(command, csr_command_not_found);
+      \r}
+    \r
+    else
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line,
+              error_to_string((int) GetLastError(), 0));
+      \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                       command->context->pos);
+      \rcommand_handle_failure(command,
+                              csr_create_process_function_failure);
+    \r\r\r}
+  \r
+  else
+    \r {
+    \r
+        /* the command is running */ \r
+        command->status = cs_in_progress;
+    \r\r
+        /* save the pid of the command */ \r
+        command->pid = pi.hProcess;
+    \r\r
+        /* close non used thread handle */ \r
+        CloseHandle(pi.hThread);
+    \r\r}
+  \r\r\r
+      /* close non used handles */ \r
+      CloseHandle(child_stdin_handle[1]);
+  \rCloseHandle(child_stdout_handle[0]);
+  \rCloseHandle(child_stderr);
+\r\r\r}
+
+\r
+#else   /* \r */
+void \r command_exec(command_t command, const char *command_line) \r
+{
+  \rint child_stdin_fd[2];
+  \rint child_stdout_fd[2];
+  \r\r
+#ifdef __CHKCMD\r
+  int rv =
+      is_cmd(command->unit->runner->path, command->unit->runner->builtin,
+             command_line);
+  \r\rif (rv != 0)
+    \r {
+    \r\rif (rv == EINVAL)
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line, error_to_string(rv, 0));
+      \runit_set_error(command->unit, rv, 0, command->context->pos);
+      \r}
+    \r
+    else
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line, error_to_string(rv, 1));
+      \runit_set_error(command->unit, rv, 1, command->context->pos);
+      \r}
+    \r\rcommand_handle_failure(command, csr_command_not_found);
+    \r\rreturn;
+    \r}
+  \r\r
+#endif  /* \r */
+      \r\rif (command->writer)
+    \r {
+    \rif (pipe(child_stdin_fd))
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line, error_to_string(errno, 0));
+      \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+      \r\rcommand_handle_failure(command, csr_pipe_function_failed);
+      \r\r\r\rreturn;
+      \r}
+    \r}
+  \r\rif (command->reader)
+    \r {
+    \rif (pipe(child_stdout_fd))
+      \r {
+      \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+              command->context->command_line, error_to_string(errno, 0));
+      \r\rif (command->writer)
+        \r {
+        \rclose(child_stdin_fd[0]);
+        \rclose(child_stdin_fd[1]);
+        \r}
+      \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+      \r\rcommand_handle_failure(command, csr_pipe_function_failed);
+      \r\rreturn;
+      \r}
+    \r}
+  \r\rif (command->writer)
+    \r {
+    \rif (fcntl
+         (child_stdin_fd[1], F_SETFL,
+          fcntl(child_stdin_fd[1], F_GETFL) | O_NONBLOCK) < 0)
+      \r {
+      \r\rERROR3("[%s] `%s'  : NOK (%s)", command->context->pos,
+               command->context->command_line, error_to_string(errno, 0));
+      \r\rclose(child_stdin_fd[0]);
+      \rclose(child_stdin_fd[1]);
+      \r\rif (command->reader)
+        \r {
+        \rclose(child_stdout_fd[0]);
+        \rclose(child_stdout_fd[1]);
+        \r}
+      \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+      \r\rcommand_handle_failure(command, csr_fcntl_function_failed);
+      \r\rreturn;
+      \r}
+    \r}
+  \r\r
+      /* to write to the child stdin */ \r
+      command->stdin_fd = child_stdin_fd[1];
+  \r\r
+      /* to read from the child stdout */ \r
+      command->stdout_fd = child_stdout_fd[0];
+  \r\r
+      /* launch the reader if any */ \r
+      if (command->reader)
+    \rreader_read(command->reader);
+  \r\r
+      /* launch the writer if any */ \r
+      if (command->writer)
+    \rwriter_write(command->writer);
+  \r\r
+      /* launch the timer if any */ \r
+      if (command->timer)
+    \rtimer_time(command->timer);
+  \r\r
+      /* if there is a reader wait for its starting */ \r
+      if (command->reader)
+    \rxbt_os_sem_acquire(command->reader->started);
+  \r\r
+      /* if there is a reader wait for its ending */ \r
+      if (command->writer)
+    \rxbt_os_sem_acquire(command->writer->written);
+  \r\r
+      /* if there is a reader wait for its starting */ \r
+      if (command->timer)
+    \rxbt_os_sem_acquire(command->timer->started);
+  \r\r
+      /* update the state of the command, assume it is in progress */ \r
+      command->status = cs_in_progress;
+  \r\rcommand->pid = fork();
+  \r\rif (command->pid < 0)
+    \r {                         /* error */
+    \rif (command->writer)
+      \r {
+      \rclose(child_stdin_fd[0]);
+      \rclose(child_stdin_fd[1]);
+      \r}
+    \r\rif (command->reader)
+      \r {
+      \rclose(child_stdout_fd[0]);
+      \rclose(child_stdout_fd[1]);
+      \r}
+    \r\rERROR2("[%s] Cannot fork the command `%s'", command->context->pos,
+             command->context->command_line);
+    \runit_set_error(command->unit, errno, 0, command->context->pos);
+    \rcommand_handle_failure(command, csr_fork_function_failure);
+    \r}
+  \r
+  else
+    \r {
+    \rif (command->pid)
+      \r {                       /* father */
+      \r\r
+          /* close unused file descriptors */ \r
+          if (command->writer)
+        \rclose(child_stdin_fd[0]);
+      \r\rif (command->reader)
+        \rclose(child_stdout_fd[1]);
+      \r}
+    \r
+    else
+      \r {                       /* child */
+      \r\r
+          /* close unused file descriptors */ \r
+          if (command->writer)
+        \rclose(child_stdin_fd[1]);
+      \r\rif (command->reader)
+        \rclose(child_stdout_fd[0]);
+      \r\rif (command->writer)
+        \r {
+        \r
+            /* redirect stdin to child_stdin_fd[0] (now fgets(), getchar() ... read from the pipe */ \r
+            if (dup2(child_stdin_fd[0], STDIN_FILENO) < 0)
+          \r {
+          \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+                  command->context->command_line, error_to_string(errno,
+                                                                  0));
+          \rcommand->unit->exit_code = errno;
+          \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+          \rcommand_handle_failure(command, csr_dup2_function_failure);
+          \r}
+        \r\r
+            /* close the unused file descriptor  */ \r
+            close(child_stdin_fd[0]);
+        \r}
+      \r\rif (command->reader)
+        \r {
+        \r\r
+            /* redirect stdout and stderr to child_stdout_fd[1] (now printf(), perror()... write to the pipe */ \r
+            if (dup2(child_stdout_fd[1], STDOUT_FILENO) < 0)
+          \r {
+          \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+                  command->context->command_line, error_to_string(errno,
+                                                                  0));
+          \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+          \rcommand_handle_failure(command, csr_dup2_function_failure);
+          \r}
+        \r\rif (dup2(child_stdout_fd[1], STDERR_FILENO) < 0)
+          \r {
+          \rERROR3("[%s] `%s' : NOK (%s)", command->context->pos,
+                  command->context->command_line, error_to_string(errno,
+                                                                  0));
+          \runit_set_error(command->unit, errno, 0, command->context->pos);
+          \rcommand_handle_failure(command, csr_dup2_function_failure);
+          \r}
+        \r\r
+            /* close the unused file descriptor  */ \r
+            close(child_stdout_fd[1]);
+        \r}
+      \r\r
+          /* launch the command */ \r
+          if (execlp
+              ("/bin/sh", "sh", "-c", command->context->command_line,
+               NULL) < 0)
+        \rcommand->execlp_errno = errno;
+      \r}
+    \r}
+\r}
+
+\r
+#endif  /* \r */
+    \r
 #ifdef _XBT_WIN32\r
-void\r
-command_wait(command_t command)\r
-{\r
-       /* wait for the command terminaison */\r
-       DWORD rv;\r
-\r
-       if(WAIT_FAILED == WaitForSingleObject(command->pid, INFINITE))\r
-       {\r
-               ERROR2("[%s] Cannot wait for the child`%s'", command->context->pos, command->context->command_line);\r
-\r
-               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-               command_handle_failure(command, csr_wait_failure );\r
-               /* TODO : see for the interruption      */\r
-       }\r
-       else\r
-       {\r
-               /* don't take care of the timer or the writer or the reader failue */\r
-               if(cs_failed != command->status && cs_interrupted != command->status)\r
-               {\r
-                       if(!GetExitCodeProcess(command->pid,&rv))\r
-                       {\r
-                               ERROR2("[%s] Cannot get the exit code of the process `%s'",command->context->pos, command->context->command_line);\r
-\r
-                               unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
-\r
-                               command_handle_failure(command, csr_get_exit_code_process_function_failure );\r
-                       }\r
-                       else\r
-                               command->stat_val = command->exit_code = rv;\r
-               }\r
-       }\r
-}\r
-#else\r
-void\r
-command_wait(command_t command)\r
-{\r
-       if(!command->execlp_errno)\r
-       {\r
-               /* let this thread wait for the child so that the main thread can detect the timeout without blocking on the wait */\r
-               int pid = waitpid(command->pid, &(command->stat_val), 0);\r
-\r
-               if(pid != command->pid)\r
-               {\r
-                       ERROR2("[%s] Cannot wait for the child`%s'", command->context->pos, command->context->command_line);\r
-\r
-                       unit_set_error(command->unit, errno, 0, command->context->pos);\r
-\r
-                       command_handle_failure(command, csr_waitpid_function_failure);\r
-               }\r
-               else\r
-               {\r
-                       if(WIFEXITED(command->stat_val))\r
-                               command->exit_code = WEXITSTATUS(command->stat_val);\r
-               }\r
-       }\r
-       else\r
-       {\r
-               ERROR2("[%s] Cannot execute the command `%s'", command->context->pos, command->context->command_line);\r
-\r
-               unit_set_error(command->unit, command->execlp_errno, 0, command->context->pos);\r
-\r
-               command_handle_failure(command, csr_execlp_function_failure);\r
-       }\r
-}\r
-#endif\r
-\r
-void\r
-command_check(command_t command)\r
-{\r
-       int success = 1;\r
-       cs_reason_t reason;\r
-\r
-       /* we have a signal, store it */\r
-       if(WIFSIGNALED(command->stat_val))\r
-       {\r
-               command->signal = strdup(signal_name(WTERMSIG(command->stat_val),command->context->signal));\r
-       }\r
-\r
-       /* we have a signal and no signal is expected */\r
-       if(WIFSIGNALED(command->stat_val) && !command->context->signal)\r
-       {\r
-               success = 0;\r
-               ERROR3("[%s] `%s' : NOK (unexpected signal `%s' caught)", command->context->pos, command->context->command_line, command->signal);\r
-\r
-               unit_set_error(command->unit, EUNXPSIG, 1, command->context->pos);\r
-\r
-               reason = csr_unexpected_signal_caught;\r
-       }\r
-\r
-       /* we have a signal that differ form the expected signal */\r
-       if(WIFSIGNALED(command->stat_val) && command->context->signal && strcmp(signal_name(WTERMSIG(command->stat_val),command->context->signal),command->context->signal))\r
-       {\r
-\r
-               ERROR4("[%s] `%s' : NOK (got signal `%s' instead of `%s')", command->context->pos, command->context->command_line, command->signal, command->context->signal);\r
-\r
-               if(success)\r
-               {\r
-                       success = 0;\r
-                       unit_set_error(command->unit, ESIGNOTMATCH, 1, command->context->pos);\r
-               }\r
-\r
-               reason = csr_signals_dont_match;\r
-       }\r
-\r
-       /* we don't receive the expected signal */\r
-       if(!WIFSIGNALED(command->stat_val) && command->context->signal)\r
-       {\r
-\r
-               ERROR3("[%s] `%s' : NOK (expected `%s' not received)", command->context->pos, command->context->command_line, command->context->signal);\r
-\r
-               if(success)\r
-               {\r
-                       success = 0;\r
-                       unit_set_error(command->unit, ESIGNOTRECEIVED, 1, command->context->pos);\r
-               }\r
-\r
-               reason = csr_expected_signal_not_received;\r
-       }\r
-\r
-       /* if the command exit normaly and we expect a exit code : test it */\r
-       if(WIFEXITED(command->stat_val) /* && INDEFINITE != command->context->exit_code*/)\r
-       {\r
-               /* the exit codes don't match */\r
-               if(WEXITSTATUS(command->stat_val) != command->context->exit_code)\r
-               {\r
-                       ERROR4("[%s] %s : NOK (returned code `%d' instead `%d')", command->context->pos, command->context->command_line, WEXITSTATUS(command->stat_val), command->context->exit_code);\r
-\r
-                       if(success)\r
-                       {\r
-                               success = 0;\r
-                               unit_set_error(command->unit, EEXITCODENOTMATCH, 1, command->context->pos);\r
-                       }\r
-\r
-                       reason = csr_exit_codes_dont_match;\r
-               }\r
-       }\r
-\r
-       /* make sure the reader done */\r
-       while(!command->reader->done)\r
-               xbt_os_thread_yield();\r
-\r
-       #ifdef _XBT_WIN32\r
-       CloseHandle(command->stdout_fd);\r
-       #else\r
-       close(command->stdout_fd);\r
-       #endif\r
-\r
-       command->stdout_fd = INDEFINITE_FD;\r
-\r
-       xbt_strbuff_chomp(command->output);\r
-       xbt_strbuff_chomp(command->context->output);\r
-       xbt_strbuff_trim(command->output);\r
-       xbt_strbuff_trim(command->context->output);\r
-\r
-       if(!success &&  !strcmp(command->output->data, command->context->output->data))\r
-       {\r
-               xbt_dynar_t a = xbt_str_split(command->output->data, "\n");\r
-               char *out = xbt_str_join(a,"\n||");\r
-               xbt_dynar_free(&a);\r
-               INFO2("Output of <%s> so far: \n||%s", command->context->pos,out);\r
-               free(out);\r
-       }\r
-       /* if ouput handling flag is specified check the output */\r
-       else if(oh_check == command->context->output_handling && command->reader)\r
-       {\r
-               if(command->output->used != command->context->output->used || strcmp(command->output->data, command->context->output->data))\r
-               {\r
-                       char *diff;\r
-\r
-\r
-                       ERROR2("[%s] `%s' : NOK (outputs mismatch):", command->context->pos, command->context->command_line);\r
-\r
-                       if(success)\r
-                       {\r
-                               unit_set_error(command->unit, EOUTPUTNOTMATCH, 1, command->context->pos);\r
-                               success = 0;\r
-                       }\r
-\r
-                       reason = csr_outputs_dont_match;\r
-\r
-                       /* display the diff */\r
-                       diff = xbt_str_diff(command->context->output->data,command->output->data);\r
-                       INFO1("%s",diff);\r
-                       free(diff);\r
-               }\r
-       }\r
-       else if (oh_ignore == command->context->output_handling)\r
-       {\r
-               INFO1("(ignoring the output of <%s> as requested)",command->context->line);\r
-       }\r
-       else if (oh_display == command->context->output_handling)\r
-       {\r
-               xbt_dynar_t a = xbt_str_split(command->output->data, "\n");\r
-               char *out = xbt_str_join(a,"\n||");\r
-               xbt_dynar_free(&a);\r
-               INFO3("[%s] Here is the (ignored) command `%s' output: \n||%s",command->context->pos, command->context->command_line, out);\r
-               free(out);\r
-       }\r
-\r
-       if(success)\r
-       {\r
-               xbt_os_mutex_acquire(command->mutex);\r
-\r
-               if(command->status != cs_interrupted)\r
-               {\r
-                       /* signal the success of the command */\r
-                       command->status = cs_successeded;\r
-                       command->successeded = 1;\r
-\r
-                       /* increment the number of successeded command of the unit */\r
-                       (command->root->successeded_cmd_nb)++;\r
-               }\r
-\r
-               xbt_os_mutex_release(command->mutex);\r
-       }\r
-       else\r
-       {\r
-               command_handle_failure(command, reason);\r
-       }\r
-}\r
-\r
+void \r command_wait(command_t command) \r
+{
+  \r
+      /* wait for the command terminaison */ \r
+      DWORD rv;
+  \r\rif (WAIT_FAILED == WaitForSingleObject(command->pid, INFINITE))
+    \r {
+    \rERROR2("[%s] Cannot wait for the child`%s'", command->context->pos,
+            command->context->command_line);
+    \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                     command->context->pos);
+    \r\rcommand_handle_failure(command, csr_wait_failure);
+    \r
+        /* TODO : see for the interruption      */ \r
+    }
+  \r
+  else
+    \r {
+    \r
+        /* don't take care of the timer or the writer or the reader failue */ \r
+        if (cs_failed != command->status
+            && cs_interrupted != command->status)
+      \r {
+      \rif (!GetExitCodeProcess(command->pid, &rv))
+        \r {
+        \rERROR2("[%s] Cannot get the exit code of the process `%s'",
+                command->context->pos, command->context->command_line);
+        \r\runit_set_error(command->unit, (int) GetLastError(), 0,
+                         command->context->pos);
+        \r\rcommand_handle_failure(command,
+                                 csr_get_exit_code_process_function_failure);
+        \r}
+      \r
+      else
+        \rcommand->stat_val = command->exit_code = rv;
+      \r}
+    \r}
+\r}
+
+\r
+#else   /* \r */
+void \r command_wait(command_t command) \r
+{
+  \rif (!command->execlp_errno)
+    \r {
+    \r
+        /* let this thread wait for the child so that the main thread can detect the timeout without blocking on the wait */ \r
+    int pid = waitpid(command->pid, &(command->stat_val), 0);
+    \r\rif (pid != command->pid)
+      \r {
+      \rERROR2("[%s] Cannot wait for the child`%s'", command->context->pos,
+              command->context->command_line);
+      \r\runit_set_error(command->unit, errno, 0, command->context->pos);
+      \r\rcommand_handle_failure(command, csr_waitpid_function_failure);
+      \r}
+    \r
+    else
+      \r {
+      \rif (WIFEXITED(command->stat_val))
+        \rcommand->exit_code = WEXITSTATUS(command->stat_val);
+      \r}
+    \r}
+  \r
+  else
+    \r {
+    \rERROR2("[%s] Cannot execute the command `%s'", command->context->pos,
+            command->context->command_line);
+    \r\runit_set_error(command->unit, command->execlp_errno, 0,
+                     command->context->pos);
+    \r\rcommand_handle_failure(command, csr_execlp_function_failure);
+    \r}
+\r}
+
+\r
+#endif  /* \r */
+\rvoid \r command_check(command_t command) \r
+{
+  \rint success = 1;
+  \rcs_reason_t reason;
+  \r\r
+      /* we have a signal, store it */ \r
+      if (WIFSIGNALED(command->stat_val))
+    \r {
+    \rcommand->signal =
+        strdup(signal_name
+               (WTERMSIG(command->stat_val), command->context->signal));
+    \r}
+  \r\r
+      /* we have a signal and no signal is expected */ \r
+      if (WIFSIGNALED(command->stat_val) && !command->context->signal)
+    \r {
+    \rsuccess = 0;
+    \rERROR3("[%s] `%s' : NOK (unexpected signal `%s' caught)",
+            command->context->pos, command->context->command_line,
+            command->signal);
+    \r\runit_set_error(command->unit, EUNXPSIG, 1, command->context->pos);
+    \r\rreason = csr_unexpected_signal_caught;
+    \r}
+  \r\r
+      /* we have a signal that differ form the expected signal */ \r
+      if (WIFSIGNALED(command->stat_val) && command->context->signal
+          &&
+          strcmp(signal_name
+                 (WTERMSIG(command->stat_val), command->context->signal),
+                 command->context->signal))
+    \r {
+    \r\rERROR4("[%s] `%s' : NOK (got signal `%s' instead of `%s')",
+             command->context->pos, command->context->command_line,
+             command->signal, command->context->signal);
+    \r\rif (success)
+      \r {
+      \rsuccess = 0;
+      \runit_set_error(command->unit, ESIGNOTMATCH, 1,
+                      command->context->pos);
+      \r}
+    \r\rreason = csr_signals_dont_match;
+    \r}
+  \r\r
+      /* we don't receive the expected signal */ \r
+      if (!WIFSIGNALED(command->stat_val) && command->context->signal)
+    \r {
+    \r\rERROR3("[%s] `%s' : NOK (expected `%s' not received)",
+             command->context->pos, command->context->command_line,
+             command->context->signal);
+    \r\rif (success)
+      \r {
+      \rsuccess = 0;
+      \runit_set_error(command->unit, ESIGNOTRECEIVED, 1,
+                      command->context->pos);
+      \r}
+    \r\rreason = csr_expected_signal_not_received;
+    \r}
+  \r\r
+      /* if the command exit normaly and we expect a exit code : test it */ \r
+      if (WIFEXITED(command->stat_val)
+          /* && INDEFINITE != command->context->exit_code */ )
+    \r {
+    \r
+        /* the exit codes don't match */ \r
+        if (WEXITSTATUS(command->stat_val) != command->context->exit_code)
+      \r {
+      \rERROR4("[%s] %s : NOK (returned code `%d' instead `%d')",
+              command->context->pos, command->context->command_line,
+              WEXITSTATUS(command->stat_val), command->context->exit_code);
+      \r\rif (success)
+        \r {
+        \rsuccess = 0;
+        \runit_set_error(command->unit, EEXITCODENOTMATCH, 1,
+                        command->context->pos);
+        \r}
+      \r\rreason = csr_exit_codes_dont_match;
+      \r}
+    \r}
+  \r\r
+      /* make sure the reader done */ \r
+      while (!command->reader->done)
+    \rxbt_os_thread_yield();
+  \r\r
 #ifdef _XBT_WIN32\r
-void\r
-command_kill(command_t command)\r
-{\r
-       if(INDEFINITE_PID != command->pid)\r
-       {\r
-               INFO2("[%s] Kill the process `%s'", command->context->pos, command->context->command_line);\r
-               TerminateProcess(command->pid, INDEFINITE);\r
-       }\r
-}\r
-#else\r
-void\r
-command_kill(command_t command)\r
-{\r
-       if(INDEFINITE_PID != command->pid)\r
-       {\r
-               kill(command->pid,SIGTERM);\r
-\r
-               if(!command->context->signal)\r
-                       command->context->signal = strdup("SIGTERM");\r
-\r
-               command->exit_code = INDEFINITE;\r
-               command->killed = 1;\r
-\r
-               usleep(100);\r
-\r
-               INFO2("[%s] Kill the process `%s'", command->context->pos, command->context->command_line);\r
-               kill(command->pid,SIGKILL);\r
-\r
-\r
-       }\r
-}\r
-#endif\r
-\r
-void\r
-command_interrupt(command_t command)\r
-{\r
-       xbt_os_mutex_acquire(command->mutex);\r
-\r
-       if((command->status != cs_interrupted) && (command->status != cs_failed) && (command->status != cs_successeded))\r
-       {\r
-               command->status = cs_interrupted;\r
-               command->reason = csr_interruption_request;\r
-               command->interrupted = 1;\r
-               command->unit->interrupted = 1;\r
-\r
-               xbt_os_mutex_acquire(command->root->mutex);\r
-               (command->root->interrupted_cmd_nb)++;\r
-               xbt_os_mutex_release(command->root->mutex);\r
-\r
-               if(command->pid != INDEFINITE_PID)\r
-                       command_kill(command);\r
-       }\r
-\r
-       xbt_os_mutex_release(command->mutex);\r
-\r
-\r
-}\r
-\r
-void\r
-command_summarize(command_t command)\r
-{\r
-       if(cs_successeded != command->status)\r
-       {\r
-\r
-               #ifndef _XBT_WIN32\r
-               if(command->killed)\r
-                       printf("          <killed command>\n");\r
-               #endif\r
-\r
-               /* display the reason of the status of the command */\r
-               switch(command->reason)\r
-               {\r
-                       /* the function pipe or CreatePipe() fails */\r
-                       case csr_pipe_function_failed :\r
-                       printf("          reason                      : pipe() or CreatePipe() function failed (system error)\n");\r
-                       break;\r
-\r
-                       case csr_shell_failed :\r
-                       printf("          reason                      : shell failed (may be command not found)\n");\r
-                       break;\r
-\r
-                       case csr_get_exit_code_process_function_failure :\r
-                       printf("          reason                      : ExitCodeProcess() function failed (system error)\n");\r
-                       break;\r
-\r
-                       /* reader failure reasons*/\r
-                       case csr_read_pipe_broken :\r
-                       printf("          reason                      : command read pipe broken\n");\r
-                       break;\r
-\r
-                       case csr_read_failure :\r
-                       printf("          reason                      : command stdout read failed\n");\r
-                       break;\r
-\r
-                       /* writer failure reasons */\r
-                       case csr_write_failure :\r
-                       printf("          reason                      : command stdin write failed\n");\r
-                       break;\r
-\r
-                       case csr_write_pipe_broken :\r
-                       printf("          reason                      : command write pipe broken\n");\r
-                       break;\r
-\r
-                       /* timer reason */\r
-                       case csr_timeout :\r
-                       printf("          reason                      : command timeouted\n");\r
-                       break;\r
-\r
-                       /* command failure reason */\r
-                       case csr_command_not_found :\r
-                       printf("          reason                      : command not found\n");\r
-                       break;\r
-\r
-                       /* context failure reasons */\r
-                       case csr_exit_codes_dont_match :\r
-                       printf("          reason                      : exit codes don't match\n");\r
-\r
-                       break;\r
-\r
-                       /* dup2 function failure reasons */\r
-                       case csr_dup2_function_failure :\r
-                       printf("          reason                      : dup2() function failed\n");\r
-\r
-                       break;\r
-\r
-                       /* execlp function failure reasons */\r
-                       case csr_execlp_function_failure :\r
-                       printf("          reason                      : execlp() function failed\n");\r
-\r
-                       break;\r
-\r
-                       /* waitpid function failure reasons */\r
-                       case csr_waitpid_function_failure :\r
-                       printf("          reason                      : waitpid() function failed\n");\r
-\r
-                       break;\r
-\r
-                       /* CreateProcess function failure reasons */\r
-                       case csr_create_process_function_failure :\r
-                       printf("          reason                      : CreateProcesss() function failed\n");\r
-\r
-                       break;\r
-\r
-                       case csr_outputs_dont_match :\r
-                       {\r
-                               /*char *diff;*/\r
-                               printf("          reason                      : ouputs don't match\n");\r
-                               /*diff = xbt_str_diff(command->context->output->data,command->output->data);\r
-                               printf("          output diff :\n%s\n",diff);\r
-                               free(diff);*/\r
-                       }\r
-\r
-                       break;\r
-\r
-                       case csr_signals_dont_match :\r
-                       printf("          reason                      : signals don't match\n");\r
-                       break;\r
-\r
-                       case csr_unexpected_signal_caught:\r
-                       printf("          reason                      : unexpected signal caught\n");\r
-                       break;\r
-\r
-                       case csr_expected_signal_not_received :\r
-                       printf("          reason                      : expected signal not receipt\n");\r
-                       break;\r
-\r
-                       /* system failure reasons */\r
-                       case csr_fork_function_failure :\r
-                       printf("          reason                      : fork function failed\n");\r
-                       break;\r
-\r
-                       case csr_wait_failure :\r
-                       printf("          reason                      : wait command failure\n");\r
-                       break;\r
-\r
-                       /* global/local interruption */\r
-                       case csr_interruption_request :\r
-                       printf("          reason                      : the command receive a interruption request\n");\r
-                       break;\r
-\r
-                       /* unknown ? */\r
-                       case csr_unknown :\r
-                       printf("          reason                      : unknown \n");\r
-               }\r
-       }\r
-\r
-       if(csr_command_not_found != command->reason && csr_fork_function_failure != command->reason  && csr_execlp_function_failure != command->reason)\r
-       {\r
-               if(INDEFINITE != command->exit_code)\r
-                       /* the command exit code */\r
-                       printf("          exit code                   : %d\n",command->exit_code);\r
-\r
-               /* if an expected exit code was specified display it */\r
-               if(INDEFINITE != command->context->exit_code)\r
-                       printf("          expected exit code          : %d\n",command->context->exit_code);\r
-               else\r
-                       printf("          no expected exit code specified\n");\r
-\r
-               /* no expected signal expected */\r
-               if(NULL == command->context->signal)\r
-               {\r
-                       printf("          no expected signal specified\n");\r
-\r
-                       if(command->signal)\r
-                               printf("          but got signal              : %s\n",command->signal);\r
-\r
-               }\r
-               /* if an expected exit code was specified display it */\r
-               else\r
-               {\r
-                       if(NULL != command->signal)\r
-                               printf("          signal                      : %s\n",command->signal);\r
-                       else\r
-                               printf("          no signal caugth\n");\r
-               }\r
-\r
-               /* if the command has out put and the metacommand display output is specified display it  */\r
-               if(command->output && (0 != command->output->used) && (oh_display == command->context->output_handling))\r
-               {\r
-                       xbt_dynar_t a = xbt_str_split(command->output->data, "\n");\r
-                       char *out = xbt_str_join(a,"\n||");\r
-                       xbt_dynar_free(&a);\r
-                       printf("          output :\n||%s",out);\r
-                       free(out);\r
-               }\r
-       }\r
-\r
-       printf("\n");\r
-}\r
-\r
-void\r
-command_handle_failure(command_t command, cs_reason_t reason)\r
-{\r
-       unit_t root = command->root;\r
-\r
-       xbt_os_mutex_acquire(command->mutex);\r
-\r
-       if((command->status != cs_interrupted) && (command->status != cs_failed))\r
-       {\r
-               command->status = cs_failed;\r
-               command->reason = reason;\r
-               command->failed = 1;\r
-\r
-               command->unit->failed = 1;\r
-\r
-               xbt_os_mutex_acquire(root->mutex);\r
-\r
-               /* increment the number of failed command of the unit */\r
-               root->failed_cmd_nb++;\r
-\r
-               /* if the --ignore-failures option is not specified */\r
-               if(!keep_going_unit_flag)\r
-               {\r
-                       if(!root->interrupted)\r
-                       {\r
-                               /* the unit interrupted (exit for the loop) */\r
-                               root->interrupted = 1;\r
-\r
-                               /* release the unit */\r
-                               xbt_os_sem_release(root->sem);\r
-                       }\r
-\r
-                       /* if the --keep-going option is not specified */\r
-                       if(!keep_going_flag)\r
-                       {\r
-                               if(!interrupted)\r
-                               {\r
-                                       /* request an global interruption by the runner */\r
-                                       interrupted = 1;\r
-\r
-                                       /* release the runner */\r
-                                       xbt_os_sem_release(units_sem);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               xbt_os_mutex_release(root->mutex);\r
-       }\r
-\r
-       xbt_os_mutex_release(command->mutex);\r
-}\r
-\r
-int\r
-command_free(command_t* ptr)\r
-{\r
-       /* close the stdin and the stdout pipe handles */\r
-\r
-       #ifdef _XBT_WIN32\r
-       if((*ptr)->stdin_fd != INDEFINITE_FD)\r
-               CloseHandle((*ptr)->stdin_fd);\r
-\r
-       if((*ptr)->stdout_fd != INDEFINITE_FD)\r
-               CloseHandle((*ptr)->stdout_fd);\r
-\r
-       #else\r
-\r
-       if((*ptr)->stdin_fd != INDEFINITE_FD)\r
-               close((*ptr)->stdin_fd);\r
-\r
-       if((*ptr)->stdout_fd != INDEFINITE_FD)\r
-               close((*ptr)->stdout_fd);\r
-       #endif\r
-\r
-       if((*ptr)->timer)\r
-       {\r
-               if(timer_free(&((*ptr)->timer)) < 0)\r
-                       return -1;\r
-       }\r
-\r
-       if((*ptr)->writer)\r
-       {\r
-               if(writer_free(&((*ptr)->writer)) < 0)\r
-                       return -1;\r
-       }\r
-\r
-       if((*ptr)->reader)\r
-       {\r
-               if(reader_free(&((*ptr)->reader)) < 0)\r
-                       return -1;\r
-       }\r
-\r
-       if((*ptr)->output)\r
-               xbt_strbuff_free((*ptr)->output);\r
-\r
-       if((*ptr)->context)\r
-       {\r
-               if(context_free(&((*ptr)->context)) < 0)\r
-                       return -1;\r
-       }\r
-\r
-       if((*ptr)->signal)\r
-               free((*ptr)->signal);\r
-\r
-       free(*ptr);\r
-\r
-       *ptr = NULL;\r
-\r
-       return 0;\r
-}\r
-\r
-\r
-\r
+      CloseHandle(command->stdout_fd);
+  \r
+#else   /* \r */
+      close(command->stdout_fd);
+  \r
+#endif  /* \r */
+      \rcommand->stdout_fd = INDEFINITE_FD;
+  \r\rxbt_strbuff_chomp(command->output);
+  \rxbt_strbuff_chomp(command->context->output);
+  \rxbt_strbuff_trim(command->output);
+  \rxbt_strbuff_trim(command->context->output);
+  \r\rif (!success
+        && !strcmp(command->output->data, command->context->output->data))
+    \r {
+    \rxbt_dynar_t a = xbt_str_split(command->output->data, "\n");
+    \rchar *out = xbt_str_join(a, "\n||");
+    \rxbt_dynar_free(&a);
+    \rINFO2("Output of <%s> so far: \n||%s", command->context->pos, out);
+    \rfree(out);
+    \r}
+  \r
+      /* if ouput handling flag is specified check the output */ \r
+      else if (oh_check == command->context->output_handling
+               && command->reader)
+    \r {
+    \rif (command->output->used != command->context->output->used
+         || strcmp(command->output->data, command->context->output->data))
+      \r {
+      \rchar *diff;
+      \r\r\rERROR2("[%s] `%s' : NOK (outputs mismatch):",
+                command->context->pos, command->context->command_line);
+      \r\rif (success)
+        \r {
+        \runit_set_error(command->unit, EOUTPUTNOTMATCH, 1,
+                        command->context->pos);
+        \rsuccess = 0;
+        \r}
+      \r\rreason = csr_outputs_dont_match;
+      \r\r
+          /* display the diff */ \r
+          diff =
+          xbt_str_diff(command->context->output->data,
+                       command->output->data);
+      \rINFO1("%s", diff);
+      \rfree(diff);
+      \r}
+    \r}
+  \r
+  else if (oh_ignore == command->context->output_handling)
+    \r {
+    \rINFO1("(ignoring the output of <%s> as requested)",
+           command->context->line);
+    \r}
+  \r
+  else if (oh_display == command->context->output_handling)
+    \r {
+    \rxbt_dynar_t a = xbt_str_split(command->output->data, "\n");
+    \rchar *out = xbt_str_join(a, "\n||");
+    \rxbt_dynar_free(&a);
+    \rINFO3("[%s] Here is the (ignored) command `%s' output: \n||%s",
+           command->context->pos, command->context->command_line, out);
+    \rfree(out);
+    \r}
+  \r\rif (success)
+    \r {
+    \rxbt_os_mutex_acquire(command->mutex);
+    \r\rif (command->status != cs_interrupted)
+      \r {
+      \r
+          /* signal the success of the command */ \r
+          command->status = cs_successeded;
+      \rcommand->successeded = 1;
+      \r\r
+          /* increment the number of successeded command of the unit */ \r
+          (command->root->successeded_cmd_nb)++;
+      \r}
+    \r\rxbt_os_mutex_release(command->mutex);
+    \r}
+  \r
+  else
+    \r {
+    \rcommand_handle_failure(command, reason);
+    \r}
+\r}
+
+\r\r
+#ifdef _XBT_WIN32\r
+void \r command_kill(command_t command) \r
+{
+  \rif (INDEFINITE_PID != command->pid)
+    \r {
+    \rINFO2("[%s] Kill the process `%s'", command->context->pos,
+           command->context->command_line);
+    \rTerminateProcess(command->pid, INDEFINITE);
+    \r}
+\r}
+
+\r
+#else   /* \r */
+void \r command_kill(command_t command) \r
+{
+  \rif (INDEFINITE_PID != command->pid)
+    \r {
+    \rkill(command->pid, SIGTERM);
+    \r\rif (!command->context->signal)
+      \rcommand->context->signal = strdup("SIGTERM");
+    \r\rcommand->exit_code = INDEFINITE;
+    \rcommand->killed = 1;
+    \r\rusleep(100);
+    \r\rINFO2("[%s] Kill the process `%s'", command->context->pos,
+            command->context->command_line);
+    \rkill(command->pid, SIGKILL);
+    \r\r\r}
+\r}
+
+\r
+#endif  /* \r */
+\rvoid \r command_interrupt(command_t command) \r
+{
+  \rxbt_os_mutex_acquire(command->mutex);
+  \r\rif ((command->status != cs_interrupted)
+        && (command->status != cs_failed)
+        && (command->status != cs_successeded))
+    \r {
+    \rcommand->status = cs_interrupted;
+    \rcommand->reason = csr_interruption_request;
+    \rcommand->interrupted = 1;
+    \rcommand->unit->interrupted = 1;
+    \r\rxbt_os_mutex_acquire(command->root->mutex);
+    \r(command->root->interrupted_cmd_nb)++;
+    \rxbt_os_mutex_release(command->root->mutex);
+    \r\rif (command->pid != INDEFINITE_PID)
+      \rcommand_kill(command);
+    \r}
+  \r\rxbt_os_mutex_release(command->mutex);
+\r\r\r}
+
+\r\rvoid \r command_summarize(command_t command) \r
+{
+  \rif (cs_successeded != command->status)
+    \r {
+    \r\r
+#ifndef _XBT_WIN32\r
+        if (command->killed)
+      \rprintf("          <killed command>\n");
+    \r
+#endif  /* \r */
+        \r
+        /* display the reason of the status of the command */ \r
+        switch (command->reason)
+      \r {
+      \r
+          /* the function pipe or CreatePipe() fails */ \r
+    case csr_pipe_function_failed:
+      
+      \rprintf
+          ("          reason                      : pipe() or CreatePipe() function failed (system error)\n");
+      \rbreak;
+    \r\rcase csr_shell_failed:
+      \rprintf
+          ("          reason                      : shell failed (may be command not found)\n");
+      \rbreak;
+    \r\rcase csr_get_exit_code_process_function_failure:
+      \rprintf
+          ("          reason                      : ExitCodeProcess() function failed (system error)\n");
+      \rbreak;
+      \r\r
+          /* reader failure reasons */ \r
+    case csr_read_pipe_broken:
+      
+      \rprintf
+          ("          reason                      : command read pipe broken\n");
+      \rbreak;
+    \r\rcase csr_read_failure:
+      \rprintf
+          ("          reason                      : command stdout read failed\n");
+      \rbreak;
+      \r\r
+          /* writer failure reasons */ \r
+    case csr_write_failure:
+      
+      \rprintf
+          ("          reason                      : command stdin write failed\n");
+      \rbreak;
+    \r\rcase csr_write_pipe_broken:
+      \rprintf
+          ("          reason                      : command write pipe broken\n");
+      \rbreak;
+      \r\r
+          /* timer reason */ \r
+    case csr_timeout:
+      
+      \rprintf
+          ("          reason                      : command timeouted\n");
+      \rbreak;
+      \r\r
+          /* command failure reason */ \r
+    case csr_command_not_found:
+      
+      \rprintf
+          ("          reason                      : command not found\n");
+      \rbreak;
+      \r\r
+          /* context failure reasons */ \r
+    case csr_exit_codes_dont_match:
+      
+      \rprintf
+          ("          reason                      : exit codes don't match\n");
+      \r\rbreak;
+      \r\r
+          /* dup2 function failure reasons */ \r
+    case csr_dup2_function_failure:
+      
+      \rprintf
+          ("          reason                      : dup2() function failed\n");
+      \r\rbreak;
+      \r\r
+          /* execlp function failure reasons */ \r
+    case csr_execlp_function_failure:
+      
+      \rprintf
+          ("          reason                      : execlp() function failed\n");
+      \r\rbreak;
+      \r\r
+          /* waitpid function failure reasons */ \r
+    case csr_waitpid_function_failure:
+      
+      \rprintf
+          ("          reason                      : waitpid() function failed\n");
+      \r\rbreak;
+      \r\r
+          /* CreateProcess function failure reasons */ \r
+    case csr_create_process_function_failure:
+      
+      \rprintf
+          ("          reason                      : CreateProcesss() function failed\n");
+      \r\rbreak;
+    \r\rcase csr_outputs_dont_match:
+      \r {
+        \r
+            /*char *diff; */ \r
+            printf
+            ("          reason                      : ouputs don't match\n");
+        \r
+            /*diff = xbt_str_diff(command->context->output->data,command->output->data);\r
+               printf("          output diff :\n%s\n",diff);\r
+               free(diff); */ \r
+      }
+      \r\rbreak;
+    \r\rcase csr_signals_dont_match:
+      \rprintf
+          ("          reason                      : signals don't match\n");
+      \rbreak;
+    \r\rcase csr_unexpected_signal_caught:
+      \rprintf
+          ("          reason                      : unexpected signal caught\n");
+      \rbreak;
+    \r\rcase csr_expected_signal_not_received:
+      \rprintf
+          ("          reason                      : expected signal not receipt\n");
+      \rbreak;
+      \r\r
+          /* system failure reasons */ \r
+    case csr_fork_function_failure:
+      
+      \rprintf
+          ("          reason                      : fork function failed\n");
+      \rbreak;
+    \r\rcase csr_wait_failure:
+      \rprintf
+          ("          reason                      : wait command failure\n");
+      \rbreak;
+      \r\r
+          /* global/local interruption */ \r
+    case csr_interruption_request:
+      
+      \rprintf
+          ("          reason                      : the command receive a interruption request\n");
+      \rbreak;
+      \r\r
+          /* unknown ? */ \r
+    case csr_unknown:
+      \rprintf("          reason                      : unknown \n");
+      \r}
+    \r}
+  \r\rif (csr_command_not_found != command->reason
+        && csr_fork_function_failure != command->reason
+        && csr_execlp_function_failure != command->reason)
+    \r {
+    \rif (INDEFINITE != command->exit_code)
+      \r
+          /* the command exit code */ \r
+          printf("          exit code                   : %d\n",
+                 command->exit_code);
+    \r\r
+        /* if an expected exit code was specified display it */ \r
+        if (INDEFINITE != command->context->exit_code)
+      \rprintf("          expected exit code          : %d\n",
+              command->context->exit_code);
+    \r
+    else
+      \rprintf("          no expected exit code specified\n");
+    \r\r
+        /* no expected signal expected */ \r
+        if (NULL == command->context->signal)
+      \r {
+      \rprintf("          no expected signal specified\n");
+      \r\rif (command->signal)
+        \rprintf("          but got signal              : %s\n",
+                command->signal);
+      \r\r}
+    \r
+        /* if an expected exit code was specified display it */ \r
+        else
+      \r {
+      \rif (NULL != command->signal)
+        \rprintf("          signal                      : %s\n",
+                command->signal);
+      \r
+      else
+        \rprintf("          no signal caugth\n");
+      \r}
+    \r\r
+        /* if the command has out put and the metacommand display output is specified display it  */ \r
+        if (command->output && (0 != command->output->used)
+            && (oh_display == command->context->output_handling))
+      \r {
+      \rxbt_dynar_t a = xbt_str_split(command->output->data, "\n");
+      \rchar *out = xbt_str_join(a, "\n||");
+      \rxbt_dynar_free(&a);
+      \rprintf("          output :\n||%s", out);
+      \rfree(out);
+      \r}
+    \r}
+  \r\rprintf("\n");
+\r\r\rvoid \r command_handle_failure(command_t command, cs_reason_t reason) \r
+{
+  \runit_t root = command->root;
+  \r\rxbt_os_mutex_acquire(command->mutex);
+  \r\rif ((command->status != cs_interrupted)
+        && (command->status != cs_failed))
+    \r {
+    \rcommand->status = cs_failed;
+    \rcommand->reason = reason;
+    \rcommand->failed = 1;
+    \r\rcommand->unit->failed = 1;
+    \r\rxbt_os_mutex_acquire(root->mutex);
+    \r\r
+        /* increment the number of failed command of the unit */ \r
+        root->failed_cmd_nb++;
+    \r\r
+        /* if the --ignore-failures option is not specified */ \r
+        if (!keep_going_unit_flag)
+      \r {
+      \rif (!root->interrupted)
+        \r {
+        \r
+            /* the unit interrupted (exit for the loop) */ \r
+            root->interrupted = 1;
+        \r\r
+            /* release the unit */ \r
+            xbt_os_sem_release(root->sem);
+        \r}
+      \r\r
+          /* if the --keep-going option is not specified */ \r
+          if (!keep_going_flag)
+        \r {
+        \rif (!interrupted)
+          \r {
+          \r
+              /* request an global interruption by the runner */ \r
+              interrupted = 1;
+          \r\r
+              /* release the runner */ \r
+              xbt_os_sem_release(units_sem);
+          \r}
+        \r}
+      \r}
+    \r\rxbt_os_mutex_release(root->mutex);
+    \r}
+  \r\rxbt_os_mutex_release(command->mutex);
+\r}
+
+\r\rint \r command_free(command_t * ptr) \r
+{
+  \r
+      /* close the stdin and the stdout pipe handles */ \r
+      \r
+#ifdef _XBT_WIN32\r
+      if ((*ptr)->stdin_fd != INDEFINITE_FD)
+    \rCloseHandle((*ptr)->stdin_fd);
+  \r\rif ((*ptr)->stdout_fd != INDEFINITE_FD)
+    \rCloseHandle((*ptr)->stdout_fd);
+  \r\r
+#else   /* \r */
+      \rif ((*ptr)->stdin_fd != INDEFINITE_FD)
+    \rclose((*ptr)->stdin_fd);
+  \r\rif ((*ptr)->stdout_fd != INDEFINITE_FD)
+    \rclose((*ptr)->stdout_fd);
+  \r
+#endif  /* \r */
+      \rif ((*ptr)->timer)
+    \r {
+    \rif (timer_free(&((*ptr)->timer)) < 0)
+      \rreturn -1;
+    \r}
+  \r\rif ((*ptr)->writer)
+    \r {
+    \rif (writer_free(&((*ptr)->writer)) < 0)
+      \rreturn -1;
+    \r}
+  \r\rif ((*ptr)->reader)
+    \r {
+    \rif (reader_free(&((*ptr)->reader)) < 0)
+      \rreturn -1;
+    \r}
+  \r\rif ((*ptr)->output)
+    \rxbt_strbuff_free((*ptr)->output);
+  \r\rif ((*ptr)->context)
+    \r {
+    \rif (context_free(&((*ptr)->context)) < 0)
+      \rreturn -1;
+    \r}
+  \r\rif ((*ptr)->signal)
+    \rfree((*ptr)->signal);
+  \r\rfree(*ptr);
+  \r\r*ptr = NULL;
+  \r\rreturn 0;
+\r}
+
+\r\r\r\r