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 #include <crt_externs.h>
00053 #undef environ
00054 #define environ (*_NSGetEnviron())
00055 #endif
00056
00057 #define SPT_NONE 0
00058 #define SPT_PSTAT 1
00059 #define SPT_REUSEARGV 2
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
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
00089
00090
00091
00092
00093 if (argc == 0 || argv[0] == NULL)
00094 return;
00095
00096
00097 for (i = 0; envp[i] != NULL; i++)
00098 ;
00099 if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
00100 environ = envp;
00101 return;
00102 }
00103
00104
00105
00106
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
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
00164 }
00165
00166 #endif
00167