Skip to content

Commit 520bb2e

Browse files
jcmcmb69
jcm
authored andcommitted
Fix get/set priority - error handling for MacOS and extra tests
Closes phpGH-9044.
1 parent a398a2f commit 520bb2e

7 files changed

+179
-8
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ PHP NEWS
2121
. Fixed bug GH-9090 (Support assigning function pointers in FFI). (Adam
2222
Saponara)
2323

24+
- PCNTL:
25+
. Fixed pcntl_(get|set)priority error handling for MacOS. (Juan Morales)
26+
2427
- Random:
2528
. Fixed bug GH-9067 (random extension is not thread safe). (cmb)
2629
. Fixed bug GH-9055 (segmentation fault if user engine throws). (timwolla)

ext/pcntl/pcntl.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,8 @@ PHP_FUNCTION(pcntl_getpriority)
12651265
/* needs to be cleared, since any returned value is valid */
12661266
errno = 0;
12671267

1268-
pri = getpriority(who, pid_is_null ? getpid() : pid);
1268+
pid = pid_is_null ? getpid() : pid;
1269+
pri = getpriority(who, pid);
12691270

12701271
if (errno) {
12711272
PCNTL_G(last_error) = errno;
@@ -1274,8 +1275,22 @@ PHP_FUNCTION(pcntl_getpriority)
12741275
php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno);
12751276
break;
12761277
case EINVAL:
1278+
#ifdef PRIO_DARWIN_BG
1279+
if (who != PRIO_PGRP && who != PRIO_USER && who != PRIO_PROCESS && who != PRIO_DARWIN_THREAD) {
1280+
zend_argument_value_error(2, "must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD");
1281+
RETURN_THROWS();
1282+
} else if (who == PRIO_DARWIN_THREAD && pid != 0) {
1283+
zend_argument_value_error(1, "must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter");
1284+
RETURN_THROWS();
1285+
} else {
1286+
zend_argument_value_error(1, "is not a valid process, process group, or user ID");
1287+
RETURN_THROWS();
1288+
}
1289+
#else
12771290
zend_argument_value_error(2, "must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS");
12781291
RETURN_THROWS();
1292+
#endif
1293+
12791294
default:
12801295
php_error_docref(NULL, E_WARNING, "Unknown error %d has occurred", errno);
12811296
break;
@@ -1304,15 +1319,33 @@ PHP_FUNCTION(pcntl_setpriority)
13041319
Z_PARAM_LONG(who)
13051320
ZEND_PARSE_PARAMETERS_END();
13061321

1307-
if (setpriority(who, pid_is_null ? getpid() : pid, pri)) {
1322+
pid = pid_is_null ? getpid() : pid;
1323+
1324+
if (setpriority(who, pid, pri)) {
13081325
PCNTL_G(last_error) = errno;
13091326
switch (errno) {
13101327
case ESRCH:
13111328
php_error_docref(NULL, E_WARNING, "Error %d: No process was located using the given parameters", errno);
13121329
break;
13131330
case EINVAL:
1331+
#ifdef PRIO_DARWIN_BG
1332+
if (who != PRIO_PGRP && who != PRIO_USER && who != PRIO_PROCESS && who != PRIO_DARWIN_THREAD) {
1333+
zend_argument_value_error(3, "must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD");
1334+
RETURN_THROWS();
1335+
} else if (who == PRIO_DARWIN_THREAD && pid != 0) {
1336+
zend_argument_value_error(2, "must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter");
1337+
RETURN_THROWS();
1338+
} else if (who == PRIO_DARWIN_THREAD && pid == 0 && (pri != 0 && pri != PRIO_DARWIN_BG)) {
1339+
zend_argument_value_error(1, "must be either 0 (zero) or PRIO_DARWIN_BG, for mode PRIO_DARWIN_THREAD");
1340+
RETURN_THROWS();
1341+
} else {
1342+
zend_argument_value_error(2, "is not a valid process, process group, or user ID");
1343+
RETURN_THROWS();
1344+
}
1345+
#else
13141346
zend_argument_value_error(3, "must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS");
13151347
RETURN_THROWS();
1348+
#endif
13161349
case EPERM:
13171350
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);
13181351
break;
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
pcntl_getpriority() - Wrong process identifier
2+
pcntl_getpriority() - Wrong mode passed and also for non existing process id provided
33
--EXTENSIONS--
44
pcntl
55
--SKIPIF--
@@ -8,16 +8,26 @@ pcntl
88
if (!function_exists('pcntl_getpriority')) {
99
die('skip pcntl_getpriority doesn\'t exist');
1010
}
11+
12+
if (PHP_OS == "Darwin") {
13+
die("skip This test is not for Darwin");
14+
}
15+
1116
?>
1217
--FILE--
1318
<?php
1419

1520
try {
16-
pcntl_getpriority(null, 42);
21+
pcntl_getpriority(null, PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10);
1722
} catch (ValueError $exception) {
1823
echo $exception->getMessage() . "\n";
1924
}
2025

26+
// Different behavior in MacOS than rest of operating systems
27+
pcntl_getpriority(-1, PRIO_PROCESS);
28+
2129
?>
22-
--EXPECT--
30+
--EXPECTF--
2331
pcntl_getpriority(): Argument #2 ($mode) must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS
32+
33+
Warning: pcntl_getpriority(): Error %d: No process was located using the given parameters in %s
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
pcntl_getpriority() - Wrong mode passed and also for non existing process id provided
3+
--EXTENSIONS--
4+
pcntl
5+
--SKIPIF--
6+
<?php
7+
8+
if (!function_exists('pcntl_getpriority')) {
9+
die('skip pcntl_getpriority doesn\'t exist');
10+
}
11+
12+
if (PHP_OS !== "Darwin") {
13+
die("skip This test only runs on Darwin");
14+
}
15+
16+
?>
17+
--FILE--
18+
<?php
19+
20+
try {
21+
pcntl_getpriority(null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
22+
} catch (ValueError $exception) {
23+
echo $exception->getMessage() . "\n";
24+
}
25+
26+
try {
27+
pcntl_getpriority(-1, PRIO_DARWIN_THREAD);
28+
} catch (ValueError $exception) {
29+
echo $exception->getMessage() . "\n";
30+
}
31+
32+
try {
33+
// Different behavior in MacOS than rest of operating systems
34+
pcntl_getpriority(-1, PRIO_PROCESS);
35+
} catch (ValueError $exception) {
36+
echo $exception->getMessage() . "\n";
37+
}
38+
39+
?>
40+
--EXPECT--
41+
pcntl_getpriority(): Argument #2 ($mode) must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD
42+
pcntl_getpriority(): Argument #1 ($process_id) must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter
43+
pcntl_getpriority(): Argument #1 ($process_id) is not a valid process, process group, or user ID
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
pcntl_setpriority() - Wrong process identifier
2+
pcntl_setpriority() - Check for errors
33
--EXTENSIONS--
44
pcntl
55
--SKIPIF--
@@ -8,16 +8,25 @@ pcntl
88
if (!function_exists('pcntl_setpriority')) {
99
die('skip pcntl_setpriority doesn\'t exist');
1010
}
11+
12+
if (PHP_OS == "Darwin") {
13+
die("skip This test is not for Darwin");
14+
}
15+
1116
?>
1217
--FILE--
1318
<?php
1419

1520
try {
16-
pcntl_setpriority(0, null, 42);
21+
$result = pcntl_setpriority(0, null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
1722
} catch (ValueError $exception) {
1823
echo $exception->getMessage() . "\n";
1924
}
2025

26+
pcntl_setpriority(0, -123);
27+
2128
?>
22-
--EXPECT--
29+
--EXPECTF--
2330
pcntl_setpriority(): Argument #3 ($mode) must be one of PRIO_PGRP, PRIO_USER, or PRIO_PROCESS
31+
32+
Warning: pcntl_setpriority(): Error 3: No process was located using the given parameters in %s
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
pcntl_setpriority() - Check for errors
3+
--EXTENSIONS--
4+
pcntl
5+
--SKIPIF--
6+
<?php
7+
8+
if (!function_exists('pcntl_setpriority')) {
9+
die('skip pcntl_setpriority doesn\'t exist');
10+
}
11+
12+
if (PHP_OS !== "Darwin") {
13+
die("skip This test only runs on Darwin");
14+
}
15+
16+
?>
17+
--FILE--
18+
<?php
19+
20+
try {
21+
pcntl_setpriority(0, null, (PRIO_PGRP + PRIO_USER + PRIO_PROCESS + 10));
22+
} catch (ValueError $exception) {
23+
echo $exception->getMessage() . "\n";
24+
}
25+
26+
try {
27+
pcntl_setpriority(0, -1, PRIO_DARWIN_THREAD);
28+
} catch (ValueError $exception) {
29+
echo $exception->getMessage() . "\n";
30+
}
31+
32+
try {
33+
pcntl_setpriority(0, -123);
34+
} catch (ValueError $exception) {
35+
echo $exception->getMessage() . "\n";
36+
}
37+
38+
pcntl_setpriority(-1000, 1);
39+
40+
?>
41+
--EXPECTF--
42+
pcntl_setpriority(): Argument #3 ($mode) must be one of PRIO_PGRP, PRIO_USER, PRIO_PROCESS or PRIO_DARWIN_THREAD
43+
pcntl_setpriority(): Argument #2 ($process_id) must be 0 (zero) if PRIO_DARWIN_THREAD is provided as second parameter
44+
pcntl_setpriority(): Argument #2 ($process_id) is not a valid process, process group, or user ID
45+
46+
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
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
pcntl_setpriority() - Check for errors
3+
--EXTENSIONS--
4+
pcntl
5+
--SKIPIF--
6+
<?php
7+
8+
if (!function_exists('pcntl_setpriority')) {
9+
die('skip pcntl_setpriority doesn\'t exist');
10+
}
11+
12+
if (PHP_OS !== "Linux") {
13+
die("skip This test only runs on Linux");
14+
}
15+
16+
?>
17+
--FILE--
18+
<?php
19+
20+
pcntl_setpriority(-1000, 1);
21+
pcntl_setpriority(-1000, 0);
22+
23+
?>
24+
--EXPECTF--
25+
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
26+
27+
Warning: pcntl_setpriority(): Error 13: Only a super user may attempt to increase the process priority in %s on line %d

0 commit comments

Comments
 (0)