📄 boot.c
字号:
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * @author Scott Ferguson */#ifdef WIN32#ifndef _WINSOCKAPI_ #define _WINSOCKAPI_#endif #include <windows.h>#else#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <sys/time.h>#include <grp.h>#include <pwd.h>#include <sys/resource.h>#include <limits.h>#endif#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <signal.h>#include <errno.h>/* probably system-dependent */#include <jni.h>static char *get_utf8(JNIEnv *env, jstring jaddr, char *buf, int buflen){ const char *temp_string = 0; temp_string = (*env)->GetStringUTFChars(env, jaddr, 0); if (temp_string) { strncpy(buf, temp_string, buflen); buf[buflen - 1] = 0; (*env)->ReleaseStringUTFChars(env, jaddr, temp_string); } return buf;}JNIEXPORT jboolean JNICALLJava_com_caucho_bootjni_JniProcess_isNativeBootAvailable(JNIEnv *env, jobject obj){#ifdef WIN32 return 0;#else return 1;#endif }JNIEXPORT jboolean JNICALLJava_com_caucho_bootjni_JniProcess_clearSaveOnExec(JNIEnv *env, jobject obj){#ifdef WIN32 return 0;#else { int fd; for (fd = 3; fd < 4096; fd++) { int arg = fcntl(fd, F_GETFD, 0); if (arg >= 0) { arg |= FD_CLOEXEC; fcntl(fd, F_SETFD, arg); } } }#endif}JNIEXPORT jint JNICALLJava_com_caucho_bootjni_JniProcess_getFdMax(JNIEnv *env, jobject obj){#ifdef WIN32 return -1;#else struct rlimit rlimit; if (getrlimit(RLIMIT_NOFILE, &rlimit) != 0) return -1; return rlimit.rlim_cur;#endif }JNIEXPORT jint JNICALLJava_com_caucho_bootjni_JniProcess_setFdMax(JNIEnv *env, jobject obj){#ifdef WIN32 return -1;#else struct rlimit rlimit; struct rlimit set_rlimit; int result = -1; if (getrlimit(RLIMIT_NOFILE, &rlimit) != 0) return -1;#ifdef EPOLL if (rlimit.rlim_max < 65536) { set_rlimit.rlim_cur = set_rlimit.rlim_max = 65536; result = setrlimit(RLIMIT_NOFILE, &set_rlimit); if (result < 0 && rlimit.rlim_max < 8 * 1024) { set_rlimit.rlim_cur = set_rlimit.rlim_max = 8 * 1024; result = setrlimit(RLIMIT_NOFILE, &set_rlimit); } if (result < 0 && rlimit.rlim_max < 4 * 1024) { set_rlimit.rlim_cur = set_rlimit.rlim_max = 4 * 1024; result = setrlimit(RLIMIT_NOFILE, &set_rlimit); } } else set_rlimit.rlim_cur = set_rlimit.rlim_max = rlimit.rlim_max;#else if (rlimit.rlim_cur < FD_SETSIZE) { set_rlimit.rlim_cur = set_rlimit.rlim_max = FD_SETSIZE; }#endif if (result < 0) result = setrlimit(RLIMIT_NOFILE, &set_rlimit); if (getrlimit(RLIMIT_NOFILE, &rlimit) != 0) return -1; return rlimit.rlim_cur;#endif}jbooleanJava_com_caucho_bootjni_JniProcess_exec(JNIEnv *env, jobject obj, jobjectArray j_argv, jobjectArray j_envp, jstring j_chroot, jstring j_pwd, jstring j_user, jstring j_group){ char **argv; char **envp; char chroot_path[4096]; char pwd[4096]; char user[256]; char group[256]; int uid = -1; int gid = -1; int len; int i; int pipe_fds[2]; int pid; jclass c_jni_process; jfieldID f_stdoutFd; jfieldID f_pid;#ifdef WIN32 if (1) return -1;#endif /* WIN32 */ user[0] = 0; group[0] = 0; chroot_path[0] = 0; if (! j_argv) { resin_printf_exception(env, "java/lang/NullPointerException", "argv"); return 0; } if (! j_envp) { resin_printf_exception(env, "java/lang/NullPointerException", "argv"); return 0; } if (! j_pwd) { resin_printf_exception(env, "java/lang/NullPointerException", "pwd"); return 0; } c_jni_process = (*env)->FindClass(env, "com/caucho/bootjni/JniProcess"); if (! c_jni_process) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load JniProcess"); return 0; } f_stdoutFd = (*env)->GetFieldID(env, c_jni_process, "_stdoutFd", "I"); if (! f_stdoutFd) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load field"); return 0; } f_pid = (*env)->GetFieldID(env, c_jni_process, "_pid", "I"); if (! f_pid) { resin_printf_exception(env, "java/lang/NullPointerException", "can't load field"); return 0; } len = (*env)->GetArrayLength(env, j_argv); argv = malloc((len + 1) * sizeof(char*)); argv[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_argv, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); argv[i] = (char *) malloc(strlen + 1); argv[i] = get_utf8(env, j_string, argv[i], strlen + 1); } } len = (*env)->GetArrayLength(env, j_envp); envp = malloc((len + 1) * sizeof(char*)); envp[len] = 0; for (i = 0; i < len; i++) { jstring j_string; j_string = (*env)->GetObjectArrayElement(env, j_envp, i); if (j_string) { int strlen = (*env)->GetStringUTFLength(env, j_string); envp[i] = (char *) malloc(strlen + 1); envp[i] = get_utf8(env, j_string, envp[i], strlen + 1); } } if (j_chroot) { int strlen = (*env)->GetStringUTFLength(env, j_chroot); get_utf8(env, j_chroot, chroot_path, strlen + 1); } else chroot_path[0] = 0; if (j_pwd) { int strlen = (*env)->GetStringUTFLength(env, j_pwd); get_utf8(env, j_pwd, pwd, strlen + 1); }#ifndef WIN32 if (j_user) { struct passwd *passwd; int strlen = (*env)->GetStringUTFLength(env, j_user); get_utf8(env, j_user, user, strlen + 1); passwd = getpwnam(user); if (! passwd) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "%s is an unknown user", user); return 0; } uid = passwd->pw_uid; gid = passwd->pw_gid; } if (j_group) { struct group *group_ent; int strlen = (*env)->GetStringUTFLength(env, j_group); get_utf8(env, j_group, group, strlen + 1); group_ent = getgrnam(group); if (! group_ent) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "%s is an unknown group", group); return 0; } gid = group_ent->gr_gid; } pipe(pipe_fds); pid = fork(); if (pid > 0) { close(pipe_fds[1]); (*env)->SetIntField(env, obj, f_stdoutFd, pipe_fds[0]); (*env)->SetIntField(env, obj, f_pid, pid); return 1; } else if (pid < 0) { close(pipe_fds[0]); close(pipe_fds[1]); resin_printf_exception(env, "java/lang/NullPointerException", "can't fork"); return 0; } close(pipe_fds[0]); /* if (fork()) exit(0); setsid(); */#ifndef WIN32 if (chroot_path[0]) { chroot(chroot_path); }#endif if (gid >= 0) setgid(gid); if (uid >= 0) { setuid(uid); if (getuid() != uid) { fprintf(stderr, "Can't setuid to %d, received %d\n", uid, getuid()); exit(1); } } chdir(pwd);#endif dup2(pipe_fds[1], 1); dup2(pipe_fds[1], 2); for (i = 0; envp[i]; i++) putenv(envp[i]); execvp(argv[0], argv); fprintf(stderr, "exec failed %s -> %d\n", argv[0], errno); exit(1); return -1;}jintJava_com_caucho_bootjni_JniProcess_waitpid(JNIEnv *env, jobject obj, jint pid, jboolean is_block){ int status = 0; int result;#ifdef WIN32 return -1;#else if (pid < 0) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "invalid pid"); return -1; } result = waitpid(pid, &status, is_block ? 0 : WNOHANG); if (result == 0) return -1; if (result < 0) { resin_printf_exception(env, "java/lang/IllegalArgumentException", "invalid result %d", result); return -1; } return WEXITSTATUS(status);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -