First NIT release and new clean mercurial repository
[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
18 se_exec_data_t* exec_Process_Process_basic_exec_execute_4(int c, char *prog, char *args, int len, int pipeflag) {
19 se_exec_data_t* result = NULL;
20 int id;
21 int in_fd[2];
22 int out_fd[2];
23 int err_fd[2];
24 if (pipeflag & 1)
25 pipe(in_fd);
26 if (pipeflag & 2)
27 pipe(out_fd);
28 if (pipeflag & 4)
29 pipe(err_fd);
30
31 id = fork();
32 if (id == 0)
33 { /* child */
34 char **arg = malloc(sizeof(char*) * (len+1));
35 char *c = args;
36 int i;
37
38 /* Prepare args */
39 for(i=0; i<len; i++)
40 {
41 arg[i] = c;
42 c += strlen(c) + 1;
43 }
44 arg[len] = NULL;
45
46 /* Connect pipe */
47 if (pipeflag & 1)
48 {
49 close(0);
50 dup2(in_fd[0], 0);
51 close(in_fd[0]);
52 close(in_fd[1]);
53 }
54 if (pipeflag & 2)
55 {
56 close(1);
57 dup2(out_fd[1], 1);
58 close(out_fd[0]);
59 close(out_fd[1]);
60 }
61 if (pipeflag & 4)
62 {
63 close(2);
64 dup2(err_fd[1], 2);
65 close(err_fd[0]);
66 close(err_fd[1]);
67 }
68
69 /* calls */
70 execvp(prog, arg);
71 abort();
72 }
73 else if (id > 0)
74 { /* father */
75 result = (se_exec_data_t*)malloc(sizeof(se_exec_data_t));
76 result->id = id;
77 result->running = 1;
78 if (pipeflag & 1)
79 {
80 result->in_fd = in_fd[1];
81 close(in_fd[0]);
82 } else
83 result->in_fd = -1;
84
85 if (pipeflag & 2)
86 {
87 result->out_fd = out_fd[0];
88 close(out_fd[1]);
89 } else
90 result->out_fd = -1;
91
92 if (pipeflag & 4)
93 {
94 result->err_fd = err_fd[0];
95 close(err_fd[1]);
96 } else
97 result->err_fd = -1;
98 }
99 return result;
100 }
101
102 int exec_NativeProcess_NativeProcess_is_finished_0(void*d) {
103 se_exec_data_t*data = (se_exec_data_t*)d;
104 int result = (int)0;
105 int status;
106 if (data->running) {
107 int id = waitpid(data->id, &status, WNOHANG);
108 if (id != 0) {
109 /* child is finished */
110 result = (int)(id == data->id);
111 data->status = WEXITSTATUS(status);
112 data->running = 0;
113 }
114 }
115 else{
116 result = (int)1;
117 }
118 return result;
119 }
120
121 void exec_NativeProcess_NativeProcess_wait_0(void*d) {
122 se_exec_data_t*data = (se_exec_data_t*)d;
123 int status;
124 if (data->running) {
125 waitpid(data->id, &status, 0);
126 data->status = WEXITSTATUS(status);
127 data->running = 0;
128 }
129 }