@@ -125,7 +125,15 @@ typedef psetid_t cpu_set_t;
125125#include <pthread/qos.h>
126126#endif
127127
128- #ifdef HAVE_PIDFD_OPEN
128+ #if defined(__linux__ ) && defined(HAVE_DECL_SYS_WAITID ) && HAVE_DECL_SYS_WAITID == 1 && defined(HAVE_SYSCALL )
129+ #define HAVE_LINUX_RAW_SYSCALL_WAITID 1
130+ #endif
131+
132+ #if defined(HAVE_LINUX_RAW_SYSCALL_WAITID )
133+ #include <unistd.h>
134+ #endif
135+
136+ #if defined(HAVE_PIDFD_OPEN ) || defined(HAVE_LINUX_RAW_SYSCALL_WAITID )
129137#include <sys/syscall.h>
130138#endif
131139
@@ -401,19 +409,49 @@ PHP_FUNCTION(pcntl_waitid)
401409 bool id_is_null = 1 ;
402410 zval * user_siginfo = NULL ;
403411 zend_long options = WEXITED ;
412+ zval * z_rusage = NULL ;
404413
405- ZEND_PARSE_PARAMETERS_START (0 , 4 )
414+ siginfo_t siginfo ;
415+ int status ;
416+
417+ ZEND_PARSE_PARAMETERS_START (0 , 5 )
406418 Z_PARAM_OPTIONAL
407419 Z_PARAM_LONG (idtype )
408420 Z_PARAM_LONG_OR_NULL (id , id_is_null )
409421 Z_PARAM_ZVAL (user_siginfo )
410422 Z_PARAM_LONG (options )
423+ Z_PARAM_ZVAL (z_rusage )
411424 ZEND_PARSE_PARAMETERS_END ();
412425
413426 errno = 0 ;
414- siginfo_t siginfo ;
427+ memset ( & siginfo , 0 , sizeof ( siginfo_t )) ;
415428
416- int status = waitid ((idtype_t ) idtype , (id_t ) id , & siginfo , (int ) options );
429+ #if defined(HAVE_WAIT6 ) || defined(HAVE_LINUX_RAW_SYSCALL_WAITID )
430+ if (z_rusage ) {
431+ z_rusage = zend_try_array_init (z_rusage );
432+ if (!z_rusage ) {
433+ RETURN_THROWS ();
434+ }
435+ struct rusage rusage ;
436+ # if defined(HAVE_WAIT6 ) /* FreeBSD */
437+ struct __wrusage wrusage ;
438+ memset (& wrusage , 0 , sizeof (struct __wrusage ));
439+ pid_t pid = wait6 ((idtype_t ) idtype , (id_t ) id , & status , (int ) options , & wrusage , & siginfo );
440+ status = pid > 0 ? 0 : pid ;
441+ memcpy (& rusage , & wrusage .wru_self , sizeof (struct rusage ));
442+ # else /* Linux */
443+ memset (& rusage , 0 , sizeof (struct rusage ));
444+ status = syscall (SYS_waitid , (idtype_t ) idtype , (id_t ) id , & siginfo , (int ) options , & rusage );
445+ # endif
446+ if (status == 0 ) {
447+ PHP_RUSAGE_TO_ARRAY (rusage , z_rusage );
448+ }
449+ } else { /* POSIX */
450+ status = waitid ((idtype_t ) idtype , (id_t ) id , & siginfo , (int ) options );
451+ }
452+ #else /* POSIX */
453+ status = waitid ((idtype_t ) idtype , (id_t ) id , & siginfo , (int ) options );
454+ #endif
417455
418456 if (status == -1 ) {
419457 PCNTL_G (last_error ) = errno ;
0 commit comments