parameters: (
              cls, argv, cwd=None, env=None, echo=True, preexec_fn=None,
              dimensions=(24, 80))
return_statement: return inst
docstring: Start the given command in a child process in a pseudo terminal.
  
          This does all the fork/exec type of stuff for a pty, and returns an
          instance of PtyProcess.
  
          If preexec_fn is supplied, it will be called with no arguments in the
          child process before exec-ing the specified command.
          It may, for instance, set signal handlers to SIG_DFL or SIG_IGN.
  
          Dimensions of the psuedoterminal used for the subprocess can be
          specified as a tuple (rows, cols), or the default (24, 80) will be used.
docstring_summary: Start the given command in a child process in a pseudo terminal.
docstring_tokens: Start the given command in a child process in a pseudo terminal .
function: def spawn(
              cls, argv, cwd=None, env=None, echo=True, preexec_fn=None,
              dimensions=(24, 80)):
          '''Start the given command in a child process in a pseudo terminal.
  
          This does all the fork/exec type of stuff for a pty, and returns an
          instance of PtyProcess.
  
          If preexec_fn is supplied, it will be called with no arguments in the
          child process before exec-ing the specified command.
          It may, for instance, set signal handlers to SIG_DFL or SIG_IGN.
  
          Dimensions of the psuedoterminal used for the subprocess can be
          specified as a tuple (rows, cols), or the default (24, 80) will be used.
          '''
          # Note that it is difficult for this method to fail.
          # You cannot detect if the child process cannot start.
          # So the only way you can tell if the child process started
          # or not is to try to read from the file descriptor. If you get
          # EOF immediately then it means that the child is already dead.
          # That may not necessarily be bad because you may have spawned a child
          # that performs some task; creates no stdout output; and then dies.
  
          if not isinstance(argv, (list, tuple)):
              raise TypeError("Expected a list or tuple for argv, got %r" % argv)
  
          # Shallow copy of argv so we can modify it
          argv = argv[:]
          command = argv[0]
  
          command_with_path = which(command)
          if command_with_path is None:
              raise FileNotFoundError('The command was not found or was not ' +
                                      'executable: %s.' % command)
          command = command_with_path
          argv[0] = command
  
          # [issue #119] To prevent the case where exec fails and the user is
          # stuck interacting with a python child process instead of whatever
          # was expected, we implement the solution from
          # http://stackoverflow.com/a/3703179 to pass the exception to the
          # parent process
  
          # [issue #119] 1. Before forking, open a pipe in the parent process.
          exec_err_pipe_read, exec_err_pipe_write = os.pipe()
  
          if use_native_pty_fork:
              pid, fd = pty.fork()
          else:
              # Use internal fork_pty, for Solaris
              pid, fd = _fork_pty.fork_pty()
  
          # Some platforms must call setwinsize() and setecho() from the
          # child process, and others from the master process. We do both,
          # allowing IOError for either.
  
          if pid == CHILD:
              # set window size
              try:
                  _setwinsize(STDIN_FILENO, *dimensions)
              except IOError as err:
                  if err.args[0] not in (errno.EINVAL, errno.ENOTTY):
                      raise
  
              # disable echo if spawn argument echo was unset
              if not echo:
                  try:
                      _setecho(STDIN_FILENO, False)
                  except (IOError, termios.error) as err:
                      if err.args[0] not in (errno.EINVAL, errno.ENOTTY):
                          raise
  
              # [issue #119] 3. The child closes the reading end and sets the
              # close-on-exec flag for the writing end.
              os.close(exec_err_pipe_read)
              fcntl.fcntl(exec_err_pipe_write, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
  
              # Do not allow child to inherit open file descriptors from parent,
              # with the exception of the exec_err_pipe_write of the pipe
              # Impose ceiling on max_fd: AIX bugfix for users with unlimited
              # nofiles where resource.RLIMIT_NOFILE is 2^63-1 and os.closerange()
              # occasionally raises out of range error
              max_fd = min(1048576, resource.getrlimit(resource.RLIMIT_NOFILE)[0])
              os.closerange(3, exec_err_pipe_write)
              os.closerange(exec_err_pipe_write+1, max_fd)
  
              if cwd is not None:
                  os.chdir(cwd)
  
              if preexec_fn is not None:
                  try:
                      preexec_fn()
                  except Exception as e:
                      ename = type(e).__name__
                      tosend = '{}:0:{}'.format(ename, str(e))
                      if PY3:
                          tosend = tosend.encode('utf-8')
  
                      os.write(exec_err_pipe_write, tosend)
                      os.close(exec_err_pipe_write)
                      os._exit(1)
  
              try:
                  if env is None:
                      os.execv(command, argv)
                  else:
                      os.execvpe(command, argv, env)
              except OSError as err:
                  # [issue #119] 5. If exec fails, the child writes the error
                  # code back to the parent using the pipe, then exits.
                  tosend = 'OSError:{}:{}'.format(err.errno, str(err))
                  if PY3:
                      tosend = tosend.encode('utf-8')
                  os.write(exec_err_pipe_write, tosend)
                  os.close(exec_err_pipe_write)
                  os._exit(os.EX_OSERR)
  
          # Parent
          inst = cls(pid, fd)
          
          # Set some informational attributes
          inst.argv = argv
          if env is not None:
              inst.env = env
          if cwd is not None:
              inst.launch_dir = cwd
  
          # [issue #119] 2. After forking, the parent closes the writing end
          # of the pipe and reads from the reading end.
          os.close(exec_err_pipe_write)
          exec_err_data = os.read(exec_err_pipe_read, 4096)
          os.close(exec_err_pipe_read)
  
          # [issue #119] 6. The parent reads eof (a zero-length read) if the
          # child successfully performed exec, since close-on-exec made
          # successful exec close the writing end of the pipe. Or, if exec
          # failed, the parent reads the error code and can proceed
          # accordingly. Either way, the parent blocks until the child calls
          # exec.
          if len(exec_err_data) != 0:
              try:
                  errclass, errno_s, errmsg = exec_err_data.split(b':', 2)
                  exctype = getattr(builtins, errclass.decode('ascii'), Exception)
  
                  exception = exctype(errmsg.decode('utf-8', 'replace'))
                  if exctype is OSError:
                      exception.errno = int(errno_s)
              except:
                  raise Exception('Subprocess failed, got bad error data: %r'
                                      % exec_err_data)
              else:
                  raise exception
  
          try:
              inst.setwinsize(*dimensions)
          except IOError as err:
              if err.args[0] not in (errno.EINVAL, errno.ENOTTY, errno.ENXIO):
                  raise
  
          return inst
function_tokens: def spawn ( cls , argv , cwd = None , env = None , echo = True , preexec_fn = None , dimensions = ( 24 , 80 ) ) : # Note that it is difficult for this method to fail. # You cannot detect if the child process cannot start. # So the only way you can tell if the child process started # or not is to try to read from the file descriptor. If you get # EOF immediately then it means that the child is already dead. # That may not necessarily be bad because you may have spawned a child # that performs some task; creates no stdout output; and then dies. if not isinstance ( argv , ( list , tuple ) ) : raise TypeError ( "Expected a list or tuple for argv, got %r" % argv ) # Shallow copy of argv so we can modify it argv = argv [ : ] command = argv [ 0 ] command_with_path = which ( command ) if command_with_path is None : raise FileNotFoundError ( 'The command was not found or was not ' + 'executable: %s.' % command ) command = command_with_path argv [ 0 ] = command # [issue #119] To prevent the case where exec fails and the user is # stuck interacting with a python child process instead of whatever # was expected, we implement the solution from # http://stackoverflow.com/a/3703179 to pass the exception to the # parent process # [issue #119] 1. Before forking, open a pipe in the parent process. exec_err_pipe_read , exec_err_pipe_write = os . pipe ( ) if use_native_pty_fork : pid , fd = pty . fork ( ) else : # Use internal fork_pty, for Solaris pid , fd = _fork_pty . fork_pty ( ) # Some platforms must call setwinsize() and setecho() from the # child process, and others from the master process. We do both, # allowing IOError for either. if pid == CHILD : # set window size try : _setwinsize ( STDIN_FILENO , * dimensions ) except IOError as err : if err . args [ 0 ] not in ( errno . EINVAL , errno . ENOTTY ) : raise # disable echo if spawn argument echo was unset if not echo : try : _setecho ( STDIN_FILENO , False ) except ( IOError , termios . error ) as err : if err . args [ 0 ] not in ( errno . EINVAL , errno . ENOTTY ) : raise # [issue #119] 3. The child closes the reading end and sets the # close-on-exec flag for the writing end. os . close ( exec_err_pipe_read ) fcntl . fcntl ( exec_err_pipe_write , fcntl . F_SETFD , fcntl . FD_CLOEXEC ) # Do not allow child to inherit open file descriptors from parent, # with the exception of the exec_err_pipe_write of the pipe # Impose ceiling on max_fd: AIX bugfix for users with unlimited # nofiles where resource.RLIMIT_NOFILE is 2^63-1 and os.closerange() # occasionally raises out of range error max_fd = min ( 1048576 , resource . getrlimit ( resource . RLIMIT_NOFILE ) [ 0 ] ) os . closerange ( 3 , exec_err_pipe_write ) os . closerange ( exec_err_pipe_write + 1 , max_fd ) if cwd is not None : os . chdir ( cwd ) if preexec_fn is not None : try : preexec_fn ( ) except Exception as e : ename = type ( e ) . __name__ tosend = '{}:0:{}' . format ( ename , str ( e ) ) if PY3 : tosend = tosend . encode ( 'utf-8' ) os . write ( exec_err_pipe_write , tosend ) os . close ( exec_err_pipe_write ) os . _exit ( 1 ) try : if env is None : os . execv ( command , argv ) else : os . execvpe ( command , argv , env ) except OSError as err : # [issue #119] 5. If exec fails, the child writes the error # code back to the parent using the pipe, then exits. tosend = 'OSError:{}:{}' . format ( err . errno , str ( err ) ) if PY3 : tosend = tosend . encode ( 'utf-8' ) os . write ( exec_err_pipe_write , tosend ) os . close ( exec_err_pipe_write ) os . _exit ( os . EX_OSERR ) # Parent inst = cls ( pid , fd ) # Set some informational attributes inst . argv = argv if env is not None : inst . env = env if cwd is not None : inst . launch_dir = cwd # [issue #119] 2. After forking, the parent closes the writing end # of the pipe and reads from the reading end. os . close ( exec_err_pipe_write ) exec_err_data = os . read ( exec_err_pipe_read , 4096 ) os . close ( exec_err_pipe_read ) # [issue #119] 6. The parent reads eof (a zero-length read) if the # child successfully performed exec, since close-on-exec made # successful exec close the writing end of the pipe. Or, if exec # failed, the parent reads the error code and can proceed # accordingly. Either way, the parent blocks until the child calls # exec. if len ( exec_err_data ) != 0 : try : errclass , errno_s , errmsg = exec_err_data . split ( b':' , 2 ) exctype = getattr ( builtins , errclass . decode ( 'ascii' ) , Exception ) exception = exctype ( errmsg . decode ( 'utf-8' , 'replace' ) ) if exctype is OSError : exception . errno = int ( errno_s ) except : raise Exception ( 'Subprocess failed, got bad error data: %r' % exec_err_data ) else : raise exception try : inst . setwinsize ( * dimensions ) except IOError as err : if err . args [ 0 ] not in ( errno . EINVAL , errno . ENOTTY , errno . ENXIO ) : raise return inst