|
Ruby
1.9.3p448(2013-06-27revision41675)
|
00001 /* Based on setproctitle.c from openssh-5.6p1 */ 00002 /* Based on conf.c from UCB sendmail 8.8.8 */ 00003 00004 /* 00005 * Copyright 2003 Damien Miller 00006 * Copyright (c) 1983, 1995-1997 Eric P. Allman 00007 * Copyright (c) 1988, 1993 00008 * The Regents of the University of California. All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 1. Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * 3. Neither the name of the University nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 */ 00034 00035 #include "ruby.h" 00036 #include "ruby/util.h" 00037 #define compat_init_setproctitle ruby_init_setproctitle 00038 00039 #ifndef HAVE_SETPROCTITLE 00040 00041 #include <stdarg.h> 00042 #include <stdlib.h> 00043 #ifdef HAVE_UNISTD_H 00044 #include <unistd.h> 00045 #endif 00046 #ifdef HAVE_SYS_PSTAT_H 00047 #include <sys/pstat.h> 00048 #endif 00049 #include <string.h> 00050 00051 #if defined(__APPLE__) 00052 #include <crt_externs.h> 00053 #undef environ 00054 #define environ (*_NSGetEnviron()) 00055 #endif 00056 00057 #define SPT_NONE 0 /* don't use it at all */ 00058 #define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ 00059 #define SPT_REUSEARGV 2 /* cover argv with title information */ 00060 00061 #ifndef SPT_TYPE 00062 # define SPT_TYPE SPT_NONE 00063 #endif 00064 00065 #ifndef SPT_PADCHAR 00066 # define SPT_PADCHAR '\0' 00067 #endif 00068 00069 #if SPT_TYPE == SPT_REUSEARGV 00070 static char *argv_start = NULL; 00071 static size_t argv_env_len = 0; 00072 static size_t argv_len = 0; 00073 #endif 00074 00075 #endif /* HAVE_SETPROCTITLE */ 00076 00077 void 00078 compat_init_setproctitle(int argc, char *argv[]) 00079 { 00080 #if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV 00081 extern char **environ; 00082 char *lastargv = NULL; 00083 char *lastenvp = NULL; 00084 char **envp = environ; 00085 int i; 00086 00087 /* 00088 * NB: This assumes that argv has already been copied out of the 00089 * way. This is true for sshd, but may not be true for other 00090 * programs. Beware. 00091 */ 00092 00093 if (argc == 0 || argv[0] == NULL) 00094 return; 00095 00096 /* Fail if we can't allocate room for the new environment */ 00097 for (i = 0; envp[i] != NULL; i++) 00098 ; 00099 if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { 00100 environ = envp; /* put it back */ 00101 return; 00102 } 00103 00104 /* 00105 * Find the last argv string or environment variable within 00106 * our process memory area. 00107 */ 00108 for (i = 0; i < argc; i++) { 00109 if (lastargv == NULL || lastargv + 1 == argv[i]) 00110 lastargv = argv[i] + strlen(argv[i]); 00111 } 00112 lastenvp = lastargv; 00113 for (i = 0; envp[i] != NULL; i++) { 00114 if (lastenvp + 1 == envp[i]) 00115 lastenvp = envp[i] + strlen(envp[i]); 00116 } 00117 00118 argv[1] = NULL; 00119 argv_start = argv[0]; 00120 argv_len = lastargv - argv[0]; 00121 argv_env_len = lastenvp - argv[0]; 00122 00123 for (i = 0; envp[i] != NULL; i++) 00124 environ[i] = ruby_strdup(envp[i]); 00125 environ[i] = NULL; 00126 #endif /* SPT_REUSEARGV */ 00127 } 00128 00129 #ifndef HAVE_SETPROCTITLE 00130 void 00131 setproctitle(const char *fmt, ...) 00132 { 00133 #if SPT_TYPE != SPT_NONE 00134 va_list ap; 00135 char ptitle[1024]; 00136 size_t len; 00137 size_t argvlen; 00138 #if SPT_TYPE == SPT_PSTAT 00139 union pstun pst; 00140 #endif 00141 00142 #if SPT_TYPE == SPT_REUSEARGV 00143 if (argv_env_len <= 0) 00144 return; 00145 #endif 00146 00147 va_start(ap, fmt); 00148 if (fmt != NULL) { 00149 vsnprintf(ptitle, sizeof(ptitle) , fmt, ap); 00150 } 00151 va_end(ap); 00152 00153 #if SPT_TYPE == SPT_PSTAT 00154 pst.pst_command = ptitle; 00155 pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); 00156 #elif SPT_TYPE == SPT_REUSEARGV 00157 len = strlcpy(argv_start, ptitle, argv_env_len); 00158 argvlen = len > argv_len ? argv_env_len : argv_len; 00159 for(; len < argvlen; len++) 00160 argv_start[len] = SPT_PADCHAR; 00161 #endif 00162 00163 #endif /* SPT_NONE */ 00164 } 00165 00166 #endif /* HAVE_SETPROCTITLE */ 00167
1.7.6.1