def start(self): """ Start the process. @raise FatalProcessLaunch: if process cannot be started and it is not likely to ever succeed """ super(LocalProcess, self).start() try: self.lock.acquire() if self.started: _logger.info("process[%s]: restarting os process", self.name) else: _logger.info("process[%s]: starting os process", self.name) self.started = self.stopped = False full_env = self.env # _configure_logging() can mutate self.args try: logfileout, logfileerr = self._configure_logging() except Exception, e: _logger.error(traceback.format_exc()) printerrlog("[%s] ERROR: unable to configure logging [%s]"%(self.name, str(e))) # it's not safe to inherit from this process as # rostest changes stdout to a StringIO, which is not a # proper file. logfileout, logfileerr = subprocess.PIPE, subprocess.PIPE if self.cwd == 'node': cwd = os.path.dirname(self.args[0]) elif self.cwd == 'cwd': cwd = os.getcwd() elif self.cwd == 'ros-root': cwd = get_ros_root() else: cwd = roslib.rosenv.get_ros_home() _logger.info("process[%s]: start w/ args [%s]", self.name, self.args) _logger.info("process[%s]: cwd will be [%s]", self.name, cwd) try: self.popen = subprocess.Popen(self.args, cwd=cwd, stdout=logfileout, stderr=logfileerr, env=full_env, close_fds=True, preexec_fn=os.setsid) except OSError, (errno, msg): self.started = True # must set so is_alive state is correct _logger.error("OSError(%d, %s)", errno, msg) if errno == 8: #Exec format error raise FatalProcessLaunch("Unable to launch [%s]. \nIf it is a script, you may be missing a '#!' declaration at the top."%self.name) elif errno == 2: #no such file or directory raise FatalProcessLaunch("""Roslaunch got a '%s' error while attempting to run: %s Please make sure that all the executables in this command exist and have executable permission. This is often caused by a bad launch-prefix."""%(msg, ' '.join(self.args))) else: raise FatalProcessLaunch("unable to launch [%s]: %s"%(' '.join(self.args), msg))
def start(self): """ Start the process. @raise FatalProcessLaunch: if process cannot be started and it is not likely to ever succeed """ super(LocalProcess, self).start() try: self.lock.acquire() if self.started: _logger.info("process[%s]: restarting os process", self.name) else: _logger.info("process[%s]: starting os process", self.name) self.started = self.stopped = False full_env = self.env # _configure_logging() can mutate self.args try: logfileout, logfileerr = self._configure_logging() except Exception as e: _logger.error(traceback.format_exc()) printerrlog("[%s] ERROR: unable to configure logging [%s]" % (self.name, str(e))) # it's not safe to inherit from this process as # rostest changes stdout to a StringIO, which is not a # proper file. logfileout, logfileerr = subprocess.PIPE, subprocess.PIPE if self.cwd == 'node': cwd = os.path.dirname(self.args[0]) elif self.cwd == 'cwd': cwd = os.getcwd() elif self.cwd == 'ros-root': cwd = get_ros_root() else: cwd = rospkg.get_ros_home() if not os.path.exists(cwd): try: os.makedirs(cwd) except OSError: # exist_ok=True pass _logger.info("process[%s]: start w/ args [%s]", self.name, self.args) _logger.info("process[%s]: cwd will be [%s]", self.name, cwd) try: self.popen = subprocess.Popen(self.args, cwd=cwd, stdout=logfileout, stderr=logfileerr, env=full_env, close_fds=True, preexec_fn=os.setsid) except OSError as e: self.started = True # must set so is_alive state is correct _logger.error("OSError(%d, %s)", e.errno, e.strerror) if e.errno == 8: #Exec format error raise FatalProcessLaunch( "Unable to launch [%s]. \nIf it is a script, you may be missing a '#!' declaration at the top." % self.name) elif e.errno == 2: #no such file or directory raise FatalProcessLaunch( """Roslaunch got a '%s' error while attempting to run: %s Please make sure that all the executables in this command exist and have executable permission. This is often caused by a bad launch-prefix.""" % (e.strerror, ' '.join(self.args))) else: raise FatalProcessLaunch("unable to launch [%s]: %s" % (' '.join(self.args), e.strerror)) self.started = True # Check that the process is either still running (poll returns # None) or that it completed successfully since when we # launched it above (poll returns the return code, 0). poll_result = self.popen.poll() if poll_result is None or poll_result == 0: self.pid = self.popen.pid printlog_bold("process[%s]: started with pid [%s]" % (self.name, self.pid)) return True else: printerrlog("failed to start local process: %s" % (' '.join(self.args))) return False finally: self.lock.release()
def start(self): """ Start the process. @raise FatalProcessLaunch: if process cannot be started and it is not likely to ever succeed """ super(LocalProcess, self).start() try: self.lock.acquire() if self.started: _logger.info("process[%s]: restarting os process", self.name) else: _logger.info("process[%s]: starting os process", self.name) self.started = self.stopped = False full_env = self.env # _configure_logging() can mutate self.args process_logger = None try: process_logger = self._configure_logging() # Must always return an object even if we log only on screen. except Exception as e: _logger.error(traceback.format_exc()) printerrlog("[%s] ERROR: unable to configure logging [%s]"%(self.name, str(e))) # it's not safe to inherit from this process as # rostest changes stdout to a StringIO, which is not a # proper file. #logfileout, logfileerr = subprocess.PIPE, subprocess.PIPE #if we must log into a file (so process_logger exists) : if process_logger: # stdout and stderr must of subprocess must be redirected to a pipe logfileout, logfileerr = subprocess.PIPE, subprocess.PIPE else: # stdout and stderr must of subprocess must be displayed on the screen because a problem occur when # configuring the logger logfileout, logfileerr = None, None if self.cwd == 'node': cwd = os.path.dirname(self.args[0]) elif self.cwd == 'cwd': cwd = os.getcwd() elif self.cwd == 'ros-root': cwd = get_ros_root() else: cwd = rospkg.get_ros_home() if not os.path.exists(cwd): try: os.makedirs(cwd) except OSError: # exist_ok=True pass _logger.info("process[%s]: start w/ args [%s]", self.name, self.args) _logger.info("process[%s]: cwd will be [%s]", self.name, cwd) try: if sys.platform.startswith('linux'): # the two arguments 'stdbuf' and '-oL' are necessary to have real time logging, # instead of all at once. only necessary if stdout is not a tty self.args = ['stdbuf', '-oL'] + self.args self.popen = subprocess.Popen(self.args, cwd=cwd, stdout=logfileout, stderr=logfileerr, env=full_env, close_fds=True, preexec_fn=os.setsid) except OSError as e: self.started = True # must set so is_alive state is correct _logger.error("OSError(%d, %s)", e.errno, e.strerror) if e.errno == errno.ENOEXEC: #Exec format error raise FatalProcessLaunch("Unable to launch [%s]. \nIf it is a script, you may be missing a '#!' declaration at the top."%self.name) elif e.errno == errno.ENOENT: #no such file or directory raise FatalProcessLaunch("""Roslaunch got a '%s' error while attempting to run: %s Please make sure that all the executables in this command exist and have executable permission. This is often caused by a bad launch-prefix."""%(e.strerror, ' '.join(self.args))) else: raise FatalProcessLaunch("unable to launch [%s]: %s"%(' '.join(self.args), e.strerror)) # we redirect subprocess output to proper loglevel in a dedicated thread : if logfileout: self.logThreadInfo = threading.Thread(target=stream_reader, args=(self.popen.stdout, logging.INFO, process_logger, self.popen)) self.logThreadInfo.start() if logfileerr: self.logThreadError = threading.Thread(target=stream_reader, args=(self.popen.stderr, logging.ERROR, process_logger, self.popen)) self.logThreadError.start() self.started = True # Check that the process is either still running (poll returns # None) or that it completed successfully since when we # launched it above (poll returns the return code, 0). poll_result = self.popen.poll() if poll_result is None or poll_result == 0: self.pid = self.popen.pid printlog_bold("process[%s]: started with pid [%s]"%(self.name, self.pid)) return True else: printerrlog("failed to start local process: %s"%(' '.join(self.args))) return False finally: self.lock.release()