📄 resin.c
字号:
/* * Copyright (c) 1999-2000 Caucho Technology. All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License"). In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include * an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and * may not be used to endorse products derived from this software. * "Resin" or "Caucho" may not appear in the names of products derived * from this software. * * 4. Caucho Technology requests that attribution be given to Resin * in any manner possible. We suggest using the "Resin Powered" * button or creating a "powered by Resin(tm)" link to * http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL Caucho OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. */#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <dirent.h>/* probably system-dependent */#include <dlfcn.h>#include <jni.h>#include <pwd.h>#include <grp.h>#include <errno.h>#include <signal.h>#include "cse.h"#include "version.h"#include "proxy.h"#include "proxy_jni.h"static config_t *g_config;typedef struct options_t { char *resin_home; char *java_home; char *conf; char *classpath; char *loadpath; char *stdout_path; char *stderr_path; char *pid; int verbose; int start; int stop; int restart; JavaVMOption options[64]; int n_options;} options_t;static options_t g_options;java_t g_java;voidcse_log(char *fmt, ...){}void *cse_malloc(int size){ return malloc(size);}voidcse_error(config_t *config, char *format, ...){}voidcse_set_socket_cleanup(int socket, void *pool){}voidcse_kill_socket_cleanup(int socket, void *pool){}intcse_lock(void *lock){ return 1;}voidcse_unlock(void *lock){}void *cse_create_lock(){ return 0;}/** * Add a jvm option */static voidadd_jvm_option(char *fmt, ...){ char buf[8192]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); g_options.options[g_options.n_options++].optionString = strdup(buf);}/** * Bind to a port. * * @param hostname name of the host interface * @param port port to bind * * @return server socket on success, -1 on failure. */static intcse_bind(char *hostname, int port){ struct sockaddr_in sin; int val = 0; int sock = socket(AF_INET, SOCK_STREAM, 0); memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); val = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(int)) < 0) { fprintf(stderr, "internal error: bad set sock opt\n"); return -1; } if (bind(sock, (struct sockaddr *) &sin, sizeof (sin)) < 0) { return -1; } listen(sock, 5); return sock;}static voidset_classpath(){ char classpath[16 * 1024]; char def[8192]; char path[1024]; DIR *dir; struct dirent *dir_entry; classpath[0] = 0; if (g_options.classpath) { sprintf(path, "%s", g_options.classpath); strcat(classpath, path); } if (getenv("CLASSPATH")) { strcat(classpath, ":"); strcat(classpath, getenv("CLASSPATH")); } /* classes from resin/classes */ sprintf(path, ":%s/classes", g_options.resin_home); strcat(classpath, path); /* grab jars from resin/lib */ sprintf(path, "%s/lib", g_options.resin_home); dir = opendir(path); while (dir && (dir_entry = readdir(dir))) { int len = strlen(dir_entry->d_name); if (! strcmp(dir_entry->d_name + len - 4, ".jar") || ! strcmp(dir_entry->d_name + len - 4, ".zip")) { strcat(classpath, ":"); strcat(classpath, g_options.resin_home); strcat(classpath, "/lib/"); strcat(classpath, dir_entry->d_name); } } if (dir) closedir(dir); sprintf(path, ":%s/jre/lib/rt.jar", g_options.java_home); strcat(classpath, path); sprintf(path, ":%s/lib/tools.jar", g_options.java_home); strcat(classpath, path); /* * Apparently, this doesn't get added to the list * sprintf(path, "%s/jre/lib/ext", g_options.java_home); dir = opendir(path); while ((dir_entry = readdir(dir))) { int len = strlen(dir_entry->d_name); if (! strcmp(dir_entry->d_name + len - 4, ".jar") || ! strcmp(dir_entry->d_name + len - 4, ".zip")) { strcat(classpath, ":"); strcat(classpath, g_options.java_home); strcat(classpath, "/jre/lib/ext/"); strcat(classpath, dir_entry->d_name); } } closedir(dir); */ g_options.classpath = classpath; add_jvm_option("-Djava.class.path=%s", classpath);}/** * Returns true if prefix + tail is a file. */static intis_file(char *prefix, char *tail){ struct stat st; char buf[8192]; sprintf(buf, "%s/%s", prefix, tail); return ! stat(buf, &st) && S_ISREG(st.st_mode);}voidset_library_path(char *java_home, char *resin_home){ char envpath[8192]; char newpath[8192]; char *type; strcpy(newpath, resin_home); strcat(newpath, "/libexec:"); if (is_file(java_home, "jre/bin/libjava.so")) { type = "classic"; strcat(newpath, java_home); strcat(newpath, "/jre/bin:"); strcat(newpath, java_home); strcat(newpath, "/jre/bin/"); strcat(newpath, type); strcat(newpath, ":"); } else if (is_file(java_home, "jre/lib/" CPU "/libjava.so")) { type = "server"; strcat(newpath, java_home); strcat(newpath, "/jre/lib/" CPU ":"); strcat(newpath, java_home); strcat(newpath, "/jre/lib/" CPU "/"); strcat(newpath, type); strcat(newpath, ":"); strcat(newpath, java_home); strcat(newpath, "/jre/lib/" CPU "/native_threads"); strcat(newpath, ":"); strcat(newpath, java_home); strcat(newpath, "/jre/lib/" CPU "/classic"); strcat(newpath, ":"); } else { fprintf(stderr, "can't use JAVA_HOME=%s\n", java_home); exit(1); } if (getenv("LD_LIBRARY_PATH")) strcat(newpath, getenv("LD_LIBRARY_PATH")); strcpy(envpath, "LD_LIBRARY_PATH="); strcat(envpath, newpath); putenv(strdup(envpath));}voidsetEnvVars(char *java_home){ char newpath[8192]; char *p; char *buffer = newpath; /* Now add our locale files to the beginning of XFILESEARCHPATH */ strcpy(buffer, "XFILESEARCHPATH="); strcat(buffer, java_home); strcat(buffer, "/jre/lib/locale/%L/%T/%N%S:"); p = getenv("XFILESEARCHPATH"); if (p != NULL) { strcat(buffer, p); } putenv(strdup(buffer));}int cse_test() { return 666; }static intcreate_vm(JavaVM **p_vm, void **env, JavaVMInitArgs *vm_args){ void *handle; int (*p_create_vm) (JavaVM **, void **, JavaVMInitArgs *); handle = dlopen("libjvm.so", RTLD_LAZY); if (! handle) { fprintf(stderr, "%s\n", dlerror()); exit(1); } p_create_vm = dlsym(handle, "JNI_CreateJavaVM"); if (! p_create_vm) { fprintf(stderr, "can't find JNI_CreateJavaVM\n"); exit(1); } return p_create_vm(p_vm, env, vm_args);}/** * Parses the command-line arguments */static voidparse_command_line(int argc, char **argv){ int i; for (i = 1; i < argc; i++) { if (! strcmp(argv[i], "-java_home") || ! strcmp(argv[i], "-java-home")) { g_options.java_home = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-resin_home") || ! strcmp(argv[i], "-resin-home")) { g_options.resin_home = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-conf") || ! strcmp(argv[i], "-conf")) { g_options.conf = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-classpath") || ! strcmp(argv[i], "-cp")) { g_options.classpath = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-loadpath") || ! strcmp(argv[i], "-lp")) { g_options.loadpath = strdup(argv[i + 1]); i++; } else if (! strncmp(argv[i], "-D", 2) || ! strncmp(argv[i], "-X", 2)) { add_jvm_option("%s", argv[i]); } else if (! strcmp(argv[i], "-stdout")) { g_options.stdout_path = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-stderr")) { g_options.stderr_path = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-pid")) { g_options.pid = strdup(argv[i + 1]); i++; } else if (! strcmp(argv[i], "-verbose")) { g_options.verbose = 1; } else if (! strcmp(argv[i], "start")) { g_options.start = 1; } else if (! strcmp(argv[i], "stop")) { g_options.stop = 1; } else if (! strcmp(argv[i], "restart")) { g_options.restart = 1; } }}/** * unwinds a linked path, returning the original directory. */static char *unwind_link(char *path, char *test_tail){ struct stat st; int tail = 0; path = strdup(path); while ((! lstat(path, &st)) && S_ISLNK(st.st_mode)) { char buf[8192]; readlink(path, buf, sizeof(buf)); path = strdup(buf); } for (tail = strlen(path); tail >= 0; tail--) { if (path[tail] == '/') { path[tail] = 0; if (is_file(path, test_tail)) { return path; } } } return 0;}/** * Finds a link in a classpath-like path */static char *find_link_in_path(char *path, char *test_tail, char *exe){ char *head; char *tail = 0; for (head = path; head && *head; head = tail) { char buf[8192]; struct stat st; tail = strchr(head, ':'); if (tail) { *tail = 0; tail++; } sprintf(buf, "%s/%s", head, exe); if (! stat(buf, &st)) { char *dir = unwind_link(buf, test_tail); if (dir) return dir; } } return 0;}/** * Finds the value of java_home * * 1) command-line * 2) getenv("JAVA_HOME") * 3) find by searching back the "java" command * 4) trying /usr/java */static voidfind_java_home(){ char *java_home; char *path; if (g_options.java_home) return; if ((java_home = getenv("JAVA_HOME"))) { g_options.java_home = strdup(java_home); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -