Example #1
0
 def switch_pgid(self):
     try:
         if os.getpgrp() != os.tcgetpgrp(0):
             self.__old_pgid = os.getpgrp()
             os.setpgid(0, os.tcgetpgrp(0))
         else:
             self.__old_pgid = None
     except OSError:
         self.__old_pgid = None
Example #2
0
    def stop_was_requested(self):
        """Check whether a 'keyboard stop' instruction has been sent.

        Returns true if ^X has been sent on the controlling terminal.

        Consumes all available input on /dev/tty.

        """
        if not self.enabled:
            return False
        # Don't try to read the terminal if we're in the background.
        # There's a race here, if we're backgrounded just after this check, but
        # I don't see a clean way to avoid it.
        if os.tcgetpgrp(self.tty.fileno()) != os.getpid():
            return False
        try:
            termios.tcsetattr(self.tty, termios.TCSANOW, self.cbreak_tcattr)
        except EnvironmentError:
            return False
        try:
            seen_ctrl_x = False
            while True:
                c = os.read(self.tty.fileno(), 1)
                if not c:
                    break
                if c == "\x18":
                    seen_ctrl_x = True
        except EnvironmentError:
            seen_ctrl_x = False
        finally:
            termios.tcsetattr(self.tty, termios.TCSANOW, self.clean_tcattr)
        return seen_ctrl_x
Example #3
0
 def _shell_tty():
     try:
         _st = sys.stderr.fileno()
         if os.tcgetpgrp(_st) != os.getpgid(os.getpid()):
             # we don't own it
             _st = None
     except OSError:
         _st = None
     return _st
Example #4
0
def tcgetpgrp(space, fd):
    """ tcgetpgrp(fd) -> pgid

    Return the process group associated with the terminal given by a fd.
    """
    try:
        pgid = os.tcgetpgrp(fd)
    except OSError, e:
        raise wrap_oserror(space, e)
Example #5
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        pgrp = os.tcgetpgrp(fd)

        try:
            return get_proc_name(pgrp)
        except IOError:
            pass
def is_stdout_attached_to_terminal():
    '''判断当前进程组是不是前台进程组(主要关注stdout是否被关联到/dev/tty)'''
    try:
        # 如果stdout被绑定到终端设备上,则是前端进程组
        if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
            return True
        else:
            return False
    except OSError: # sys.stdout 未绑定到任何设备
        return False
Example #7
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        pgrp = os.tcgetpgrp(fd)

        try:
            return get_proc_name(pgrp)
        except IOError:
            pass
Example #8
0
 def initialise(self):
     if not self.enabled:
         return
     if termios is None:
         self.enabled = False
         return
     try:
         self.tty = open("/dev/tty", "w+")
         os.tcgetpgrp(self.tty.fileno())
         self.clean_tcattr = termios.tcgetattr(self.tty)
         iflag, oflag, cflag, lflag, ispeed, ospeed, cc = self.clean_tcattr
         new_lflag = lflag & (0xffffffff ^ termios.ICANON)
         new_cc = cc[:]
         new_cc[termios.VMIN] = 0
         self.cbreak_tcattr = [
             iflag, oflag, cflag, new_lflag, ispeed, ospeed, new_cc]
     except Exception:
         self.enabled = False
         return
Example #9
0
def tcgetpgrp(space, fd):
    """ tcgetpgrp(fd) -> pgid

    Return the process group associated with the terminal given by a fd.
    """
    try:
        pgid = os.tcgetpgrp(fd)
    except OSError as e:
        raise wrap_oserror(space, e)
    return space.newint(pgid)
Example #10
0
def execWithRedirect(command, argv, stdin = 0, stdout = 1, stderr = 2,
                searchPath = 0, root = '/', newPgrp = 0, ignoreTermSigs = 0):
    stdin = getfd(stdin)
    if stdout == stderr:
        stdout = getfd(stdout)
        stderr = stdout
    else:
        stdout = getfd(stdout)
        stderr = getfd(stderr)

    childpid = os.fork()
    if (not childpid):
        if (root and root != '/'):
            os.chroot(root)
            os.chdir("/")

        if ignoreTermSigs:
            signal.signal(signal.SIGTSTP, signal.SIG_IGN)
            signal.signal(signal.SIGINT, signal.SIG_IGN)

        if type(stdin) == type("a"):
            stdin = os.open(stdin, os.O_RDONLY)
        if type(stdout) == type("a"):
            stdout = os.open(stdout, os.O_RDWR)
        if type(stderr) == type("a"):
            stderr = os.open(stderr, os.O_RDWR)

        if stdin != 0:
            os.dup2(stdin, 0)
            os.close(stdin)
        if stdout != 1:
            os.dup2(stdout, 1)
            if stdout != stderr:
                os.close(stdout)
        if stderr != 2:
            os.dup2(stderr, 2)
            os.close(stderr)

        if (searchPath):
            os.execvp(command, argv)
        else:
            os.execv(command, argv)

        sys.exit(1)

    if newPgrp:
        os.setpgid(childpid, childpid)
        oldPgrp = os.tcgetpgrp(0)
        os.tcsetpgrp(0, childpid)

    status = -1
    try:
        (pid, status) = os.waitpid(childpid, 0)
    except OSError, (errno, msg):
        print __name__, "waitpid:", msg
Example #11
0
    def show_progress(self, done=False):
        """Display progress bar if enabled and if running on correct terminal"""
        if SHOWPROG and self.showprog and (done or self.index % 500 == 0) \
          and (os.getpgrp() == os.tcgetpgrp(sys.stderr.fileno())):
            rows, columns = struct.unpack('hh', fcntl.ioctl(2, termios.TIOCGWINSZ, "1234"))
            if columns < 100:
                sps = 30
            else:
                # Terminal is wide enough, include bytes/sec
                sps = 42
            # Progress bar length
            wlen = int(columns) - len(str_units(self.filesize)) - sps
            # Number of bytes per progress bar unit
            xunit = float(self.filesize)/wlen
            # Progress bar units done so far
            xdone = int(self.offset/xunit)
            xtime = time.time()
            progress = 100.0*self.offset/self.filesize

            # Display progress only if there is some change in progress
            if (done and not self.progdone) or (self.prevdone != xdone or \
               int(self.prevtime) != int(xtime) or \
               round(self.prevprog) != round(progress)):
                if done:
                    # Do not display progress again when done=True
                    self.progdone = 1
                otime  = xtime - self.timestart # Overall time
                tdelta = xtime - self.prevtime  # Segment time
                self.prevprog = progress
                self.prevdone = xdone
                self.prevtime = xtime
                # Number of progress bar units for completion
                slen = wlen - xdone
                if done:
                    # Overall average bytes/sec
                    bps = self.offset / otime
                else:
                    # Segment average bytes/sec
                    bps = (self.offset - self.prevoff) / tdelta
                self.prevoff = self.offset
                # Progress bar has both foreground and background colors
                # as green and in case the terminal does not support colors
                # then a "=" is displayed instead instead of a green block
                pbar = " [\033[32m\033[42m%s\033[m%s] " % ("="*xdone, " "*slen)
                # Add progress percentage and how many bytes have been
                # processed so far relative to the total number of bytes
                pbar += "%5.1f%% %9s/%s" % (progress, str_units(self.offset), str_units(self.filesize))
                if columns < 100:
                    sys.stderr.write("%s %-6s\r" % (pbar, str_time(otime)))
                else:
                    # Terminal is wide enough, include bytes/sec
                    sys.stderr.write("%s %9s/s %-6s\r" % (pbar, str_units(bps), str_time(otime)))
                if done:
                    sys.stderr.write("\n")
Example #12
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        pgrp = os.tcgetpgrp(fd)

        try:
            with open("/proc/%s/cmdline" % pgrp, "rb") as f:
                return f.read().decode("utf-8", "ignore").split("\0")[0]
        except IOError:
            pass
Example #13
0
 def initialise(self):
     if not self.enabled:
         return
     if termios is None:
         self.enabled = False
         return
     try:
         self.tty = open("/dev/tty", "w+")
         os.tcgetpgrp(self.tty.fileno())
         self.clean_tcattr = termios.tcgetattr(self.tty)
         iflag, oflag, cflag, lflag, ispeed, ospeed, cc = self.clean_tcattr
         new_lflag = lflag & (0xffffffff ^ termios.ICANON)
         new_cc = cc[:]
         new_cc[termios.VMIN] = 0
         self.cbreak_tcattr = [
             iflag, oflag, cflag, new_lflag, ispeed, ospeed, new_cc
         ]
     except Exception:
         self.enabled = False
         return
Example #14
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        pgrp = os.tcgetpgrp(fd)

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').partition('\0')[0]
        except IOError:
            pass
Example #15
0
 def cb_launchSpectra(self):
     '''
     make sure that main() is started as a foreground process
     '''
     if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
         Spectra.gra_input()
     else:
         QtGui.QMessageBox.critical(
             self, 'Error',
             "cb_launchSpectra: no TTY connected.\nMain runs as  a background process",
             QtGui.QMessageBox.Ok)
Example #16
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        pgrp = os.tcgetpgrp(fd)

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').split('\0')[0]
        except IOError:
            pass
Example #17
0
def is_interactive(fd=None):
    if fd is None:
        return False

    if isatty(fd):
        # Compare the current process group to the process group associated
        # with terminal of the given file descriptor to determine if the process
        # is running in the background.
        return getpgrp() == tcgetpgrp(fd)
    else:
        return False
Example #18
0
def isRunningInBackground():
    # type: () -> bool
    import os
    import sys

    try:
        if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
            return False
        else:
            return True
    except OSError:
        return True
Example #19
0
def _is_daemon():
    try:
        is_daemon = os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno())
    except OSError as err:
        if err.errno == errno.ENOTTY:
            is_daemon = True
        else:
            raise
    except UnsupportedOperation:
        is_daemon = True

    return is_daemon
def runing_in_terminal() -> bool:
  # by BlackJack: http://stackoverflow.com/a/24862213/2334951
  try:
    terminal_prgc_gr_id = os.tcgetpgrp(sys.stdout.fileno())
  except OSError:
    return False
  else:
    current_prgc_gr_id = os.getpgrp()
    if current_prgc_gr_id == terminal_prgc_gr_id:
      return True
    else:
      return False
    def _shell_is_busy(self):
        """Check if the shell is waiting for a command or not."""

        pty = self.term.get_pty()
        fd = pty.get_fd()

        fgpid = os.tcgetpgrp(fd)

        if fgpid == -1 or fgpid == self.shell_pid:
            return False

        return True
Example #22
0
def get_name_for_fd(fd):
    """
    Return the process name for a given process ID.
    """
    if sys.platform in ('linux', 'linux2'):
        pgrp = os.tcgetpgrp(fd)

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').split('\0')[0]
        except IOError:
            pass
Example #23
0
def _is_daemon():
    try:
        is_daemon = os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno())
    except OSError as err:
        if err.errno == errno.ENOTTY:
            # Assume we are a daemon because there is no terminal.
            is_daemon = True
        else:
            raise
    except UnsupportedOperation:
        # Could not get the fileno for stdout, so we must be a daemon.
        is_daemon = True
    return is_daemon
Example #24
0
def check_foreground():
    ''' function that returns True if the process executing this module
        is in foreground. If in background, this module won't
        print to stderr/stdout.
    '''
    if (not platform.system().lower().startswith('linux')):
        return True
    try:
        if (os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno())):
            return True
    except OSError:
        pass
    return False
Example #25
0
    def signalHandler(self, signo, _frame):
        logging.debug("signalHandler: signo=%d", signo)
        if signo == signal.SIGINT or signo == signal.SIGTERM:
            self.job.kill()

        elif signo == signal.SIGCHLD:
            # Get status of child
            try:
                (pid, status) = os.waitpid(
                    self.job.pid, os.WNOHANG + os.WCONTINUED + os.WUNTRACED)
            except OSError as ex:
                # Simulate success in case of error (very rare case...)
                logging.debug("waitpid: %s", str(ex))
                pid = self.job.pid
                status = 512
            logging.debug("waitpid: pid=%d status=%s", pid, status)
            self.job.updateStatus(status)

            if self.job.stopped:
                # If sub-process was associated with console, change it to us
                if os.tcgetpgrp(0) == self.job.pgid:
                    logging.debug("tcsetpgrp(0, %d)", os.getpgrp())
                    os.tcsetpgrp(0, os.getpgrp())
                # Propagate the stop to our process group
                logging.debug("killpg(0, SIGSTOP)")
                os.killpg(0, signal.SIGSTOP)

        elif signo == signal.SIGCONT:
            # If we are associated with console, change it to sub-process
            self.tcpgrp = os.tcgetpgrp(0)
            self.foreground = (self.tcpgrp == os.getpgrp())
            logging.debug("tcpgrp=%d foreground=%d", self.tcpgrp,
                          self.foreground)
            if self.foreground:
                logging.debug("tcsetpgrp(0, %d)", self.job.pgid)
                os.tcsetpgrp(0, self.job.pgid)
            # Propagate continue to sub-process
            logging.debug("killpg(%d, SIGCONT)", self.job.pgid)
            os.killpg(self.job.pgid, signal.SIGCONT)
Example #26
0
 def serve_forever(self):
     ctx = context.get_context()
     ctx.running = True
     try:
         # set up greenlet switch monitoring
         import greenlet
         greenlet.settrace(ctx._trace)
     except AttributeError:
         pass  # oh well
     if not self.prefork:
         self.start()
         log_msg = 'Group initialized and serving forever...'
         ctx.log.critical('GROUP.INIT').success(log_msg)
         if ctx.dev and ctx.dev_service_repl_enabled and os.isatty(0):
             if not hasattr(os, "getpgrp"):  # Windows
                 fg = True
             else:
                 try:
                     fg = os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno())
                 except OSError:
                     fg = False
             if fg:
                 # only start REPL on unix machines if running in foreground
                 async .start_repl({'server': ctx.server_group})
         try:
             while 1:
                 async .sleep(1.0)
         finally:
             self.stop()
         return
     if not ufork:
         raise RuntimeError(
             'attempted to run pre-forked on platform without fork')
     if ctx.tracing:  # a little bit hacky, disable tracing in aribter
         self.trace_in_child = True
         ctx.set_greenlet_trace(False)
     else:
         self.trace_in_child = False
     self.arbiter = ufork.Arbiter(post_fork=self._post_fork,
                                  child_pre_exit=self.stop,
                                  parent_pre_stop=ctx.stop,
                                  size=self.num_workers,
                                  sleep=async .sleep,
                                  fork=gevent.fork,
                                  child_memlimit=ctx.worker_memlimit)
     if self.daemonize:
         pgrpfile = os.path.join(ctx.process_group_file_path,
                                 '{0}.pgrp'.format(ctx.appname))
         self.arbiter.spawn_daemon(pgrpfile=pgrpfile)
     else:
         self.arbiter.run()
Example #27
0
    def signalHandler(self, signo, _frame):
        logging.debug("signalHandler: signo=%d", signo)
        if signo == signal.SIGINT or signo == signal.SIGTERM:
            self.job.kill()

        elif signo == signal.SIGCHLD:
            # Get status of child
            try:
                (pid, status) = os.waitpid(self.job.pid,
                        os.WNOHANG + os.WCONTINUED + os.WUNTRACED)
            except OSError as ex:
                # Simulate success in case of error (very rare case...)
                logging.debug("waitpid: %s", str(ex))
                pid = self.job.pid
                status = 512
            logging.debug("waitpid: pid=%d status=%s", pid, status)
            self.job.updateStatus(status)

            if self.job.stopped:
                # If sub-process was associated with console, change it to us
                if os.tcgetpgrp(0) == self.job.pgid:
                    logging.debug("tcsetpgrp(0, %d)", os.getpgrp())
                    os.tcsetpgrp(0, os.getpgrp())
                # Propagate the stop to our process group
                logging.debug("killpg(0, SIGSTOP)")
                os.killpg(0, signal.SIGSTOP)

        elif signo == signal.SIGCONT:
            # If we are associated with console, change it to sub-process
            self.tcpgrp = os.tcgetpgrp(0)
            self.foreground = (self.tcpgrp == os.getpgrp())
            logging.debug("tcpgrp=%d foreground=%d", self.tcpgrp, self.foreground)
            if self.foreground:
                logging.debug("tcsetpgrp(0, %d)", self.job.pgid)
                os.tcsetpgrp(0, self.job.pgid)
            # Propagate continue to sub-process
            logging.debug("killpg(%d, SIGCONT)", self.job.pgid)
            os.killpg(self.job.pgid, signal.SIGCONT)
Example #28
0
def _safe_tcsetpgrp(fd, pgrp):
    """Set |pgrp| as the controller of the tty |fd|."""
    try:
        curr_pgrp = os.tcgetpgrp(fd)
    except OSError as e:
        # This can come up when the fd is not connected to a terminal.
        if e.errno == errno.ENOTTY:
            return
        raise

    # We can change the owner only if currently own it.  Otherwise we'll get
    # stopped by the kernel with SIGTTOU and that'll hit the whole group.
    if curr_pgrp == os.getpgrp():
        os.tcsetpgrp(fd, pgrp)
Example #29
0
def _safe_tcsetpgrp(fd, pgrp):
    """Set |pgrp| as the controller of the tty |fd|."""
    try:
        curr_pgrp = os.tcgetpgrp(fd)
    except OSError as e:
        # This can come up when the fd is not connected to a terminal.
        if e.errno == errno.ENOTTY:
            return
        raise

    # We can change the owner only if currently own it.  Otherwise we'll get
    # stopped by the kernel with SIGTTOU and that'll hit the whole group.
    if curr_pgrp == os.getpgrp():
        os.tcsetpgrp(fd, pgrp)
Example #30
0
def setup_py_main():
    """Main function for setup script."""
    if sys.stdin.isatty() and sys.stdout.isatty() and sys.stderr.isatty():
        if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
            if os.geteuid() == 0:
                main()
                terminate()
            else:
                print("[!] Run me as superuser (a.k.a. root)")
                sys.exit(2)
        else:
            sys.exit(2)
    else:
        sys.exit(2)
Example #31
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        try:
            pgrp = os.tcgetpgrp(fd)
        except OSError:
            # See: https://github.com/jonathanslenders/pymux/issues/46
            return

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').partition('\0')[0]
        except IOError:
            pass
Example #32
0
	def determine_interactive(self):
		"""Determine whether we're in an interactive shell.
		Sets interactivity off if appropriate.
		cf http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process
		"""
		try:
			if not sys.stdout.isatty() or os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno()):
				self.interactive = 0
				return False
		except Exception:
			self.interactive = 0
			return False
		if self.interactive == 0:
			return False
		return True
 def _maybe_become_foreground(self):
     """
     Become the foreground process if the user requested it and it is
     possible. Allows the "Parent" process (aka this one) to get
     SIGINT (Ctrl+C). Useful if running in your terminal or from python repl.
     :return:
     """
     if self._should_become_foreground():
         hdlr = signal.signal(signal.SIGTTOU, signal.SIG_IGN)  # ignore since would cause this process to stop
         self.controlling_terminal = os.open(os.ctermid(), os.O_RDWR)
         self.orig_fore_pg = os.tcgetpgrp(self.controlling_terminal)  # sends SIGTTOU to this process
         os.tcsetpgrp(self.controlling_terminal, self.childpid)
         signal.signal(signal.SIGTTOU, hdlr)
         return True
     return False
Example #34
0
	def determine_interactive(self):
		"""Determine whether we're in an interactive shell.
		Sets interactivity off if appropriate.
		cf http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process
		"""
		try:
			if not sys.stdout.isatty() or os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno()):
				self.set_noninteractive()
				return False
		except Exception:
			self.set_noninteractive(msg='Problems determining interactivity, assuming not.')
			return False
		if self.interactive == 0:
			return False
		return True
Example #35
0
    def __enter__(self):
        assert not self._tty_settings
        # False if the pipeline is being piped somewhere
        if sys.stdin.isatty() and sys.stdout.isatty():
            # False if the process is running in the background
            if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
                try:
                    # Store old settings
                    self._tty_settings = termios.tcgetattr(sys.stdin)
                    # Disable echo
                    tty.setcbreak(sys.stdin.fileno())
                except tty.error:
                    pass  # Silently ignore failures

        return self
Example #36
0
    def __enter__(self):
        assert not self._tty_settings
        # False if the pipeline is being piped somewhere
        if sys.stdin.isatty() and sys.stdout.isatty():
            # False if the process is running in the background
            if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
                try:
                    # Store old settings
                    self._tty_settings = termios.tcgetattr(sys.stdin)
                    # Disable echo
                    tty.setcbreak(sys.stdin.fileno())
                except tty.error:
                    pass  # Silently ignore failures

        return self
Example #37
0
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.
        """
        try:
            pgrp = os.tcgetpgrp(fd)
        except OSError:
            # See: https://github.com/jonathanslenders/pymux/issues/46
            return

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').partition('\0')[0]
        except IOError:
            pass
Example #38
0
File: posix.py Project: riag/ptterm
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.

        NOTE: on Linux, this seems to require the master FD.
        """
        try:
            pgrp = os.tcgetpgrp(fd)
        except OSError:
            return

        try:
            return get_proc_name(pgrp)
        except IOError:
            pass
  def __init__(self,debug):
    """ Constructor """
    self._debug = debug
    self._lock = threading.Lock()
    try:
      if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
        self._syslog = False
        self._debug  = "1"
      else:
        self._syslog = True
    except:
      self._syslog = True

    if self._syslog:
      syslog.openlog("nerd-alarmclock")
Example #40
0
    def foreground_processes(self):
        try:
            pgrp = os.tcgetpgrp(self.child_fd)
            foreground_processes = processes_in_group(pgrp) if pgrp >= 0 else []

            def process_desc(pid):
                ans = {'pid': pid}
                with suppress(Exception):
                    ans['cmdline'] = cmdline_of_process(pid)
                with suppress(Exception):
                    ans['cwd'] = cwd_of_process(pid) or None
                return ans

            return list(map(process_desc, foreground_processes))
        except Exception:
            return []
Example #41
0
 def serve_forever(self):
     ctx = context.get_context()
     ctx.running = True
     try:
         # set up greenlet switch monitoring
         import greenlet
         greenlet.settrace(ctx._trace)
     except AttributeError:
         pass  # oh well
     if not self.prefork:
         self.start()
         log_msg = 'Group initialized and serving forever...'
         ctx.log.critical('GROUP.INIT').success(log_msg)
         if ctx.dev and ctx.dev_service_repl_enabled and os.isatty(0):
             if not hasattr(os, "getpgrp"):  # Windows
                 fg = True
             else:
                 try:
                     fg = os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno())
                 except OSError:
                     fg = False
             if fg:
                 # only start REPL on unix machines if running in foreground
                 async.start_repl({'server': ctx.server_group})
         try:
             while 1:
                 async.sleep(1.0)
         finally:
             self.stop()
         return
     if not ufork:
         raise RuntimeError('attempted to run pre-forked on platform without fork')
     if ctx.tracing:  # a little bit hacky, disable tracing in aribter
         self.trace_in_child = True
         ctx.set_greenlet_trace(False)
     else:
         self.trace_in_child = False
     self.arbiter = ufork.Arbiter(
         post_fork=self._post_fork, child_pre_exit=self.stop, parent_pre_stop=ctx.stop,
         size=self.num_workers, sleep=async.sleep, fork=gevent.fork, child_memlimit=ctx.worker_memlimit)
     if self.daemonize:
         pgrpfile = os.path.join(ctx.process_group_file_path,
                                '{0}.pgrp'.format(ctx.appname))
         self.arbiter.spawn_daemon(pgrpfile=pgrpfile)
     else:
         self.arbiter.run()
Example #42
0
def _is_daemon():
    # The process group for a foreground process will match the
    # process group of the controlling terminal. If those values do
    # not match, or ioctl() fails on the stdout file handle, we assume
    # the process is running in the background as a daemon.
    # http://www.gnu.org/software/bash/manual/bashref.html#Job-Control-Basics
    try:
        is_daemon = os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno())
    except io.UnsupportedOperation:
        # Could not get the fileno for stdout, so we must be a daemon.
        is_daemon = True
    except OSError as err:
        if err.errno == errno.ENOTTY:
            # Assume we are a daemon because there is no terminal.
            is_daemon = True
        else:
            raise
    return is_daemon
Example #43
0
File: posix.py Project: riag/ptterm
    def get_name_for_fd(fd):
        """
        Return the process name for a given process ID.

        :param fd: Slave file descriptor. (Often the master fd works as well,
            but apparentsly on WSL only the slave FD works.)
        """
        try:
            pgrp = os.tcgetpgrp(fd)
        except OSError:
            # See: https://github.com/jonathanslenders/pymux/issues/46
            return

        try:
            with open('/proc/%s/cmdline' % pgrp, 'rb') as f:
                return f.read().decode('utf-8', 'ignore').partition('\0')[0]
        except IOError:
            pass
Example #44
0
    def foreground_processes(self) -> List[ProcessDesc]:
        if self.child_fd is None:
            return []
        try:
            pgrp = os.tcgetpgrp(self.child_fd)
            foreground_processes = processes_in_group(pgrp) if pgrp >= 0 else []

            def process_desc(pid: int) -> ProcessDesc:
                ans: ProcessDesc = {'pid': pid, 'cmdline': None, 'cwd': None}
                with suppress(Exception):
                    ans['cmdline'] = cmdline_of_process(pid)
                with suppress(Exception):
                    ans['cwd'] = cwd_of_process(pid) or None
                return ans

            return [process_desc(x) for x in foreground_processes]
        except Exception:
            return []
Example #45
0
def _is_daemon():
    # The process group for a foreground process will match the
    # process group of the controlling terminal. If those values do
    # not match, or ioctl() fails on the stdout file handle, we assume
    # the process is running in the background as a daemon.
    # http://www.gnu.org/software/bash/manual/bashref.html#Job-Control-Basics
    try:
        is_daemon = os.getpgrp() != os.tcgetpgrp(sys.stdout.fileno())
    except OSError as err:
        if err.errno == errno.ENOTTY:
            # Assume we are a daemon because there is no terminal.
            is_daemon = True
        else:
            raise
    except UnsupportedOperation:
        # Could not get the fileno for stdout, so we must be a daemon.
        is_daemon = True
    return is_daemon
Example #46
0
 def get_pid_for_cwd(self, oldest: bool = False) -> Optional[int]:
     with suppress(Exception):
         assert self.child_fd is not None
         pgrp = os.tcgetpgrp(self.child_fd)
         foreground_processes = processes_in_group(pgrp) if pgrp >= 0 else []
         if foreground_processes:
             # there is no easy way that I know of to know which process is the
             # foreground process in this group from the users perspective,
             # so we assume the one with the highest PID is as that is most
             # likely to be the newest process. This situation can happen
             # for example with a shell script such as:
             # #!/bin/bash
             # cd /tmp
             # vim
             # With this script , the foreground process group will contain
             # both the bash instance running the script and vim.
             return min(foreground_processes) if oldest else max(foreground_processes)
     return self.pid
Example #47
0
    def __init__(self, parent, model):
        super().__init__(model)
        self.width = parent.width
        self.height = parent.height
        self.previous_screen = 0

        # ncurses stops the process if in the background
        if os.tcgetpgrp(sys.stdin.fileno()) != os.getpgrp():
            logging.getLogger("display").warn("please run speculos in the foreground to allow the initialization of the display")

        self.stdscr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.start_color()
        curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
        curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)
        self.stdscr.nodelay(1)    # returns -1 if nothing
        self.stdscr.clear()
        self.stdscr.keypad(1)   # interpret escape sequences generated by keypad and function keys
Example #48
0
def stdin_is_foregrounded_tty(stream):
    """
    Detect if given stdin ``stream`` seems to be in the foreground of a TTY.

    Specifically, compares the current Python process group ID to that of the
    stream's file descriptor to see if they match; if they do not match, it is
    likely that the process has been placed in the background.

    This is used as a test to determine whether we should manipulate an active
    stdin so it runs in a character-buffered mode; touching the terminal in
    this way when the process is backgrounded, causes most shells to pause
    execution.

    .. note::
        Processes that aren't attached to a terminal to begin with, will always
        fail this test, as it starts with "do you have a real ``fileno``?".
    """
    if not has_fileno(stream):
        return False
    return os.getpgrp() == os.tcgetpgrp(stream.fileno())
Example #49
0
def stdin_is_foregrounded_tty(stream):
    """
    Detect if given stdin ``stream`` seems to be in the foreground of a TTY.

    Specifically, compares the current Python process group ID to that of the
    stream's file descriptor to see if they match; if they do not match, it is
    likely that the process has been placed in the background.

    This is used as a test to determine whether we should manipulate an active
    stdin so it runs in a character-buffered mode; touching the terminal in
    this way when the process is backgrounded, causes most shells to pause
    execution.

    .. note::
        Processes that aren't attached to a terminal to begin with, will always
        fail this test, as it starts with "do you have a real ``fileno``?".
    """
    if not has_fileno(stream):
        return False
    return os.getpgrp() == os.tcgetpgrp(stream.fileno())
Example #50
0
 def send_signal_for_key(self, key_num: int) -> bool:
     import signal
     import termios
     if self.child_fd is None:
         return False
     t = termios.tcgetattr(self.child_fd)
     if not t[3] & termios.ISIG:
         return False
     cc = t[-1]
     if key_num == cc[termios.VINTR]:
         s = signal.SIGINT
     elif key_num == cc[termios.VSUSP]:
         s = signal.SIGTSTP
     elif key_num == cc[termios.VQUIT]:
         s = signal.SIGQUIT
     else:
         return False
     pgrp = os.tcgetpgrp(self.child_fd)
     os.killpg(pgrp, s)
     return True
 def _goto_current_terminal_directory(self):
     """Navigate the active Nemo pane to the current working directory
     of the VTE
     
     This functionality depends on some changes to Nemo's extension
     interface.
     """
     # Well behaved shells will be updating VTE for us but it doesn't always
     # work.
     workingDir = self.term.get_current_directory_uri()
     if workingDir is None:
         # Find the current foreground process in terminal
         pty = self.term.get_pty_object()
         ptyfd = pty.get_fd()
         pgroup = os.tcgetpgrp(ptyfd)
         workingDir = os.readlink('/proc/%s/cwd' % pgroup)
     gfile = Gio.file_parse_name(workingDir)
     workingDirUri = gfile.get_uri()
     print workingDirUri
     # TODO: something useful (like changing the working dir)
     return
    def _goto_current_terminal_directory(self):
        """Navigate the active Nemo pane to the current working directory
        of the VTE

        This functionality depends on some changes to Nemo's extension
        interface.
        """
        # Well behaved shells will be updating VTE for us but it doesn't always
        # work.
        workingDir = self.term.get_current_directory_uri()
        if workingDir is None:
            # Find the current foreground process in terminal
            pty = self.term.get_pty_object()
            ptyfd = pty.get_fd()
            pgroup = os.tcgetpgrp(ptyfd)
            workingDir = os.readlink('/proc/%s/cwd' % pgroup)
        gfile = Gio.file_parse_name(workingDir)
        workingDirUri = gfile.get_uri()
        print workingDirUri
        # TODO: something useful (like changing the working dir)
        return
Example #53
0
 def check_dir(self, out_dir):
     if os.path.exists(out_dir):
         #check if the process is run in background
         try: 
             if os.getpgrp() == os.tcgetpgrp(sys.stdout.fileno()):
                 print  self.user_message % out_dir
                 user_input = raw_input()
                 while user_input not in ["1", "2", "3"]:
                     user_input = raw_input().strip()
                 if user_input == "1":
                     return False 
                 if user_input == "2":
                     shutil.rmtree(out_dir)
                     os.mkdir(out_dir)
                     return True 
                 if user_input == "3":
                     sys.exit(1)
             else:
                 sys.stderr.write(self.error_message % out_dir)
         except OSError:
                 sys.stderr.write(self.error_message % out_dir)
     else: 
         os.mkdir(out_dir)
         return True
Example #54
0
    def startLog(self):
        """Starts the log to path.  The parent process becomes the "slave"
        process: its stdin, stdout, and stderr are redirected to a pseudo tty.
        A child logging process controls the real stdin, stdout, and stderr,
        and writes stdout and stderr both to the screen and to the logfile
        at path.
        """
        self.restoreTerminalControl = (sys.stdin.isatty() and
            os.tcgetpgrp(0) == os.getpid())

        masterFd, slaveFd = os.openpty()
        signal.signal(signal.SIGTTOU, signal.SIG_IGN)

        pid = os.fork()
        if pid:
            # make parent process the pty slave - the opposite of
            # pty.fork().  In this setup, the parent process continues
            # to act normally, while the child process performs the
            # logging.  This makes it simple to kill the logging process
            # when we are done with it and restore the parent process to
            # normal, unlogged operation.
            os.close(masterFd)
            self._becomeLogSlave(slaveFd, pid)
            return
        try:
            os.close(slaveFd)
            for writer in self.writers:
                writer.start()
            logger = _ChildLogger(masterFd, self.lexer,
                                  self.restoreTerminalControl, self.withStdin)
            try:
                logger.log()
            finally:
                self.lexer.close()
        finally:
            os._exit(0)
Example #55
0
def _running_in_bg():
    try:
        return (not os.isatty(0)) or (os.getpgrp() != os.tcgetpgrp(0))
    except OSError:
        return True
Example #56
0

    def _give_terminal_to(pgid):
        # over-simplified version of:
        #    give_terminal_to from bash 4.3 source, jobs.c, line 4030
        # this will give the terminal to the process group pgid
        if _shell_tty is not None and os.isatty(_shell_tty):
            oldmask = signal.pthread_sigmask(signal.SIG_BLOCK, _block_when_giving)
            os.tcsetpgrp(_shell_tty, pgid)
            signal.pthread_sigmask(signal.SIG_SETMASK, oldmask)


    # check for shell tty
    try:
        _shell_tty = sys.stderr.fileno()
        if os.tcgetpgrp(_shell_tty) != os.getpgid(os.getpid()):
            # we don't own it
            _shell_tty = None
    except OSError:
        _shell_tty = None


    def wait_for_active_job(signal_to_send=None):
        """
        Wait for the active job to finish, to be killed by SIGINT, or to be
        suspended by ctrl-z.
        """
        _clear_dead_jobs()
        act = builtins.__xonsh_active_job__
        if act is None:
            return
Example #57
0
        peer = peer.split(':')
        if len(peer) != 2:
            raise Exception('peer %s is not valid' % ':'.join(peer))
        _discoro_config['peers'].append(asyncoro.Location(peer[0], peer[1]))
    del peer, peers

    _discoro_name = _discoro_config['name']
    if not _discoro_name:
        _discoro_name = socket.gethostname()
        if not _discoro_name:
            _discoro_name = 'discoro_server'

    _discoro_daemon = _discoro_config.pop('daemon', False)
    if not _discoro_daemon:
        try:
            if os.getpgrp() != os.tcgetpgrp(sys.stdin.fileno()):
                _discoro_daemon = True
        except:
            pass
    _discoro_auth = hashlib.sha1(''.join(hex(_)[2:] for _ in os.urandom(10)).encode()).hexdigest()

    # delete variables not needed anymore
    del parser
    for _discoro_var in ['argparse', 'socket', 'os']:
        del sys.modules[_discoro_var], globals()[_discoro_var]
    del _discoro_var

    _discoro_server_infos = []
    _discoro_ServerInfo = collections.namedtuple('DiscoroServerInfo', ['Proc', 'Queue'])
    _discoro_mp_queue = None
    _discoro_ntotal_coros = multiprocessing.Value('L', 0)
Example #58
0
    def _create_preexec_fn(self, process):
        """Create and return a function to do cleanup before exec

        The cleanup function will close all file descriptors which are not
        needed by the child process.  This is required to prevent unnecessary
        blocking on the final read of pipes not set FD_CLOEXEC due to gpg
        inheriting an open copy of the input end of the pipe.  This can cause
        delays in unrelated parts of the program or deadlocks in the case that
        one end of the pipe is passed to attach_fds.

        FIXME:  There is a race condition where a pipe can be created in
        another thread after this function runs before exec is called and it
        will not be closed.  This race condition will remain until a better
        way to avoid closing the error pipe created by submodule is identified.
        """
        if sys.platform == "win32":
            return None     # No cleanup necessary

        try:
            MAXFD = os.sysconf("SC_OPEN_MAX")
            if MAXFD == -1:
                MAXFD = 256
        except:
            MAXFD = 256

        # Get list of fds to close now, so we don't close the error pipe
        # created by submodule for reporting exec errors
        child_fds = [p.child for p in process._pipes.values()]
        child_fds.sort()
        child_fds.append(MAXFD) # Sentinel value, simplifies code greatly

        child_fds_iter = iter(child_fds)
        child_fd = next(child_fds_iter)
        while child_fd < 3:
            child_fd = next(child_fds_iter)

        extra_fds = []
        # FIXME:  Is there a better (portable) way to list all open FDs?
        for fd in range(3, MAXFD):
            if fd > child_fd:
                child_fd = next(child_fds_iter)

            if fd == child_fd:
                continue

            try:
                # Note:  Can't use lseek, can cause nul byte in pipes
                #        where the position has not been set by read/write
                #os.lseek(fd, os.SEEK_CUR, 0)
                os.tcgetpgrp(fd)
            except OSError:
                # FIXME:  When support for Python 2.5 is dropped, use 'as'
                oe = sys.exc_info()[1]
                if oe.errno == errno.EBADF:
                    continue

            extra_fds.append(fd)

        def preexec_fn():
            # Note:  This function runs after standard FDs have been renumbered
            #        from their original values to 0, 1, 2

            for fd in extra_fds:
                try:
                    os.close(fd)
                except OSError:
                    pass

            # Ensure that all descriptors passed to the child will remain open
            # Arguably FD_CLOEXEC descriptors should be an argument error
            # But for backwards compatibility, we just fix it here (after fork)
            for fd in [0, 1, 2] + child_fds[:-1]:
                try:
                    fcntl.fcntl(fd, fcntl.F_SETFD, 0)
                except OSError:
                    # Will happen for renumbered FDs
                    pass

        return preexec_fn
Example #59
0
def main():
    """clush script entry point"""
    sys.excepthook = clush_excepthook

    #
    # Argument management
    #
    usage = "%prog [options] command"

    parser = OptionParser(usage)

    parser.add_option("-n", "--nostdin", action="store_true", dest="nostdin",
                      help="don't watch for possible input from stdin")

    parser.install_groupsconf_option()
    parser.install_clush_config_options()
    parser.install_nodes_options()
    parser.install_display_options(verbose_options=True)
    parser.install_filecopy_options()
    parser.install_connector_options()

    (options, args) = parser.parse_args()

    set_std_group_resolver_config(options.groupsconf)

    #
    # Load config file and apply overrides
    #
    config = ClushConfig(options, options.conf)

    # Initialize logging
    if config.verbosity >= VERB_DEBUG:
        logging.basicConfig(level=logging.DEBUG)
        logging.debug("clush: STARTING DEBUG")
    else:
        logging.basicConfig(level=logging.CRITICAL)

    # Should we use ANSI colors for nodes?
    if config.color == "auto":
        color = sys.stdout.isatty() and (options.gatherall or \
                                         sys.stderr.isatty())
    else:
        color = config.color == "always"

    try:
        # Create and configure display object.
        display = Display(options, config, color)
    except ValueError as exc:
        parser.error("option mismatch (%s)" % exc)

    if options.groupsource:
        # Be sure -a/g -s source work as espected.
        std_group_resolver().default_source_name = options.groupsource

    # Compute the nodeset and warn for possible use of shell pathname
    # expansion (#225)
    wnodelist = []
    xnodelist = []
    if options.nodes:
        wnodelist = [NodeSet(nodes) for nodes in options.nodes]

    if options.exclude:
        xnodelist = [NodeSet(nodes) for nodes in options.exclude]

    for (opt, nodelist) in (('w', wnodelist), ('x', xnodelist)):
        for nodes in nodelist:
            if len(nodes) == 1 and exists(str(nodes)):
                display.vprint_err(VERB_STD, "Warning: using '-%s %s' and "
                                   "local path '%s' exists, was it expanded "
                                   "by the shell?" % (opt, nodes, nodes))

    # --hostfile support (#235)
    for opt_hostfile in options.hostfile:
        try:
            fnodeset = NodeSet()
            with open(opt_hostfile) as hostfile:
                for line in hostfile.read().splitlines():
                    fnodeset.updaten(nodes for nodes in line.split())
            display.vprint_err(VERB_DEBUG,
                               "Using nodeset %s from hostfile %s"
                               % (fnodeset, opt_hostfile))
            wnodelist.append(fnodeset)
        except IOError as exc:
            # re-raise as OSError to be properly handled
            errno, strerror = exc.args
            raise OSError(errno, strerror, exc.filename)

    # Instantiate target nodeset from command line and hostfile
    nodeset_base = NodeSet.fromlist(wnodelist)
    # Instantiate filter nodeset (command line only)
    nodeset_exclude = NodeSet.fromlist(xnodelist)

    # Specified engine prevails over default engine
    DEFAULTS.engine = options.engine

    # Do we have nodes group?
    task = task_self()
    task.set_info("debug", config.verbosity >= VERB_DEBUG)
    if config.verbosity == VERB_DEBUG:
        std_group_resolver().set_verbosity(1)
    if options.nodes_all:
        all_nodeset = NodeSet.fromall()
        display.vprint(VERB_DEBUG, "Adding nodes from option -a: %s" % \
                                   all_nodeset)
        nodeset_base.add(all_nodeset)

    if options.group:
        grp_nodeset = NodeSet.fromlist(options.group,
                                       resolver=RESOLVER_NOGROUP)
        for grp in grp_nodeset:
            addingrp = NodeSet("@" + grp)
            display.vprint(VERB_DEBUG, \
                "Adding nodes from option -g %s: %s" % (grp, addingrp))
            nodeset_base.update(addingrp)

    if options.exgroup:
        grp_nodeset = NodeSet.fromlist(options.exgroup,
                                       resolver=RESOLVER_NOGROUP)
        for grp in grp_nodeset:
            removingrp = NodeSet("@" + grp)
            display.vprint(VERB_DEBUG, \
                "Excluding nodes from option -X %s: %s" % (grp, removingrp))
            nodeset_exclude.update(removingrp)

    # Do we have an exclude list? (-x ...)
    nodeset_base.difference_update(nodeset_exclude)
    if len(nodeset_base) < 1:
        parser.error('No node to run on.')

    if options.pick and options.pick < len(nodeset_base):
        # convert to string for sample as nsiter() is slower for big
        # nodesets; and we assume options.pick will remain small-ish
        keep = random.sample(list(nodeset_base), options.pick)
        nodeset_base.intersection_update(','.join(keep))
        if config.verbosity >= VERB_VERB:
            msg = "Picked random nodes: %s" % nodeset_base
            print(Display.COLOR_RESULT_FMT % msg)

    # Set open files limit.
    set_fdlimit(config.fd_max, display)

    #
    # Task management
    #
    # check for clush interactive mode
    interactive = not len(args) and \
                  not (options.copy or options.rcopy)
    # check for foreground ttys presence (input)
    stdin_isafgtty = sys.stdin.isatty() and \
        os.tcgetpgrp(sys.stdin.fileno()) == os.getpgrp()
    # check for special condition (empty command and stdin not a tty)
    if interactive and not stdin_isafgtty:
        # looks like interactive but stdin is not a tty:
        # switch to non-interactive + disable ssh pseudo-tty
        interactive = False
        # SSH: disable pseudo-tty allocation (-T)
        ssh_options = config.ssh_options or ''
        ssh_options += ' -T'
        config._set_main("ssh_options", ssh_options)
    if options.nostdin and interactive:
        parser.error("illegal option `--nostdin' in that case")

    # Force user_interaction if Clush._f_user_interaction for test purposes
    user_interaction = hasattr(sys.modules[__name__], '_f_user_interaction')
    if not options.nostdin:
        # Try user interaction: check for foreground ttys presence (ouput)
        stdout_isafgtty = sys.stdout.isatty() and \
            os.tcgetpgrp(sys.stdout.fileno()) == os.getpgrp()
        user_interaction |= stdin_isafgtty and stdout_isafgtty
    display.vprint(VERB_DEBUG, "User interaction: %s" % user_interaction)
    if user_interaction:
        # Standard input is a terminal and we want to perform some user
        # interactions in the main thread (using blocking calls), so
        # we run cluster commands in a new ClusterShell Task (a new
        # thread is created).
        task = Task()
    # else: perform everything in the main thread

    # Handle special signal only when user_interaction is set
    task.set_default("USER_handle_SIGUSR1", user_interaction)

    task.excepthook = sys.excepthook
    task.set_default("USER_stdin_worker", not (sys.stdin.isatty() or \
                                               options.nostdin or \
                                               user_interaction))
    display.vprint(VERB_DEBUG, "Create STDIN worker: %s" % \
                               task.default("USER_stdin_worker"))

    task.set_info("debug", config.verbosity >= VERB_DEBUG)
    task.set_info("fanout", config.fanout)

    if options.worker:
        try:
            if options.remote == 'no':
                task.set_default('local_worker',
                                 _load_workerclass(options.worker))
            else:
                task.set_default('distant_worker',
                                 _load_workerclass(options.worker))
        except (ImportError, AttributeError):
            msg = "ERROR: Could not load worker '%s'" % options.worker
            display.vprint_err(VERB_QUIET, msg)
            clush_exit(1, task)

    if options.topofile or task._default_tree_is_enabled():
        if options.topofile:
            task.load_topology(options.topofile)
        if config.verbosity >= VERB_VERB:
            roots = len(task.topology.root.nodeset)
            gws = task.topology.inner_node_count() - roots
            msg = "enabling tree topology (%d gateways)" % gws
            print("clush: %s" % msg, file=sys.stderr)

    if options.grooming_delay:
        if config.verbosity >= VERB_VERB:
            msg = Display.COLOR_RESULT_FMT % ("Grooming delay: %f" %
                                              options.grooming_delay)
            print(msg, file=sys.stderr)
        task.set_info("grooming_delay", options.grooming_delay)
    elif options.rcopy:
        # By default, --rcopy should inhibit grooming
        task.set_info("grooming_delay", 0)

    if config.ssh_user:
        task.set_info("ssh_user", config.ssh_user)
    if config.ssh_path:
        task.set_info("ssh_path", config.ssh_path)
    if config.ssh_options:
        task.set_info("ssh_options", config.ssh_options)
    if config.scp_path:
        task.set_info("scp_path", config.scp_path)
    if config.scp_options:
        task.set_info("scp_options", config.scp_options)
    if config.rsh_path:
        task.set_info("rsh_path", config.rsh_path)
    if config.rcp_path:
        task.set_info("rcp_path", config.rcp_path)
    if config.rsh_options:
        task.set_info("rsh_options", config.rsh_options)

    # Set detailed timeout values
    task.set_info("connect_timeout", config.connect_timeout)
    task.set_info("command_timeout", config.command_timeout)

    # Enable stdout/stderr separation
    task.set_default("stderr", not options.gatherall)

    # Prevent reading from stdin?
    task.set_default("stdin", not options.nostdin)

    # Disable MsgTree buffering if not gathering outputs
    task.set_default("stdout_msgtree", display.gather or display.line_mode)

    # Always disable stderr MsgTree buffering
    task.set_default("stderr_msgtree", False)

    # Set timeout at worker level when command_timeout is defined.
    if config.command_timeout > 0:
        timeout = config.command_timeout
    else:
        timeout = -1

    # Configure task custom status
    task.set_default("USER_interactive", interactive)
    task.set_default("USER_running", False)

    if (options.copy or options.rcopy) and not args:
        parser.error("--[r]copy option requires at least one argument")
    if options.copy:
        if not options.dest_path:
            # append '/' to clearly indicate a directory for tree mode
            options.dest_path = join(dirname(abspath(args[0])), '')
        op = "copy sources=%s dest=%s" % (args, options.dest_path)
    elif options.rcopy:
        if not options.dest_path:
            options.dest_path = dirname(abspath(args[0]))
        op = "rcopy sources=%s dest=%s" % (args, options.dest_path)
    else:
        op = "command=\"%s\"" % ' '.join(args)

    # print debug values (fanout value is get from the config object
    # and not task itself as set_info() is an asynchronous call.
    display.vprint(VERB_DEBUG, "clush: nodeset=%s fanout=%d [timeout " \
                   "conn=%.1f cmd=%.1f] %s" %  (nodeset_base, config.fanout,
                                                config.connect_timeout,
                                                config.command_timeout,
                                                op))
    if not task.default("USER_interactive"):
        if display.verbosity >= VERB_DEBUG and task.topology:
            print(Display.COLOR_RESULT_FMT % '-' * 15)
            print(Display.COLOR_RESULT_FMT % task.topology, end='')
            print(Display.COLOR_RESULT_FMT % '-' * 15)
        if options.copy:
            run_copy(task, args, options.dest_path, nodeset_base, timeout,
                     options.preserve_flag, display)
        elif options.rcopy:
            run_rcopy(task, args, options.dest_path, nodeset_base, timeout,
                      options.preserve_flag, display)
        else:
            run_command(task, ' '.join(args), nodeset_base, timeout, display,
                        options.remote != 'no')

    if user_interaction:
        ttyloop(task, nodeset_base, timeout, display, options.remote != 'no')
    elif task.default("USER_interactive"):
        display.vprint_err(VERB_QUIET, \
            "ERROR: interactive mode requires a tty")
        clush_exit(1, task)

    rc = 0
    if options.maxrc:
        # Instead of clush return code, return commands retcode
        rc = task.max_retcode()
        if task.num_timeout() > 0:
            rc = 255
    clush_exit(rc, task)
Example #60
0
    nodeset_base.difference_update(nodeset_exclude)
    if len(nodeset_base) < 1:
        parser.error('No node to run on.')

    # Set open files limit.
    set_fdlimit(config.fd_max, display)

    #
    # Task management
    #
    # check for clush interactive mode
    interactive = not len(args) and \
                  not (options.copy or options.rcopy)
    # check for foreground ttys presence (input)
    stdin_isafgtty = sys.stdin.isatty() and \
        os.tcgetpgrp(sys.stdin.fileno()) == os.getpgrp()
    # check for special condition (empty command and stdin not a tty)
    if interactive and not stdin_isafgtty:
        # looks like interactive but stdin is not a tty:
        # switch to non-interactive + disable ssh pseudo-tty
        interactive = False
        # SSH: disable pseudo-tty allocation (-T)
        ssh_options = config.ssh_options or ''
        ssh_options += ' -T'
        config._set_main("ssh_options", ssh_options)
    if options.nostdin and interactive:
        parser.error("illegal option `--nostdin' in that case")

    # Force user_interaction if Clush._f_user_interaction for test purposes
    user_interaction = hasattr(sys.modules[__name__], '_f_user_interaction')
    if not options.nostdin: