Пример #1
0
 /**
  * Запуск сервиса.
  * 
  * @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);
     }
 }