1 |
/* java_lang_VMProcess.c -- native code for java.lang.VMProcess |
/* java_lang_VMProcess.c -- native code for java.lang.VMProcess |
2 |
Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. |
Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
135 |
JNIEXPORT void JNICALL |
JNIEXPORT void JNICALL |
136 |
Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, |
Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, |
137 |
jobjectArray cmdArray, |
jobjectArray cmdArray, |
138 |
jobjectArray envArray, jobject dirFile) |
jobjectArray envArray, jobject dirFile, |
139 |
|
jboolean redirect) |
140 |
{ |
{ |
141 |
int fds[3][2] = { {-1, -1}, {-1, -1}, {-1, -1} }; |
int fds[3][2] = { {-1, -1}, {-1, -1}, {-1, -1} }; |
142 |
jobject streams[3] = { NULL, NULL, NULL }; |
jobject streams[3] = { NULL, NULL, NULL }; |
152 |
jmethodID method; |
jmethodID method; |
153 |
jclass clazz; |
jclass clazz; |
154 |
int i; |
int i; |
155 |
|
int pipe_count = redirect ? 2 : 3; |
156 |
|
|
157 |
/* Check for null */ |
/* Check for null */ |
158 |
if (cmdArray == NULL) |
if (cmdArray == NULL) |
220 |
} |
} |
221 |
|
|
222 |
/* Create inter-process pipes */ |
/* Create inter-process pipes */ |
223 |
for (i = 0; i < 3; i++) |
for (i = 0; i < pipe_count; i++) |
224 |
{ |
{ |
225 |
if (pipe (fds[i]) == -1) |
if (pipe (fds[i]) == -1) |
226 |
{ |
{ |
234 |
/* Set close-on-exec flag for parent's ends of pipes */ |
/* Set close-on-exec flag for parent's ends of pipes */ |
235 |
(void) fcntl (fds[0][1], F_SETFD, 1); |
(void) fcntl (fds[0][1], F_SETFD, 1); |
236 |
(void) fcntl (fds[1][0], F_SETFD, 1); |
(void) fcntl (fds[1][0], F_SETFD, 1); |
237 |
(void) fcntl (fds[2][0], F_SETFD, 1); |
if (pipe_count == 3) |
238 |
|
(void) fcntl (fds[2][0], F_SETFD, 1); |
239 |
|
|
240 |
/* Fork into parent and child processes */ |
/* Fork into parent and child processes */ |
241 |
if ((pid = fork ()) == (pid_t) - 1) |
if ((pid = fork ()) == (pid_t) - 1) |
270 |
} |
} |
271 |
close (fds[1][1]); |
close (fds[1][1]); |
272 |
} |
} |
273 |
if (fds[2][1] != 2) |
if (pipe_count == 3) |
274 |
|
{ |
275 |
|
/* Duplicate stdout to stderr. */ |
276 |
|
if (dup2 (1, 2) == -1) |
277 |
|
{ |
278 |
|
fprintf (stderr, "dup2: %s", strerror (errno)); |
279 |
|
exit (127); |
280 |
|
} |
281 |
|
} |
282 |
|
else if (fds[2][1] != 2) |
283 |
{ |
{ |
284 |
if (dup2 (fds[2][1], 2) == -1) |
if (dup2 (fds[2][1], 2) == -1) |
285 |
{ |
{ |
320 |
method = (*env)->GetMethodID (env, clazz, "<init>", "(II)V"); |
method = (*env)->GetMethodID (env, clazz, "<init>", "(II)V"); |
321 |
if ((*env)->ExceptionOccurred (env)) |
if ((*env)->ExceptionOccurred (env)) |
322 |
goto done; |
goto done; |
323 |
for (i = 0; i < 3; i++) |
for (i = 0; i < pipe_count; i++) |
324 |
{ |
{ |
|
/* Mode is WRITE (2) for in and READ (1) for out and err. */ |
|
325 |
const int fd = fds[i][i == 0]; |
const int fd = fds[i][i == 0]; |
326 |
const int mode = (i == 0) ? 2 : 1; |
const int mode = ((i == 0) |
327 |
|
? gnu_java_nio_channels_FileChannelImpl_WRITE |
328 |
|
: gnu_java_nio_channels_FileChannelImpl_READ); |
329 |
jclass sclazz; |
jclass sclazz; |
330 |
jmethodID smethod; |
jmethodID smethod; |
331 |
|
|
333 |
if ((*env)->ExceptionOccurred (env)) |
if ((*env)->ExceptionOccurred (env)) |
334 |
goto done; |
goto done; |
335 |
|
|
336 |
if (mode == 2) |
if (mode == gnu_java_nio_channels_FileChannelImpl_WRITE) |
337 |
sclazz = (*env)->FindClass (env, "java/io/FileOutputStream"); |
sclazz = (*env)->FindClass (env, "java/io/FileOutputStream"); |
338 |
else |
else |
339 |
sclazz = (*env)->FindClass (env, "java/io/FileInputStream"); |
sclazz = (*env)->FindClass (env, "java/io/FileInputStream"); |
373 |
*/ |
*/ |
374 |
|
|
375 |
/* Close child's ends of pipes */ |
/* Close child's ends of pipes */ |
376 |
for (i = 0; i < 3; i++) |
for (i = 0; i < pipe_count; i++) |
377 |
{ |
{ |
378 |
const int fd = fds[i][i != 0]; |
const int fd = fds[i][i != 0]; |
379 |
|
|
387 |
* was created for a file descriptor, we don't close it because it |
* was created for a file descriptor, we don't close it because it |
388 |
* will get closed when the Stream object is finalized. |
* will get closed when the Stream object is finalized. |
389 |
*/ |
*/ |
390 |
for (i = 0; i < 3; i++) |
for (i = 0; i < pipe_count; i++) |
391 |
{ |
{ |
392 |
const int fd = fds[i][i == 0]; |
const int fd = fds[i][i == 0]; |
393 |
|
|