JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

  • AbstractApplication
  • AbstractCliApplication
  • AbstractDaemonApplication
  • AbstractWebApplication
  1 <?php
  2 /**
  3  * Part of the Joomla Framework Application Package
  4  *
  5  * @copyright  Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
  6  * @license    GNU General Public License version 2 or later; see LICENSE
  7  */
  8 
  9 namespace Joomla\Application;
 10 
 11 use Joomla\Input;
 12 use Joomla\Registry\Registry;
 13 use Psr\Log\LoggerAwareInterface;
 14 
 15 /**
 16  * Class to turn Cli applications into daemons.  It requires CLI and PCNTL support built into PHP.
 17  *
 18  * @see    http://www.php.net/manual/en/book.pcntl.php
 19  * @see    http://php.net/manual/en/features.commandline.php
 20  * @since  1.0
 21  */
 22 abstract class AbstractDaemonApplication extends AbstractCliApplication implements LoggerAwareInterface
 23 {
 24     /**
 25      * @var    array  The available POSIX signals to be caught by default.
 26      * @see    http://php.net/manual/pcntl.constants.php
 27      * @since  1.0
 28      */
 29     protected static $signals = array(
 30         'SIGHUP',
 31         'SIGINT',
 32         'SIGQUIT',
 33         'SIGILL',
 34         'SIGTRAP',
 35         'SIGABRT',
 36         'SIGIOT',
 37         'SIGBUS',
 38         'SIGFPE',
 39         'SIGUSR1',
 40         'SIGSEGV',
 41         'SIGUSR2',
 42         'SIGPIPE',
 43         'SIGALRM',
 44         'SIGTERM',
 45         'SIGSTKFLT',
 46         'SIGCLD',
 47         'SIGCHLD',
 48         'SIGCONT',
 49         'SIGTSTP',
 50         'SIGTTIN',
 51         'SIGTTOU',
 52         'SIGURG',
 53         'SIGXCPU',
 54         'SIGXFSZ',
 55         'SIGVTALRM',
 56         'SIGPROF',
 57         'SIGWINCH',
 58         'SIGPOLL',
 59         'SIGIO',
 60         'SIGPWR',
 61         'SIGSYS',
 62         'SIGBABY',
 63         'SIG_BLOCK',
 64         'SIG_UNBLOCK',
 65         'SIG_SETMASK'
 66     );
 67 
 68     /**
 69      * @var    boolean  True if the daemon is in the process of exiting.
 70      * @since  1.0
 71      */
 72     protected $exiting = false;
 73 
 74     /**
 75      * @var    integer  The parent process id.
 76      * @since  1.0
 77      */
 78     protected $parentId = 0;
 79 
 80     /**
 81      * @var    integer  The process id of the daemon.
 82      * @since  1.0
 83      */
 84     protected $processId = 0;
 85 
 86     /**
 87      * @var    boolean  True if the daemon is currently running.
 88      * @since  1.0
 89      */
 90     protected $running = false;
 91 
 92     /**
 93      * Class constructor.
 94      *
 95      * @param   Input\Cli      $input     An optional argument to provide dependency injection for the application's input object.  If the
 96      *                                    argument is an Input\Cli object that object will become the application's input object, otherwise
 97      *                                    a default input object is created.
 98      * @param   Registry       $config    An optional argument to provide dependency injection for the application's config object.  If the
 99      *                                    argument is a Registry object that object will become the application's config object, otherwise
100      *                                    a default config object is created.
101      * @param   Cli\CliOutput  $output    An optional argument to provide dependency injection for the application's output object.  If the
102      *                                    argument is a Cli\CliOutput object that object will become the application's input object, otherwise
103      *                                    a default output object is created.
104      * @param   Cli\CliInput   $cliInput  An optional argument to provide dependency injection for the application's CLI input object.  If the
105      *                                    argument is a Cli\CliInput object that object will become the application's input object, otherwise
106      *                                    a default input object is created.
107      *
108      * @since   1.0
109      */
110     public function __construct(Cli $input = null, Registry $config = null, Cli\CliOutput $output = null, Cli\CliInput $cliInput = null)
111     {
112         // Verify that the process control extension for PHP is available.
113         // @codeCoverageIgnoreStart
114         if (!defined('SIGHUP'))
115         {
116             $this->getLogger()->error('The PCNTL extension for PHP is not available.');
117 
118             throw new \RuntimeException('The PCNTL extension for PHP is not available.');
119         }
120 
121         // Verify that POSIX support for PHP is available.
122         if (!function_exists('posix_getpid'))
123         {
124             $this->getLogger()->error('The POSIX extension for PHP is not available.');
125 
126             throw new \RuntimeException('The POSIX extension for PHP is not available.');
127         }
128 
129         // @codeCoverageIgnoreEnd
130 
131         // Call the parent constructor.
132         parent::__construct($input, $config, $output, $cliInput);
133 
134         // Set some system limits.
135         @set_time_limit($this->get('max_execution_time', 0));
136 
137         if ($this->get('max_memory_limit') !== null)
138         {
139             ini_set('memory_limit', $this->get('max_memory_limit', '256M'));
140         }
141 
142         // Flush content immediately.
143         ob_implicit_flush();
144     }
145 
146     /**
147      * Method to handle POSIX signals.
148      *
149      * @param   integer  $signal  The received POSIX signal.
150      *
151      * @return  void
152      *
153      * @since   1.0
154      * @see     pcntl_signal()
155      * @throws  \RuntimeException
156      */
157     public function signal($signal)
158     {
159         // Log all signals sent to the daemon.
160         $this->getLogger()->debug('Received signal: ' . $signal);
161 
162         // Let's make sure we have an application instance.
163         if (!is_subclass_of($this, __CLASS__))
164         {
165             $this->getLogger()->emergency('Cannot find the application instance.');
166 
167             throw new \RuntimeException('Cannot find the application instance.');
168         }
169 
170         // @event onReceiveSignal
171 
172         switch ($signal)
173         {
174             case SIGINT:
175             case SIGTERM:
176                 // Handle shutdown tasks
177                 if ($this->running && $this->isActive())
178                 {
179                     $this->shutdown();
180                 }
181                 else
182                 {
183                     $this->close();
184                 }
185 
186                 break;
187 
188             case SIGHUP:
189                 // Handle restart tasks
190                 if ($this->running && $this->isActive())
191                 {
192                     $this->shutdown(true);
193                 }
194                 else
195                 {
196                     $this->close();
197                 }
198 
199                 break;
200 
201             case SIGCHLD:
202                 // A child process has died
203                 while ($this->pcntlWait($signal, WNOHANG || WUNTRACED) > 0)
204                 {
205                     usleep(1000);
206                 }
207 
208                 break;
209 
210             case SIGCLD:
211                 while ($this->pcntlWait($signal, WNOHANG) > 0)
212                 {
213                     $signal = $this->pcntlChildExitStatus($signal);
214                 }
215 
216                 break;
217 
218             default:
219                 break;
220         }
221     }
222 
223     /**
224      * Check to see if the daemon is active.  This does not assume that $this daemon is active, but
225      * only if an instance of the application is active as a daemon.
226      *
227      * @return  boolean  True if daemon is active.
228      *
229      * @since   1.0
230      */
231     public function isActive()
232     {
233         // Get the process id file location for the application.
234         $pidFile = $this->get('application_pid_file');
235 
236         // If the process id file doesn't exist then the daemon is obviously not running.
237         if (!is_file($pidFile))
238         {
239             return false;
240         }
241 
242         // Read the contents of the process id file as an integer.
243         $fp = fopen($pidFile, 'r');
244         $pid = fread($fp, filesize($pidFile));
245         $pid = (int) $pid;
246         fclose($fp);
247 
248         // Check to make sure that the process id exists as a positive integer.
249         if (!$pid)
250         {
251             return false;
252         }
253 
254         // Check to make sure the process is active by pinging it and ensure it responds.
255         if (!posix_kill($pid, 0))
256         {
257             // No response so remove the process id file and log the situation.
258             @ unlink($pidFile);
259 
260             $this->getLogger()->warning('The process found based on PID file was unresponsive.');
261 
262             return false;
263         }
264 
265         return true;
266     }
267 
268     /**
269      * Load an object or array into the application configuration object.
270      *
271      * @param   mixed  $data  Either an array or object to be loaded into the configuration object.
272      *
273      * @return  AbstractDaemonApplication  Instance of $this to allow chaining.
274      *
275      * @since   1.0
276      */
277     public function loadConfiguration($data)
278     {
279         /*
280          * Setup some application metadata options.  This is useful if we ever want to write out startup scripts
281          * or just have some sort of information available to share about things.
282          */
283 
284         // The application author name.  This string is used in generating startup scripts and has
285         // a maximum of 50 characters.
286         $tmp = (string) $this->get('author_name', 'Joomla Framework');
287         $this->set('author_name', (strlen($tmp) > 50) ? substr($tmp, 0, 50) : $tmp);
288 
289         // The application author email.  This string is used in generating startup scripts.
290         $tmp = (string) $this->get('author_email', 'admin@joomla.org');
291         $this->set('author_email', filter_var($tmp, FILTER_VALIDATE_EMAIL));
292 
293         // The application name.  This string is used in generating startup scripts.
294         $tmp = (string) $this->get('application_name', 'JApplicationDaemon');
295         $this->set('application_name', (string) preg_replace('/[^A-Z0-9_-]/i', '', $tmp));
296 
297         // The application description.  This string is used in generating startup scripts.
298         $tmp = (string) $this->get('application_description', 'A generic Joomla Framework application.');
299         $this->set('application_description', filter_var($tmp, FILTER_SANITIZE_STRING));
300 
301         /*
302          * Setup the application path options.  This defines the default executable name, executable directory,
303          * and also the path to the daemon process id file.
304          */
305 
306         // The application executable daemon.  This string is used in generating startup scripts.
307         $tmp = (string) $this->get('application_executable', basename($this->input->executable));
308         $this->set('application_executable', $tmp);
309 
310         // The home directory of the daemon.
311         $tmp = (string) $this->get('application_directory', dirname($this->input->executable));
312         $this->set('application_directory', $tmp);
313 
314         // The pid file location.  This defaults to a path inside the /tmp directory.
315         $name = $this->get('application_name');
316         $tmp = (string) $this->get('application_pid_file', strtolower('/tmp/' . $name . '/' . $name . '.pid'));
317         $this->set('application_pid_file', $tmp);
318 
319         /*
320          * Setup the application identity options.  It is important to remember if the default of 0 is set for
321          * either UID or GID then changing that setting will not be attempted as there is no real way to "change"
322          * the identity of a process from some user to root.
323          */
324 
325         // The user id under which to run the daemon.
326         $tmp = (int) $this->get('application_uid', 0);
327         $options = array('options' => array('min_range' => 0, 'max_range' => 65000));
328         $this->set('application_uid', filter_var($tmp, FILTER_VALIDATE_INT, $options));
329 
330         // The group id under which to run the daemon.
331         $tmp = (int) $this->get('application_gid', 0);
332         $options = array('options' => array('min_range' => 0, 'max_range' => 65000));
333         $this->set('application_gid', filter_var($tmp, FILTER_VALIDATE_INT, $options));
334 
335         // Option to kill the daemon if it cannot switch to the chosen identity.
336         $tmp = (bool) $this->get('application_require_identity', 1);
337         $this->set('application_require_identity', $tmp);
338 
339         /*
340          * Setup the application runtime options.  By default our execution time limit is infinite obviously
341          * because a daemon should be constantly running unless told otherwise.  The default limit for memory
342          * usage is 128M, which admittedly is a little high, but remember it is a "limit" and PHP's memory
343          * management leaves a bit to be desired :-)
344          */
345 
346         // The maximum execution time of the application in seconds.  Zero is infinite.
347         $tmp = $this->get('max_execution_time');
348 
349         if ($tmp !== null)
350         {
351             $this->set('max_execution_time', (int) $tmp);
352         }
353 
354         // The maximum amount of memory the application can use.
355         $tmp = $this->get('max_memory_limit', '256M');
356 
357         if ($tmp !== null)
358         {
359             $this->set('max_memory_limit', (string) $tmp);
360         }
361 
362         return $this;
363     }
364 
365     /**
366      * Execute the daemon.
367      *
368      * @return  void
369      *
370      * @since   1.0
371      */
372     public function execute()
373     {
374         // @event onBeforeExecute
375 
376         // Enable basic garbage collection.
377         gc_enable();
378 
379         $this->getLogger()->info('Starting ' . $this->name);
380 
381         // Set off the process for becoming a daemon.
382         if ($this->daemonize())
383         {
384             // Declare ticks to start signal monitoring. When you declare ticks, PCNTL will monitor
385             // incoming signals after each tick and call the relevant signal handler automatically.
386             declare (ticks = 1);
387 
388             // Start the main execution loop.
389             while (true)
390             {
391                 // Perform basic garbage collection.
392                 $this->gc();
393 
394                 // Don't completely overload the CPU.
395                 usleep(1000);
396 
397                 // Execute the main application logic.
398                 $this->doExecute();
399             }
400         }
401         else
402         // We were not able to daemonize the application so log the failure and die gracefully.
403         {
404             $this->getLogger()->info('Starting ' . $this->name . ' failed');
405         }
406 
407         // @event onAfterExecute
408     }
409 
410     /**
411      * Restart daemon process.
412      *
413      * @return  void
414      *
415      * @codeCoverageIgnore
416      * @since   1.0
417      */
418     public function restart()
419     {
420         $this->getLogger()->info('Stopping ' . $this->name);
421 
422         $this->shutdown(true);
423     }
424 
425     /**
426      * Stop daemon process.
427      *
428      * @return  void
429      *
430      * @codeCoverageIgnore
431      * @since   1.0
432      */
433     public function stop()
434     {
435         $this->getLogger()->info('Stopping ' . $this->name);
436 
437         $this->shutdown();
438     }
439 
440     /**
441      * Method to change the identity of the daemon process and resources.
442      *
443      * @return  boolean  True if identity successfully changed
444      *
445      * @since   1.0
446      * @see     posix_setuid()
447      */
448     protected function changeIdentity()
449     {
450         // Get the group and user ids to set for the daemon.
451         $uid = (int) $this->get('application_uid', 0);
452         $gid = (int) $this->get('application_gid', 0);
453 
454         // Get the application process id file path.
455         $file = $this->get('application_pid_file');
456 
457         // Change the user id for the process id file if necessary.
458         if ($uid && (fileowner($file) != $uid) && (!@ chown($file, $uid)))
459         {
460             $this->getLogger()->error('Unable to change user ownership of the process id file.');
461 
462             return false;
463         }
464 
465         // Change the group id for the process id file if necessary.
466         if ($gid && (filegroup($file) != $gid) && (!@ chgrp($file, $gid)))
467         {
468             $this->getLogger()->error('Unable to change group ownership of the process id file.');
469 
470             return false;
471         }
472 
473         // Set the correct home directory for the process.
474         if ($uid && ($info = posix_getpwuid($uid)) && is_dir($info['dir']))
475         {
476             system('export HOME="' . $info['dir'] . '"');
477         }
478 
479         // Change the user id for the process necessary.
480         if ($uid && (posix_getuid($file) != $uid) && (!@ posix_setuid($uid)))
481         {
482             $this->getLogger()->error('Unable to change user ownership of the proccess.');
483 
484             return false;
485         }
486 
487         // Change the group id for the process necessary.
488         if ($gid && (posix_getgid($file) != $gid) && (!@ posix_setgid($gid)))
489         {
490             $this->getLogger()->error('Unable to change group ownership of the proccess.');
491 
492             return false;
493         }
494 
495         // Get the user and group information based on uid and gid.
496         $user = posix_getpwuid($uid);
497         $group = posix_getgrgid($gid);
498 
499         $this->getLogger()->info('Changed daemon identity to ' . $user['name'] . ':' . $group['name']);
500 
501         return true;
502     }
503 
504     /**
505      * Method to put the application into the background.
506      *
507      * @return  boolean
508      *
509      * @since   1.0
510      * @throws  \RuntimeException
511      */
512     protected function daemonize()
513     {
514         // Is there already an active daemon running?
515         if ($this->isActive())
516         {
517             $this->getLogger()->emergency($this->name . ' daemon is still running. Exiting the application.');
518 
519             return false;
520         }
521 
522         // Reset Process Information
523         $this->safeMode = !!@ ini_get('safe_mode');
524         $this->processId = 0;
525         $this->running = false;
526 
527         // Detach process!
528         try
529         {
530             // Check if we should run in the foreground.
531             if (!$this->input->get('f'))
532             {
533                 // Detach from the terminal.
534                 $this->detach();
535             }
536             else
537             {
538                 // Setup running values.
539                 $this->exiting = false;
540                 $this->running = true;
541 
542                 // Set the process id.
543                 $this->processId = (int) posix_getpid();
544                 $this->parentId = $this->processId;
545             }
546         }
547         catch (\RuntimeException $e)
548         {
549             $this->getLogger()->emergency('Unable to fork.');
550 
551             return false;
552         }
553 
554         // Verify the process id is valid.
555         if ($this->processId < 1)
556         {
557             $this->getLogger()->emergency('The process id is invalid; the fork failed.');
558 
559             return false;
560         }
561 
562         // Clear the umask.
563         @ umask(0);
564 
565         // Write out the process id file for concurrency management.
566         if (!$this->writeProcessIdFile())
567         {
568             $this->getLogger()->emergency('Unable to write the pid file at: ' . $this->get('application_pid_file'));
569 
570             return false;
571         }
572 
573         // Attempt to change the identity of user running the process.
574         if (!$this->changeIdentity())
575         {
576             // If the identity change was required then we need to return false.
577             if ($this->get('application_require_identity'))
578             {
579                 $this->getLogger()->critical('Unable to change process owner.');
580 
581                 return false;
582             }
583             else
584             {
585                 $this->getLogger()->warning('Unable to change process owner.');
586             }
587         }
588 
589         // Setup the signal handlers for the daemon.
590         if (!$this->setupSignalHandlers())
591         {
592             return false;
593         }
594 
595         // Change the current working directory to the application working directory.
596         @ chdir($this->get('application_directory'));
597 
598         return true;
599     }
600 
601     /**
602      * This is truly where the magic happens.  This is where we fork the process and kill the parent
603      * process, which is essentially what turns the application into a daemon.
604      *
605      * @return  void
606      *
607      * @since   1.0
608      * @throws  \RuntimeException
609      */
610     protected function detach()
611     {
612         $this->getLogger()->debug('Detaching the ' . $this->name . ' daemon.');
613 
614         // Attempt to fork the process.
615         $pid = $this->fork();
616 
617         // If the pid is positive then we successfully forked, and can close this application.
618         if ($pid)
619         {
620             // Add the log entry for debugging purposes and exit gracefully.
621             $this->getLogger()->debug('Ending ' . $this->name . ' parent process');
622 
623             $this->close();
624         }
625         else
626         // We are in the forked child process.
627         {
628             // Setup some protected values.
629             $this->exiting = false;
630             $this->running = true;
631 
632             // Set the parent to self.
633             $this->parentId = $this->processId;
634         }
635     }
636 
637     /**
638      * Method to fork the process.
639      *
640      * @return  integer  The child process id to the parent process, zero to the child process.
641      *
642      * @since   1.0
643      * @throws  \RuntimeException
644      */
645     protected function fork()
646     {
647         // Attempt to fork the process.
648         $pid = $this->pcntlFork();
649 
650         // If the fork failed, throw an exception.
651         if ($pid === -1)
652         {
653             throw new \RuntimeException('The process could not be forked.');
654         }
655         elseif ($pid === 0)
656         // Update the process id for the child.
657         {
658             $this->processId = (int) posix_getpid();
659         }
660         else
661         // Log the fork in the parent.
662         {
663             // Log the fork.
664             $this->getLogger()->debug('Process forked ' . $pid);
665         }
666 
667         // Trigger the onFork event.
668         $this->postFork();
669 
670         return $pid;
671     }
672 
673     /**
674      * Method to perform basic garbage collection and memory management in the sense of clearing the
675      * stat cache.  We will probably call this method pretty regularly in our main loop.
676      *
677      * @return  void
678      *
679      * @codeCoverageIgnore
680      * @since   1.0
681      */
682     protected function gc()
683     {
684         // Perform generic garbage collection.
685         gc_collect_cycles();
686 
687         // Clear the stat cache so it doesn't blow up memory.
688         clearstatcache();
689     }
690 
691     /**
692      * Method to attach the AbstractDaemonApplication signal handler to the known signals.  Applications
693      * can override these handlers by using the pcntl_signal() function and attaching a different
694      * callback method.
695      *
696      * @return  boolean
697      *
698      * @since   1.0
699      * @see     pcntl_signal()
700      */
701     protected function setupSignalHandlers()
702     {
703         // We add the error suppression for the loop because on some platforms some constants are not defined.
704         foreach (self::$signals as $signal)
705         {
706             // Ignore signals that are not defined.
707             if (!defined($signal) || !is_int(constant($signal)) || (constant($signal) === 0))
708             {
709                 // Define the signal to avoid notices.
710                 $this->getLogger()->debug('Signal "' . $signal . '" not defined. Defining it as null.');
711 
712                 define($signal, null);
713 
714                 // Don't listen for signal.
715                 continue;
716             }
717 
718             // Attach the signal handler for the signal.
719             if (!$this->pcntlSignal(constant($signal), array($this, 'signal')))
720             {
721                 $this->getLogger()->emergency(sprintf('Unable to reroute signal handler: %s', $signal));
722 
723                 return false;
724             }
725         }
726 
727         return true;
728     }
729 
730     /**
731      * Method to shut down the daemon and optionally restart it.
732      *
733      * @param   boolean  $restart  True to restart the daemon on exit.
734      *
735      * @return  void
736      *
737      * @since   1.0
738      */
739     protected function shutdown($restart = false)
740     {
741         // If we are already exiting, chill.
742         if ($this->exiting)
743         {
744             return;
745         }
746         else
747         // If not, now we are.
748         {
749             $this->exiting = true;
750         }
751 
752         // If we aren't already daemonized then just kill the application.
753         if (!$this->running && !$this->isActive())
754         {
755             $this->getLogger()->info('Process was not daemonized yet, just halting current process');
756 
757             $this->close();
758         }
759 
760         // Only read the pid for the parent file.
761         if ($this->parentId == $this->processId)
762         {
763             // Read the contents of the process id file as an integer.
764             $fp = fopen($this->get('application_pid_file'), 'r');
765             $pid = fread($fp, filesize($this->get('application_pid_file')));
766             $pid = (int) $pid;
767             fclose($fp);
768 
769             // Remove the process id file.
770             @ unlink($this->get('application_pid_file'));
771 
772             // If we are supposed to restart the daemon we need to execute the same command.
773             if ($restart)
774             {
775                 $this->close(exec(implode(' ', $GLOBALS['argv']) . ' > /dev/null &'));
776             }
777             else
778             // If we are not supposed to restart the daemon let's just kill -9.
779             {
780                 passthru('kill -9 ' . $pid);
781                 $this->close();
782             }
783         }
784     }
785 
786     /**
787      * Method to write the process id file out to disk.
788      *
789      * @return  boolean
790      *
791      * @since   1.0
792      */
793     protected function writeProcessIdFile()
794     {
795         // Verify the process id is valid.
796         if ($this->processId < 1)
797         {
798             $this->getLogger()->emergency('The process id is invalid.');
799 
800             return false;
801         }
802 
803         // Get the application process id file path.
804         $file = $this->get('application_pid_file');
805 
806         if (empty($file))
807         {
808             $this->getLogger()->error('The process id file path is empty.');
809 
810             return false;
811         }
812 
813         // Make sure that the folder where we are writing the process id file exists.
814         $folder = dirname($file);
815 
816         if (!is_dir($folder) && !@ mkdir($folder, $this->get('folder_permission', 0755)))
817         {
818             $this->getLogger()->error('Unable to create directory: ' . $folder);
819 
820             return false;
821         }
822 
823         // Write the process id file out to disk.
824         if (!file_put_contents($file, $this->processId))
825         {
826             $this->getLogger()->error('Unable to write proccess id file: ' . $file);
827 
828             return false;
829         }
830 
831         // Make sure the permissions for the proccess id file are accurate.
832         if (!chmod($file, $this->get('file_permission', 0644)))
833         {
834             $this->getLogger()->error('Unable to adjust permissions for the proccess id file: ' . $file);
835 
836             return false;
837         }
838 
839         return true;
840     }
841 
842     /**
843      * Method to handle post-fork triggering of the onFork event.
844      *
845      * @return  void
846      *
847      * @since   1.0
848      */
849     protected function postFork()
850     {
851         // @event onFork
852     }
853 
854     /**
855      * Method to return the exit code of a terminated child process.
856      *
857      * @param   integer  $status  The status parameter is the status parameter supplied to a successful call to pcntl_waitpid().
858      *
859      * @return  integer  The child process exit code.
860      *
861      * @codeCoverageIgnore
862      * @see     pcntl_wexitstatus()
863      * @since   1.0
864      */
865     protected function pcntlChildExitStatus($status)
866     {
867         return pcntl_wexitstatus($status);
868     }
869 
870     /**
871      * Method to return the exit code of a terminated child process.
872      *
873      * @return  integer  On success, the PID of the child process is returned in the parent's thread
874      *                   of execution, and a 0 is returned in the child's thread of execution. On
875      *                   failure, a -1 will be returned in the parent's context, no child process
876      *                   will be created, and a PHP error is raised.
877      *
878      * @codeCoverageIgnore
879      * @see     pcntl_fork()
880      * @since   1.0
881      */
882     protected function pcntlFork()
883     {
884         return pcntl_fork();
885     }
886 
887     /**
888      * Method to install a signal handler.
889      *
890      * @param   integer   $signal   The signal number.
891      * @param   callable  $handler  The signal handler which may be the name of a user created function,
892      *                              or method, or either of the two global constants SIG_IGN or SIG_DFL.
893      * @param   boolean   $restart  Specifies whether system call restarting should be used when this
894      *                              signal arrives.
895      *
896      * @return  boolean  True on success.
897      *
898      * @codeCoverageIgnore
899      * @see     pcntl_signal()
900      * @since   1.0
901      */
902     protected function pcntlSignal($signal , $handler, $restart = true)
903     {
904         return pcntl_signal($signal, $handler, $restart);
905     }
906 
907     /**
908      * Method to wait on or return the status of a forked child.
909      *
910      * @param   integer  &$status  Status information.
911      * @param   integer  $options  If wait3 is available on your system (mostly BSD-style systems),
912      *                             you can provide the optional options parameter.
913      *
914      * @return  integer  The process ID of the child which exited, -1 on error or zero if WNOHANG
915      *                   was provided as an option (on wait3-available systems) and no child was available.
916      *
917      * @codeCoverageIgnore
918      * @see     pcntl_wait()
919      * @since   1.0
920      */
921     protected function pcntlWait(&$status, $options = 0)
922     {
923         return pcntl_wait($status, $options);
924     }
925 }
926 
Joomla! Framework TM API documentation generated by ApiGen 2.8.0
Joomla!® and Joomla! Framework™ are trademarks of Open Source Matters, Inc. in the United States and other countries.