Ejemplo n.º 1
0
static int create_subproc_thread(const char *name)
{
    stinfo *sti;
    adb_thread_t t;
    int ret_fd;
    pid_t pid;
    if (name) {
        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
    } else {
        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
    }
    D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);

    sti = malloc(sizeof(stinfo));
    if (sti == 0)
        fatal("cannot allocate stinfo");
    sti->func = subproc_waiter_service;
    sti->cookie = (void *) pid;
    sti->fd = ret_fd;

    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
        free(sti);
        adb_close(ret_fd);
        printf("cannot create service thread\n");
        return -1;
    }

    D("service thread started, fd=%d pid=%d\n", ret_fd, pid);
    return ret_fd;
}
Ejemplo n.º 2
0
static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
    jintArray processIdArray)
{


    int procId;
    int ptm = create_subprocess(&procId);

    if (processIdArray) {
        int procIdLen = env->GetArrayLength(processIdArray);
        if (procIdLen > 0) {
            jboolean isCopy;

            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
            if (pProcId) {
                *pProcId = procId;
                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
            }
        }
    }

    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);

    if (!result) {
        LOGE("Couldn't create a FileDescriptor.");
    }
    else {
        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
    }

    return result;
}
Ejemplo n.º 3
0
static int create_subproc_thread(const char *name)
{
    adb_thread_t t;
    int ret_fd;
    pid_t pid;

    long mem_free = 0;
    read_meminfo(&mem_free);
    D("read_meminfo() mem_free=%d\n", mem_free);
    XLOGV("read_meminfo() mem_free=%d\n", mem_free);

    if(name) {
        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
    } else {
        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
    }
    D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
    XLOGV("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);

    if ( sti == 0 )
    {
    sti = malloc(sizeof(stinfo));
    if(sti == 0) fatal("cannot allocate stinfo");
    sti->func = subproc_waiter_service;
    sti->cookie = (void*)pid;
    sti->fd = ret_fd;

        int nRet = adb_thread_create( &t, service_bootstrap_func, sti);

        if(nRet)
        {
            D("adb_thread_create() nRet=%d errno=%d\n", nRet, errno);
            XLOGW("adb_thread_create() nRet=%d errno=%d\n", nRet, errno);
        free(sti);
            sti = 0;
        adb_close(ret_fd);
        printf("cannot create service thread\n");
        return -1;
    }
    }

    D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
    return ret_fd;
}
static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
    jstring cmd, jstring arg0, jstring arg1, jintArray processIdArray)
{
    const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
    String8 cmd_8;
    if (str) {
        cmd_8.set(str, env->GetStringLength(cmd));
        env->ReleaseStringCritical(cmd, str);
    }

    str = arg0 ? env->GetStringCritical(arg0, 0) : 0;
    const char* arg0Str = 0;
    String8 arg0_8;
    if (str) {
        arg0_8.set(str, env->GetStringLength(arg0));
        env->ReleaseStringCritical(arg0, str);
        arg0Str = arg0_8.string();
    }

    str = arg1 ? env->GetStringCritical(arg1, 0) : 0;
    const char* arg1Str = 0;
    String8 arg1_8;
    if (str) {
        arg1_8.set(str, env->GetStringLength(arg1));
        env->ReleaseStringCritical(arg1, str);
        arg1Str = arg1_8.string();
    }

    int procId;
    int ptm = create_subprocess(cmd_8.string(), arg0Str, arg1Str, &procId);

    if (processIdArray) {
        int procIdLen = env->GetArrayLength(processIdArray);
        if (procIdLen > 0) {
            jboolean isCopy;

            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
            if (pProcId) {
                *pProcId = procId;
                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
            }
        }
    }

    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);

    if (!result) {
        LOGE("Couldn't create a FileDescriptor.");
    }
    else {
        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
    }

    return result;
}
Ejemplo n.º 5
0
JNIEXPORT jobject JNICALL Java_com_google_ase_Exec_createSubprocess(
    JNIEnv* env, jclass clazz, jstring cmd, jstring arg0, jstring arg1,
    jintArray processIdArray) {
  char* cmd_8 = JNU_GetStringNativeChars(env, cmd);
  char* arg0_8 = JNU_GetStringNativeChars(env, arg0);
  char* arg1_8 = JNU_GetStringNativeChars(env, arg1);

  int procId;
  int ptm = create_subprocess(cmd_8, arg0_8, arg1_8, &procId);

  if (processIdArray) {
    int procIdLen = env->GetArrayLength(processIdArray);
    if (procIdLen > 0) {
      jboolean isCopy;
      int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
      if (pProcId) {
        *pProcId = procId;
        env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
      }
    }
  }

  jclass Class_java_io_FileDescriptor = env->FindClass("java/io/FileDescriptor");
  jmethodID init = env->GetMethodID(Class_java_io_FileDescriptor,
                                    "<init>", "()V");
  jobject result = env->NewObject(Class_java_io_FileDescriptor, init);

  if (!result) {
    LOG("Couldn't create a FileDescriptor.");
  } else {
    jfieldID descriptor = env->GetFieldID(Class_java_io_FileDescriptor,
                                        "descriptor", "I");
    env->SetIntField(result, descriptor, ptm);
  }

  return result;
}
Ejemplo n.º 6
0
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;
    if (str) {
        cmd_8.set(str, env->GetStringLength(cmd));
        env->ReleaseStringCritical(cmd, str);
    }

    jsize size = args ? env->GetArrayLength(args) : 0;
    char **argv = NULL;
    String8 tmp_8;
    if (size > 0) {
        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) {
            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;
            }
            tmp_8.set(str, env->GetStringLength(arg));
            env->ReleaseStringCritical(arg, str);
            argv[i] = strdup(tmp_8.string());
        }
        argv[size] = NULL;
    }

    size = envVars ? env->GetArrayLength(envVars) : 0;
    char **envp = NULL;
    if (size > 0) {
        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);
            if (!str) {
                throwOutOfMemoryError(env, "Couldn't get env var from array");
                return NULL;
            }
            tmp_8.set(str, env->GetStringLength(var));
            env->ReleaseStringCritical(var, str);
            envp[i] = strdup(tmp_8.string());
        }
        envp[size] = NULL;
    }

    int procId;
    int ptm = create_subprocess(cmd_8.string(), argv, envp, &procId);

    if (argv) {
        for (char **tmp = argv; *tmp; ++tmp) {
            free(*tmp);
        }
        free(argv);
    }
    if (envp) {
        for (char **tmp = envp; *tmp; ++tmp) {
            free(*tmp);
        }
        free(envp);
    }

    if (processIdArray) {
        int procIdLen = env->GetArrayLength(processIdArray);
        if (procIdLen > 0) {
            jboolean isCopy;

            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
            if (pProcId) {
                *pProcId = procId;
                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
            }
        }
    }

    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);

    if (!result) {
        LOGE("Couldn't create a FileDescriptor.");
    }
    else {
        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
    }

    return result;
}
Ejemplo n.º 7
0
JNIEXPORT jint JNICALL Java_jackpal_androidterm_TermExec_createSubprocessInternal(JNIEnv *env, jclass clazz,
    jstring cmd, jobjectArray args, jobjectArray envVars, jint masterFd)
{
    const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
    String8 cmd_8;
    if (str) {
        cmd_8.set(str, env->GetStringLength(cmd));
        env->ReleaseStringCritical(cmd, str);
    }

    jsize size = args ? env->GetArrayLength(args) : 0;
    char **argv = NULL;
    String8 tmp_8;
    if (size > 0) {
        argv = (char **)malloc((size+1)*sizeof(char *));
        if (!argv) {
            throwOutOfMemoryError(env, "Couldn't allocate argv array");
            return 0;
        }
        for (int i = 0; i < size; ++i) {
            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 0;
            }
            tmp_8.set(str, env->GetStringLength(arg));
            env->ReleaseStringCritical(arg, str);
            argv[i] = strdup(tmp_8.string());
        }
        argv[size] = NULL;
    }

    size = envVars ? env->GetArrayLength(envVars) : 0;
    char **envp = NULL;
    if (size > 0) {
        envp = (char **)malloc((size+1)*sizeof(char *));
        if (!envp) {
            throwOutOfMemoryError(env, "Couldn't allocate envp array");
            return 0;
        }
        for (int i = 0; i < size; ++i) {
            jstring var = reinterpret_cast<jstring>(env->GetObjectArrayElement(envVars, i));
            str = env->GetStringCritical(var, 0);
            if (!str) {
                throwOutOfMemoryError(env, "Couldn't get env var from array");
                return 0;
            }
            tmp_8.set(str, env->GetStringLength(var));
            env->ReleaseStringCritical(var, str);
            envp[i] = strdup(tmp_8.string());
        }
        envp[size] = NULL;
    }

    int ptm = create_subprocess(env, cmd_8.string(), argv, envp, masterFd);

    if (argv) {
        for (char **tmp = argv; *tmp; ++tmp) {
            free(*tmp);
        }
        free(argv);
    }
    if (envp) {
        for (char **tmp = envp; *tmp; ++tmp) {
            free(*tmp);
        }
        free(envp);
    }

    return ptm;
}
Ejemplo n.º 8
0
static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char* const argv[], char** envp, int* pProcessId)
{
        int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC);
        if (ptm < 0) return throw_runtime_exception(env, "Cannot open /dev/ptmx");

#ifdef LACKS_PTSNAME_R
        char* devname;
#else
        char devname[64];
#endif
        if (grantpt(ptm) || unlockpt(ptm) ||
#ifdef LACKS_PTSNAME_R
			(devname = ptsname(ptm)) == NULL
#else
			ptsname_r(ptm, devname, sizeof(devname))
#endif
			) {
                return throw_runtime_exception(env, "Cannot grantpt()/unlockpt()/ptsname_r() on /dev/ptmx");
        }

        // Enable UTF-8 mode and disable flow control to prevent Ctrl+S from locking up the display.
        struct termios tios;
        tcgetattr(ptm, &tios);
        tios.c_iflag |= IUTF8;
        tios.c_iflag &= ~(IXON | IXOFF);
        tcsetattr(ptm, TCSANOW, &tios);

		/** Set initial winsize (better too small than too large). */
        struct winsize sz = { .ws_row = 20, .ws_col = 20 };
        ioctl(ptm, TIOCSWINSZ, &sz);

        pid_t pid = fork();
        if (pid < 0) {
                return throw_runtime_exception(env, "Fork failed");
        } else if (pid > 0) {
                *pProcessId = (int) pid;
                return ptm;
        } else {
		// Clear signals which the Android java process may have blocked:
		sigset_t signals_to_unblock;
		sigfillset(&signals_to_unblock);
		sigprocmask(SIG_UNBLOCK, &signals_to_unblock, 0);

                close(ptm);
                setsid();

                int pts = open(devname, O_RDWR);
                if (pts < 0) exit(-1);

                dup2(pts, 0);
                dup2(pts, 1);
                dup2(pts, 2);

                DIR* self_dir = opendir("/proc/self/fd");
                if (self_dir != NULL) {
                        int self_dir_fd = dirfd(self_dir);
                        struct dirent* entry;
                        while ((entry = readdir(self_dir)) != NULL) {
                                int fd = atoi(entry->d_name);
                                if(fd > 2 && fd != self_dir_fd) close(fd);
                        }
                        closedir(self_dir);
                }

		clearenv();
                if (envp) for (; *envp; ++envp) putenv(*envp);

                if (chdir(cwd) != 0) {
                        char* error_message;
                        // No need to free asprintf()-allocated memory since doing execvp() or exit() below.
                        if (asprintf(&error_message, "chdir(\"%s\")", cwd) == -1) error_message = "chdir()";
                        perror(error_message);
                        fflush(stderr);
                }
                execvp(cmd, argv);
                // Show terminal output about failing exec() call:
		char* error_message;
		if (asprintf(&error_message, "exec(\"%s\")", cmd) == -1) error_message = "exec()";
                perror(error_message);
                _exit(1);
        }
}

JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(JNIEnv* env, jclass TERMUX_UNUSED(clazz), jstring cmd, jstring cwd, jobjectArray args, jobjectArray envVars, jintArray processIdArray)
{
        jsize size = args ? (*env)->GetArrayLength(env, args) : 0;
        char** argv = NULL;
        if (size > 0) {
                argv = (char**) malloc((size + 1) * sizeof(char*));
                if (!argv) return throw_runtime_exception(env, "Couldn't allocate argv array");
                for (int i = 0; i < size; ++i) {
                        jstring arg_java_string = (jstring) (*env)->GetObjectArrayElement(env, args, i);
                        char const* arg_utf8 = (*env)->GetStringUTFChars(env, arg_java_string, NULL);
                        if (!arg_utf8) return throw_runtime_exception(env, "GetStringUTFChars() failed for argv");
                        argv[i] = strdup(arg_utf8);
                        (*env)->ReleaseStringUTFChars(env, arg_java_string, arg_utf8);
                }
                argv[size] = NULL;
        }

        size = envVars ? (*env)->GetArrayLength(env, envVars) : 0;
        char** envp = NULL;
        if (size > 0) {
                envp = (char**) malloc((size + 1) * sizeof(char *));
                if (!envp) return throw_runtime_exception(env, "malloc() for envp array failed");
                for (int i = 0; i < size; ++i) {
                        jstring env_java_string = (jstring) (*env)->GetObjectArrayElement(env, envVars, i);
                        char const* env_utf8 = (*env)->GetStringUTFChars(env, env_java_string, 0);
                        if (!env_utf8) return throw_runtime_exception(env, "GetStringUTFChars() failed for env");
                        envp[i] = strdup(env_utf8);
                        (*env)->ReleaseStringUTFChars(env, env_java_string, env_utf8);
                }
                envp[size] = NULL;
        }

        int procId = 0;
	char const* cmd_cwd = (*env)->GetStringUTFChars(env, cwd, NULL);
        char const* cmd_utf8 = (*env)->GetStringUTFChars(env, cmd, NULL);
        int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId);
        (*env)->ReleaseStringUTFChars(env, cmd, cmd_utf8);
        (*env)->ReleaseStringUTFChars(env, cmd, cmd_cwd);

        if (argv) {
                for (char** tmp = argv; *tmp; ++tmp) free(*tmp);
                free(argv);
        }
        if (envp) {
                for (char** tmp = envp; *tmp; ++tmp) free(*tmp);
                free(envp);
        }

        int* pProcId = (int*) (*env)->GetPrimitiveArrayCritical(env, processIdArray, NULL);
        if (!pProcId) return throw_runtime_exception(env, "JNI call GetPrimitiveArrayCritical(processIdArray, &isCopy) failed");

        *pProcId = procId;
        (*env)->ReleasePrimitiveArrayCritical(env, processIdArray, pProcId, 0);

        return ptm;
}
Ejemplo n.º 9
0
int service_to_fd(const char *name)
{
    int ret = -1;

    if(!strncmp(name, "tcp:", 4)) {
        int port = atoi(name + 4);
        name = strchr(name + 4, ':');
        if(name == 0) {
            ret = socket_loopback_client(port, SOCK_STREAM);
            if (ret >= 0)
                disable_tcp_nagle(ret);
        } else {
#if ADB_HOST
            adb_mutex_lock(&dns_lock);
            ret = socket_network_client(name + 1, port, SOCK_STREAM);
            adb_mutex_unlock(&dns_lock);
#else
            return -1;
#endif
        }
#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
    } else if(!strncmp(name, "local:", 6)) {
        ret = socket_local_client(name + 6,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localreserved:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localabstract:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    } else if(!strncmp(name, "localfilesystem:", 16)) {
        ret = socket_local_client(name + 16,
                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
#if ADB_HOST
    } else if(!strncmp("dns:", name, 4)){
        char *n = strdup(name + 4);
        if(n == 0) return -1;
        ret = create_service_thread(dns_service, n);
#else /* !ADB_HOST */
    } else if(!strncmp("dev:", name, 4)) {
        ret = unix_open(name + 4, O_RDWR);
    } else if(!strncmp(name, "framebuffer:", 12)) {
        ret = create_service_thread(framebuffer_service, 0);
    } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
        ret = create_service_thread(recover_service, (void*) atoi(name + 8));
    } else if (!strncmp(name, "jdwp:", 5)) {
        ret = create_jdwp_connection_fd(atoi(name+5));
    } else if (!strncmp(name, "log:", 4)) {
        ret = create_service_thread(log_service, get_log_file_path(name + 4));
#endif
    } else if(!HOST && !strncmp(name, "shell:", 6)) {
        if(name[6]) {
            ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
        } else {
            ret = create_subprocess(SHELL_COMMAND, "-", 0);
        }
#if !ADB_HOST
    } else if(!strncmp(name, "sync:", 5)) {
        ret = create_service_thread(file_sync_service, NULL);
    } else if(!strncmp(name, "remount:", 8)) {
        ret = create_service_thread(remount_service, NULL);
    } else if(!strncmp(name, "reboot:", 7)) {
        void* arg = strdup(name + 7);
        if(arg == 0) return -1;
        ret = create_service_thread(reboot_service, arg);
    } else if(!strncmp(name, "root:", 5)) {
        ret = create_service_thread(restart_root_service, NULL);
    } else if(!strncmp(name, "tcpip:", 6)) {
        int port;
        if (sscanf(name + 6, "%d", &port) == 0) {
            port = 0;
        }
        ret = create_service_thread(restart_tcp_service, (void *)port);
    } else if(!strncmp(name, "usb:", 4)) {
        ret = create_service_thread(restart_usb_service, NULL);
#endif
#if 0
    } else if(!strncmp(name, "echo:", 5)){
        ret = create_service_thread(echo_service, 0);
#endif
    }
    if (ret >= 0) {
        close_on_exec(ret);
    }
    return ret;
}
Ejemplo n.º 10
0
static jobject DEF_JNI(createSubprocess,
                       jstring cmd, jstring arg0, jstring arg1,
                       jobjectArray envVars, jintArray processIdArray)
{
    char const* cmd_str = cmd ? env->GetStringUTFChars(cmd, NULL) : NULL;
    char const* arg0_str = arg0 ? env->GetStringUTFChars(arg0, NULL) : NULL;
    char const* arg1_str = arg1 ? env->GetStringUTFChars(arg1, NULL) : NULL;
    LOGI("cmd_str = '%s'", cmd_str);
    LOGI("arg0_str = '%s'", arg0_str);
    LOGI("arg1_str = '%s'", arg1_str);

    int num_env_vars = envVars ? env->GetArrayLength(envVars) : 0;
    char **envp = NULL;
    char const* tmp = NULL;

    if (num_env_vars > 0)
    {
        envp = (char **)malloc((num_env_vars + 1) * sizeof(char*));

        if (!envp)
        {
            throwOutOfMemoryError(env, "Couldn't allocate envp array");
            return NULL;
        }

        for (int i = 0; i < num_env_vars; ++i)
        {
            jobject obj = env->GetObjectArrayElement(envVars, i);
            jstring env_var = reinterpret_cast<jstring>(obj);
            tmp = env->GetStringUTFChars(env_var, 0);

            if (tmp == NULL)
            {
                throwOutOfMemoryError(env, "Couldn't get env var from array");
                return NULL;
            }

            envp[i] = strdup(tmp);

            if (envp[i] == NULL)
            {
                throwOutOfMemoryError(env, "Couldn't strdup() env var");
                return NULL;
            }

            env->ReleaseStringUTFChars(env_var, tmp);
        }

        envp[num_env_vars] = NULL;
    }

    int procId;
    int ptm = create_subprocess(cmd_str, arg0_str, arg1_str, envp, &procId);

    env->ReleaseStringUTFChars(cmd, cmd_str);
    if(arg0 != NULL) env->ReleaseStringUTFChars(arg0, arg0_str);
    if(arg1 != NULL) env->ReleaseStringUTFChars(arg1, arg1_str);

    for (int i = 0; i < num_env_vars; ++i)
        free(envp[i]);

    free(envp);

    if (processIdArray) {
        int procIdLen = env->GetArrayLength(processIdArray);
        if (procIdLen > 0) {
            jboolean isCopy;
    
            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
            if (pProcId) {
                *pProcId = procId;
                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
            }
        }
    }
    
    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);
    
    if (!result) {
        LOGE("Couldn't create a FileDescriptor.");
    }
    else {
        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
    }
    
    return result;
}