2 * src/command.c - type representing a command.
4 * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package.
10 * This file contains all the definitions of the functions related with
11 * the tesh command type.
22 #include <sys/types.h>
28 tow32cmd(const char* cmd)
\r
30 static char w32cmd[PATH_MAX + 1] = {0};
\r
31 char cmd_buf[PATH_MAX + 1] = {0};
\r
43 strcpy(w32cmd, cmd);
\r
52 if(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '>')
\r
53 cmd_buf[j++] = cmd[i];
\r
60 _fullpath(w32cmd, cmd_buf, sizeof(w32cmd));
\r
62 if(!strstr(w32cmd, ".exe"))
\r
63 strcat(w32cmd, ".exe ");
\r
65 strcat(w32cmd, cmd + i);
\r
68 /*printf("w32cmd : %s", w32cmd);*/
\r
80 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);
83 command_start(void* p);
87 command_new(unit_t unit, context_t context, xbt_os_mutex_t mutex)
91 command = xbt_new0(s_command_t, 1);
93 /* get the context of the execution of the command */
94 if(!(command->context = context_dup(context)))
100 /* the exit code of the command is indefinite */
101 command->exit_code = INDEFINITE;
103 /* the signal of the command is indefinite */
104 command->signal = INDEFINITE_SIGNAL;
107 command->interrupted = 0;
109 /* the mutex used to safetly access to the command unit properties */
110 command->mutex = mutex;
112 command->output = xbt_strbuff_new();
114 command->pid = INDEFINITE_PID;
116 command->stat_val = -1;
118 /* set the unit of the command */
119 command->root = unit->root ? unit->root : unit;
120 command->unit = unit;
122 /* all the commands are runned in a thread */
123 command->thread = NULL;
125 command->successeded = 0;
127 command->reader = reader_new(command);
129 if(context->input->used)
130 command->writer = writer_new(command);
132 command->writer = NULL;
134 if(context->timeout != INDEFINITE)
135 command->timer = timer_new(command);
137 command->timer = NULL;
139 command->status = cs_initialized;
140 command->reason = csr_unknown;
142 command->stdin_fd = INDEFINITE_FD;
143 command->stdout_fd = INDEFINITE_FD;
146 /* register the command */
147 xbt_os_mutex_acquire(mutex);
149 xbt_dynar_push(unit->commands, &command);
150 command->root->cmd_nb++;
151 xbt_os_mutex_release(mutex);
155 command->execlp_errno = 0;
163 command_run(command_t command)
166 INFO2("[%s] %s",command->context->pos, command->context->command_line);
172 /* start the command in a thread*/
173 if(command->context->async)
175 command->thread = xbt_os_thread_create("", command_start, command);
180 /* start the command in the main thread */
181 command_start(command);
186 command_interrupt(command);
197 command_start(void* p)
199 command_t command = (command_t)p;
200 unit_t root = command->root;
202 /* the command is started */
203 command->status = cs_started;
205 /* increment the number of started commands of the unit */
206 xbt_os_mutex_acquire(command->mutex);
207 (root->started_cmd_nb)++;
208 xbt_os_mutex_release(command->mutex);
210 /* execute the command of the test */
211 command_exec(command, command->context->command_line);
213 if(cs_in_progress == command->status)
215 /* wait the process if it is in progress */
216 command_wait(command);
218 if(cs_failed != command->status && cs_interrupted != command->status)
219 command_check(command);
222 xbt_os_mutex_acquire(command->mutex);
224 /* if it's the last command of the root unit */
225 if(!root->interrupted && root->parsed && (root->started_cmd_nb == (root->failed_cmd_nb + root->interrupted_cmd_nb + root->successeded_cmd_nb)))
227 /* first release the mutex */
229 xbt_os_mutex_release(command->mutex);
230 /* the last command release the unit */
231 xbt_os_sem_release(root->sem);
234 xbt_os_mutex_release(command->mutex);
237 /* wait the end of the timer, the reader and the writer */
238 if(command->timer && command->timer->thread)
239 timer_wait(command->timer);
241 /* wait the end of the writer */
242 if(command->writer && command->writer->thread)
243 writer_wait(command->writer);
245 /* wait the end of the reader */
246 if(command->reader && command->reader->thread)
247 reader_wait(command->reader);
257 #define BUFSIZE 4096
\r
260 command_exec(command_t command, const char* command_line)
263 STARTUPINFO si = {0}; /* contains the informations about the child process windows*/
264 PROCESS_INFORMATION pi = {0}; /* contains child process informations */
265 SECURITY_ATTRIBUTES sa = {0}; /* contains the security descriptor for the pipe handles */
266 HANDLE child_stdin_handle[2] = {NULL}; /* child_stdin_handle[1] <-> stdout of the child process */
267 HANDLE child_stdout_handle[2] = {NULL}; /* child_stdout_handle[0] <-> stdin of the child process */
268 HANDLE child_stderr = NULL;
271 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
272 sa.lpSecurityDescriptor = NULL; /* use default security for the pipe handles */
274 sa.bInheritHandle = TRUE; /* the pipe handles can be inherited */
276 if(!CreatePipe(&(child_stdin_handle[0]),&(child_stdin_handle[1]),&sa,0))
278 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
280 unit_set_error(command->unit, (int)GetLastError(), 0);
283 command->status = cs_failed;
289 if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[1]),GetCurrentProcess(),&(child_stderr),0,TRUE,DUPLICATE_SAME_ACCESS))
291 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
293 unit_set_error(command->unit, (int)GetLastError(), 0);
295 CloseHandle(child_stdin_handle[0]);
296 CloseHandle(child_stdin_handle[1]);
299 command->status = cs_failed;
304 if(!CreatePipe(&(child_stdout_handle[0]),&(child_stdout_handle[1]),&sa,0))
306 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
307 unit_set_error(command->unit, (int)GetLastError(), 0);
309 CloseHandle(child_stdout_handle[0]);
310 CloseHandle(child_stdout_handle[1]);
311 CloseHandle(child_stdin_handle[0]);
312 CloseHandle(child_stdin_handle[1]);
315 command->status = cs_failed;
320 /* Read handle for read operations on the child std output. */
321 if(!DuplicateHandle(GetCurrentProcess(),(child_stdin_handle[0]),GetCurrentProcess(),&(command->stdout_fd),0,FALSE, DUPLICATE_SAME_ACCESS))
323 CloseHandle(child_stdout_handle[0]);
324 CloseHandle(child_stdout_handle[1]);
325 CloseHandle(child_stdin_handle[0]);
326 CloseHandle(child_stdin_handle[1]);
329 command->status = cs_failed;
331 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
332 unit_set_error(command->unit, (int)GetLastError(), 0);
338 /* Write handle for write operations on the child std input. */
339 if(!DuplicateHandle(GetCurrentProcess(),(child_stdout_handle[1]),GetCurrentProcess(),&(command->stdin_fd), 0,FALSE,DUPLICATE_SAME_ACCESS))
341 CloseHandle(child_stdout_handle[0]);
342 CloseHandle(child_stdout_handle[1]);
343 CloseHandle(child_stdin_handle[0]);
344 CloseHandle(child_stdin_handle[1]);
347 command->status = cs_failed;
349 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
351 unit_set_error(command->unit, (int)GetLastError(), 0);
356 CloseHandle(child_stdin_handle[0]);
357 CloseHandle(child_stdout_handle[1]);
362 /* launch the timer */
363 timer_time(command->timer);
368 /* launch the reader */
369 reader_read(command->reader);
375 /* launch the writer */
376 writer_write(command->writer);
379 /* if there is a reader wait for its starting */
381 xbt_os_sem_acquire(command->reader->started);
383 /* if there is a reader wait for its ending */
385 xbt_os_sem_acquire(command->writer->written);
387 /* if there is a reader wait for its starting */
389 xbt_os_sem_acquire(command->timer->started);
391 si.cb = sizeof(STARTUPINFO);
393 si.dwFlags |= STARTF_USESTDHANDLES;
394 si.hStdOutput = child_stdin_handle[1];
395 si.hStdInput = child_stdout_handle[0];
396 si.hStdError = child_stderr;
398 /* launch the process */
401 tow32cmd(command_line),
413 if(ERROR_FILE_NOT_FOUND == GetLastError())
415 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(ECMDNOTFOUND, 1));
416 unit_set_error(command->unit, ECMDNOTFOUND, 1);
417 command_handle_failure(command, csr_command_not_found);
421 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string((int)GetLastError(), 0));
423 unit_set_error(command->unit, (int)GetLastError(), 0);
424 command_handle_failure(command, csr_create_process_function_failure);
430 /* the command is running */
431 command->status = cs_in_progress;
433 /* save the pid of the command */
434 command->pid = pi.hProcess;
436 /* close non used thread handle */
437 CloseHandle(pi.hThread);
442 /* close non used handles */
443 CloseHandle(child_stdin_handle[1]);
444 CloseHandle(child_stdout_handle[0]);
445 CloseHandle(child_stderr);
451 command_exec(command_t command, const char* command_line)
453 int child_stdin_fd[2] ;
454 int child_stdout_fd[2];
457 int rv = is_cmd(command->unit->runner->path, command->unit->runner->builtin, command_line);
464 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(rv, 0));
465 unit_set_error(command->unit, rv, 0);
469 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(rv, 1));
470 unit_set_error(command->unit, rv, 1);
473 command_handle_failure(command, csr_command_not_found);
483 if(pipe(child_stdin_fd))
485 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
487 unit_set_error(command->unit, errno, 0);
489 command_handle_failure(command, csr_pipe_function_failed);
499 if(pipe(child_stdout_fd))
501 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
505 close(child_stdin_fd[0]);
506 close(child_stdin_fd[1]);
509 unit_set_error(command->unit, errno, 0);
511 command_handle_failure(command, csr_pipe_function_failed);
519 if(fcntl(child_stdin_fd[1], F_SETFL, fcntl(child_stdin_fd[1], F_GETFL) | O_NONBLOCK) < 0)
522 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
524 close(child_stdin_fd[0]);
525 close(child_stdin_fd[1]);
529 close(child_stdout_fd[0]);
530 close(child_stdout_fd[1]);
533 unit_set_error(command->unit, errno, 0);
535 command_handle_failure(command, csr_fcntl_function_failed);
541 /* to write to the child stdin */
542 command->stdin_fd = child_stdin_fd[1];
544 /* to read from the child stdout */
545 command->stdout_fd = child_stdout_fd[0];
547 /* launch the reader if any*/
549 reader_read(command->reader);
551 /* launch the writer if any */
553 writer_write(command->writer);
555 /* launch the timer if any */
557 timer_time(command->timer);
559 /* if there is a reader wait for its starting */
561 xbt_os_sem_acquire(command->reader->started);
563 /* if there is a reader wait for its ending */
565 xbt_os_sem_acquire(command->writer->written);
567 /* if there is a reader wait for its starting */
569 xbt_os_sem_acquire(command->timer->started);
571 /* update the state of the command, assume it is in progress */
572 command->status = cs_in_progress;
574 command->pid= fork();
580 close(child_stdin_fd[0]);
581 close(child_stdin_fd[1]);
586 close(child_stdout_fd[0]);
587 close(child_stdout_fd[1]);
590 ERROR2("[%s] Cannot fork the command `%s'", command->context->pos, command->context->command_line);
591 unit_set_error(command->unit, errno, 0);
592 command_handle_failure(command,csr_fork_function_failure);
599 /* close unused file descriptors */
601 close(child_stdin_fd[0]);
604 close(child_stdout_fd[1]);
609 /* close unused file descriptors */
611 close(child_stdin_fd[1]);
614 close(child_stdout_fd[0]);
618 /* redirect stdin to child_stdin_fd[0] (now fgets(), getchar() ... read from the pipe */
619 if(dup2(child_stdin_fd[0],STDIN_FILENO) < 0)
621 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
622 command->unit->exit_code = errno;
624 unit_set_error(command->unit, errno, 0);
625 command_handle_failure(command,csr_dup2_function_failure);
628 /* close the unused file descriptor */
629 close(child_stdin_fd[0]);
635 /* redirect stdout and stderr to child_stdout_fd[1] (now printf(), perror()... write to the pipe */
636 if(dup2(child_stdout_fd[1],STDOUT_FILENO) < 0)
638 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
640 unit_set_error(command->unit, errno, 0);
641 command_handle_failure(command, csr_dup2_function_failure);
644 if(dup2(child_stdout_fd[1], STDERR_FILENO) < 0)
646 ERROR3("[%s] `%s' : NOK (%s)", command->context->pos, command->context->command_line, error_to_string(errno, 0));
647 unit_set_error(command->unit, errno, 0);
648 command_handle_failure(command, csr_dup2_function_failure);
651 /* close the unused file descriptor */
652 close(child_stdout_fd[1]);
655 /* launch the command */
656 if(execlp("/bin/sh", "sh", "-c", command->context->command_line, NULL) < 0)
657 command->execlp_errno = errno;
665 command_wait(command_t command)
667 /* wait for the command terminaison */
670 if(WAIT_FAILED == WaitForSingleObject(command->pid, INFINITE))
672 ERROR2("[%s] Cannot wait for the child`%s'", command->context->pos, command->context->command_line);
674 unit_set_error(command->unit, (int)GetLastError(), 0);
676 command_handle_failure(command, csr_wait_failure );
677 /* TODO : see for the interruption */
681 /* don't take care of the timer or the writer or the reader failue */
682 if(cs_failed != command->status && cs_interrupted != command->status)
684 if(!GetExitCodeProcess(command->pid,&rv))
686 ERROR2("[%s] Cannot get the exit code of the process `%s'",command->context->pos, command->context->command_line);
688 unit_set_error(command->unit, (int)GetLastError(), 0);
690 command_handle_failure(command, csr_get_exit_code_process_function_failure );
693 command->stat_val = command->exit_code = rv;
699 command_wait(command_t command)
701 if(!command->execlp_errno)
703 /* let this thread wait for the child so that the main thread can detect the timeout without blocking on the wait */
704 int pid = waitpid(command->pid, &(command->stat_val), 0);
706 if(pid != command->pid)
708 ERROR2("[%s] Cannot wait for the child`%s'", command->context->pos, command->context->command_line);
710 unit_set_error(command->unit, errno, 0);
712 command_handle_failure(command, csr_waitpid_function_failure);
716 if(WIFEXITED(command->stat_val))
717 command->exit_code = WEXITSTATUS(command->stat_val);
722 ERROR2("[%s] Cannot execute the command `%s'", command->context->pos, command->context->command_line);
724 unit_set_error(command->unit, command->execlp_errno, 0);
726 command_handle_failure(command, csr_execlp_function_failure);
732 command_check(command_t command)
737 /* we have a signal, store it */
738 if(WIFSIGNALED(command->stat_val))
740 command->signal = strdup(signal_name(WTERMSIG(command->stat_val),command->context->signal));
743 /* we have a signal and no signal is expected */
744 if(WIFSIGNALED(command->stat_val) && !command->context->signal)
747 ERROR3("[%s] `%s' : NOK (unexpected signal `%s' caught)", command->context->pos, command->context->command_line, command->signal);
749 unit_set_error(command->unit, EUNXPSIG, 1);
751 reason = csr_unexpected_signal_caught;
754 /* we have a signal that differ form the expected signal */
755 if(WIFSIGNALED(command->stat_val) && command->context->signal && strcmp(signal_name(WTERMSIG(command->stat_val),command->context->signal),command->context->signal))
758 ERROR4("[%s] `%s' : NOK (got signal `%s' instead of `%s')", command->context->pos, command->context->command_line, command->signal, command->context->signal);
763 unit_set_error(command->unit, ESIGNOTMATCH, 1);
766 reason = csr_signals_dont_match;
769 /* we don't receipt the expected signal */
770 if(!WIFSIGNALED(command->stat_val) && command->context->signal)
773 ERROR3("[%s] `%s' : NOK (expected `%s' not receipt)", command->context->pos, command->context->command_line, command->context->signal);
778 unit_set_error(command->unit, ESIGNOTRECEIPT, 1);
781 reason = csr_expected_signal_not_receipt;
784 /* if the command exit normaly and we expect a exit code : test it */
785 if(WIFEXITED(command->stat_val) /* && INDEFINITE != command->context->exit_code*/)
787 /* the exit codes don't match */
788 if(WEXITSTATUS(command->stat_val) != command->context->exit_code)
790 ERROR4("[%s] %s : NOK (returned code `%d' instead `%d')", command->context->pos, command->context->command_line, WEXITSTATUS(command->stat_val), command->context->exit_code);
795 unit_set_error(command->unit, EEXITCODENOTMATCH, 1);
798 reason = csr_exit_codes_dont_match;
802 /* make sure the reader done */
803 while(!command->reader->done)
804 xbt_os_thread_yield();
807 CloseHandle(command->stdout_fd);
809 close(command->stdout_fd);
812 command->stdout_fd = INDEFINITE_FD;
814 xbt_strbuff_chomp(command->output);
815 xbt_strbuff_chomp(command->context->output);
816 xbt_strbuff_trim(command->output);
817 xbt_strbuff_trim(command->context->output);
821 xbt_dynar_t a = xbt_str_split(command->output->data, "\n");
822 char *out = xbt_str_join(a,"\n||");
824 INFO2("Output of <%s> so far: \n||%s", command->context->pos,out);
827 /* if ouput handling flag is specified check the output */
828 else if(oh_check == command->context->output_handling && command->reader)
830 if(command->output->used != command->context->output->used || strcmp(command->output->data, command->context->output->data))
834 ERROR2("[%s] `%s' : NOK (outputs mismatch):", command->context->pos, command->context->command_line);
838 unit_set_error(command->unit, EOUTPUTNOTMATCH, 1);
842 reason = csr_outputs_dont_match;
844 /* display the diff */
845 diff = xbt_str_diff(command->context->output->data,command->output->data);
850 else if (oh_ignore == command->context->output_handling)
852 INFO1("(ignoring the output of <%s> as requested)",command->context->line);
854 else if (oh_display == command->context->output_handling)
856 xbt_dynar_t a = xbt_str_split(command->output->data, "\n");
857 char *out = xbt_str_join(a,"\n||");
859 INFO3("[%s] Here is the (ignored) command `%s' output: \n||%s",command->context->pos, command->context->command_line, out);
865 xbt_os_mutex_acquire(command->mutex);
867 if(command->status != cs_interrupted)
869 /* signal the success of the command */
870 command->status = cs_successeded;
871 command->successeded = 1;
873 /* increment the number of successeded command of the unit */
874 (command->root->successeded_cmd_nb)++;
877 xbt_os_mutex_release(command->mutex);
881 command_handle_failure(command, reason);
887 command_kill(command_t command)
889 if(INDEFINITE_PID != command->pid)
891 INFO2("[%s] Kill the process `%s'", command->context->pos, command->context->command_line);
892 TerminateProcess(command->pid, INDEFINITE);
897 command_kill(command_t command)
899 if(INDEFINITE_PID != command->pid)
901 kill(command->pid,SIGTERM);
903 if(!command->context->signal)
904 command->context->signal = strdup("SIGTERM");
906 command->exit_code = INDEFINITE;
911 INFO2("[%s] Kill the process `%s'", command->context->pos, command->context->command_line);
912 kill(command->pid,SIGKILL);
920 command_interrupt(command_t command)
922 xbt_os_mutex_acquire(command->mutex);
924 if((command->status != cs_interrupted) && (command->status != cs_failed) && (command->status != cs_successeded))
926 command->status = cs_interrupted;
927 command->reason = csr_interruption_request;
928 command->interrupted = 1;
929 command->unit->interrupted = 1;
931 xbt_os_mutex_acquire(command->root->mutex);
932 (command->root->interrupted_cmd_nb)++;
933 xbt_os_mutex_release(command->root->mutex);
935 if(command->pid != INDEFINITE_PID)
936 command_kill(command);
939 xbt_os_mutex_release(command->mutex);
945 command_summarize(command_t command)
947 if(cs_successeded != command->status)
952 printf(" <killed command>\n");
955 /* display the reason of the status of the command */
956 switch(command->reason)
958 /* the function pipe or CreatePipe() fails */
959 case csr_pipe_function_failed :
960 printf(" reason : pipe() or CreatePipe() function failed (system error)\n");
963 case csr_shell_failed :
964 printf(" reason : shell failed (may be command not found)\n");
967 case csr_get_exit_code_process_function_failure :
968 printf(" reason : ExitCodeProcess() function failed (system error)\n");
971 /* reader failure reasons*/
972 case csr_read_pipe_broken :
973 printf(" reason : command read pipe broken\n");
976 case csr_read_failure :
977 printf(" reason : command stdout read failed\n");
980 /* writer failure reasons */
981 case csr_write_failure :
982 printf(" reason : command stdin write failed\n");
985 case csr_write_pipe_broken :
986 printf(" reason : command write pipe broken\n");
991 printf(" reason : command timeouted\n");
994 /* command failure reason */
995 case csr_command_not_found :
996 printf(" reason : command not found\n");
999 /* context failure reasons */
1000 case csr_exit_codes_dont_match :
1001 printf(" reason : exit codes don't match\n");
1005 /* dup2 function failure reasons */
1006 case csr_dup2_function_failure :
1007 printf(" reason : dup2() function failed\n");
1011 /* execlp function failure reasons */
1012 case csr_execlp_function_failure :
1013 printf(" reason : execlp() function failed\n");
1017 /* waitpid function failure reasons */
1018 case csr_waitpid_function_failure :
1019 printf(" reason : waitpid() function failed\n");
1023 /* CreateProcess function failure reasons */
1024 case csr_create_process_function_failure :
1025 printf(" reason : CreateProcesss() function failed\n");
1029 case csr_outputs_dont_match :
1032 printf(" reason : ouputs don't match\n");
1033 diff = xbt_str_diff(command->context->output->data,command->output->data);
1034 printf(" output diff :\n%s\n",diff);
1040 case csr_signals_dont_match :
1041 printf(" reason : signals don't match\n");
1044 case csr_unexpected_signal_caught:
1045 printf(" reason : unexpected signal caught\n");
1048 case csr_expected_signal_not_receipt :
1049 printf(" reason : expected signal not receipt\n");
1052 /* system failure reasons */
1053 case csr_fork_function_failure :
1054 printf(" reason : fork function failed\n");
1057 case csr_wait_failure :
1058 printf(" reason : wait command failure\n");
1061 /* global/local interruption */
1062 case csr_interruption_request :
1063 printf(" reason : the command receive a interruption request\n");
1068 printf(" reason : unknown \n");
1072 if(csr_command_not_found != command->reason && csr_fork_function_failure != command->reason && csr_execlp_function_failure != command->reason)
1074 if(INDEFINITE != command->exit_code)
1075 /* the command exit code */
1076 printf(" exit code : %d\n",command->exit_code);
1078 /* if an expected exit code was specified display it */
1079 if(INDEFINITE != command->context->exit_code)
1080 printf(" expected exit code : %d\n",command->context->exit_code);
1082 printf(" no expected exit code specified\n");
1084 /* no expected signal expected */
1085 if(NULL == command->context->signal)
1087 printf(" no expected signal specified\n");
1090 printf(" but got signal : %s\n",command->signal);
1093 /* if an expected exit code was specified display it */
1096 if(NULL != command->signal)
1097 printf(" signal : %s\n",command->signal);
1099 printf(" no signal caugth\n");
1102 /* if the command has out put and the metacommand display output is specified display it */
1103 if(command->output && (0 != command->output->used) && (oh_display == command->context->output_handling))
1105 xbt_dynar_t a = xbt_str_split(command->output->data, "\n");
1106 char *out = xbt_str_join(a,"\n||");
1108 printf(" output :\n||%s",out);
1117 command_handle_failure(command_t command, cs_reason_t reason)
1119 unit_t root = command->root;
1121 xbt_os_mutex_acquire(command->mutex);
1123 if((command->status != cs_interrupted) && (command->status != cs_failed))
1125 command->status = cs_failed;
1126 command->reason = reason;
1127 command->failed = 1;
1129 command->unit->failed = 1;
1131 xbt_os_mutex_acquire(root->mutex);
1133 /* increment the number of failed command of the unit */
1134 root->failed_cmd_nb++;
1136 /* if the --ignore-failures option is not specified */
1137 if(!keep_going_unit_flag)
1139 if(!root->interrupted)
1141 /* the unit interrupted (exit for the loop) */
1142 root->interrupted = 1;
1144 /* release the unit */
1145 xbt_os_sem_release(root->sem);
1148 /* if the --keep-going option is not specified */
1149 if(!keep_going_flag)
1153 /* request an global interruption by the runner */
1156 /* release the runner */
1157 xbt_os_sem_release(units_sem);
1162 xbt_os_mutex_release(root->mutex);
1165 xbt_os_mutex_release(command->mutex);
1169 command_free(command_t* ptr)
1171 /* close the stdin and the stdout pipe handles */
1174 if((*ptr)->stdin_fd != INDEFINITE_FD)
1175 CloseHandle((*ptr)->stdin_fd);
1177 if((*ptr)->stdout_fd != INDEFINITE_FD)
1178 CloseHandle((*ptr)->stdout_fd);
1182 if((*ptr)->stdin_fd != INDEFINITE_FD)
1183 close((*ptr)->stdin_fd);
1185 if((*ptr)->stdout_fd != INDEFINITE_FD)
1186 close((*ptr)->stdout_fd);
1191 if(timer_free(&((*ptr)->timer)) < 0)
1197 if(writer_free(&((*ptr)->writer)) < 0)
1203 if(reader_free(&((*ptr)->reader)) < 0)
1208 xbt_strbuff_free((*ptr)->output);
1212 if(context_free(&((*ptr)->context)) < 0)
1217 free((*ptr)->signal);