Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Kill tesh2 out of the source tree
[simgrid.git] / tools / tesh2 / src / command.c
diff --git a/tools/tesh2/src/command.c b/tools/tesh2/src/command.c
deleted file mode 100644 (file)
index d43adf1..0000000
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*\r
- * src/command.c - type representing a command.\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 command type.\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
-#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
-{
-  \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
-#include <xsignal.h>\r
-    \r
-#include <is_cmd.h>\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
-#ifndef BUFSIZE\r
-#define BUFSIZE        4096\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\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
-      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