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 #define SPT_NONE 0
00052 #define SPT_PSTAT 1
00053 #define SPT_REUSEARGV 2
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
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
00083
00084
00085
00086
00087 if (argc == 0 || argv[0] == NULL)
00088 return;
00089
00090
00091 for (i = 0; envp[i] != NULL; i++)
00092 ;
00093 if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
00094 environ = envp;
00095 return;
00096 }
00097
00098
00099
00100
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
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
00158 }
00159
00160 #endif
00161