@@ -340,6 +340,36 @@ void php_register_signal_constants(INIT_FUNC_ARGS)
340340 REGISTER_LONG_CONSTANT ("CLONE_NEWCGROUP" , CLONE_NEWCGROUP , CONST_CS | CONST_PERSISTENT );
341341#endif
342342#endif
343+
344+ #ifdef HAVE_RFORK
345+ #ifdef RFPROC
346+ REGISTER_LONG_CONSTANT ("RFPROC" , RFPROC , CONST_CS | CONST_PERSISTENT );
347+ #endif
348+ #ifdef RFNOWAIT
349+ REGISTER_LONG_CONSTANT ("RFNOWAIT" , RFNOWAIT , CONST_CS | CONST_PERSISTENT );
350+ #endif
351+ #ifdef RFCFDG
352+ REGISTER_LONG_CONSTANT ("RFCFDG" , RFCFDG , CONST_CS | CONST_PERSISTENT );
353+ #endif
354+ #ifdef RFFDG
355+ REGISTER_LONG_CONSTANT ("RFFDG" , RFFDG , CONST_CS | CONST_PERSISTENT );
356+ #endif
357+ #ifdef RFLINUXTHPN
358+ REGISTER_LONG_CONSTANT ("RFLINUXTHPN" , RFLINUXTHPN , CONST_CS | CONST_PERSISTENT );
359+ #endif
360+ #ifdef RFMEM
361+ REGISTER_LONG_CONSTANT ("RFMEM" , RFMEM , CONST_CS | CONST_PERSISTENT );
362+ #endif
363+ #ifdef RFSIGSHARE
364+ REGISTER_LONG_CONSTANT ("RFSIGSHARE" , RFSIGSHARE , CONST_CS | CONST_PERSISTENT );
365+ #endif
366+ #ifdef RFSIGZMB
367+ REGISTER_LONG_CONSTANT ("RFSIGSZMB" , RFSIGSZMB , CONST_CS | CONST_PERSISTENT );
368+ #endif
369+ #ifdef RFTHREAD
370+ REGISTER_LONG_CONSTANT ("RFTHREAD" , RFTHREAD , CONST_CS | CONST_PERSISTENT );
371+ #endif
372+ #endif
343373}
344374
345375static void php_pcntl_register_errno_constants (INIT_FUNC_ARGS )
@@ -1468,6 +1498,54 @@ PHP_FUNCTION(pcntl_unshare)
14681498/* }}} */
14691499#endif
14701500
1501+ #ifdef HAVE_RFORK
1502+ /* {{{ proto bool pcntl_rfork([int flags|custom signal)
1503+ More control over the process creation is given over fork/vfork. */
1504+ PHP_FUNCTION (pcntl_rfork )
1505+ {
1506+ zend_long flags ;
1507+ zend_long csignal ;
1508+ pid_t pid ;
1509+
1510+ ZEND_PARSE_PARAMETERS_START (1 , 2 )
1511+ Z_PARAM_LONG (flags )
1512+ Z_PARAM_OPTIONAL
1513+ Z_PARAM_LONG (csignal )
1514+ ZEND_PARSE_PARAMETERS_END ();
1515+
1516+ /* This is a flag to use with great caution in general, preferably not within PHP */
1517+ if ((flags & RFMEM ) != 0 ) {
1518+ flags &= ~RFMEM ;
1519+ }
1520+
1521+ /* A new pid is required */
1522+ flags |= RFPROC ;
1523+
1524+ if (ZEND_NUM_ARGS () == 2 && (flags & RFTSIGZMB ) != 0 ) {
1525+ flags |= RFTSIGFLAGS (csignal );
1526+ }
1527+
1528+ pid = rfork (flags );
1529+
1530+ if (pid == -1 ) {
1531+ PCNTL_G (last_error ) = errno ;
1532+ switch (errno ) {
1533+ case EINVAL :
1534+ php_error_docref (NULL , E_WARNING , "RFFDG and RFCFDG modes are mutually exclusive" );
1535+ break ;
1536+ case EAGAIN :
1537+ php_error_docref (NULL , E_WARNING , "Maximum process creations limit reached\n" );
1538+ break ;
1539+ default :
1540+ php_error_docref (NULL , E_WARNING , "Error %d" , errno );
1541+ }
1542+ }
1543+
1544+ RETURN_LONG ((zend_long ) pid );
1545+ }
1546+ #endif
1547+ /* }}} */
1548+
14711549static void pcntl_interrupt_function (zend_execute_data * execute_data )
14721550{
14731551 pcntl_signal_dispatch ();
0 commit comments