diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index e1aedb101c91..b6f492f6a78c 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1265,7 +1265,8 @@ PHP_FUNCTION(pcntl_getpriority) /* needs to be cleared, since any returned value is valid */ errno = 0; - pri = getpriority(who, pid_is_null ? getpid() : pid); + pid = pid_is_null ? getpid() : pid; + pri = getpriority(who, pid); if (errno) { PCNTL_G(last_error) = errno; @@ -1274,8 +1275,22 @@ PHP_FUNCTION(pcntl_getpriority) php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno); break; case EINVAL: +#ifdef PRIO_DARWIN_BG + if (who != PRIO_PGRP && who != PRIO_USER && who != PRIO_PROCESS && who != PRIO_DARWIN_THREAD) { + zend_argument_value_error(2, "must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD"); + RETURN_THROWS(); + } else if (who == PRIO_DARWIN_THREAD && pid != 0) { + zend_argument_value_error(1, "must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter"); + RETURN_THROWS(); + } else { + zend_argument_value_error(1, "is not a valid process, process group, or user ID"); + RETURN_THROWS(); + } +#else zend_argument_value_error(2, "must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS"); RETURN_THROWS(); +#endif + default: php_error_docref(NULL, E_WARNING, "Unknown error %d has occurred", errno); break; @@ -1304,15 +1319,33 @@ PHP_FUNCTION(pcntl_setpriority) Z_PARAM_LONG(who) ZEND_PARSE_PARAMETERS_END(); - if (setpriority(who, pid_is_null ? getpid() : pid, pri)) { + pid = pid_is_null ? getpid() : pid; + + if (setpriority(who, pid, pri)) { PCNTL_G(last_error) = errno; switch (errno) { case ESRCH: php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno); break; case EINVAL: +#ifdef PRIO_DARWIN_BG + if (who != PRIO_PGRP && who != PRIO_USER && who != PRIO_PROCESS && who != PRIO_DARWIN_THREAD) { + zend_argument_value_error(3, "must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD"); + RETURN_THROWS(); + } else if (who == PRIO_DARWIN_THREAD && pid != 0) { + zend_argument_value_error(2, "must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter"); + RETURN_THROWS(); + } else if (who == PRIO_DARWIN_THREAD && pid == 0 && (pri != 0 && pri != PRIO_DARWIN_BG)) { + zend_argument_value_error(1, "must be either 0 (zero) or PRIO_DARWIN_BG, for mode PRIO_DARWIN_THREAD"); + RETURN_THROWS(); + } else { + zend_argument_value_error(2, "is not a valid process, process group, or user ID"); + RETURN_THROWS(); + } +#else zend_argument_value_error(3, "must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS"); RETURN_THROWS(); +#endif case EPERM: 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); break; diff --git a/ext/pcntl/tests/pcntl_getpriority_error.phpt b/ext/pcntl/tests/pcntl_getpriority_error.phpt index 4339e0ebf483..19936f0b59da 100644 --- a/ext/pcntl/tests/pcntl_getpriority_error.phpt +++ b/ext/pcntl/tests/pcntl_getpriority_error.phpt @@ -1,5 +1,5 @@ --TEST-- -pcntl_getpriority() - Wrong process identifier +pcntl_getpriority() - Wrong mode passed and also for non existing process id provided --EXTENSIONS-- pcntl --SKIPIF-- @@ -8,16 +8,26 @@ pcntl if (!function_exists('pcntl_getpriority')) { die('skip pcntl_getpriority doesn\'t exist'); } + +if (PHP_OS == "Darwin") { + die("skip This test is not for Darwin"); +} + ?> --FILE-- getMessage() . "\n"; } +// Different behavior in MacOS than rest of operating systems +pcntl_getpriority(-1, PRIO_PROCESS); + ?> ---EXPECT-- +--EXPECTF-- pcntl_getpriority(): Argument #2 ($mode) must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS + +Warning: pcntl_getpriority(): Error %d: No process was located using the given parameters in %s diff --git a/ext/pcntl/tests/pcntl_getpriority_error_darwin.phpt b/ext/pcntl/tests/pcntl_getpriority_error_darwin.phpt new file mode 100644 index 000000000000..8c7f1c5c726d --- /dev/null +++ b/ext/pcntl/tests/pcntl_getpriority_error_darwin.phpt @@ -0,0 +1,43 @@ +--TEST-- +pcntl_getpriority() - Wrong mode passed and also for non existing process id provided +--EXTENSIONS-- +pcntl +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +try { + pcntl_getpriority(-1, PRIO_DARWIN_THREAD); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + // Different behavior in MacOS than rest of operating systems + pcntl_getpriority(-1, PRIO_PROCESS); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +pcntl_getpriority(): Argument #2 ($mode) must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD +pcntl_getpriority(): Argument #1 ($process_id) must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter +pcntl_getpriority(): Argument #1 ($process_id) is not a valid process, process group, or user ID diff --git a/ext/pcntl/tests/pcntl_setpriority_error.phpt b/ext/pcntl/tests/pcntl_setpriority_error.phpt index cdb8d404afcd..418b6bb58816 100644 --- a/ext/pcntl/tests/pcntl_setpriority_error.phpt +++ b/ext/pcntl/tests/pcntl_setpriority_error.phpt @@ -1,5 +1,5 @@ --TEST-- -pcntl_setpriority() - Wrong process identifier +pcntl_setpriority() - Check for errors --EXTENSIONS-- pcntl --SKIPIF-- @@ -8,16 +8,25 @@ pcntl if (!function_exists('pcntl_setpriority')) { die('skip pcntl_setpriority doesn\'t exist'); } + +if (PHP_OS == "Darwin") { + die("skip This test is not for Darwin"); +} + ?> --FILE-- getMessage() . "\n"; } +pcntl_setpriority(0, -123); + ?> ---EXPECT-- +--EXPECTF-- pcntl_setpriority(): Argument #3 ($mode) must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS + +Warning: pcntl_setpriority(): Error 3: No process was located using the given parameters in %s diff --git a/ext/pcntl/tests/pcntl_setpriority_error_darwin.phpt b/ext/pcntl/tests/pcntl_setpriority_error_darwin.phpt new file mode 100644 index 000000000000..9596b8f7e038 --- /dev/null +++ b/ext/pcntl/tests/pcntl_setpriority_error_darwin.phpt @@ -0,0 +1,46 @@ +--TEST-- +pcntl_setpriority() - Check for errors +--EXTENSIONS-- +pcntl +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +try { + pcntl_setpriority(0, -1, PRIO_DARWIN_THREAD); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + pcntl_setpriority(0, -123); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +pcntl_setpriority(-1000, 1); + +?> +--EXPECTF-- +pcntl_setpriority(): Argument #3 ($mode) must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD +pcntl_setpriority(): Argument #2 ($process_id) must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter +pcntl_setpriority(): Argument #2 ($process_id) is not a valid process, process group, or user ID + +Warning: pcntl_setpriority(): Error 1: A process was located, but neither its effective nor real user ID matched the effective user ID of the caller in %s diff --git a/ext/pcntl/tests/pcntl_setpriority_error_linux.phpt b/ext/pcntl/tests/pcntl_setpriority_error_linux.phpt new file mode 100644 index 000000000000..8d9249d15702 --- /dev/null +++ b/ext/pcntl/tests/pcntl_setpriority_error_linux.phpt @@ -0,0 +1,27 @@ +--TEST-- +pcntl_setpriority() - Check for errors +--EXTENSIONS-- +pcntl +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: pcntl_setpriority(): Error 1: A process was located, but neither its effective nor real user ID matched the effective user ID of the caller in %s + +Warning: pcntl_setpriority(): Error 13: Only a super user may attempt to increase the process priority in %s on line %d