lib: fix return value of the system method
[nit.git] / lib / standard / exec_nit.c
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
2 *
3 * Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 *
5 * This file is free software, which comes along with NIT. This software is
6 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 * is kept unaltered, and a notification of the changes is added.
10 * You are allowed to redistribute it and sell it, alone or is a part of
11 * another product.
12 */
13
14 #include "exec_nit.h"
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <stdio.h>
19
20 se_exec_data_t* exec_Process_Process_basic_exec_execute_4(void *s, char *prog, char *args, int len, int pipeflag) {
21 se_exec_data_t* result = NULL;
22 int id;
23 int in_fd[2];
24 int out_fd[2];
25 int err_fd[2];
26 if (pipeflag & 1) {
27 int res = pipe(in_fd);
28 if ( res == -1 ) {
29 return NULL;
30 }
31 }
32 if (pipeflag & 2) {
33 int res = pipe(out_fd);
34 if ( res == -1 ) {
35 return NULL;
36 }
37 }
38 if (pipeflag & 4) {
39 int res = pipe(err_fd);
40 if ( res == -1 ) {
41 return NULL;
42 }
43 }
44
45 id = fork();
46 if (id == 0)
47 { /* child */
48 char **arg = malloc(sizeof(char*) * (len+1));
49 char *c = args;
50 int i;
51
52 /* Prepare args */
53 for(i=0; i<len; i++)
54 {
55 arg[i] = c;
56 c += strlen(c) + 1;
57 }
58 arg[len] = NULL;
59
60 /* Connect pipe */
61 if (pipeflag & 1)
62 {
63 close(0);
64 dup2(in_fd[0], 0);
65 close(in_fd[0]);
66 close(in_fd[1]);
67 }
68 if (pipeflag & 2)
69 {
70 close(1);
71 dup2(out_fd[1], 1);
72 close(out_fd[0]);
73 close(out_fd[1]);
74 }
75 if (pipeflag & 4)
76 {
77 close(2);
78 dup2(err_fd[1], 2);
79 close(err_fd[0]);
80 close(err_fd[1]);
81 }
82
83 /* calls */
84 execvp(prog, arg);
85 _exit(127);
86 }
87 else if (id > 0)
88 { /* father */
89 result = (se_exec_data_t*)malloc(sizeof(se_exec_data_t));
90 result->id = id;
91 result->running = 1;
92 if (pipeflag & 1)
93 {
94 result->in_fd = in_fd[1];
95 close(in_fd[0]);
96 } else
97 result->in_fd = -1;
98
99 if (pipeflag & 2)
100 {
101 result->out_fd = out_fd[0];
102 close(out_fd[1]);
103 } else
104 result->out_fd = -1;
105
106 if (pipeflag & 4)
107 {
108 result->err_fd = err_fd[0];
109 close(err_fd[1]);
110 } else
111 result->err_fd = -1;
112 }
113
114 return result;
115 }
116
117 int exec_NativeProcess_NativeProcess_is_finished_0(void*d) {
118 se_exec_data_t*data = (se_exec_data_t*)d;
119 int result = (int)0;
120 int status;
121 if (data->running) {
122 int id = waitpid(data->id, &status, WNOHANG);
123 if (id != 0) {
124 /* child is finished */
125 result = (int)(id == data->id);
126 data->status = WEXITSTATUS(status);
127 data->running = 0;
128 }
129 }
130 else{
131 result = (int)1;
132 }
133 return result;
134 }
135
136 void exec_NativeProcess_NativeProcess_wait_0(void*d) {
137 se_exec_data_t*data = (se_exec_data_t*)d;
138 int status;
139 if (data->running) {
140 waitpid(data->id, &status, 0);
141 data->status = WEXITSTATUS(status);
142 data->running = 0;
143 }
144 }
145
146 int string_NativeString_NativeString_system_0(const char *cmd) {
147 int status = system(cmd);
148 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) {
149 // cmd exited on SIGINT: in my opinion the user wants the main to be discontinued
150 kill(getpid(), SIGINT);
151 }
152 return status;
153 }