This source file includes following definitions.
- save_ps_args
- is_ps_title_available
- ps_title_errno
- set_ps_title
- get_ps_title
- cleanup_ps_args
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include "ps_title.h"
32 #include <stdio.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <string.h>
39 #include <stdlib.h>
40
41 #ifdef PHP_WIN32
42 #include "config.w32.h"
43 #include <windows.h>
44 #include <process.h>
45 #else
46 #include "php_config.h"
47 extern char** environ;
48 #endif
49
50 #ifdef HAVE_SYS_PSTAT_H
51 #include <sys/pstat.h>
52 #endif
53 #ifdef HAVE_PS_STRINGS
54 #include <machine/vmparam.h>
55 #include <sys/exec.h>
56 #endif
57 #if defined(DARWIN)
58 #include <crt_externs.h>
59 #endif
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 #if defined(HAVE_SETPROCTITLE)
86 #define PS_USE_SETPROCTITLE
87 #elif defined(HAVE_SYS_PSTAT_H) && defined(PSTAT_SETCMD)
88 #define PS_USE_PSTAT
89 #elif defined(HAVE_PS_STRINGS)
90 #define PS_USE_PS_STRINGS
91 #elif defined(BSD) && !defined(DARWIN)
92 #define PS_USE_CHANGE_ARGV
93 #elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__osf__) || defined(DARWIN)
94 #define PS_USE_CLOBBER_ARGV
95 #elif defined(PHP_WIN32)
96 #define PS_USE_WIN32
97 #else
98 #define PS_USE_NONE
99 #endif
100
101
102 #if defined(_AIX) || defined(__linux__) || defined(DARWIN)
103 #define PS_PADDING '\0'
104 #else
105 #define PS_PADDING ' '
106 #endif
107
108 #ifdef PS_USE_WIN32
109 static char windows_error_details[64];
110 static char ps_buffer[MAX_PATH];
111 static const size_t ps_buffer_size = MAX_PATH;
112 #elif defined(PS_USE_CLOBBER_ARGV)
113 static char *ps_buffer;
114 static size_t ps_buffer_size;
115 static char *empty_environ[] = {0};
116 #else
117 #define PS_BUFFER_SIZE 256
118 static char ps_buffer[PS_BUFFER_SIZE];
119 static const size_t ps_buffer_size = PS_BUFFER_SIZE;
120 #endif
121
122 static size_t ps_buffer_cur_len;
123
124
125 static int save_argc;
126 static char** save_argv;
127
128
129
130
131
132 static char** frozen_environ, **new_environ;
133
134
135
136
137
138
139
140
141 char** save_ps_args(int argc, char** argv)
142 {
143 save_argc = argc;
144 save_argv = argv;
145
146 #if defined(PS_USE_CLOBBER_ARGV)
147
148
149
150
151 {
152 char* end_of_area = NULL;
153 int non_contiguous_area = 0;
154 int i;
155
156
157
158
159 for (i = 0; (non_contiguous_area == 0) && (i < argc); i++)
160 {
161 if (i != 0 && end_of_area + 1 != argv[i])
162 non_contiguous_area = 1;
163 end_of_area = argv[i] + strlen(argv[i]);
164 }
165
166
167
168
169 for (i = 0; (non_contiguous_area == 0) && (environ[i] != NULL); i++)
170 {
171 if (end_of_area + 1 != environ[i])
172 non_contiguous_area = 1;
173 end_of_area = environ[i] + strlen(environ[i]);
174 }
175
176 if (non_contiguous_area != 0)
177 goto clobber_error;
178
179 ps_buffer = argv[0];
180 ps_buffer_size = end_of_area - argv[0];
181
182
183
184
185 new_environ = (char **) malloc((i + 1) * sizeof(char *));
186 frozen_environ = (char **) malloc((i + 1) * sizeof(char *));
187 if (!new_environ || !frozen_environ)
188 goto clobber_error;
189 for (i = 0; environ[i] != NULL; i++)
190 {
191 new_environ[i] = strdup(environ[i]);
192 if (!new_environ[i])
193 goto clobber_error;
194 }
195 new_environ[i] = NULL;
196 environ = new_environ;
197 memcpy((char *)frozen_environ, (char *)new_environ, sizeof(char *) * (i + 1));
198
199 }
200 #endif
201
202 #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
203
204
205
206
207
208
209
210
211
212
213 {
214 char** new_argv;
215 int i;
216
217 new_argv = (char **) malloc((argc + 1) * sizeof(char *));
218 if (!new_argv)
219 goto clobber_error;
220 for (i = 0; i < argc; i++)
221 {
222 new_argv[i] = strdup(argv[i]);
223 if (!new_argv[i])
224 goto clobber_error;
225 }
226 new_argv[argc] = NULL;
227
228 #if defined(DARWIN)
229
230
231
232
233 *_NSGetArgv() = new_argv;
234 #endif
235
236 argv = new_argv;
237
238 }
239 #endif
240
241 #if defined(PS_USE_CLOBBER_ARGV)
242 {
243
244 int i;
245 for (i = 1; i < save_argc; i++)
246 save_argv[i] = ps_buffer + ps_buffer_size;
247 }
248 #endif
249
250 #ifdef PS_USE_CHANGE_ARGV
251 save_argv[0] = ps_buffer;
252 save_argv[1] = NULL;
253 #endif
254
255 return argv;
256
257 #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
258 clobber_error:
259
260
261
262
263 save_argv = NULL;
264 save_argc = 0;
265 ps_buffer = NULL;
266 ps_buffer_size = 0;
267 return argv;
268 #endif
269 }
270
271
272
273
274
275
276 int is_ps_title_available()
277 {
278 #ifdef PS_USE_NONE
279 return PS_TITLE_NOT_AVAILABLE;
280 #endif
281
282 if (!save_argv)
283 return PS_TITLE_NOT_INITIALIZED;
284
285 #ifdef PS_USE_CLOBBER_ARGV
286 if (!ps_buffer)
287 return PS_TITLE_BUFFER_NOT_AVAILABLE;
288 #endif
289
290 return PS_TITLE_SUCCESS;
291 }
292
293
294
295
296 const char* ps_title_errno(int rc)
297 {
298 switch(rc)
299 {
300 case PS_TITLE_SUCCESS:
301 return "Success";
302
303 case PS_TITLE_NOT_AVAILABLE:
304 return "Not available on this OS";
305
306 case PS_TITLE_NOT_INITIALIZED:
307 return "Not initialized correctly";
308
309 case PS_TITLE_BUFFER_NOT_AVAILABLE:
310 return "Buffer not contiguous";
311
312 #ifdef PS_USE_WIN32
313 case PS_TITLE_WINDOWS_ERROR:
314 sprintf(windows_error_details, "Windows error code: %d", GetLastError());
315 return windows_error_details;
316 #endif
317 }
318
319 return "Unknown error code";
320 }
321
322
323
324
325
326
327
328
329 int set_ps_title(const char* title)
330 {
331 int rc = is_ps_title_available();
332 if (rc != PS_TITLE_SUCCESS)
333 return rc;
334
335 strncpy(ps_buffer, title, ps_buffer_size);
336 ps_buffer[ps_buffer_size - 1] = '\0';
337 ps_buffer_cur_len = strlen(ps_buffer);
338
339 #ifdef PS_USE_SETPROCTITLE
340 setproctitle("%s", ps_buffer);
341 #endif
342
343 #ifdef PS_USE_PSTAT
344 {
345 union pstun pst;
346
347 pst.pst_command = ps_buffer;
348 pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
349 }
350 #endif
351
352 #ifdef PS_USE_PS_STRINGS
353 PS_STRINGS->ps_nargvstr = 1;
354 PS_STRINGS->ps_argvstr = ps_buffer;
355 #endif
356
357 #ifdef PS_USE_CLOBBER_ARGV
358
359 if (ps_buffer_cur_len < ps_buffer_size)
360 {
361 memset(ps_buffer + ps_buffer_cur_len, PS_PADDING,
362 ps_buffer_size - ps_buffer_cur_len);
363 }
364 #endif
365
366 #ifdef PS_USE_WIN32
367 {
368 if (!SetConsoleTitle(ps_buffer))
369 return PS_TITLE_WINDOWS_ERROR;
370 }
371 #endif
372
373 return PS_TITLE_SUCCESS;
374 }
375
376
377
378
379
380
381
382 int get_ps_title(int *displen, const char** string)
383 {
384 int rc = is_ps_title_available();
385 if (rc != PS_TITLE_SUCCESS)
386 return rc;
387
388 #ifdef PS_USE_WIN32
389 if (!(ps_buffer_cur_len = GetConsoleTitle(ps_buffer, ps_buffer_size)))
390 return PS_TITLE_WINDOWS_ERROR;
391 #endif
392 *displen = (int)ps_buffer_cur_len;
393 *string = ps_buffer;
394 return PS_TITLE_SUCCESS;
395 }
396
397
398
399
400
401
402
403
404 void cleanup_ps_args(char **argv)
405 {
406 #ifndef PS_USE_NONE
407 if (save_argv)
408 {
409 save_argv = NULL;
410 save_argc = 0;
411
412 #ifdef PS_USE_CLOBBER_ARGV
413 {
414 int i;
415 for (i = 0; frozen_environ[i] != NULL; i++)
416 free(frozen_environ[i]);
417 free(frozen_environ);
418 free(new_environ);
419
420
421 environ = empty_environ;
422 }
423 #endif
424
425 #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
426 {
427 int i;
428 for (i=0; argv[i] != NULL; i++)
429 free(argv[i]);
430 free(argv);
431 }
432 #endif
433 }
434 #endif
435
436 return;
437 }