/** * Запуск сервиса. * * @access protected * @static */ protected static function cmdStart() { echo "Starting Pinger service... "; try { // проверка PID-файла Assets\PID::PreLock(); $ruid = posix_getpwnam(Assets\Config::$exec_user)['uid']; $rgid = posix_getgrnam(Assets\Config::$exec_group)['gid']; if (null === $ruid || null === $rgid) { printf(" [FAIL]\nRequired exec user:group [%s:%s] was not found.\n", Assets\Config::$exec_user, Assets\Config::$exec_group); exit(1); } // попытка запуска Мастер-процесса $pid = @pcntl_fork(); if ($pid == -1) { // ошибка ветвления throw new Assets\Exceptions\Master_Fork_Fail_Exception(); } elseif ($pid) { // // рутины родительского процесса - сценария SBINDIR/pinger // printf(" [OK]\nLooks like Master forked with PID=%d\n", $pid); exit(0); } else { // // рутины дочернего процесса - Мастер-процесса // // переключение группы-владельца процесса // выполняется ДО переключения пользователя-владельца if (!posix_setegid($rgid)) { printf("Failed to posix_setegid(%d) [%s].\n", $rgid, Assets\Config::$exec_group); exit(1); } // переключение пользователя-владельца процесса if (!posix_seteuid($ruid)) { printf("Failed to posix_seteuid(%d) [%s].\n", $ruid, Assets\Config::$exec_user); exit(1); } // открытие журналов TwinLog::init(PINGER_LOGDIR, 'Master'); // закрытие дескрипторов @fclose(STDIN); @fclose(STDOUT); @fclose(STDERR); // вход в Мастер-процесс Daemon\Master::main(); // закрытие журналов TwinLog::kill(); // успешный выход // exit(0) не используется для возможности перезапуска // с применением этого метода } } catch (Assets\Exceptions\PID_Open_Fail_Exception $e) { echo " [FAIL]\n PID-file exists but unreadable\n"; exit(1); } catch (Assets\Exceptions\PID_Lock_Fail_Exception $e) { printf("\n Daemon already running with PID=%d", Assets\PID::$pid); exit(1); } catch (Assets\Exceptions\PID_Read_Fail_Exception $e) { echo " [FAIL]\n PID-file exists and locked\n"; echo " PID-file reading failed!\n"; exit(1); } catch (Assets\Exceptions\PID_Unlink_Fail_Exception $e) { echo " [FAIL]\n PID-file exists but failed to unlink\n"; exit(1); } catch (Assets\Exceptions\Master_Fork_Fail_Exception $e) { echo " [FAIL]\n fork() failed\n"; exit(1); } catch (\Exception $e) { echo " [FAIL]\n Unexpected exception:\n"; var_export($e->getMessage()); var_export($e->getTraceAsString()); exit(1); } }