Ruby
2.0.0p247(2013-06-27revision41674)
|
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 # ifdef HAVE_CRT_EXTERNS_H 00053 # include <crt_externs.h> 00054 # undef environ 00055 # define environ (*_NSGetEnviron()) 00056 # else 00057 # include "crt_externs.h" 00058 # endif 00059 #endif 00060 00061 #define SPT_NONE 0 /* don't use it at all */ 00062 #define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ 00063 #define SPT_REUSEARGV 2 /* cover argv with title information */ 00064 00065 #ifndef SPT_TYPE 00066 # define SPT_TYPE SPT_NONE 00067 #endif 00068 00069 #ifndef SPT_PADCHAR 00070 # define SPT_PADCHAR '\0' 00071 #endif 00072 00073 #if SPT_TYPE == SPT_REUSEARGV 00074 static char *argv_start = NULL; 00075 static size_t argv_env_len = 0; 00076 static size_t argv_len = 0; 00077 #endif 00078 00079 #endif /* HAVE_SETPROCTITLE */ 00080 00081 void 00082 compat_init_setproctitle(int argc, char *argv[]) 00083 { 00084 #if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV 00085 extern char **environ; 00086 char *lastargv = NULL; 00087 char *lastenvp = NULL; 00088 char **envp = environ; 00089 int i; 00090 00091 /* 00092 * NB: This assumes that argv has already been copied out of the 00093 * way. This is true for sshd, but may not be true for other 00094 * programs. Beware. 00095 */ 00096 00097 if (argc == 0 || argv[0] == NULL) 00098 return; 00099 00100 /* Fail if we can't allocate room for the new environment */ 00101 for (i = 0; envp[i] != NULL; i++) 00102 ; 00103 if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { 00104 environ = envp; /* put it back */ 00105 return; 00106 } 00107 00108 /* 00109 * Find the last argv string or environment variable within 00110 * our process memory area. 00111 */ 00112 for (i = 0; i < argc; i++) { 00113 if (lastargv == NULL || lastargv + 1 == argv[i]) 00114 lastargv = argv[i] + strlen(argv[i]); 00115 } 00116 lastenvp = lastargv; 00117 for (i = 0; envp[i] != NULL; i++) { 00118 if (lastenvp + 1 == envp[i]) 00119 lastenvp = envp[i] + strlen(envp[i]); 00120 } 00121 00122 argv[1] = NULL; 00123 argv_start = argv[0]; 00124 argv_len = lastargv - argv[0]; 00125 argv_env_len = lastenvp - argv[0]; 00126 00127 for (i = 0; envp[i] != NULL; i++) 00128 environ[i] = ruby_strdup(envp[i]); 00129 environ[i] = NULL; 00130 #endif /* SPT_REUSEARGV */ 00131 } 00132 00133 #ifndef HAVE_SETPROCTITLE 00134 void 00135 setproctitle(const char *fmt, ...) 00136 { 00137 #if SPT_TYPE != SPT_NONE 00138 va_list ap; 00139 char ptitle[1024]; 00140 size_t len; 00141 size_t argvlen; 00142 #if SPT_TYPE == SPT_PSTAT 00143 union pstun pst; 00144 #endif 00145 00146 #if SPT_TYPE == SPT_REUSEARGV 00147 if (argv_env_len <= 0) 00148 return; 00149 #endif 00150 00151 va_start(ap, fmt); 00152 if (fmt != NULL) { 00153 vsnprintf(ptitle, sizeof(ptitle) , fmt, ap); 00154 } 00155 va_end(ap); 00156 00157 #if SPT_TYPE == SPT_PSTAT 00158 pst.pst_command = ptitle; 00159 pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); 00160 #elif SPT_TYPE == SPT_REUSEARGV 00161 len = strlcpy(argv_start, ptitle, argv_env_len); 00162 argvlen = len > argv_len ? argv_env_len : argv_len; 00163 for(; len < argvlen; len++) 00164 argv_start[len] = SPT_PADCHAR; 00165 #endif 00166 00167 #endif /* SPT_NONE */ 00168 } 00169 00170 #endif /* HAVE_SETPROCTITLE */ 00171