1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

2004-11-16 Alain Magloire

Fix for 27663, allow to exec with pty emulation.
	* library/Makefile
	* library/openpty.c(set_noecho): new function
	* library/opentpty.h: update header.
	* library/pty.c: refactor forkpyt to openMaster()
	* library/PTY.h: regenerate
	* library/spawner.c: add exec2() support
	* library/Spawner.h: regenerate

	* os/linux/x86/libpty.so
	* os/linux/x86/libspawner.so
This commit is contained in:
Alain Magloire 2004-11-16 20:49:27 +00:00
parent 4dec40862e
commit 580b6dfb45
20 changed files with 611 additions and 102 deletions

View file

@ -1,3 +1,17 @@
2004-11-16 Alain Magloire
Fix for 27663, allow to exec with pty emulation.
* library/Makefile
* library/openpty.c(set_noecho): new function
* library/opentpty.h: update header.
* library/pty.c: refactor forkpyt to openMaster()
* library/PTY.h: regenerate
* library/spawner.c: add exec2() support
* library/Spawner.h: regenerate
* os/linux/x86/libpty.so
* os/linux/x86/libspawner.so
2004-07-12 Tom Tromey <tromey@redhat.com>
* library/Makefile (CFLAGS): Define _GNU_SOURCE.

View file

@ -19,7 +19,7 @@ INSTALL_DIR = ../os/$(OS)/$(ARCH)
LIB_NAME_SPAWNER = libspawner.so
LIB_NAME_FULL_SPAWNER = $(INSTALL_DIR)/libspawner.so
OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o
OBJS_SPAWNER=spawner.o io.o exec_unix.o exec_pty.o pfind.o openpty.o
LIB_NAME_PTY = libpty.so
LIB_NAME_FULL_PTY = $(INSTALL_DIR)/libpty.so

View file

@ -7,12 +7,13 @@
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: hasPTY */
/*
* Class: org_eclipse_cdt_utils_pty_PTY
* Method: forkpty
* Signature: ()I
* Method: openMaster
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster
(JNIEnv *, jobject);
#ifdef __cplusplus

View file

@ -1,9 +1,9 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_qnx_tools_utils_spawner_Spawner */
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
#ifndef _Included_com_qnx_tools_utils_spawner_Spawner
#define _Included_com_qnx_tools_utils_spawner_Spawner
#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner
#define _Included_org_eclipse_cdt_utils_spawner_Spawner
#ifdef __cplusplus
extern "C" {
#endif
@ -17,12 +17,20 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec0
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
* Method: exec1
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring);
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec2
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint);
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: raise

View file

@ -0,0 +1,152 @@
#include "exec0.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>
#include <stdlib.h>
#include <termios.h>
/* from pfind.c */
extern char *pfind(const char *name);
pid_t
exec_pty(const char *path, char *const argv[], char *const envp[],
const char *dirpath, int channels[3], const char *pts_name, int fdm)
{
int pipe2[2];
pid_t childpid;
char *full_path;
/*
* We use pfind() to check that the program exists and is an executable.
* If not pass the error up. Also execve() wants a full path.
*/
full_path = pfind(path);
if (full_path == NULL) {
fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : "");
return -1;
}
/*
* Make sure we can create our pipes before forking.
*/
if (channels != NULL) {
if (pipe(pipe2) < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
free(full_path);
return -1;
}
}
childpid = fork();
if (childpid < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
free(full_path);
return -1;
} else if (childpid == 0) { /* child */
chdir(dirpath);
if (channels != NULL) {
int fds;
fds = ptys_open(fdm, pts_name);
if (fds < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
return -1;
}
/* Close the read end of pipe2 */
if (close(pipe2[0]) == -1)
perror("close(pipe2[0]))");
/* close the master, no need in the child */
close(fdm);
set_noecho(fds);
/* redirections */
dup2(fds, STDIN_FILENO); /* dup stdin */
dup2(fds, STDOUT_FILENO); /* dup stdout */
dup2(pipe2[1], STDERR_FILENO); /* dup stderr */
close(fds); /* done with fds. */
}
/* Close all the fd's in the child */
{
int fdlimit = sysconf(_SC_OPEN_MAX);
int fd = 3;
while (fd < fdlimit)
close(fd++);
}
if (envp[0] == NULL) {
execv(full_path, argv);
} else {
execve(full_path, argv, envp);
}
_exit(127);
} else if (childpid != 0) { /* parent */
set_noecho(fdm);
if (channels != NULL) {
/* close the write end of pipe1 */
if (close(pipe2[1]) == -1)
perror("close(pipe2[1])");
channels[0] = fdm; /* Input Stream. */
channels[1] = fdm; /* Output Stream. */
channels[2] = pipe2[0]; /* stderr Stream. */
//channels[2] = fdm; /* Input Stream. */
}
free(full_path);
return childpid;
}
free(full_path);
return -1; /*NOT REACHED */
}
#ifdef __STAND_ALONE__
int main(int argc, char **argv, char **envp) {
const char *path = "./bufferring_test";
int channels[3] = { -1, -1, -1};
int status;
FILE *app_stdin;
FILE *app_stdout;
FILE *app_stderr;
char pts_name[32];
int fdm;
char buffer[32];
fdm = ptym_open(pts_name);
status = exec_pty(path, argv, envp, ".", channels, pts_name, fdm);
if (status >= 0) {
app_stdin = fdopen(channels[0], "w");
app_stdout = fdopen(channels[1], "r");
app_stderr = fdopen(channels[2], "r");
if (app_stdout == NULL || app_stderr == NULL || app_stdin == NULL) {
fprintf(stderr, "PROBLEMS\n");
} else {
fputs("foo\n", app_stdin);
fputs("bar\n", app_stdin);
while(fgets(buffer, sizeof buffer, app_stdout) != NULL) {
fprintf(stdout, "STDOUT: %s\n", buffer);
}
while(fgets(buffer, sizeof buffer, app_stderr) != NULL) {
fprintf(stdout, "STDERR: %s\n", buffer);
}
}
}
fputs("bye\n", stdout);
close(channels[0]);
close(channels[1]);
close(channels[2]);
return 0;
}
#endif

View file

@ -24,6 +24,7 @@
int ptym_open (char *pts_name);
int ptys_open (int fdm, char * pts_name);
void set_noecho(int fd);
int
openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp)
@ -38,6 +39,7 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct win
close(*amaster);
return -1;
}
if (name)
strcpy(name, line);
#ifndef TCSAFLUSH
@ -52,6 +54,24 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct win
return 0;
}
void
set_noecho(int fd)
{
struct termios stermios;
if (tcgetattr(fd, &stermios) < 0) {
return ;
}
/* turn off echo */
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
/* Turn off the NL to CR/NL mapping ou output. */
/*stermios.c_oflag &= ~(ONLCR);*/
stermios.c_iflag |= (IGNCR);
tcsetattr(fd, TCSANOW, &stermios);
}
int
ptym_open(char * pts_name)
{
@ -89,6 +109,7 @@ ptys_open(int fdm, char * pts_name)
close(fdm);
return -5;
}
/*
if (ioctl(fds, I_PUSH, "ptem") < 0) {
printf("pterm:%s\n", strerror(errno));
close(fdm);
@ -101,5 +122,6 @@ ptys_open(int fdm, char * pts_name)
close(fds);
return -7;
}
*/
return fds;
}

View file

@ -7,4 +7,5 @@
#define _OPENPTY_H
int ptym_open (char *pts_name);
int ptys_open (int fdm, char * pts_name);
void set_noecho(int fd);
#endif

View file

@ -7,7 +7,7 @@
* Signature: ()I
*/
JNIEXPORT jstring JNICALL
Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj) {
jfieldID fid; /* Store the field ID */
jstring jstr = NULL;
int master = -1;
@ -18,6 +18,9 @@ Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
master = ptym_open(line);
if (master >= 0) {
// turn off echo
set_noecho(master);
/* Get a reference to the obj's class */
cls = (*env)->GetObjectClass(env, jobj);

View file

@ -71,6 +71,63 @@ static void free_c_array(char **c_array)
}
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec2
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILorg/eclipse/cdt/utils/pty/PTY;)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels,
jstring jslaveName, jint masterFD)
{
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
const char *pts_name = (*env)->GetStringUTFChars(env, jslaveName, NULL);
char **cmd;
char **envp;
int fd[3];
pid_t pid = -1;
if (channels == NULL)
goto bail_out;
cmd = alloc_c_array(env, jcmd);
if (cmd == NULL)
goto bail_out;
envp = alloc_c_array(env, jenv);
if (envp == NULL)
goto bail_out;
#if DEBUGIT
fprintf(stderr, "command:");
print_array(cmd);
fprintf(stderr, "Envp:");
print_array(envp);
fprintf(stderr, "dirpath: %s\n", dirpath);
fprintf(stderr, "pts_name: %s\n", pts_name);
#endif
pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD);
if (pid < 0)
goto bail_out;
channels[0] = fd[0];
channels[1] = fd[1];
channels[2] = fd[2];
bail_out:
(*env)->ReleaseIntArrayElements(env, jchannels, channels, 0);
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
(*env)->ReleaseStringUTFChars(env, jslaveName, pts_name);
if (cmd)
free_c_array(cmd);
if (envp)
free_c_array(envp);
return pid;
}
JNIEXPORT jint JNICALL
Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
jobjectArray jcmd,

View file

@ -1,3 +1,14 @@
2004-11-16 Alain Magloire
Fix for 27663, allow to exec with pty emulation.
* library/Makefile
* library/openpty.c(set_noecho): new function
* library/opentpty.h: update header.
* library/pty.c: refactor forkpyt to openMaster()
* library/PTY.h: regenerate
* library/spawner.c: add exec2() support
* library/Spawner.h: regenerate
2004-03-25 David Inglis
Added platform attribute to processlist extension

View file

@ -10,7 +10,7 @@ CFLAGS +=-fpic -D_REENTRANT
LIB_NAME_SPAWNER = libspawner.so
LIB_NAME_FULL_SPAWNER = ../os/solaris/sparc/libspawner.so
OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o
OBJS_SPAWNER=spawner.o io.o exec_unix.o exec_pty.o openpty.o pfind.o
LIB_NAME_PTY = libpty.so
LIB_NAME_FULL_PTY = ../os/solaris/sparc/libpty.so

View file

@ -7,12 +7,13 @@
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: hasPTY */
/*
* Class: org_eclipse_cdt_utils_pty_PTY
* Method: forkpty
* Signature: ()I
* Method: openMaster
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster
(JNIEnv *, jobject);
#ifdef __cplusplus

View file

@ -1,9 +1,9 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_qnx_tools_utils_spawner_Spawner */
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
#ifndef _Included_com_qnx_tools_utils_spawner_Spawner
#define _Included_com_qnx_tools_utils_spawner_Spawner
#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner
#define _Included_org_eclipse_cdt_utils_spawner_Spawner
#ifdef __cplusplus
extern "C" {
#endif
@ -17,12 +17,20 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec0
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
* Method: exec1
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring);
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec2
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint);
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: raise

View file

@ -0,0 +1,152 @@
#include "exec0.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>
#include <stdlib.h>
#include <termios.h>
/* from pfind.c */
extern char *pfind(const char *name);
pid_t
exec_pty(const char *path, char *const argv[], char *const envp[],
const char *dirpath, int channels[3], const char *pts_name, int fdm)
{
int pipe2[2];
pid_t childpid;
char *full_path;
/*
* We use pfind() to check that the program exists and is an executable.
* If not pass the error up. Also execve() wants a full path.
*/
full_path = pfind(path);
if (full_path == NULL) {
fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : "");
return -1;
}
/*
* Make sure we can create our pipes before forking.
*/
if (channels != NULL) {
if (pipe(pipe2) < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
free(full_path);
return -1;
}
}
childpid = fork();
if (childpid < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
free(full_path);
return -1;
} else if (childpid == 0) { /* child */
chdir(dirpath);
if (channels != NULL) {
int fds;
fds = ptys_open(fdm, pts_name);
if (fds < 0) {
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
return -1;
}
/* Close the read end of pipe2 */
if (close(pipe2[0]) == -1)
perror("close(pipe2[0]))");
/* close the master, no need in the child */
close(fdm);
set_noecho(fds);
/* redirections */
dup2(fds, STDIN_FILENO); /* dup stdin */
dup2(fds, STDOUT_FILENO); /* dup stdout */
dup2(pipe2[1], STDERR_FILENO); /* dup stderr */
close(fds); /* done with fds. */
}
/* Close all the fd's in the child */
{
int fdlimit = sysconf(_SC_OPEN_MAX);
int fd = 3;
while (fd < fdlimit)
close(fd++);
}
if (envp[0] == NULL) {
execv(full_path, argv);
} else {
execve(full_path, argv, envp);
}
_exit(127);
} else if (childpid != 0) { /* parent */
set_noecho(fdm);
if (channels != NULL) {
/* close the write end of pipe1 */
if (close(pipe2[1]) == -1)
perror("close(pipe2[1])");
channels[0] = fdm; /* Input Stream. */
channels[1] = fdm; /* Output Stream. */
channels[2] = pipe2[0]; /* stderr Stream. */
//channels[2] = fdm; /* Input Stream. */
}
free(full_path);
return childpid;
}
free(full_path);
return -1; /*NOT REACHED */
}
#ifdef __STAND_ALONE__
int main(int argc, char **argv, char **envp) {
const char *path = "./bufferring_test";
int channels[3] = { -1, -1, -1};
int status;
FILE *app_stdin;
FILE *app_stdout;
FILE *app_stderr;
char pts_name[32];
int fdm;
char buffer[32];
fdm = ptym_open(pts_name);
status = exec_pty(path, argv, envp, ".", channels, pts_name, fdm);
if (status >= 0) {
app_stdin = fdopen(channels[0], "w");
app_stdout = fdopen(channels[1], "r");
app_stderr = fdopen(channels[2], "r");
if (app_stdout == NULL || app_stderr == NULL || app_stdin == NULL) {
fprintf(stderr, "PROBLEMS\n");
} else {
fputs("foo\n", app_stdin);
fputs("bar\n", app_stdin);
while(fgets(buffer, sizeof buffer, app_stdout) != NULL) {
fprintf(stdout, "STDOUT: %s\n", buffer);
}
while(fgets(buffer, sizeof buffer, app_stderr) != NULL) {
fprintf(stdout, "STDERR: %s\n", buffer);
}
}
}
fputs("bye\n", stdout);
close(channels[0]);
close(channels[1]);
close(channels[2]);
return 0;
}
#endif

View file

@ -105,3 +105,22 @@ ptys_open(int fdm, char * pts_name)
}
return fds;
}
void
set_noecho(int fd)
{
struct termios stermios;
if (tcgetattr(fd, &stermios) < 0) {
return ;
}
/* turn off echo */
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
/* Turn off the NL to CR/NL mapping ou output. */
/*stermios.c_oflag &= ~(ONLCR);*/
stermios.c_iflag |= (IGNCR);
tcsetattr(fd, TCSANOW, &stermios);
}

View file

@ -7,4 +7,5 @@
#define _OPENPTY_H
int ptym_open (char *pts_name);
int ptys_open (int fdm, char * pts_name);
void set_noecho(int fd);
#endif

View file

@ -7,7 +7,7 @@
* Signature: ()I
*/
JNIEXPORT jstring JNICALL
Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj) {
jfieldID fid; /* Store the field ID */
jstring jstr = NULL;
int master = -1;
@ -18,6 +18,9 @@ Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
master = ptym_open(line);
if (master >= 0) {
// turn off echo
set_noecho(master);
/* Get a reference to the obj's class */
cls = (*env)->GetObjectClass(env, jobj);

View file

@ -13,7 +13,7 @@
/*
* Header for class com_qnx_utils_spawner_Spawner
* Header for class org_eclipse_cdt_utils_spawner_Spawner
*/
@ -71,6 +71,63 @@ static void free_c_array(char **c_array)
}
/*
* Class: org_eclipse_cdt_utils_spawner_Spawner
* Method: exec2
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILorg/eclipse/cdt/utils/pty/PTY;)I
*/
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels,
jstring jslaveName, jint masterFD)
{
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
const char *pts_name = (*env)->GetStringUTFChars(env, jslaveName, NULL);
char **cmd;
char **envp;
int fd[3];
pid_t pid = -1;
if (channels == NULL)
goto bail_out;
cmd = alloc_c_array(env, jcmd);
if (cmd == NULL)
goto bail_out;
envp = alloc_c_array(env, jenv);
if (envp == NULL)
goto bail_out;
#if DEBUGIT
fprintf(stderr, "command:");
print_array(cmd);
fprintf(stderr, "Envp:");
print_array(envp);
fprintf(stderr, "dirpath: %s\n", dirpath);
fprintf(stderr, "pts_name: %s\n", pts_name);
#endif
pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD);
if (pid < 0)
goto bail_out;
channels[0] = fd[0];
channels[1] = fd[1];
channels[2] = fd[2];
bail_out:
(*env)->ReleaseIntArrayElements(env, jchannels, channels, 0);
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
(*env)->ReleaseStringUTFChars(env, jslaveName, pts_name);
if (cmd)
free_c_array(cmd);
if (envp)
free_c_array(envp);
return pid;
}
JNIEXPORT jint JNICALL
Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
jobjectArray jcmd,
@ -80,7 +137,6 @@ Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
char **cmd;
char **envp;
int fd[3];
pid_t pid = -1;
cmd = alloc_c_array(env, jcmd);