1
0
mirror of https://github.com/php/php-src.git synced 2026-03-28 10:12:18 +01:00

Fix get/set priority - error handling for MacOS and extra tests

Closes GH-9044.
This commit is contained in:
jcm
2022-07-22 18:38:59 +02:00
committed by Christoph M. Becker
parent a398a2fd3d
commit 520bb2ec6c
7 changed files with 179 additions and 8 deletions

3
NEWS
View File

@@ -21,6 +21,9 @@ PHP NEWS
. Fixed bug GH-9090 (Support assigning function pointers in FFI). (Adam
Saponara)
- PCNTL:
. Fixed pcntl_(get|set)priority error handling for MacOS. (Juan Morales)
- Random:
. Fixed bug GH-9067 (random extension is not thread safe). (cmb)
. Fixed bug GH-9055 (segmentation fault if user engine throws). (timwolla)

View File

@@ -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;

View File

@@ -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--
<?php
try {
pcntl_getpriority(null, 42);
pcntl_getpriority(null, PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10);
} catch (ValueError $exception) {
echo $exception->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

View File

@@ -0,0 +1,43 @@
--TEST--
pcntl_getpriority() - Wrong mode passed and also for non existing process id provided
--EXTENSIONS--
pcntl
--SKIPIF--
<?php
if (!function_exists('pcntl_getpriority')) {
die('skip pcntl_getpriority doesn\'t exist');
}
if (PHP_OS !== "Darwin") {
die("skip This test only runs on Darwin");
}
?>
--FILE--
<?php
try {
pcntl_getpriority(null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
} catch (ValueError $exception) {
echo $exception->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

View File

@@ -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--
<?php
try {
pcntl_setpriority(0, null, 42);
$result = pcntl_setpriority(0, null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
} catch (ValueError $exception) {
echo $exception->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

View File

@@ -0,0 +1,46 @@
--TEST--
pcntl_setpriority() - Check for errors
--EXTENSIONS--
pcntl
--SKIPIF--
<?php
if (!function_exists('pcntl_setpriority')) {
die('skip pcntl_setpriority doesn\'t exist');
}
if (PHP_OS !== "Darwin") {
die("skip This test only runs on Darwin");
}
?>
--FILE--
<?php
try {
pcntl_setpriority(0, null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
} catch (ValueError $exception) {
echo $exception->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

View File

@@ -0,0 +1,27 @@
--TEST--
pcntl_setpriority() - Check for errors
--EXTENSIONS--
pcntl
--SKIPIF--
<?php
if (!function_exists('pcntl_setpriority')) {
die('skip pcntl_setpriority doesn\'t exist');
}
if (PHP_OS !== "Linux") {
die("skip This test only runs on Linux");
}
?>
--FILE--
<?php
pcntl_setpriority(-1000, 1);
pcntl_setpriority(-1000, 0);
?>
--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