00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00062 #define SPT_PSTAT 1
00063 #define SPT_REUSEARGV 2
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
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
00093
00094
00095
00096
00097 if (argc == 0 || argv[0] == NULL)
00098 return;
00099
00100
00101 for (i = 0; envp[i] != NULL; i++)
00102 ;
00103 if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
00104 environ = envp;
00105 return;
00106 }
00107
00108
00109
00110
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
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
00168 }
00169
00170 #endif
00171