- 论坛徽章:
- 0
|
抱歉,在此附上源码
static int create_subprocess(const char *cmd,
char *const argv[], char *const envp[], int* pProcessId)
{
char *devname;
int ptm;
pid_t pid;
LOGE("create_subprocess:%s");
ptm = open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
if(ptm < 0){
LOGE("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
return -1;
}
LOGE(" fcntl");
fcntl(ptm, F_SETFD, FD_CLOEXEC);
if(grantpt(ptm) || unlockpt(ptm) ||
((devname = (char*) ptsname(ptm)) == 0)){
LOGE("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
return -1;
}
LOGE(" fork");
pid = fork();
if(pid < 0) {
LOGE("- fork failed: %s -\n", strerror(errno));
return -1;
}
if(pid == 0){
close(ptm);
int pts;
LOGE(" setsid");
setsid();
LOGE(" pts");
pts = open(devname, O_RDWR);
if(pts < 0) exit(-1);
LOGE(" dup2");
dup2(pts, 0);
dup2(pts, 1);
dup2(pts, 2);
LOGE(" envp");
if (envp) {
for (; *envp; ++envp) {
putenv(*envp);
}
}
LOGE(" execv");
//execv(cmd, argv);
if(execv(cmd, argv)<0){
LOGE("Err on execv"); }
else{
LOGE("NO Err on execv");
}
exit(-1);
} else {
*pProcessId = (int) pid;
return ptm;
}
}
static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
jstring cmd, jobjectArray args, jobjectArray envVars,
jintArray processIdArray)
{
const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
String8 cmd_8;
LOGE("android_os_Exec_createSubProcess");
LOGE("1");
if (str) {
LOGE("1");
cmd_8.set(str, env->GetStringLength(cmd));
env->ReleaseStringCritical(cmd, str);
}
LOGE(" size");
jsize size = args ? env->GetArrayLength(args) : 0;
char **argv = NULL;
String8 tmp_8;
if (size > 0) {
LOGE(" size>0 argv");
argv = (char **)malloc((size+1)*sizeof(char *));
if (!argv) {
throwOutOfMemoryError(env, "Couldn't allocate argv array");
return NULL;
}
for (int i = 0; i < size; ++i) {
LOGE(" size>0 args");
jstring arg = reinterpret_cast<jstring>(env->GetObjectArrayElement(args, i));
str = env->GetStringCritical(arg, 0);
if (!str) {
throwOutOfMemoryError(env, "Couldn't get argument from array");
return NULL;
}
LOGE(" tmp_8 arg");
tmp_8.set(str, env->GetStringLength(arg));
LOGE(" ReleaseStringCritical");
env->ReleaseStringCritical(arg, str);
LOGE(" argv[i] = strdup(tmp_8.string())");
argv[i] = strdup(tmp_8.string());
LOGE(" argv[OK] = strdup(tmp_8.string())");
}
argv[size] = NULL;
LOGE(" argv[size] = NULL;");
}
size = envVars ? env->GetArrayLength(envVars) : 0;
LOGE(" size = envVars ? env->GetArrayLength(envVars) : 0;");
char **envp = NULL;
if (size > 0) {
LOGE("envVars size > 0");
envp = (char **)malloc((size+1)*sizeof(char *));
LOGE(" envp = (char **)malloc((size+1)*sizeof(char *))");
if (!envp) {
throwOutOfMemoryError(env, "Couldn't allocate envp array");
return NULL;
}
for (int i = 0; i < size; ++i) {
jstring var = reinterpret_cast<jstring>(env->GetObjectArrayElement(envVars, i));
str = env->GetStringCritical(var, 0);
LOGE(" envVars str = env->GetStringCritical(var, 0 ");
if (!str) {
throwOutOfMemoryError(env, "Couldn't get env var from array");
return NULL;
}
tmp_8.set(str, env->GetStringLength(var));
LOGE(" envVars tmp_8.set(str, env->GetStringLength(var)) ");
env->ReleaseStringCritical(var, str);
LOGE(" env->ReleaseStringCritical(var, str) ");
envp[i] = strdup(tmp_8.string());
LOGE(" envp[i] = strdup(tmp_8.string()); ");
}
envp[size] = NULL;
}
int procId;
LOGE(" ptm ");
int ptm = create_subprocess(cmd_8.string(), argv, envp, &procId);
LOGE(" create_subprocess(cmd_8.string(), argv, envp, &procId) ");
if (argv) {
LOGE(" if (argv) ");
for (char **tmp = argv; *tmp; ++tmp) {
free(*tmp);
}
free(argv);
LOGE(" free(argv) ");
}
if (envp) {
LOGE(" envp ");
for (char **tmp = envp; *tmp; ++tmp) {
free(*tmp);
}
free(envp);
LOGE(" free(envp) ");
}
if (processIdArray) {
LOGE(" if (processIdArray) ");
int procIdLen = env->GetArrayLength(processIdArray);
if (procIdLen > 0) {
jboolean isCopy;
LOGE(" if (procIdLen > 0) ");
int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
if (pProcId) {
LOGE(" if (pProcId)");
*pProcId = procId;
env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
}
}
}
LOGE(" result");
jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);
LOGE("11111111");
if (!result) {
LOGE("Couldn't create a FileDescriptor.");
}
else {
env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
LOGE("22222222");
}
return result;
}
static void android_os_Exec_setPtyWindowSize(JNIEnv *env, jobject clazz,
jobject fileDescriptor, jint row, jint col, jint xpixel, jint ypixel)
{
int fd;
struct winsize sz;
LOGE("android_os_Exec_setPtyWindowSize");
fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
if (env->ExceptionOccurred() != NULL) {
return;
}
sz.ws_row = row;
sz.ws_col = col;
sz.ws_xpixel = xpixel;
sz.ws_ypixel = ypixel;
ioctl(fd, TIOCSWINSZ, &sz);
}
static void android_os_Exec_setPtyUTF8Mode(JNIEnv *env, jobject clazz,
jobject fileDescriptor, jboolean utf8Mode)
{
int fd;
struct termios tios;
LOGE("android_os_Exec_setPtyUTF8Mode");
fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
if (env->ExceptionOccurred() != NULL) {
return;
}
tcgetattr(fd, &tios);
if (utf8Mode) {
tios.c_iflag |= IUTF8;
} else {
tios.c_iflag &= ~IUTF8;
}
tcsetattr(fd, TCSANOW, &tios);
}
static int android_os_Exec_waitFor(JNIEnv *env, jobject clazz,
jint procId) {
int status;
LOGE("android_os_Exec_waitFor");
waitpid(procId, &status, 0);
int result = 0;
if (WIFEXITED(status)) {
result = WEXITSTATUS(status);
}
return result;
} |
|