20#define DEBUG_OUT printf("DEBUG: ");printf
36#if defined(HAVE_GETPRIORITY) || defined(HAVE_SETPRIORITY) || defined(HAVE_WAIT3)
39#include <sys/resource.h>
43#if defined (HAVE_DECL_P_ALL) && HAVE_DECL_P_ALL == 1
44#define HAVE_POSIX_IDTYPES 1
46#if defined (HAVE_DECL_P_PIDFD) && HAVE_DECL_P_PIDFD == 1
47#define HAVE_LINUX_IDTYPES 1
49#if defined (HAVE_DECL_P_UID) && HAVE_DECL_P_UID == 1
50#define HAVE_NETBSD_IDTYPES 1
52#if defined (HAVE_DECL_P_JAILID) && HAVE_DECL_P_JAILID == 1
53#define HAVE_FREEBSD_IDTYPES 1
59#if defined(HAVE_UNSHARE) || defined(HAVE_SCHED_SETAFFINITY) || defined(HAVE_SCHED_GETCPU)
61#if defined(__FreeBSD__)
63#include <sys/cpuset.h>
64typedef cpuset_t cpu_set_t;
66 #define PCNTL_CPUSET(mask) &mask
67 #define PCNTL_CPUSET_SIZE(mask) sizeof(mask)
68 #define PCNTL_CPU_ISSET(i, mask) CPU_ISSET(i, &mask)
69 #define PCNTL_CPU_SET(i, mask) CPU_SET(i, &mask)
70 #define PCNTL_CPU_ZERO(mask) CPU_ZERO(&mask)
71 #define PCNTL_CPU_DESTROY(mask) ((void)0)
72#elif defined(__NetBSD__)
73#include <sys/syscall.h>
75typedef cpuset_t *cpu_set_t;
76 #define sched_getaffinity(p, c, m) syscall(SYS__sched_getaffinity, p, 0, c, m)
77 #define sched_setaffinity(p, c, m) syscall(SYS__sched_setaffinity, p, 0, c, m)
78 #define PCNTL_CPUSET(mask) mask
79 #define PCNTL_CPUSET_SIZE(mask) cpuset_size(mask)
80 #define PCNTL_CPU_ISSET(i, mask) cpuset_isset((cpuid_t)i, mask)
81 #define PCNTL_CPU_SET(i, mask) cpuset_set((cpuid_t)i, mask)
82 #define PCNTL_CPU_ZERO(mask) \
84 mask = cpuset_create(); \
85 if (UNEXPECTED(!mask)) { \
86 php_error_docref(NULL, E_WARNING, "cpuset_create: Insufficient memory"); \
91 #define PCNTL_CPU_DESTROY(mask) cpuset_destroy(mask)
92 #define HAVE_SCHED_SETAFFINITY 1
93#elif defined(HAVE_PSET_BIND)
95typedef psetid_t cpu_set_t;
96 #define sched_getaffinity(p, c, m) pset_bind(PS_QUERY, P_PID, (p <= 0 ? getpid() : p), &m)
97 #define sched_setaffinity(p, c, m) pset_bind(m, P_PID, (p <= 0 ? getpid() : p), NULL)
98 #define PCNTL_CPUSET(mask) mask
99 #define PCNTL_CPU_ISSET(i, mask) (pset_assign(PS_QUERY, (processorid_t)i, &query) == 0 && query == mask)
100 #define PCNTL_CPU_SET(i, mask) pset_assign(mask, (processorid_t)i, NULL)
101 #define PCNTL_CPU_ZERO(mask) \
104 if (UNEXPECTED(pset_create(&mask) != 0)) { \
105 php_error_docref(NULL, E_WARNING, "pset_create: %s", strerror(errno)); \
109 #define PCNTL_CPU_DESTROY(mask) \
111 if (UNEXPECTED(mask != PS_NONE && pset_destroy(mask) != 0)) { \
112 php_error_docref(NULL, E_WARNING, "pset_destroy: %s", strerror(errno)); \
115 #define HAVE_SCHED_SETAFFINITY 1
118#if defined(HAVE_GETCPUID)
119#include <sys/processor.h>
120#define sched_getcpu getcpuid
121#define HAVE_SCHED_GETCPU 1
124#if defined(HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP)
125#include <pthread/qos.h>
128#ifdef HAVE_PIDFD_OPEN
129#include <sys/syscall.h>
140#define LONG_CONST(c) (zend_long) c
168#ifdef COMPILE_DL_PCNTL
177#ifdef HAVE_STRUCT_SIGINFO_T
178static void pcntl_signal_handler(
int, siginfo_t*,
void*);
179static void pcntl_siginfo_to_zval(
int, siginfo_t*,
zval*);
181static void pcntl_signal_handler(
int);
183static void pcntl_signal_dispatch(
void);
184static void pcntl_signal_dispatch_tick_function(
int dummy_int,
void *dummy_pointer);
189#if defined(COMPILE_DL_PCNTL) && defined(ZTS)
192 memset(pcntl_globals, 0,
sizeof(*pcntl_globals));
215 QosClass_ce = register_class_Pcntl_QosClass();
216 register_pcntl_symbols(module_number);
294 }
else if (
id == 0) {
315#define PHP_RUSAGE_PARA(from, to, field) \
316 add_assoc_long(to, #field, from.field)
318 #define PHP_RUSAGE_SPECIAL(from, to) \
319 PHP_RUSAGE_PARA(from, to, ru_oublock); \
320 PHP_RUSAGE_PARA(from, to, ru_inblock); \
321 PHP_RUSAGE_PARA(from, to, ru_msgsnd); \
322 PHP_RUSAGE_PARA(from, to, ru_msgrcv); \
323 PHP_RUSAGE_PARA(from, to, ru_maxrss); \
324 PHP_RUSAGE_PARA(from, to, ru_ixrss); \
325 PHP_RUSAGE_PARA(from, to, ru_idrss); \
326 PHP_RUSAGE_PARA(from, to, ru_minflt); \
327 PHP_RUSAGE_PARA(from, to, ru_majflt); \
328 PHP_RUSAGE_PARA(from, to, ru_nsignals); \
329 PHP_RUSAGE_PARA(from, to, ru_nvcsw); \
330 PHP_RUSAGE_PARA(from, to, ru_nivcsw); \
331 PHP_RUSAGE_PARA(from, to, ru_nswap);
333 #define PHP_RUSAGE_SPECIAL(from, to)
336#define PHP_RUSAGE_COMMON(from ,to) \
337 PHP_RUSAGE_PARA(from, to, ru_utime.tv_usec); \
338 PHP_RUSAGE_PARA(from, to, ru_utime.tv_sec); \
339 PHP_RUSAGE_PARA(from, to, ru_stime.tv_usec); \
340 PHP_RUSAGE_PARA(from, to, ru_stime.tv_sec);
342#define PHP_RUSAGE_TO_ARRAY(from, to) \
344 PHP_RUSAGE_SPECIAL(from, to) \
345 PHP_RUSAGE_COMMON(from, to); \
367 status = zval_get_long(z_status);
371 z_rusage = zend_try_array_init(z_rusage);
401#if defined (HAVE_WAITID) && defined (HAVE_POSIX_IDTYPES) && defined (HAVE_DECL_WEXITED) && HAVE_DECL_WEXITED == 1
421 int status = waitid((idtype_t) idtype, (id_t)
id, &siginfo, (
int)
options);
428 pcntl_siginfo_to_zval(
SIGCHLD, &siginfo, user_siginfo);
452 status = zval_get_long(z_status);
455 z_rusage = zend_try_array_init(z_rusage);
486#undef PHP_RUSAGE_PARA
487#undef PHP_RUSAGE_SPECIAL
488#undef PHP_RUSAGE_COMMON
489#undef PHP_RUSAGE_TO_ARRAY
501 int int_status_word = (int) status_word;
502 if (WIFEXITED(int_status_word)) {
521 int int_status_word = (int) status_word;
522 if (WIFSTOPPED(int_status_word)) {
541 int int_status_word = (int) status_word;
542 if (WIFSIGNALED(int_status_word)) {
560#ifdef HAVE_WCONTINUED
561 int int_status_word = (int) status_word;
562 if (WIFCONTINUED(int_status_word)) {
581 int int_status_word = (int) status_word;
599 int int_status_word = (int) status_word;
617 int int_status_word = (int) status_word;
631 int argc = 0, argi = 0;
632 int envc = 0, envi = 0;
634 char **current_arg, **pair;
652 argc = zend_hash_num_elements(args_hash);
656 current_arg = argv+1;
658 if (argi >= argc)
break;
659 if (!try_convert_to_string(element)) {
670 argv =
emalloc(2 *
sizeof(
char *));
679 envc = zend_hash_num_elements(envs_hash);
681 size_t envp_len = (envc + 1);
682 pair = envp =
safe_emalloc(envp_len,
sizeof(
char *), 0);
683 memset(envp, 0,
sizeof(
char *) * envp_len);
685 if (envi >= envc)
break;
689 zend_string_addref(
key);
692 if (!try_convert_to_string(element)) {
693 zend_string_release(
key);
694 goto cleanup_env_vars;
702 strlcat(*pair,
"=", pair_length);
712 if (execve(path, argv, envp) == -1) {
719 for (pair = envp; *pair !=
NULL; pair++)
efree(*pair);
723 if (execv(path, argv) == -1) {
740 bool restart_syscalls = 1;
741 bool restart_syscalls_is_null = 1;
776 restart_syscalls = 0;
825 int sigmax =
NSIG - 1;
850 pcntl_signal_dispatch();
856#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) || defined(HAVE_SIGPROCMASK)
857static bool php_pcntl_set_user_signal_infos(
861 bool allow_empty_signal_array
863 if (!allow_empty_signal_array && zend_hash_num_elements(user_signals) == 0) {
869 if (sigemptyset(set) != 0) {
875 zval *user_signal_no;
892 int signal_no = (int) tmp;
894 if (sigaddset(set, signal_no) != 0) {
904#ifdef HAVE_SIGPROCMASK
927 if (sigemptyset(&old_set) != 0) {
934 bool status = php_pcntl_set_user_signal_infos(user_set, &set, 2, how ==
SIG_SETMASK);
940 if (sigprocmask(how, &set, &old_set) != 0) {
946 if (user_old_set !=
NULL) {
947 user_old_set = zend_try_array_init(user_old_set);
953 if (sigismember(&old_set, signal_no) != 1) {
965#ifdef HAVE_STRUCT_SIGINFO_T
966# ifdef HAVE_SIGWAITINFO
982 bool status = php_pcntl_set_user_signal_infos(user_set, &set, 1, false);
990 int signal_no = sigwaitinfo(&set, &siginfo);
992 if (signal_no == -1) {
999 if (!signal_no && siginfo.si_signo) {
1000 signal_no = siginfo.si_signo;
1003 pcntl_siginfo_to_zval(signal_no, &siginfo, user_siginfo);
1009# ifdef HAVE_SIGTIMEDWAIT
1028 bool status = php_pcntl_set_user_signal_infos(user_set, &set, 1, false);
1038 if (tv_nsec < 0 || tv_nsec >= 1000000000) {
1042 if (
UNEXPECTED(tv_sec == 0 && tv_nsec == 0)) {
1043 zend_value_error(
"pcntl_sigtimedwait(): At least one of argument #3 ($seconds) or argument #4 ($nanoseconds) must be greater than 0");
1052 int signal_no = sigtimedwait(&set, &siginfo, &timeout);
1053 if (signal_no == -1) {
1062 if (!signal_no && siginfo.si_signo) {
1063 signal_no = siginfo.si_signo;
1066 pcntl_siginfo_to_zval(signal_no, &siginfo, user_siginfo);
1073static void pcntl_siginfo_to_zval(
int signo, siginfo_t *siginfo,
zval *user_siginfo)
1075 if (signo > 0 && user_siginfo) {
1076 user_siginfo = zend_try_array_init(user_siginfo);
1077 if (!user_siginfo) {
1087 add_assoc_long_ex(user_siginfo,
"status",
sizeof(
"status")-1, siginfo->si_status);
1109#if defined(SIGPOLL) && !defined(__CYGWIN__)
1120# if defined(si_syscall) && defined(__FreeBSD__)
1121 if (siginfo->si_code == TRAP_CAP) {
1132#if defined(SIGRTMIN) && defined(SIGRTMAX)
1143#ifdef HAVE_GETPRIORITY
1149 bool pid_is_null = 1;
1161 pid = pid_is_null ? 0 : pid;
1162 pri = getpriority(who, pid);
1171#ifdef PRIO_DARWIN_BG
1199#ifdef HAVE_SETPRIORITY
1205 bool pid_is_null = 1;
1215 pid = pid_is_null ? 0 : pid;
1217 if (setpriority(who, pid, pri)) {
1224#ifdef PRIO_DARWIN_BG
1283#ifdef HAVE_STRUCT_SIGINFO_T
1284static void pcntl_signal_handler(
int signo, siginfo_t *siginfo,
void *
context)
1286static void pcntl_signal_handler(
int signo)
1299#ifdef HAVE_STRUCT_SIGINFO_T
1300 psig->siginfo = *siginfo;
1313 zend_atomic_bool_store_ex(&
EG(vm_interrupt),
true);
1317void pcntl_signal_dispatch(
void)
1330 sigprocmask(
SIG_BLOCK, &mask, &old_mask);
1353#ifdef HAVE_STRUCT_SIGINFO_T
1355 pcntl_siginfo_to_zval(queue->
signo, &queue->siginfo, ¶ms[1]);
1364#ifdef HAVE_STRUCT_SIGINFO_T
1388static void pcntl_signal_dispatch_tick_function(
int dummy_int,
void *dummy_pointer)
1390 return pcntl_signal_dispatch();
1396 bool on, on_is_null = 1;
1427 zend_argument_value_error(1,
"must be a combination of CLONE_* flags, or at least one flag is unsupported by the kernel");
1484 if ((
flags & RFSIGSHARE) != 0) {
1501 flags |= RFTSIGFLAGS(csignal);
1567#ifdef HAVE_PIDFD_OPEN
1573 bool pid_is_null = 1;
1582 pid = pid_is_null ? getpid() : pid;
1583 fd = syscall(SYS_pidfd_open, pid, 0);
1609 ret = setns(
fd, (
int)nstype);
1637#ifdef HAVE_SCHED_SETAFFINITY
1641 bool pid_is_null = 1;
1650 pid = pid_is_null ? 0 : pid;
1652 PCNTL_CPU_ZERO(mask);
1654 if (sched_getaffinity(pid, PCNTL_CPUSET_SIZE(mask), PCNTL_CPUSET(mask)) != 0) {
1655 PCNTL_CPU_DESTROY(mask);
1678 if (PCNTL_CPU_ISSET(i, mask)) {
1682 PCNTL_CPU_DESTROY(mask);
1688 bool pid_is_null = 1;
1699 if (!hmask || zend_hash_num_elements(
Z_ARRVAL_P(hmask)) == 0) {
1705 pid = pid_is_null ? 0 : pid;
1706 zend_long maxcpus = sysconf(_SC_NPROCESSORS_CONF);
1707 PCNTL_CPU_ZERO(mask);
1717 PCNTL_CPU_DESTROY(mask);
1724 PCNTL_CPU_DESTROY(mask);
1731 if (cpu < 0 || cpu >= maxcpus) {
1736 if (!PCNTL_CPU_ISSET(cpu, mask)) {
1737 PCNTL_CPU_SET(cpu, mask);
1741 if (sched_setaffinity(pid, PCNTL_CPUSET_SIZE(mask), PCNTL_CPUSET(mask)) != 0) {
1742 PCNTL_CPU_DESTROY(mask);
1759 PCNTL_CPU_DESTROY(mask);
1765#if defined(HAVE_SCHED_GETCPU)
1774#if defined(HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP)
1775static qos_class_t qos_zval_to_lval(
const zval *qos_obj)
1777 qos_class_t qos_class = QOS_CLASS_DEFAULT;
1781 qos_class = QOS_CLASS_USER_INTERACTIVE;
1783 qos_class = QOS_CLASS_USER_INITIATED;
1785 qos_class = QOS_CLASS_UTILITY;
1787 qos_class = QOS_CLASS_BACKGROUND;
1793static zend_object *qos_lval_to_zval(qos_class_t qos_class)
1795 const char *entryname;
1798 case QOS_CLASS_USER_INTERACTIVE:
1799 entryname =
"UserInteractive";
1801 case QOS_CLASS_USER_INITIATED:
1802 entryname =
"UserInitiated";
1804 case QOS_CLASS_UTILITY:
1805 entryname =
"Utility";
1807 case QOS_CLASS_BACKGROUND:
1808 entryname =
"Background";
1810 case QOS_CLASS_DEFAULT:
1812 entryname =
"Default";
1821 qos_class_t qos_class;
1825 if (
UNEXPECTED(pthread_get_qos_class_np(pthread_self(), &qos_class,
NULL) != 0))
1844 qos_class_t qos_class = qos_zval_to_lval(qos_obj);
1846 if (
UNEXPECTED(pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0))
1858 pcntl_signal_dispatch();
1859 if (orig_interrupt_function) {
memset(ptr, 0, type->size)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
zend_module_entry pcntl_module_entry
#define PHP_RUSAGE_TO_ARRAY(from, to)
pcntl_signal(int $signal, $handler, bool $restart_syscalls=true)
pcntl_wait(&$status, int $flags=0, &$resource_usage=[])
pcntl_wifstopped(int $status)
pcntl_signal_get_handler(int $signal)
pcntl_waitpid(int $process_id, &$status, int $flags=0, &$resource_usage=[])
pcntl_setcpuaffinity(?int $process_id=null, array $cpu_ids=[])
pcntl_exec(string $path, array $args=[], array $env_vars=[])
pcntl_wifcontinued(int $status)
pcntl_getpriority(?int $process_id=null, int $mode=PRIO_PROCESS)
pcntl_alarm(int $seconds)
pcntl_wstopsig(int $status)
pcntl_wexitstatus(int $status)
pcntl_strerror(int $error_code)
pcntl_sigprocmask(int $mode, array $signals, &$old_signals=null)
pcntl_setpriority(int $priority, ?int $process_id=null, int $mode=PRIO_PROCESS)
pcntl_sigtimedwait(array $signals, &$info=[], int $seconds=0, int $nanoseconds=0)
pcntl_wifsignaled(int $status)
pcntl_sigwaitinfo(array $signals, &$info=[])
pcntl_getcpuaffinity(?int $process_id=null)
pcntl_rfork(int $flags, int $signal=0)
pcntl_waitid(int $idtype=P_ALL, ?int $id=null, &$info=[], int $flags=WEXITED)
pcntl_wtermsig(int $status)
pcntl_setqos_class(Pcntl\QosClass $qos_class=Pcntl\QosClass::Default)
pcntl_setns(?int $process_id=null, int $nstype=CLONE_NEWNET)
pcntl_unshare(int $flags)
pcntl_wifexited(int $status)
pcntl_async_signals(?bool $enable=null)
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_MINFO_FUNCTION
#define PHP_GINIT_FUNCTION
#define PHP_RINIT_FUNCTION
#define PHP_RSHUTDOWN_FUNCTION
#define PHP_MODULE_GLOBALS
PHP_JSON_API size_t int options
#define PHP_PCNTL_VERSION
struct php_pcntl_pending_signal * head
int processing_signal_queue
volatile char pending_signals
struct php_pcntl_pending_signal * tail
struct php_pcntl_pending_signal * spares
HashTable php_signal_table
unsigned char key[REFLECTION_KEY_LEN]
Sigfunc * php_signal(int signo, Sigfunc *func, int restart)
Sigfunc * php_signal4(int signo, Sigfunc *func, int restart, int mask_all)
PHPAPI void php_add_tick_function(void(*func)(int, void *), void *arg)
struct php_pcntl_pending_signal * next
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
ZEND_API void(* zend_interrupt_function)(zend_execute_data *execute_data)
#define ZEND_TSRMLS_CACHE_UPDATE()
#define ZEND_TSRMLS_CACHE_DEFINE()
ZEND_API const char * zend_zval_value_name(const zval *arg)
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
ZEND_API void add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d)
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error)
ZEND_API void add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
#define ZEND_PARSE_PARAMETERS_END()
#define ZEND_PARSE_PARAMETERS_NONE()
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define ZEND_GET_MODULE(name)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_BOOL_OR_NULL(dest, is_null)
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
#define Z_PARAM_LONG(dest)
#define RETURN_OBJ_COPY(r)
#define Z_PARAM_ARRAY_HT(dest)
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
#define call_user_function(function_table, object, function_name, retval_ptr, param_count, params)
#define Z_PARAM_OBJECT_OF_CLASS(dest, _ce)
#define Z_PARAM_PATH(dest, dest_len)
#define Z_PARAM_ARRAY(dest)
#define Z_PARAM_ZVAL(dest)
#define safe_emalloc(nmemb, size, offset)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_object * zend_enum_get_case_cstr(zend_class_entry *ce, const char *name)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API void zend_fiber_switch_unblock(void)
ZEND_API void zend_fiber_switch_block(void)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, _h, _val)
#define ZEND_HANDLE_NUMERIC(key, idx)
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
struct _zend_string zend_string
#define zend_max_execution_timer_init()
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
ZEND_API zend_string *ZEND_FASTCALL zend_long_to_str(zend_long num)
ZEND_API zend_long ZEND_FASTCALL zval_try_get_long(const zval *op, bool *failed)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define zend_string_equals_literal(str, literal)
#define Z_TRY_ADDREF_P(pz)
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
#define SEPARATE_ARRAY(zv)
struct _zend_execute_data zend_execute_data
ZEND_API void zval_ptr_dtor(zval *zval_ptr)