Example #1
0
 def NoneAreRunning(self):
     # type: () -> bool
     """Test if all jobs are done.  Used by 'wait' builtin."""
     for _, job in iteritems(self.jobs):  # mycpp rewite: from itervalues()
         if job.State() == job_state_e.Running:
             return False
     return True
Example #2
0
File: dev.py Project: ilyash/oil
def _PrintShValue(val, buf):
    # type: (value_t, mylib.BufWriter) -> None
    """Using maybe_shell_encode() for legacy xtrace_details."""

    # NOTE: This is a bit like _PrintVariables for declare -p
    result = '?'
    UP_val = val
    with tagswitch(val) as case:
        if case(value_e.Str):
            val = cast(value__Str, UP_val)
            result = qsn.maybe_shell_encode(val.s)

        elif case(value_e.MaybeStrArray):
            val = cast(value__MaybeStrArray, UP_val)
            parts = ['(']
            for s in val.strs:
                parts.append(qsn.maybe_shell_encode(s))
            parts.append(')')
            result = ' '.join(parts)

        elif case(value_e.AssocArray):
            val = cast(value__AssocArray, UP_val)
            parts = ['(']
            for k, v in iteritems(val.d):
                parts.append(
                    '[%s]=%s' %
                    (qsn.maybe_shell_encode(k), qsn.maybe_shell_encode(v)))
            parts.append(')')
            result = ' '.join(parts)

    buf.write(result)
Example #3
0
    def List(self):
        # type: () -> None
        """Used by the 'jobs' builtin.

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/jobs.html

    "By default, the jobs utility shall display the status of all stopped jobs,
    running background jobs and all jobs whose status has changed and have not
    been reported by the shell."
    """
        # NOTE: A job is a background process or pipeline.
        #
        # echo hi | wc -l    -- this starts two processes.  Wait for TWO
        # echo hi | wc -l &   -- this starts a process which starts two processes
        #                        Wait for ONE.
        #
        # bash GROUPS the PIDs by job.  And it has their state and code.

        # $ jobs -l
        # [1]+ 24414 Stopped                 sleep 5
        #      24415                       | sleep 5
        # [2]  24502 Running                 sleep 6
        #      24503                       | sleep 6
        #      24504                       | sleep 5 &
        # [3]- 24508 Running                 sleep 6
        #      24509                       | sleep 6
        #      24510                       | sleep 5 &
        #
        # zsh has VERY similar UI.

        # NOTE: Jobs don't need to show state?  Because pipelines are never stopped
        # -- only the jobs within them are.

        if mylib.PYTHON:
            # TODO: don't use __repr__ and so forth

            print('Jobs:')
            for pid, job in iteritems(self.jobs):
                # Use the %1 syntax
                print('%%%d %s %s' % (pid, job.State(), job))

            print('')
            print('Processes:')
            for pid, proc in iteritems(self.child_procs):
                print('%d %s %s' % (pid, proc.state, proc.thunk.DisplayLine()))
Example #4
0
File: args.py Project: grahamc/oil
    def __init__(self, defaults):
        # type: (Dict[str, value_t]) -> None

        # New style
        self.attrs = {}  # type: Dict[str, value_t]

        self.opt_changes = []  # type: List[OptChange]  # -o errexit +o nounset
        self.shopt_changes = [
        ]  # type: List[OptChange]  # -O nullglob +O nullglob
        self.show_options = False  # 'set -o' without an argument
        self.actions = []  # type: List[str]  # for compgen -A
        self.saw_double_dash = False  # for set --
        for name, v in iteritems(defaults):
            self.Set(name, v)
Example #5
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        attrs, arg_r = flag_spec.ParseCmdVal('trap', cmd_val)
        arg = arg_types.trap(attrs.attrs)

        if arg.p:  # Print registered handlers
            for name, value in iteritems(self.traps):
                # The unit tests rely on this being one line.
                # bash prints a line that can be re-parsed.
                print('%s %s' % (name, value.__class__.__name__))

            return 0

        if arg.l:  # List valid signals and hooks
            for name in _HOOK_NAMES:
                print('   %s' % name)
            for name, int_val in signal_def.AllNames():
                print('%2d %s' % (int_val, name))

            return 0

        code_str = arg_r.ReadRequired('requires a code string')
        sig_spec, sig_spid = arg_r.ReadRequired2(
            'requires a signal or hook name')

        # sig_key is NORMALIZED sig_spec: a signal number string or string hook
        # name.
        sig_key = None  # type: Optional[str]
        sig_num = None
        if sig_spec in _HOOK_NAMES:
            sig_key = sig_spec
        elif sig_spec == '0':  # Special case
            sig_key = 'EXIT'
        else:
            sig_num = _GetSignalNumber(sig_spec)
            if sig_num is not None:
                sig_key = str(sig_num)

        if sig_key is None:
            self.errfmt.Print_("Invalid signal or hook %r" % sig_spec,
                               span_id=cmd_val.arg_spids[2])
            return 1

        # NOTE: sig_spec isn't validated when removing handlers.
        if code_str == '-':
            if sig_key in _HOOK_NAMES:
                try:
                    del self.traps[sig_key]
                except KeyError:
                    pass
                return 0

            if sig_num is not None:
                try:
                    del self.traps[sig_key]
                except KeyError:
                    pass

                self.sig_state.RemoveUserTrap(sig_num)
                return 0

            raise AssertionError('Signal or trap')

        # Try parsing the code first.
        node = self._ParseTrapCode(code_str)
        if node is None:
            return 1  # ParseTrapCode() prints an error for us.

        # Register a hook.
        if sig_key in _HOOK_NAMES:
            if sig_key in ('ERR', 'RETURN', 'DEBUG'):
                stderr_line("osh warning: The %r hook isn't implemented",
                            sig_spec)
            self.traps[sig_key] = _TrapHandler(node, self.nodes_to_run)
            return 0

        # Register a signal.
        if sig_num is not None:
            handler = _TrapHandler(node, self.nodes_to_run)
            # For signal handlers, the traps dictionary is used only for debugging.
            self.traps[sig_key] = handler
            if sig_num in (signal.SIGKILL, signal.SIGSTOP):
                self.errfmt.Print_("Signal %r can't be handled" % sig_spec,
                                   span_id=sig_spid)
                # Other shells return 0, but this seems like an obvious error
                return 1
            self.sig_state.AddUserTrap(sig_num, handler)
            return 0

        raise AssertionError('Signal or trap')