Refine some exceptions

This commit is contained in:
J. King 2021-06-21 19:51:27 -04:00
parent b9fd9ac32e
commit 5b3e8fbef0
2 changed files with 19 additions and 9 deletions

View file

@ -109,6 +109,10 @@ abstract class AbstractException extends \Exception {
"Service/Exception.pidUnreadable" => 10805,
"Service/Exception.pidUnwritable" => 10806,
"Service/Exception.pidUncreatable" => 10807,
"Service/Exception.pidCorrupt" => 10808,
"Service/Exception.pidDuplicate" => 10809,
"Service/Exception.pidLocked" => 10810,
"Service/Exception.pidInaccessible" => 10811,
];
protected $symbol;

View file

@ -7,6 +7,8 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Service;
class Daemon {
protected const PID_PATTERN = "/^(?:[1-9]\d{0,77})*$/s"; // no more than 78 digits (256-bit unsigned integer), starting with a digit other than zero
/** Daemonizes the process via the traditional sysvinit double-fork procedure
*
* @codeCoverageIgnore
@ -20,7 +22,7 @@ class Daemon {
# Reset all signal handlers to their default. This is best done by iterating through the available signals up to the limit of _NSIG and resetting them to SIG_DFL.
// We have not yet set any signal handlers, so this should be fine
# Reset the signal mask using sigprocmask().
// Not possible to my knowledge
pcntl_sigprocmask(\SIG_SETMASK, []);
# Sanitize the environment block, removing or resetting environment variables that might negatively impact daemon runtime.
//Not necessary; we don't use the environment
# Call fork(), to create a background process.
@ -77,10 +79,12 @@ class Daemon {
protected function checkPID(string $pidfile) {
if (file_exists($pidfile)) {
$pid = (string) @file_get_contents($pidfile);
if (preg_match("/^\d+$/s", $pid)) {
if ($this->processExists((int) $pid)) {
throw new \Exception("Process already exists");
if (preg_match(static::PID_PATTERN, $pid)) {
if (strlen($pid) && $this->processExists((int) $pid)) {
throw new Exception("pidDuplicate", ['pid' => $pid]);
}
} else {
throw new Exception("pidCorrupt", ['pidfile' => $pidfile]);
}
}
}
@ -89,11 +93,13 @@ class Daemon {
if ($f = @fopen($pidfile, "c+")) {
if (@flock($f, \LOCK_EX | \LOCK_NB)) {
// confirm that some other process didn't get in before us
$pid = fread($f, 100);
if (preg_match("/^\d+$/s", (string) $pid)) {
$pid = fread($f, 80);
if (preg_match(static::PID_PATTERN, (string) $pid)) {
if ($this->processExists((int) $pid)) {
throw new \Exception("Process already exists");
throw new Exception("pidDuplicate", ['pid' => $pid]);
}
} else {
throw new Exception("pidCorrupt", ['pidfile' => $pidfile]);
}
// write the PID to the pidfile
rewind($f);
@ -101,10 +107,10 @@ class Daemon {
fwrite($f, (string) posix_getpid());
fclose($f);
} else {
throw new \Exception("Process already exists");
throw new Exception("pidLocked", ['pidfile' => $pidfile]);
}
} else {
throw new \Exception("Could not write to PID file");
throw new Exception("pidInaccessible", ['pidfile' => $pidfile]);
}
}