This source file includes following definitions.
- ZEND_GET_MODULE
- php_pcntl_register_errno_constants
- PHP_GINIT_FUNCTION
- PHP_RINIT_FUNCTION
- PHP_MINIT_FUNCTION
- PHP_MSHUTDOWN_FUNCTION
- PHP_RSHUTDOWN_FUNCTION
- PHP_MINFO_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- pcntl_sigwaitinfo
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- pcntl_signal_handler
- pcntl_signal_dispatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #define PCNTL_DEBUG 0
22
23 #if PCNTL_DEBUG
24 #define DEBUG_OUT printf("DEBUG: ");printf
25 #define IF_DEBUG(z) z
26 #else
27 #define IF_DEBUG(z)
28 #endif
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "php.h"
35 #include "php_ini.h"
36 #include "ext/standard/info.h"
37 #include "php_pcntl.h"
38 #include "php_signal.h"
39 #include "php_ticks.h"
40
41 #if HAVE_GETPRIORITY || HAVE_SETPRIORITY || HAVE_WAIT3
42 #include <sys/wait.h>
43 #include <sys/time.h>
44 #include <sys/resource.h>
45 #endif
46
47 #include <errno.h>
48
49 ZEND_DECLARE_MODULE_GLOBALS(pcntl)
50 static PHP_GINIT_FUNCTION(pcntl);
51
52
53 ZEND_BEGIN_ARG_INFO(arginfo_pcntl_void, 0)
54 ZEND_END_ARG_INFO()
55
56 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_waitpid, 0, 0, 2)
57 ZEND_ARG_INFO(0, pid)
58 ZEND_ARG_INFO(1, status)
59 ZEND_ARG_INFO(0, options)
60 ZEND_ARG_INFO(1, rusage)
61 ZEND_END_ARG_INFO()
62
63 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wait, 0, 0, 1)
64 ZEND_ARG_INFO(1, status)
65 ZEND_ARG_INFO(0, options)
66 ZEND_ARG_INFO(1, rusage)
67 ZEND_END_ARG_INFO()
68
69 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_signal, 0, 0, 2)
70 ZEND_ARG_INFO(0, signo)
71 ZEND_ARG_INFO(0, handler)
72 ZEND_ARG_INFO(0, restart_syscalls)
73 ZEND_END_ARG_INFO()
74
75 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigprocmask, 0, 0, 2)
76 ZEND_ARG_INFO(0, how)
77 ZEND_ARG_INFO(0, set)
78 ZEND_ARG_INFO(1, oldset)
79 ZEND_END_ARG_INFO()
80
81 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigwaitinfo, 0, 0, 1)
82 ZEND_ARG_INFO(0, set)
83 ZEND_ARG_INFO(1, info)
84 ZEND_END_ARG_INFO()
85
86 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_sigtimedwait, 0, 0, 1)
87 ZEND_ARG_INFO(0, set)
88 ZEND_ARG_INFO(1, info)
89 ZEND_ARG_INFO(0, seconds)
90 ZEND_ARG_INFO(0, nanoseconds)
91 ZEND_END_ARG_INFO()
92
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifexited, 0, 0, 1)
94 ZEND_ARG_INFO(0, status)
95 ZEND_END_ARG_INFO()
96
97 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifstopped, 0, 0, 1)
98 ZEND_ARG_INFO(0, status)
99 ZEND_END_ARG_INFO()
100
101 #ifdef HAVE_WCONTINUED
102 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifcontinued, 0, 0, 1)
103 ZEND_ARG_INFO(0, status)
104 ZEND_END_ARG_INFO()
105 #endif
106
107 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifsignaled, 0, 0, 1)
108 ZEND_ARG_INFO(0, status)
109 ZEND_END_ARG_INFO()
110
111 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wifexitstatus, 0, 0, 1)
112 ZEND_ARG_INFO(0, status)
113 ZEND_END_ARG_INFO()
114
115 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wtermsig, 0, 0, 1)
116 ZEND_ARG_INFO(0, status)
117 ZEND_END_ARG_INFO()
118
119 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_wstopsig, 0, 0, 1)
120 ZEND_ARG_INFO(0, status)
121 ZEND_END_ARG_INFO()
122
123 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_exec, 0, 0, 1)
124 ZEND_ARG_INFO(0, path)
125 ZEND_ARG_INFO(0, args)
126 ZEND_ARG_INFO(0, envs)
127 ZEND_END_ARG_INFO()
128
129 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_alarm, 0, 0, 1)
130 ZEND_ARG_INFO(0, seconds)
131 ZEND_END_ARG_INFO()
132
133 #ifdef HAVE_GETPRIORITY
134 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_getpriority, 0, 0, 0)
135 ZEND_ARG_INFO(0, pid)
136 ZEND_ARG_INFO(0, process_identifier)
137 ZEND_END_ARG_INFO()
138 #endif
139
140 #ifdef HAVE_SETPRIORITY
141 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_setpriority, 0, 0, 1)
142 ZEND_ARG_INFO(0, priority)
143 ZEND_ARG_INFO(0, pid)
144 ZEND_ARG_INFO(0, process_identifier)
145 ZEND_END_ARG_INFO()
146 #endif
147
148 ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_strerror, 0, 0, 1)
149 ZEND_ARG_INFO(0, errno)
150 ZEND_END_ARG_INFO()
151
152
153 const zend_function_entry pcntl_functions[] = {
154 PHP_FE(pcntl_fork, arginfo_pcntl_void)
155 PHP_FE(pcntl_waitpid, arginfo_pcntl_waitpid)
156 PHP_FE(pcntl_wait, arginfo_pcntl_wait)
157 PHP_FE(pcntl_signal, arginfo_pcntl_signal)
158 PHP_FE(pcntl_signal_dispatch, arginfo_pcntl_void)
159 PHP_FE(pcntl_wifexited, arginfo_pcntl_wifexited)
160 PHP_FE(pcntl_wifstopped, arginfo_pcntl_wifstopped)
161 PHP_FE(pcntl_wifsignaled, arginfo_pcntl_wifsignaled)
162 PHP_FE(pcntl_wexitstatus, arginfo_pcntl_wifexitstatus)
163 PHP_FE(pcntl_wtermsig, arginfo_pcntl_wtermsig)
164 PHP_FE(pcntl_wstopsig, arginfo_pcntl_wstopsig)
165 PHP_FE(pcntl_exec, arginfo_pcntl_exec)
166 PHP_FE(pcntl_alarm, arginfo_pcntl_alarm)
167 PHP_FE(pcntl_get_last_error, arginfo_pcntl_void)
168 PHP_FALIAS(pcntl_errno, pcntl_get_last_error, NULL)
169 PHP_FE(pcntl_strerror, arginfo_pcntl_strerror)
170 #ifdef HAVE_GETPRIORITY
171 PHP_FE(pcntl_getpriority, arginfo_pcntl_getpriority)
172 #endif
173 #ifdef HAVE_SETPRIORITY
174 PHP_FE(pcntl_setpriority, arginfo_pcntl_setpriority)
175 #endif
176 #ifdef HAVE_SIGPROCMASK
177 PHP_FE(pcntl_sigprocmask, arginfo_pcntl_sigprocmask)
178 #endif
179 #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
180 PHP_FE(pcntl_sigwaitinfo, arginfo_pcntl_sigwaitinfo)
181 PHP_FE(pcntl_sigtimedwait, arginfo_pcntl_sigtimedwait)
182 #endif
183 #ifdef HAVE_WCONTINUED
184 PHP_FE(pcntl_wifcontinued, arginfo_pcntl_wifcontinued)
185 #endif
186 PHP_FE_END
187 };
188
189 zend_module_entry pcntl_module_entry = {
190 STANDARD_MODULE_HEADER,
191 "pcntl",
192 pcntl_functions,
193 PHP_MINIT(pcntl),
194 PHP_MSHUTDOWN(pcntl),
195 PHP_RINIT(pcntl),
196 PHP_RSHUTDOWN(pcntl),
197 PHP_MINFO(pcntl),
198 PHP_PCNTL_VERSION,
199 PHP_MODULE_GLOBALS(pcntl),
200 PHP_GINIT(pcntl),
201 NULL,
202 NULL,
203 STANDARD_MODULE_PROPERTIES_EX
204 };
205
206 #ifdef COMPILE_DL_PCNTL
207 ZEND_GET_MODULE(pcntl)
208 #endif
209
210 static void pcntl_signal_handler(int);
211 static void pcntl_signal_dispatch();
212
213 void php_register_signal_constants(INIT_FUNC_ARGS)
214 {
215
216
217 #ifdef WNOHANG
218 REGISTER_LONG_CONSTANT("WNOHANG", (zend_long) WNOHANG, CONST_CS | CONST_PERSISTENT);
219 #endif
220 #ifdef WUNTRACED
221 REGISTER_LONG_CONSTANT("WUNTRACED", (zend_long) WUNTRACED, CONST_CS | CONST_PERSISTENT);
222 #endif
223 #ifdef HAVE_WCONTINUED
224 REGISTER_LONG_CONSTANT("WCONTINUED", (zend_long) WCONTINUED, CONST_CS | CONST_PERSISTENT);
225 #endif
226
227
228 REGISTER_LONG_CONSTANT("SIG_IGN", (zend_long) SIG_IGN, CONST_CS | CONST_PERSISTENT);
229 REGISTER_LONG_CONSTANT("SIG_DFL", (zend_long) SIG_DFL, CONST_CS | CONST_PERSISTENT);
230 REGISTER_LONG_CONSTANT("SIG_ERR", (zend_long) SIG_ERR, CONST_CS | CONST_PERSISTENT);
231 REGISTER_LONG_CONSTANT("SIGHUP", (zend_long) SIGHUP, CONST_CS | CONST_PERSISTENT);
232 REGISTER_LONG_CONSTANT("SIGINT", (zend_long) SIGINT, CONST_CS | CONST_PERSISTENT);
233 REGISTER_LONG_CONSTANT("SIGQUIT", (zend_long) SIGQUIT, CONST_CS | CONST_PERSISTENT);
234 REGISTER_LONG_CONSTANT("SIGILL", (zend_long) SIGILL, CONST_CS | CONST_PERSISTENT);
235 REGISTER_LONG_CONSTANT("SIGTRAP", (zend_long) SIGTRAP, CONST_CS | CONST_PERSISTENT);
236 REGISTER_LONG_CONSTANT("SIGABRT", (zend_long) SIGABRT, CONST_CS | CONST_PERSISTENT);
237 #ifdef SIGIOT
238 REGISTER_LONG_CONSTANT("SIGIOT", (zend_long) SIGIOT, CONST_CS | CONST_PERSISTENT);
239 #endif
240 REGISTER_LONG_CONSTANT("SIGBUS", (zend_long) SIGBUS, CONST_CS | CONST_PERSISTENT);
241 REGISTER_LONG_CONSTANT("SIGFPE", (zend_long) SIGFPE, CONST_CS | CONST_PERSISTENT);
242 REGISTER_LONG_CONSTANT("SIGKILL", (zend_long) SIGKILL, CONST_CS | CONST_PERSISTENT);
243 REGISTER_LONG_CONSTANT("SIGUSR1", (zend_long) SIGUSR1, CONST_CS | CONST_PERSISTENT);
244 REGISTER_LONG_CONSTANT("SIGSEGV", (zend_long) SIGSEGV, CONST_CS | CONST_PERSISTENT);
245 REGISTER_LONG_CONSTANT("SIGUSR2", (zend_long) SIGUSR2, CONST_CS | CONST_PERSISTENT);
246 REGISTER_LONG_CONSTANT("SIGPIPE", (zend_long) SIGPIPE, CONST_CS | CONST_PERSISTENT);
247 REGISTER_LONG_CONSTANT("SIGALRM", (zend_long) SIGALRM, CONST_CS | CONST_PERSISTENT);
248 REGISTER_LONG_CONSTANT("SIGTERM", (zend_long) SIGTERM, CONST_CS | CONST_PERSISTENT);
249 #ifdef SIGSTKFLT
250 REGISTER_LONG_CONSTANT("SIGSTKFLT",(zend_long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT);
251 #endif
252 #ifdef SIGCLD
253 REGISTER_LONG_CONSTANT("SIGCLD", (zend_long) SIGCLD, CONST_CS | CONST_PERSISTENT);
254 #endif
255 #ifdef SIGCHLD
256 REGISTER_LONG_CONSTANT("SIGCHLD", (zend_long) SIGCHLD, CONST_CS | CONST_PERSISTENT);
257 #endif
258 REGISTER_LONG_CONSTANT("SIGCONT", (zend_long) SIGCONT, CONST_CS | CONST_PERSISTENT);
259 REGISTER_LONG_CONSTANT("SIGSTOP", (zend_long) SIGSTOP, CONST_CS | CONST_PERSISTENT);
260 REGISTER_LONG_CONSTANT("SIGTSTP", (zend_long) SIGTSTP, CONST_CS | CONST_PERSISTENT);
261 REGISTER_LONG_CONSTANT("SIGTTIN", (zend_long) SIGTTIN, CONST_CS | CONST_PERSISTENT);
262 REGISTER_LONG_CONSTANT("SIGTTOU", (zend_long) SIGTTOU, CONST_CS | CONST_PERSISTENT);
263 REGISTER_LONG_CONSTANT("SIGURG", (zend_long) SIGURG , CONST_CS | CONST_PERSISTENT);
264 REGISTER_LONG_CONSTANT("SIGXCPU", (zend_long) SIGXCPU, CONST_CS | CONST_PERSISTENT);
265 REGISTER_LONG_CONSTANT("SIGXFSZ", (zend_long) SIGXFSZ, CONST_CS | CONST_PERSISTENT);
266 REGISTER_LONG_CONSTANT("SIGVTALRM",(zend_long) SIGVTALRM, CONST_CS | CONST_PERSISTENT);
267 REGISTER_LONG_CONSTANT("SIGPROF", (zend_long) SIGPROF, CONST_CS | CONST_PERSISTENT);
268 REGISTER_LONG_CONSTANT("SIGWINCH", (zend_long) SIGWINCH, CONST_CS | CONST_PERSISTENT);
269 #ifdef SIGPOLL
270 REGISTER_LONG_CONSTANT("SIGPOLL", (zend_long) SIGPOLL, CONST_CS | CONST_PERSISTENT);
271 #endif
272 REGISTER_LONG_CONSTANT("SIGIO", (zend_long) SIGIO, CONST_CS | CONST_PERSISTENT);
273 #ifdef SIGPWR
274 REGISTER_LONG_CONSTANT("SIGPWR", (zend_long) SIGPWR, CONST_CS | CONST_PERSISTENT);
275 #endif
276 #ifdef SIGSYS
277 REGISTER_LONG_CONSTANT("SIGSYS", (zend_long) SIGSYS, CONST_CS | CONST_PERSISTENT);
278 REGISTER_LONG_CONSTANT("SIGBABY", (zend_long) SIGSYS, CONST_CS | CONST_PERSISTENT);
279 #endif
280
281 #if HAVE_GETPRIORITY || HAVE_SETPRIORITY
282 REGISTER_LONG_CONSTANT("PRIO_PGRP", PRIO_PGRP, CONST_CS | CONST_PERSISTENT);
283 REGISTER_LONG_CONSTANT("PRIO_USER", PRIO_USER, CONST_CS | CONST_PERSISTENT);
284 REGISTER_LONG_CONSTANT("PRIO_PROCESS", PRIO_PROCESS, CONST_CS | CONST_PERSISTENT);
285 #endif
286
287
288 #ifdef HAVE_SIGPROCMASK
289 REGISTER_LONG_CONSTANT("SIG_BLOCK", SIG_BLOCK, CONST_CS | CONST_PERSISTENT);
290 REGISTER_LONG_CONSTANT("SIG_UNBLOCK", SIG_UNBLOCK, CONST_CS | CONST_PERSISTENT);
291 REGISTER_LONG_CONSTANT("SIG_SETMASK", SIG_SETMASK, CONST_CS | CONST_PERSISTENT);
292 #endif
293
294
295
296 #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
297 REGISTER_LONG_CONSTANT("SI_USER", SI_USER, CONST_CS | CONST_PERSISTENT);
298 #ifdef SI_NOINFO
299 REGISTER_LONG_CONSTANT("SI_NOINFO", SI_NOINFO, CONST_CS | CONST_PERSISTENT);
300 #endif
301 #ifdef SI_KERNEL
302 REGISTER_LONG_CONSTANT("SI_KERNEL", SI_KERNEL, CONST_CS | CONST_PERSISTENT);
303 #endif
304 REGISTER_LONG_CONSTANT("SI_QUEUE", SI_QUEUE, CONST_CS | CONST_PERSISTENT);
305 REGISTER_LONG_CONSTANT("SI_TIMER", SI_TIMER, CONST_CS | CONST_PERSISTENT);
306 REGISTER_LONG_CONSTANT("SI_MESGQ", SI_MESGQ, CONST_CS | CONST_PERSISTENT);
307 REGISTER_LONG_CONSTANT("SI_ASYNCIO", SI_ASYNCIO, CONST_CS | CONST_PERSISTENT);
308 #ifdef SI_SIGIO
309 REGISTER_LONG_CONSTANT("SI_SIGIO", SI_SIGIO, CONST_CS | CONST_PERSISTENT);
310 #endif
311 #ifdef SI_TKILL
312 REGISTER_LONG_CONSTANT("SI_TKILL", SI_TKILL, CONST_CS | CONST_PERSISTENT);
313 #endif
314
315
316 #ifdef CLD_EXITED
317 REGISTER_LONG_CONSTANT("CLD_EXITED", CLD_EXITED, CONST_CS | CONST_PERSISTENT);
318 #endif
319 #ifdef CLD_KILLED
320 REGISTER_LONG_CONSTANT("CLD_KILLED", CLD_KILLED, CONST_CS | CONST_PERSISTENT);
321 #endif
322 #ifdef CLD_DUMPED
323 REGISTER_LONG_CONSTANT("CLD_DUMPED", CLD_DUMPED, CONST_CS | CONST_PERSISTENT);
324 #endif
325 #ifdef CLD_TRAPPED
326 REGISTER_LONG_CONSTANT("CLD_TRAPPED", CLD_TRAPPED, CONST_CS | CONST_PERSISTENT);
327 #endif
328 #ifdef CLD_STOPPED
329 REGISTER_LONG_CONSTANT("CLD_STOPPED", CLD_STOPPED, CONST_CS | CONST_PERSISTENT);
330 #endif
331 #ifdef CLD_CONTINUED
332 REGISTER_LONG_CONSTANT("CLD_CONTINUED", CLD_CONTINUED, CONST_CS | CONST_PERSISTENT);
333 #endif
334
335
336 #ifdef TRAP_BRKPT
337 REGISTER_LONG_CONSTANT("TRAP_BRKPT", TRAP_BRKPT, CONST_CS | CONST_PERSISTENT);
338 #endif
339 #ifdef TRAP_TRACE
340 REGISTER_LONG_CONSTANT("TRAP_TRACE", TRAP_TRACE, CONST_CS | CONST_PERSISTENT);
341 #endif
342
343
344 #ifdef POLL_IN
345 REGISTER_LONG_CONSTANT("POLL_IN", POLL_IN, CONST_CS | CONST_PERSISTENT);
346 #endif
347 #ifdef POLL_OUT
348 REGISTER_LONG_CONSTANT("POLL_OUT", POLL_OUT, CONST_CS | CONST_PERSISTENT);
349 #endif
350 #ifdef POLL_MSG
351 REGISTER_LONG_CONSTANT("POLL_MSG", POLL_MSG, CONST_CS | CONST_PERSISTENT);
352 #endif
353 #ifdef POLL_ERR
354 REGISTER_LONG_CONSTANT("POLL_ERR", POLL_ERR, CONST_CS | CONST_PERSISTENT);
355 #endif
356 #ifdef POLL_PRI
357 REGISTER_LONG_CONSTANT("POLL_PRI", POLL_PRI, CONST_CS | CONST_PERSISTENT);
358 #endif
359 #ifdef POLL_HUP
360 REGISTER_LONG_CONSTANT("POLL_HUP", POLL_HUP, CONST_CS | CONST_PERSISTENT);
361 #endif
362
363 #ifdef ILL_ILLOPC
364 REGISTER_LONG_CONSTANT("ILL_ILLOPC", ILL_ILLOPC, CONST_CS | CONST_PERSISTENT);
365 #endif
366 #ifdef ILL_ILLOPN
367 REGISTER_LONG_CONSTANT("ILL_ILLOPN", ILL_ILLOPN, CONST_CS | CONST_PERSISTENT);
368 #endif
369 #ifdef ILL_ILLADR
370 REGISTER_LONG_CONSTANT("ILL_ILLADR", ILL_ILLADR, CONST_CS | CONST_PERSISTENT);
371 #endif
372 #ifdef ILL_ILLTRP
373 REGISTER_LONG_CONSTANT("ILL_ILLTRP", ILL_ILLTRP, CONST_CS | CONST_PERSISTENT);
374 #endif
375 #ifdef ILL_PRVOPC
376 REGISTER_LONG_CONSTANT("ILL_PRVOPC", ILL_PRVOPC, CONST_CS | CONST_PERSISTENT);
377 #endif
378 #ifdef ILL_PRVREG
379 REGISTER_LONG_CONSTANT("ILL_PRVREG", ILL_PRVREG, CONST_CS | CONST_PERSISTENT);
380 #endif
381 #ifdef ILL_COPROC
382 REGISTER_LONG_CONSTANT("ILL_COPROC", ILL_COPROC, CONST_CS | CONST_PERSISTENT);
383 #endif
384 #ifdef ILL_BADSTK
385 REGISTER_LONG_CONSTANT("ILL_BADSTK", ILL_BADSTK, CONST_CS | CONST_PERSISTENT);
386 #endif
387
388 #ifdef FPE_INTDIV
389 REGISTER_LONG_CONSTANT("FPE_INTDIV", FPE_INTDIV, CONST_CS | CONST_PERSISTENT);
390 #endif
391 #ifdef FPE_INTOVF
392 REGISTER_LONG_CONSTANT("FPE_INTOVF", FPE_INTOVF, CONST_CS | CONST_PERSISTENT);
393 #endif
394 #ifdef FPE_FLTDIV
395 REGISTER_LONG_CONSTANT("FPE_FLTDIV", FPE_FLTDIV, CONST_CS | CONST_PERSISTENT);
396 #endif
397 #ifdef FPE_FLTOVF
398 REGISTER_LONG_CONSTANT("FPE_FLTOVF", FPE_FLTOVF, CONST_CS | CONST_PERSISTENT);
399 #endif
400 #ifdef FPE_FLTUND
401 REGISTER_LONG_CONSTANT("FPE_FLTUND", FPE_FLTINV, CONST_CS | CONST_PERSISTENT);
402 #endif
403 #ifdef FPE_FLTRES
404 REGISTER_LONG_CONSTANT("FPE_FLTRES", FPE_FLTRES, CONST_CS | CONST_PERSISTENT);
405 #endif
406 #ifdef FPE_FLTINV
407 REGISTER_LONG_CONSTANT("FPE_FLTINV", FPE_FLTINV, CONST_CS | CONST_PERSISTENT);
408 #endif
409 #ifdef FPE_FLTSUB
410 REGISTER_LONG_CONSTANT("FPE_FLTSUB", FPE_FLTSUB, CONST_CS | CONST_PERSISTENT);
411 #endif
412
413 #ifdef SEGV_MAPERR
414 REGISTER_LONG_CONSTANT("SEGV_MAPERR", SEGV_MAPERR, CONST_CS | CONST_PERSISTENT);
415 #endif
416 #ifdef SEGV_ACCERR
417 REGISTER_LONG_CONSTANT("SEGV_ACCERR", SEGV_ACCERR, CONST_CS | CONST_PERSISTENT);
418 #endif
419
420 #ifdef BUS_ADRALN
421 REGISTER_LONG_CONSTANT("BUS_ADRALN", BUS_ADRALN, CONST_CS | CONST_PERSISTENT);
422 #endif
423 #ifdef BUS_ADRERR
424 REGISTER_LONG_CONSTANT("BUS_ADRERR", BUS_ADRERR, CONST_CS | CONST_PERSISTENT);
425 #endif
426 #ifdef BUS_OBJERR
427 REGISTER_LONG_CONSTANT("BUS_OBJERR", BUS_OBJERR, CONST_CS | CONST_PERSISTENT);
428 #endif
429 #endif
430
431 }
432
433 static void php_pcntl_register_errno_constants(INIT_FUNC_ARGS)
434 {
435 #ifdef EINTR
436 REGISTER_PCNTL_ERRNO_CONSTANT(EINTR);
437 #endif
438 #ifdef ECHILD
439 REGISTER_PCNTL_ERRNO_CONSTANT(ECHILD);
440 #endif
441 #ifdef EINVAL
442 REGISTER_PCNTL_ERRNO_CONSTANT(EINVAL);
443 #endif
444 #ifdef EAGAIN
445 REGISTER_PCNTL_ERRNO_CONSTANT(EAGAIN);
446 #endif
447 #ifdef ESRCH
448 REGISTER_PCNTL_ERRNO_CONSTANT(ESRCH);
449 #endif
450 #ifdef EACCES
451 REGISTER_PCNTL_ERRNO_CONSTANT(EACCES);
452 #endif
453 #ifdef EPERM
454 REGISTER_PCNTL_ERRNO_CONSTANT(EPERM);
455 #endif
456 #ifdef ENOMEM
457 REGISTER_PCNTL_ERRNO_CONSTANT(ENOMEM);
458 #endif
459 #ifdef E2BIG
460 REGISTER_PCNTL_ERRNO_CONSTANT(E2BIG);
461 #endif
462 #ifdef EFAULT
463 REGISTER_PCNTL_ERRNO_CONSTANT(EFAULT);
464 #endif
465 #ifdef EIO
466 REGISTER_PCNTL_ERRNO_CONSTANT(EIO);
467 #endif
468 #ifdef EISDIR
469 REGISTER_PCNTL_ERRNO_CONSTANT(EISDIR);
470 #endif
471 #ifdef ELIBBAD
472 REGISTER_PCNTL_ERRNO_CONSTANT(ELIBBAD);
473 #endif
474 #ifdef ELOOP
475 REGISTER_PCNTL_ERRNO_CONSTANT(ELOOP);
476 #endif
477 #ifdef EMFILE
478 REGISTER_PCNTL_ERRNO_CONSTANT(EMFILE);
479 #endif
480 #ifdef ENAMETOOLONG
481 REGISTER_PCNTL_ERRNO_CONSTANT(ENAMETOOLONG);
482 #endif
483 #ifdef ENFILE
484 REGISTER_PCNTL_ERRNO_CONSTANT(ENFILE);
485 #endif
486 #ifdef ENOENT
487 REGISTER_PCNTL_ERRNO_CONSTANT(ENOENT);
488 #endif
489 #ifdef ENOEXEC
490 REGISTER_PCNTL_ERRNO_CONSTANT(ENOEXEC);
491 #endif
492 #ifdef ENOTDIR
493 REGISTER_PCNTL_ERRNO_CONSTANT(ENOTDIR);
494 #endif
495 #ifdef ETXTBSY
496 REGISTER_PCNTL_ERRNO_CONSTANT(ETXTBSY);
497 #endif
498 }
499
500 static PHP_GINIT_FUNCTION(pcntl)
501 {
502 memset(pcntl_globals, 0, sizeof(*pcntl_globals));
503 }
504
505 PHP_RINIT_FUNCTION(pcntl)
506 {
507 zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 0);
508 PCNTL_G(head) = PCNTL_G(tail) = PCNTL_G(spares) = NULL;
509 return SUCCESS;
510 }
511
512 PHP_MINIT_FUNCTION(pcntl)
513 {
514 php_register_signal_constants(INIT_FUNC_ARGS_PASSTHRU);
515 php_pcntl_register_errno_constants(INIT_FUNC_ARGS_PASSTHRU);
516 php_add_tick_function(pcntl_signal_dispatch, NULL);
517
518 return SUCCESS;
519 }
520
521 PHP_MSHUTDOWN_FUNCTION(pcntl)
522 {
523 return SUCCESS;
524 }
525
526 PHP_RSHUTDOWN_FUNCTION(pcntl)
527 {
528 struct php_pcntl_pending_signal *sig;
529
530
531
532 zend_hash_destroy(&PCNTL_G(php_signal_table));
533 while (PCNTL_G(head)) {
534 sig = PCNTL_G(head);
535 PCNTL_G(head) = sig->next;
536 efree(sig);
537 }
538 while (PCNTL_G(spares)) {
539 sig = PCNTL_G(spares);
540 PCNTL_G(spares) = sig->next;
541 efree(sig);
542 }
543 return SUCCESS;
544 }
545
546 PHP_MINFO_FUNCTION(pcntl)
547 {
548 php_info_print_table_start();
549 php_info_print_table_header(2, "pcntl support", "enabled");
550 php_info_print_table_end();
551 }
552
553
554
555 PHP_FUNCTION(pcntl_fork)
556 {
557 pid_t id;
558
559 id = fork();
560 if (id == -1) {
561 PCNTL_G(last_error) = errno;
562 php_error_docref(NULL, E_WARNING, "Error %d", errno);
563 }
564
565 RETURN_LONG((zend_long) id);
566 }
567
568
569
570
571 PHP_FUNCTION(pcntl_alarm)
572 {
573 zend_long seconds;
574
575 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &seconds) == FAILURE)
576 return;
577
578 RETURN_LONG ((zend_long) alarm(seconds));
579 }
580
581
582 #define PHP_RUSAGE_PARA(from, to, field) \
583 add_assoc_long(to, #field, from.field)
584 #if !defined(_OSD_POSIX) && !defined(__BEOS__)
585 #define PHP_RUSAGE_SPECIAL(from, to) \
586 PHP_RUSAGE_PARA(from, to, ru_oublock); \
587 PHP_RUSAGE_PARA(from, to, ru_inblock); \
588 PHP_RUSAGE_PARA(from, to, ru_msgsnd); \
589 PHP_RUSAGE_PARA(from, to, ru_msgrcv); \
590 PHP_RUSAGE_PARA(from, to, ru_maxrss); \
591 PHP_RUSAGE_PARA(from, to, ru_ixrss); \
592 PHP_RUSAGE_PARA(from, to, ru_idrss); \
593 PHP_RUSAGE_PARA(from, to, ru_minflt); \
594 PHP_RUSAGE_PARA(from, to, ru_majflt); \
595 PHP_RUSAGE_PARA(from, to, ru_nsignals); \
596 PHP_RUSAGE_PARA(from, to, ru_nvcsw); \
597 PHP_RUSAGE_PARA(from, to, ru_nivcsw); \
598 PHP_RUSAGE_PARA(from, to, ru_nswap);
599 #else
600 #define PHP_RUSAGE_SPECIAL(from, to)
601 #endif
602
603 #define PHP_RUSAGE_COMMON(from ,to) \
604 PHP_RUSAGE_PARA(from, to, ru_utime.tv_usec); \
605 PHP_RUSAGE_PARA(from, to, ru_utime.tv_sec); \
606 PHP_RUSAGE_PARA(from, to, ru_stime.tv_usec); \
607 PHP_RUSAGE_PARA(from, to, ru_stime.tv_sec);
608
609 #define PHP_RUSAGE_TO_ARRAY(from, to) \
610 if (to) { \
611 PHP_RUSAGE_SPECIAL(from, to) \
612 PHP_RUSAGE_COMMON(from, to); \
613 }
614
615
616
617 PHP_FUNCTION(pcntl_waitpid)
618 {
619 zend_long pid, options = 0;
620 zval *z_status = NULL, *z_rusage = NULL;
621 int status;
622 pid_t child_id;
623 #ifdef HAVE_WAIT4
624 struct rusage rusage;
625 #endif
626
627 if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz/|lz/", &pid, &z_status, &options, &z_rusage) == FAILURE)
628 return;
629
630 convert_to_long_ex(z_status);
631
632 status = Z_LVAL_P(z_status);
633
634 #ifdef HAVE_WAIT4
635 if (z_rusage) {
636 if (Z_TYPE_P(z_rusage) != IS_ARRAY) {
637 zval_dtor(z_rusage);
638 array_init(z_rusage);
639 } else {
640 zend_hash_clean(Z_ARRVAL_P(z_rusage));
641 }
642
643 memset(&rusage, 0, sizeof(struct rusage));
644 child_id = wait4((pid_t) pid, &status, options, &rusage);
645 } else {
646 child_id = waitpid((pid_t) pid, &status, options);
647 }
648 #else
649 child_id = waitpid((pid_t) pid, &status, options);
650 #endif
651
652 if (child_id < 0) {
653 PCNTL_G(last_error) = errno;
654 }
655
656 #ifdef HAVE_WAIT4
657 if (child_id > 0) {
658 PHP_RUSAGE_TO_ARRAY(rusage, z_rusage);
659 }
660 #endif
661
662 Z_LVAL_P(z_status) = status;
663
664 RETURN_LONG((zend_long) child_id);
665 }
666
667
668
669
670 PHP_FUNCTION(pcntl_wait)
671 {
672 zend_long options = 0;
673 zval *z_status = NULL, *z_rusage = NULL;
674 int status;
675 pid_t child_id;
676 #ifdef HAVE_WAIT3
677 struct rusage rusage;
678 #endif
679
680 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z/|lz/", &z_status, &options, &z_rusage) == FAILURE)
681 return;
682
683 convert_to_long_ex(z_status);
684
685 status = Z_LVAL_P(z_status);
686 #ifdef HAVE_WAIT3
687 if (z_rusage) {
688 if (Z_TYPE_P(z_rusage) != IS_ARRAY) {
689 zval_dtor(z_rusage);
690 array_init(z_rusage);
691 } else {
692 zend_hash_clean(Z_ARRVAL_P(z_rusage));
693 }
694
695 memset(&rusage, 0, sizeof(struct rusage));
696 child_id = wait3(&status, options, &rusage);
697 } else if (options) {
698 child_id = wait3(&status, options, NULL);
699 } else {
700 child_id = wait(&status);
701 }
702 #else
703 child_id = wait(&status);
704 #endif
705 if (child_id < 0) {
706 PCNTL_G(last_error) = errno;
707 }
708
709 #ifdef HAVE_WAIT3
710 if (child_id > 0) {
711 PHP_RUSAGE_TO_ARRAY(rusage, z_rusage);
712 }
713 #endif
714 Z_LVAL_P(z_status) = status;
715
716 RETURN_LONG((zend_long) child_id);
717 }
718
719
720 #undef PHP_RUSAGE_PARA
721 #undef PHP_RUSAGE_SPECIAL
722 #undef PHP_RUSAGE_COMMON
723 #undef PHP_RUSAGE_TO_ARRAY
724
725
726
727 PHP_FUNCTION(pcntl_wifexited)
728 {
729 #ifdef WIFEXITED
730 zend_long status_word;
731
732 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
733 return;
734 }
735
736 if (WIFEXITED(status_word))
737 RETURN_TRUE;
738 #endif
739 RETURN_FALSE;
740 }
741
742
743
744
745 PHP_FUNCTION(pcntl_wifstopped)
746 {
747 #ifdef WIFSTOPPED
748 zend_long status_word;
749
750 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
751 return;
752 }
753
754 if (WIFSTOPPED(status_word))
755 RETURN_TRUE;
756 #endif
757 RETURN_FALSE;
758 }
759
760
761
762
763 PHP_FUNCTION(pcntl_wifsignaled)
764 {
765 #ifdef WIFSIGNALED
766 zend_long status_word;
767
768 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
769 return;
770 }
771
772 if (WIFSIGNALED(status_word))
773 RETURN_TRUE;
774 #endif
775 RETURN_FALSE;
776 }
777
778
779
780 PHP_FUNCTION(pcntl_wifcontinued)
781 {
782 #ifdef HAVE_WCONTINUED
783 zend_long status_word;
784
785 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
786 return;
787 }
788
789 if (WIFCONTINUED(status_word))
790 RETURN_TRUE;
791 #endif
792 RETURN_FALSE;
793 }
794
795
796
797
798
799 PHP_FUNCTION(pcntl_wexitstatus)
800 {
801 #ifdef WEXITSTATUS
802 zend_long status_word;
803
804 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
805 return;
806 }
807
808 RETURN_LONG(WEXITSTATUS(status_word));
809 #else
810 RETURN_FALSE;
811 #endif
812 }
813
814
815
816
817 PHP_FUNCTION(pcntl_wtermsig)
818 {
819 #ifdef WTERMSIG
820 zend_long status_word;
821
822 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
823 return;
824 }
825
826 RETURN_LONG(WTERMSIG(status_word));
827 #else
828 RETURN_FALSE;
829 #endif
830 }
831
832
833
834
835 PHP_FUNCTION(pcntl_wstopsig)
836 {
837 #ifdef WSTOPSIG
838 zend_long status_word;
839
840 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &status_word) == FAILURE) {
841 return;
842 }
843
844 RETURN_LONG(WSTOPSIG(status_word));
845 #else
846 RETURN_FALSE;
847 #endif
848 }
849
850
851
852
853 PHP_FUNCTION(pcntl_exec)
854 {
855 zval *args = NULL, *envs = NULL;
856 zval *element;
857 HashTable *args_hash, *envs_hash;
858 int argc = 0, argi = 0;
859 int envc = 0, envi = 0;
860 char **argv = NULL, **envp = NULL;
861 char **current_arg, **pair;
862 int pair_length;
863 zend_string *key;
864 char *path;
865 size_t path_len;
866 zend_ulong key_num;
867
868 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|aa", &path, &path_len, &args, &envs) == FAILURE) {
869 return;
870 }
871
872 if (ZEND_NUM_ARGS() > 1) {
873
874 args_hash = Z_ARRVAL_P(args);
875 argc = zend_hash_num_elements(args_hash);
876
877 argv = safe_emalloc((argc + 2), sizeof(char *), 0);
878 *argv = path;
879 current_arg = argv+1;
880 ZEND_HASH_FOREACH_VAL(args_hash, element) {
881 if (argi >= argc) break;
882 convert_to_string_ex(element);
883 *current_arg = Z_STRVAL_P(element);
884 argi++;
885 current_arg++;
886 } ZEND_HASH_FOREACH_END();
887 *(current_arg) = NULL;
888 } else {
889 argv = emalloc(2 * sizeof(char *));
890 *argv = path;
891 *(argv+1) = NULL;
892 }
893
894 if ( ZEND_NUM_ARGS() == 3 ) {
895
896 envs_hash = Z_ARRVAL_P(envs);
897 envc = zend_hash_num_elements(envs_hash);
898
899 pair = envp = safe_emalloc((envc + 1), sizeof(char *), 0);
900 ZEND_HASH_FOREACH_KEY_VAL(envs_hash, key_num, key, element) {
901 if (envi >= envc) break;
902 if (!key) {
903 key = zend_long_to_str(key_num);
904 } else {
905 zend_string_addref(key);
906 }
907
908 convert_to_string_ex(element);
909
910
911 pair_length = Z_STRLEN_P(element) + ZSTR_LEN(key) + 2;
912 *pair = emalloc(pair_length);
913 strlcpy(*pair, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
914 strlcat(*pair, "=", pair_length);
915 strlcat(*pair, Z_STRVAL_P(element), pair_length);
916
917
918 zend_string_release(key);
919 envi++;
920 pair++;
921 } ZEND_HASH_FOREACH_END();
922 *(pair) = NULL;
923
924 if (execve(path, argv, envp) == -1) {
925 PCNTL_G(last_error) = errno;
926 php_error_docref(NULL, E_WARNING, "Error has occurred: (errno %d) %s", errno, strerror(errno));
927 }
928
929
930 for (pair = envp; *pair != NULL; pair++) efree(*pair);
931 efree(envp);
932 } else {
933
934 if (execv(path, argv) == -1) {
935 PCNTL_G(last_error) = errno;
936 php_error_docref(NULL, E_WARNING, "Error has occurred: (errno %d) %s", errno, strerror(errno));
937 }
938 }
939
940 efree(argv);
941
942 RETURN_FALSE;
943 }
944
945
946
947
948 PHP_FUNCTION(pcntl_signal)
949 {
950 zval *handle;
951 zend_string *func_name;
952 zend_long signo;
953 zend_bool restart_syscalls = 1;
954
955 if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz|b", &signo, &handle, &restart_syscalls) == FAILURE) {
956 return;
957 }
958
959 if (signo < 1 || signo > 32) {
960 php_error_docref(NULL, E_WARNING, "Invalid signal");
961 RETURN_FALSE;
962 }
963
964 if (!PCNTL_G(spares)) {
965
966
967 int i;
968 for (i = 0; i < 32; i++) {
969 struct php_pcntl_pending_signal *psig;
970
971 psig = emalloc(sizeof(*psig));
972 psig->next = PCNTL_G(spares);
973 PCNTL_G(spares) = psig;
974 }
975 }
976
977
978 if (Z_TYPE_P(handle) == IS_LONG) {
979 if (Z_LVAL_P(handle) != (zend_long) SIG_DFL && Z_LVAL_P(handle) != (zend_long) SIG_IGN) {
980 php_error_docref(NULL, E_WARNING, "Invalid value for handle argument specified");
981 RETURN_FALSE;
982 }
983 if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == SIG_ERR) {
984 PCNTL_G(last_error) = errno;
985 php_error_docref(NULL, E_WARNING, "Error assigning signal");
986 RETURN_FALSE;
987 }
988 zend_hash_index_del(&PCNTL_G(php_signal_table), signo);
989 RETURN_TRUE;
990 }
991
992 if (!zend_is_callable(handle, 0, &func_name)) {
993 PCNTL_G(last_error) = EINVAL;
994 php_error_docref(NULL, E_WARNING, "%s is not a callable function name error", ZSTR_VAL(func_name));
995 zend_string_release(func_name);
996 RETURN_FALSE;
997 }
998 zend_string_release(func_name);
999
1000
1001 if (zend_hash_index_update(&PCNTL_G(php_signal_table), signo, handle)) {
1002 if (Z_REFCOUNTED_P(handle)) Z_ADDREF_P(handle);
1003 }
1004
1005 if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == SIG_ERR) {
1006 PCNTL_G(last_error) = errno;
1007 php_error_docref(NULL, E_WARNING, "Error assigning signal");
1008 RETURN_FALSE;
1009 }
1010 RETURN_TRUE;
1011 }
1012
1013
1014
1015
1016 PHP_FUNCTION(pcntl_signal_dispatch)
1017 {
1018 pcntl_signal_dispatch();
1019 RETURN_TRUE;
1020 }
1021
1022
1023 #ifdef HAVE_SIGPROCMASK
1024
1025
1026 PHP_FUNCTION(pcntl_sigprocmask)
1027 {
1028 zend_long how, signo;
1029 zval *user_set, *user_oldset = NULL, *user_signo;
1030 sigset_t set, oldset;
1031
1032 if (zend_parse_parameters(ZEND_NUM_ARGS(), "la|z/", &how, &user_set, &user_oldset) == FAILURE) {
1033 return;
1034 }
1035
1036 if (sigemptyset(&set) != 0 || sigemptyset(&oldset) != 0) {
1037 PCNTL_G(last_error) = errno;
1038 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1039 RETURN_FALSE;
1040 }
1041
1042 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(user_set), user_signo) {
1043 signo = zval_get_long(user_signo);
1044 if (sigaddset(&set, signo) != 0) {
1045 PCNTL_G(last_error) = errno;
1046 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1047 RETURN_FALSE;
1048 }
1049 } ZEND_HASH_FOREACH_END();
1050
1051 if (sigprocmask(how, &set, &oldset) != 0) {
1052 PCNTL_G(last_error) = errno;
1053 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1054 RETURN_FALSE;
1055 }
1056
1057 if (user_oldset != NULL) {
1058 if (Z_TYPE_P(user_oldset) != IS_ARRAY) {
1059 zval_dtor(user_oldset);
1060 array_init(user_oldset);
1061 } else {
1062 zend_hash_clean(Z_ARRVAL_P(user_oldset));
1063 }
1064 for (signo = 1; signo < MAX(NSIG-1, SIGRTMAX); ++signo) {
1065 if (sigismember(&oldset, signo) != 1) {
1066 continue;
1067 }
1068 add_next_index_long(user_oldset, signo);
1069 }
1070 }
1071
1072 RETURN_TRUE;
1073 }
1074
1075 #endif
1076
1077 #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT
1078 static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait)
1079 {
1080 zval *user_set, *user_signo, *user_siginfo = NULL;
1081 zend_long tv_sec = 0, tv_nsec = 0;
1082 sigset_t set;
1083 int signo;
1084 siginfo_t siginfo;
1085 struct timespec timeout;
1086
1087 if (timedwait) {
1088 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|z/ll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) {
1089 return;
1090 }
1091 } else {
1092 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|z/", &user_set, &user_siginfo) == FAILURE) {
1093 return;
1094 }
1095 }
1096
1097 if (sigemptyset(&set) != 0) {
1098 PCNTL_G(last_error) = errno;
1099 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1100 RETURN_FALSE;
1101 }
1102
1103 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(user_set), user_signo) {
1104 signo = zval_get_long(user_signo);
1105 if (sigaddset(&set, signo) != 0) {
1106 PCNTL_G(last_error) = errno;
1107 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1108 RETURN_FALSE;
1109 }
1110 } ZEND_HASH_FOREACH_END();
1111
1112 if (timedwait) {
1113 timeout.tv_sec = (time_t) tv_sec;
1114 timeout.tv_nsec = tv_nsec;
1115 signo = sigtimedwait(&set, &siginfo, &timeout);
1116 } else {
1117 signo = sigwaitinfo(&set, &siginfo);
1118 }
1119 if (signo == -1 && errno != EAGAIN) {
1120 PCNTL_G(last_error) = errno;
1121 php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
1122 }
1123
1124
1125
1126
1127
1128 if (!signo && siginfo.si_signo) {
1129 signo = siginfo.si_signo;
1130 }
1131
1132 if (signo > 0 && user_siginfo) {
1133 if (Z_TYPE_P(user_siginfo) != IS_ARRAY) {
1134 zval_dtor(user_siginfo);
1135 array_init(user_siginfo);
1136 } else {
1137 zend_hash_clean(Z_ARRVAL_P(user_siginfo));
1138 }
1139 add_assoc_long_ex(user_siginfo, "signo", sizeof("signo")-1, siginfo.si_signo);
1140 add_assoc_long_ex(user_siginfo, "errno", sizeof("errno")-1, siginfo.si_errno);
1141 add_assoc_long_ex(user_siginfo, "code", sizeof("code")-1, siginfo.si_code);
1142 switch(signo) {
1143 #ifdef SIGCHLD
1144 case SIGCHLD:
1145 add_assoc_long_ex(user_siginfo, "status", sizeof("status")-1, siginfo.si_status);
1146 # ifdef si_utime
1147 add_assoc_double_ex(user_siginfo, "utime", sizeof("utime")-1, siginfo.si_utime);
1148 # endif
1149 # ifdef si_stime
1150 add_assoc_double_ex(user_siginfo, "stime", sizeof("stime")-1, siginfo.si_stime);
1151 # endif
1152 add_assoc_long_ex(user_siginfo, "pid", sizeof("pid")-1, siginfo.si_pid);
1153 add_assoc_long_ex(user_siginfo, "uid", sizeof("uid")-1, siginfo.si_uid);
1154 break;
1155 #endif
1156 case SIGILL:
1157 case SIGFPE:
1158 case SIGSEGV:
1159 case SIGBUS:
1160 add_assoc_double_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo.si_addr);
1161 break;
1162 #ifdef SIGPOLL
1163 case SIGPOLL:
1164 add_assoc_long_ex(user_siginfo, "band", sizeof("band")-1, siginfo.si_band);
1165 # ifdef si_fd
1166 add_assoc_long_ex(user_siginfo, "fd", sizeof("fd")-1, siginfo.si_fd);
1167 # endif
1168 break;
1169 #endif
1170 }
1171 }
1172
1173 RETURN_LONG(signo);
1174 }
1175
1176
1177
1178
1179 PHP_FUNCTION(pcntl_sigwaitinfo)
1180 {
1181 pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1182 }
1183
1184
1185
1186
1187 PHP_FUNCTION(pcntl_sigtimedwait)
1188 {
1189 pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1190 }
1191
1192 #endif
1193
1194 #ifdef HAVE_GETPRIORITY
1195
1196
1197 PHP_FUNCTION(pcntl_getpriority)
1198 {
1199 zend_long who = PRIO_PROCESS;
1200 zend_long pid = getpid();
1201 int pri;
1202
1203 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &pid, &who) == FAILURE) {
1204 RETURN_FALSE;
1205 }
1206
1207
1208 errno = 0;
1209
1210 pri = getpriority(who, pid);
1211
1212 if (errno) {
1213 PCNTL_G(last_error) = errno;
1214 switch (errno) {
1215 case ESRCH:
1216 php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno);
1217 break;
1218 case EINVAL:
1219 php_error_docref(NULL, E_WARNING, "Error %d: Invalid identifier flag", errno);
1220 break;
1221 default:
1222 php_error_docref(NULL, E_WARNING, "Unknown error %d has occurred", errno);
1223 break;
1224 }
1225 RETURN_FALSE;
1226 }
1227
1228 RETURN_LONG(pri);
1229 }
1230
1231 #endif
1232
1233 #ifdef HAVE_SETPRIORITY
1234
1235
1236 PHP_FUNCTION(pcntl_setpriority)
1237 {
1238 zend_long who = PRIO_PROCESS;
1239 zend_long pid = getpid();
1240 zend_long pri;
1241
1242 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &pri, &pid, &who) == FAILURE) {
1243 RETURN_FALSE;
1244 }
1245
1246 if (setpriority(who, pid, pri)) {
1247 PCNTL_G(last_error) = errno;
1248 switch (errno) {
1249 case ESRCH:
1250 php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno);
1251 break;
1252 case EINVAL:
1253 php_error_docref(NULL, E_WARNING, "Error %d: Invalid identifier flag", errno);
1254 break;
1255 case EPERM:
1256 php_error_docref(NULL, E_WARNING, "Error %d: A process was located, but neither its effective nor real user ID matched the effective user ID of the caller", errno);
1257 break;
1258 case EACCES:
1259 php_error_docref(NULL, E_WARNING, "Error %d: Only a super user may attempt to increase the process priority", errno);
1260 break;
1261 default:
1262 php_error_docref(NULL, E_WARNING, "Unknown error %d has occurred", errno);
1263 break;
1264 }
1265 RETURN_FALSE;
1266 }
1267
1268 RETURN_TRUE;
1269 }
1270
1271 #endif
1272
1273
1274
1275 PHP_FUNCTION(pcntl_get_last_error)
1276 {
1277 RETURN_LONG(PCNTL_G(last_error));
1278 }
1279
1280
1281
1282
1283 PHP_FUNCTION(pcntl_strerror)
1284 {
1285 zend_long error;
1286
1287 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &error) == FAILURE) {
1288 RETURN_FALSE;
1289 }
1290
1291 RETURN_STRING(strerror(error));
1292 }
1293
1294
1295
1296 static void pcntl_signal_handler(int signo)
1297 {
1298 struct php_pcntl_pending_signal *psig;
1299
1300 psig = PCNTL_G(spares);
1301 if (!psig) {
1302
1303 return;
1304 }
1305 PCNTL_G(spares) = psig->next;
1306
1307 psig->signo = signo;
1308 psig->next = NULL;
1309
1310
1311
1312 if (PCNTL_G(head) && PCNTL_G(tail)) {
1313 PCNTL_G(tail)->next = psig;
1314 } else {
1315 PCNTL_G(head) = psig;
1316 }
1317 PCNTL_G(tail) = psig;
1318 PCNTL_G(pending_signals) = 1;
1319 }
1320
1321 void pcntl_signal_dispatch()
1322 {
1323 zval param, *handle, retval;
1324 struct php_pcntl_pending_signal *queue, *next;
1325 sigset_t mask;
1326 sigset_t old_mask;
1327
1328 if(!PCNTL_G(pending_signals)) {
1329 return;
1330 }
1331
1332
1333 sigfillset(&mask);
1334 sigprocmask(SIG_BLOCK, &mask, &old_mask);
1335
1336
1337 if (! PCNTL_G(head) || PCNTL_G(processing_signal_queue)) {
1338 sigprocmask(SIG_SETMASK, &old_mask, NULL);
1339 return;
1340 }
1341
1342
1343 PCNTL_G(processing_signal_queue) = 1;
1344
1345 queue = PCNTL_G(head);
1346 PCNTL_G(head) = NULL;
1347
1348
1349
1350 while (queue) {
1351 if ((handle = zend_hash_index_find(&PCNTL_G(php_signal_table), queue->signo)) != NULL) {
1352 ZVAL_NULL(&retval);
1353 ZVAL_LONG(¶m, queue->signo);
1354
1355
1356
1357 call_user_function(EG(function_table), NULL, handle, &retval, 1, ¶m);
1358 zval_ptr_dtor(¶m);
1359 zval_ptr_dtor(&retval);
1360 }
1361
1362 next = queue->next;
1363 queue->next = PCNTL_G(spares);
1364 PCNTL_G(spares) = queue;
1365 queue = next;
1366 }
1367
1368 PCNTL_G(pending_signals) = 0;
1369
1370
1371 PCNTL_G(processing_signal_queue) = 0;
1372
1373
1374 sigprocmask(SIG_SETMASK, &old_mask, NULL);
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385