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