<commit_before># encoding: utf-8
# frozen_string_literal: true

require 'tempfile'
require 'securerandom'
require 'io/console'

module TTY
  class Command
    module ChildProcess
      # Execute command in a child process with all IO streams piped
      # in and out. The interface is similar to Process.spawn
      #
      # The caller should ensure that all IO objects are closed
      # when the child process is finished. However, when block
      # is provided this will be taken care of automatically.
      #
      # @param [Cmd] cmd
      #   the command to spawn
      #
      # @return [pid, stdin, stdout, stderr]
      #
      # @api public
      def spawn(cmd)
        process_opts = normalize_redirect_options(cmd.options)
        binmode = cmd.options[:binmode] || false
        pty     = cmd.options[:pty] || false

        pty = try_loading_pty if pty
        require('pty') if pty # load within this scope

        # Create pipes
        in_rd,  in_wr  = pty ? PTY.open : IO.pipe('utf-8') # reading
        out_rd, out_wr = pty ? PTY.open : IO.pipe('utf-8') # writing
        err_rd, err_wr = pty ? PTY.open : IO.pipe('utf-8') # error
        in_wr.sync = true

        if binmode
          in_wr.binmode
          out_rd.binmode
          err_rd.binmode
        end

        if pty
          in_wr.raw!
          out_wr.raw!
          err_wr.raw!
        end

        # redirect fds
        opts = {
          in: in_rd,
          out: out_wr,
          err: err_wr
        }
        unless TTY::Command.windows?
          close_child_fds = {
            in_wr  => :close,
            out_rd => :close,
            err_rd => :close
          }
          opts.merge!(close_child_fds)
        end
        opts.merge!(process_opts)

        pid = Process.spawn(cmd.to_command, opts)

        # close in parent process
        [in_rd, out_wr, err_wr].each { |fd| fd.close if fd }

        tuple = [pid, in_wr, out_rd, err_rd]

        if block_given?
          begin
            return yield(*tuple)
          ensure
            # ensure parent pipes are closed
            [in_wr, out_rd, err_rd].each { |fd| fd.close if fd && !fd.closed? }
          end
        else
          tuple
        end
      end
      module_function :spawn

      # Try loading pty module
      #
      # @return [Boolean]
      #
      # @api private
      def try_loading_pty<commit_msg>Change to unify closing fds<commit_after># encoding: utf-8
# frozen_string_literal: true

require 'tempfile'
require 'securerandom'
require 'io/console'

module TTY
  class Command
    module ChildProcess
      # Execute command in a child process with all IO streams piped
      # in and out. The interface is similar to Process.spawn
      #
      # The caller should ensure that all IO objects are closed
      # when the child process is finished. However, when block
      # is provided this will be taken care of automatically.
      #
      # @param [Cmd] cmd
      #   the command to spawn
      #
      # @return [pid, stdin, stdout, stderr]
      #
      # @api public
      def spawn(cmd)
        process_opts = normalize_redirect_options(cmd.options)
        binmode = cmd.options[:binmode] || false
        pty     = cmd.options[:pty] || false

        pty = try_loading_pty if pty
        require('pty') if pty # load within this scope

        # Create pipes
        in_rd,  in_wr  = pty ? PTY.open : IO.pipe('utf-8') # reading
        out_rd, out_wr = pty ? PTY.open : IO.pipe('utf-8') # writing
        err_rd, err_wr = pty ? PTY.open : IO.pipe('utf-8') # error
        in_wr.sync = true

        if binmode
          in_wr.binmode
          out_rd.binmode
          err_rd.binmode
        end

        if pty
          in_wr.raw!
          out_wr.raw!
          err_wr.raw!
        end

        # redirect fds
        opts = {
          in: in_rd,
          out: out_wr,
          err: err_wr
        }
        unless TTY::Command.windows?
          close_child_fds = {
            in_wr  => :close,
            out_rd => :close,
            err_rd => :close
          }
          opts.merge!(close_child_fds)
        end
        opts.merge!(process_opts)

        pid = Process.spawn(cmd.to_command, opts)

        # close streams in parent process talking to the child
        close_fds(in_rd, out_wr, err_wr)

        tuple = [pid, in_wr, out_rd, err_rd]

        if block_given?
          begin
            return yield(*tuple)
          ensure
            # ensure parent pipes are closed
            close_fds(in_wr, out_rd, err_rd)
          end
        else
          tuple
        end
      end
      module_function :spawn

      # Close all streams
      # @api private
      def close_fds(*fds)
        fds.each { |fd| fd && !fd.closed? && fd.close }
      end
      module_function :close_fds

      # Try loading pty module
      #
      # @return [Boolean]
      #
      # @api private
      def try_loading_pty
{'fraction_non_alphanumeric': 0.08382382788715242, 'fraction_numerical': 0.0016237061091942358, 'mean_word_length': 1.6296691568836712, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '4902174', 'n_tokens_mistral': 1531, 'n_tokens_neox': 1507, 'n_words': 434}