update NOTICE
[nit.git] / c_src / 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 fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
30 exit(1);
31 }
32 }
33 if (pipeflag & 2) {
34 int res = pipe(out_fd);
35 if ( res == -1 ) {
36 fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
37 exit(1);
38 }
39 }
40 if (pipeflag & 4) {
41 int res = pipe(err_fd);
42 if ( res == -1 ) {
43 fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
44 exit(1);
45 }
46 }
47
48 id = fork();
49 if (id == 0)
50 { /* child */
51 char **arg = malloc(sizeof(char*) * (len+1));
52 char *c = args;
53 int i;
54
55 /* Prepare args */
56 for(i=0; i<len; i++)
57 {
58 arg[i] = c;
59 c += strlen(c) + 1;
60 }
61 arg[len] = NULL;
62
63 /* Connect pipe */
64 if (pipeflag & 1)
65 {
66 close(0);
67 dup2(in_fd[0], 0);
68 close(in_fd[0]);
69 close(in_fd[1]);
70 }
71 if (pipeflag & 2)
72 {
73 close(1);
74 dup2(out_fd[1], 1);
75 close(out_fd[0]);
76 close(out_fd[1]);
77 }
78 if (pipeflag & 4)
79 {
80 close(2);
81 dup2(err_fd[1], 2);
82 close(err_fd[0]);
83 close(err_fd[1]);
84 }
85
86 /* calls */
87 execvp(prog, arg);
88 abort();
89 }
90 else if (id > 0)
91 { /* father */
92 result = (se_exec_data_t*)malloc(sizeof(se_exec_data_t));
93 result->id = id;
94 result->running = 1;
95 if (pipeflag & 1)
96 {
97 result->in_fd = in_fd[1];
98 close(in_fd[0]);
99 } else
100 result->in_fd = -1;
101
102 if (pipeflag & 2)
103 {
104 result->out_fd = out_fd[0];
105 close(out_fd[1]);
106 } else
107 result->out_fd = -1;
108
109 if (pipeflag & 4)
110 {
111 result->err_fd = err_fd[0];
112 close(err_fd[1]);
113 } else
114 result->err_fd = -1;
115 }
116
117 return result;
118 }
119
120 int exec_NativeProcess_NativeProcess_is_finished_0(void*d) {
121 se_exec_data_t*data = (se_exec_data_t*)d;
122 int result = (int)0;
123 int status;
124 if (data->running) {
125 int id = waitpid(data->id, &status, WNOHANG);
126 if (id != 0) {
127 /* child is finished */
128 result = (int)(id == data->id);
129 data->status = WEXITSTATUS(status);
130 data->running = 0;
131 }
132 }
133 else{
134 result = (int)1;
135 }
136 return result;
137 }
138
139 void exec_NativeProcess_NativeProcess_wait_0(void*d) {
140 se_exec_data_t*data = (se_exec_data_t*)d;
141 int status;
142 if (data->running) {
143 waitpid(data->id, &status, 0);
144 data->status = WEXITSTATUS(status);
145 data->running = 0;
146 }
147 }