<commit_before><?php
/* This class is part of the XP framework
 *
 * $Id$ 
 */

  uses('io.File');

  /**
   * Process
   *
   * Example (get uptime information on a *NIX system)
   * <code>
   *   $p= new Process('uptime');
   *   $uptime= $p->out->readLine();
   *   $p->close();
   *
   *   var_dump($uptime);
   * </code>
   *
   * @test     xp://net.xp_framework.unittest.core.ProcessTest
   * @see      xp://lang.Runtime#getExecutable
   * @see      php://proc_open
   * @purpose  Execute external programs
   */
  class Process extends Object {
    public
      $in     = NULL,
      $out    = NULL,
      $err    = NULL,
      $exitv  = -1;
      
    protected
      $_proc  = NULL,
      $status = array();

    /**
     * Constructor
     *
     * @param   string command default NULL
     * @param   string[] arguments default []
     * @param   string cwd default NULL the working directory
     * @param   array<string, string> default NULL the environment
     * @throws  io.IOException in case the command could not be executed
     */
    public function __construct($command= NULL, $arguments= array(), $cwd= NULL, $env= NULL) {
      static $spec= array(
        0 => array('pipe', 'r'),  // stdin
        1 => array('pipe', 'w'),  // stdout
        2 => array('pipe', 'w')   // stderr
      );
      
      // For `new self()` used in getProcessById()
      if (NULL === $command) return;

      // Check whether the given command is executable.
      $binary= $this->resolve($command);
      if (!is_executable($binary)) {
        throw new IOException('Command "'.$binary.'" is not executable');
      }
      
      // Build command line
      if (strstr($command, ' ')) {
        $command= escapeshellarg($command);
      }
      $cmd= $command.' '.implode(' ', $arguments);

      // Open process
      if (!is_resource($this->_proc= proc_open($cmd, $spec, $pipes, $cwd, $env, array('bypass_shell' => TRUE)))) {
        throw new IOException('Could not execute "'.$cmd.'"');
      }

      $this->status= proc_get_status($this->_proc);
      $this->status['exe']= $binary;

      // Assign in, out and err members
      $this->in= new File($pipes[0]);
      $this->out= new File($pipes[1]);
      $this->err= new File($pipes[2]);
    }
<commit_msg>- Check that $binary is a file in addition for the is_executable() check # Fixes net.xp_framework.unittest.core.ProcessTest::runningDirectory<commit_after><?php
/* This class is part of the XP framework
 *
 * $Id$ 
 */

  uses('io.File');

  /**
   * Process
   *
   * Example (get uptime information on a *NIX system)
   * <code>
   *   $p= new Process('uptime');
   *   $uptime= $p->out->readLine();
   *   $p->close();
   *
   *   var_dump($uptime);
   * </code>
   *
   * @test     xp://net.xp_framework.unittest.core.ProcessTest
   * @see      xp://lang.Runtime#getExecutable
   * @see      php://proc_open
   * @purpose  Execute external programs
   */
  class Process extends Object {
    public
      $in     = NULL,
      $out    = NULL,
      $err    = NULL,
      $exitv  = -1;
      
    protected
      $_proc  = NULL,
      $status = array();

    /**
     * Constructor
     *
     * @param   string command default NULL
     * @param   string[] arguments default []
     * @param   string cwd default NULL the working directory
     * @param   array<string, string> default NULL the environment
     * @throws  io.IOException in case the command could not be executed
     */
    public function __construct($command= NULL, $arguments= array(), $cwd= NULL, $env= NULL) {
      static $spec= array(
        0 => array('pipe', 'r'),  // stdin
        1 => array('pipe', 'w'),  // stdout
        2 => array('pipe', 'w')   // stderr
      );
      
      // For `new self()` used in getProcessById()
      if (NULL === $command) return;

      // Check whether the given command is executable.
      $binary= $this->resolve($command);
      if (!is_file($binary) || !is_executable($binary)) {
        throw new IOException('Command "'.$binary.'" is not an executable file');
      }
      
      // Build command line
      if (strstr($command, ' ')) {
        $command= escapeshellarg($command);
      }
      $cmd= $command.' '.implode(' ', $arguments);

      // Open process
      if (!is_resource($this->_proc= proc_open($cmd, $spec, $pipes, $cwd, $env, array('bypass_shell' => TRUE)))) {
        throw new IOException('Could not execute "'.$cmd.'"');
      }

      $this->status= proc_get_status($this->_proc);
      $this->status['exe']= $binary;

      // Assign in, out and err members
      $this->in= new File($pipes[0]);
      $this->out= new File($pipes[1]);
      $this->err= new File($pipes[2]);
    }

{'fraction_non_alphanumeric': 0.16181160961088667, 'fraction_numerical': 0.002976823304273868, 'mean_word_length': 2.2374397797660013, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '948604', 'n_tokens_mistral': 1495, 'n_tokens_neox': 1459, 'n_words': 401}