def startProc(self, id, cmd): try: (pid, fd) = os.forkpty() except Exception as e: log.exception("ProcRunner.startProc: exception while forkpty(): ") return False sh = '/bin/sh' if pid == 0: # child try: os.execlp(sh, sh, '-c', cmd) except Exception as e: log.error("ProcRunner.startProc: exception: %s", str(e)) os._exit(1) return False # daddy # set raw mode # several reasons: # a) suppress echos # b) prevents size limitation while sending data to child processes tty.setraw(fd) self.processes[id] = fd self.invProcesses[fd] = id self.main.proxy.addProc(fd) log.debug("ProcRunner.startProc %d : %s started", id, cmd) return True
def fork(): """fork() -> (pid, master_fd) Fork and make the child a session leader with a controlling terminal.""" try: pid, fd = os.forkpty() except (AttributeError, OSError): pass else: if pid == CHILD: try: os.setsid() except OSError: pass return (pid, fd) master_fd, slave_fd = openpty() pid = os.fork() if pid == CHILD: os.setsid() os.close(master_fd) os.dup2(slave_fd, STDIN_FILENO) os.dup2(slave_fd, STDOUT_FILENO) os.dup2(slave_fd, STDERR_FILENO) if slave_fd > STDERR_FILENO: os.close(slave_fd) tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR) os.close(tmp_fd) else: os.close(slave_fd) return (pid, master_fd)
def fork(): try: (pid, fd) = os.forkpty() except (AttributeError, OSError): pass if pid == CHILD: try: os.setsid() except OSError: pass return (pid, fd) (master_fd, slave_fd) = openpty() pid = os.fork() if pid == CHILD: os.setsid() os.close(master_fd) os.dup2(slave_fd, STDIN_FILENO) os.dup2(slave_fd, STDOUT_FILENO) os.dup2(slave_fd, STDERR_FILENO) if slave_fd > STDERR_FILENO: os.close(slave_fd) tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR) os.close(tmp_fd) else: os.close(slave_fd) return (pid, master_fd)
def rscp(pw,dir1,cmd): pid, fd = os.forkpty() # If Child; execute external process if pid == 0: os.execv("/usr/bin/scp", ["scp","-o","StrictHostKeyChecking=no","-o","PubkeyAuthentication=no",dir1,]+cmd) else: pause() k=os.read(fd, 1000) count=0 while k.find("password") < 0: pause() count+=1 try: k=os.read(fd, 1000) except: return if count > 3: return os.write(fd, pw + "\n") pause() k=os.read(fd, 1000) pause() res = '' print k return res
def test_B_Stdio(self): # lookup file descriptors for original stdio objects stdio_fo = [sys.__stdin__, sys.__stdout__, sys.__stderr__] stdio_fd = [f.fileno() for f in stdio_fo] # create subprocess to deamonize. pipe will be used to communicate # back information about daemonized process pipe_r, pipe_w = os.pipe() # forkpty is used to make situation more tricky for phlsys_daemonize: # the child process will be a controlling process which makes its # children potential targets of SIGHUP on its exit child_pid, child_pty = os.forkpty() if child_pid == 0: os.close(pipe_r) phlsys_daemonize.do() pipe_wf = os.fdopen(pipe_w, 'w') try: # report that process survived the daemonization pipe_wf.write('daemonized\n') # dump file names of files opened as stdin, stdout and stderr proc_dir = '/proc/%i/' % os.getpid() for fd in stdio_fd: proc_entry = 'fd/%i' % fd target = os.readlink(proc_dir + proc_entry) pipe_wf.write(proc_entry + ' => ' + target + '\n') except Exception, e: pipe_wf.write(str(e)) sys.exit(0)
def __init__(self,t): #Fork a child process that has a pty associated with it. #pid works as normal for fork, fd is a file descriptor you can open for a #pipe to the stdin and stdout of the new process. (pid, fd) = os.forkpty() if pid == 0: #In here is the child process, we want to exec a login process over #python, using the client's hostname and username. #/bin/login will tell the system the client is logged in from the host #and then exec their login shell over itself. Env stuff is setup in #there somewhere too. os.execv("/bin/login",["-login","-h",str(t.trans.getpeername()[0]),"-f",str(t.trans.get_username())]) #I don't think this line can ever actually be reached. The above one #might somehow throw an exception if it does fail. Think you need to #run out of PIDs for that to happen though, so I never tested it. sys.exit("Failed to execute login shell!") #Open pipes to the slave process. self.masterr = os.fdopen(fd, "rb") self.masterw = os.fdopen(fd, "wb") #Below this we create two threads, one for reading from the slave, #one for writing to the slave. #As these calls block (and there is simple way around that) we let need #to use threads and then drop the results we get into a thread-safe queue #that we can make non-blocking calls to. try: inq = Queue() tI = Thread(target=self.ioThreadFunc, args=(self.masterr, inq)) tI.daemon = True tI.start() except Exception, e: print e time.sleep(1) sys.exit("Fatal Error: Could not start input thread.")
def startIOC(): # conf needs to be set pid, fd = os.forkpty() if pid == 0: os.chdir("../v3IOC/") os.execv(iocexecutable, ['softIoc', '../v3IOC/st.cmd']) return pid, fd
def startMongoService(): #conf needs to be set setConfMongo() pid, fd = os.forkpty() if pid == 0: os.execv(executable, ['masarServiceRun', 'mongoMasarTestService']) return pid, fd
def set_vnc_password(root, passwd, passwd_file): (pid, fd) = os.forkpty() if not pid: os.execv(root + "/usr/bin/vncpasswd", [root + "/usr/bin/vncpasswd", passwd_file]) sys.exit(1) # read password prompt os.read(fd, 1000) # write password os.write(fd, passwd + "\n") # read challenge again, and newline os.read(fd, 1000) os.read(fd, 1000) # write password again os.write(fd, passwd + "\n") # read remaining output os.read(fd, 1000) # wait for status try: (pid, status) = os.waitpid(pid, 0) except OSError, (errno, msg): print __name__, "waitpid:", msg
def fork(): """fork() -> (pid, master_fd) Fork and make the child a session leader with a controlling terminal.""" try: pid, fd = os.forkpty() except (AttributeError, OSError): pass else: if pid == CHILD: try: os.setsid() except OSError: # os.forkpty() already set us session leader pass return pid, fd master_fd, slave_fd = openpty() pid = os.fork() if pid == CHILD: # Establish a new session. os.setsid() os.close(master_fd) # Slave becomes stdin/stdout/stderr of child. os.dup2(slave_fd, STDIN_FILENO) os.dup2(slave_fd, STDOUT_FILENO) os.dup2(slave_fd, STDERR_FILENO) if slave_fd > STDERR_FILENO: os.close(slave_fd) # Parent and child process. return pid, master_fd
def open(self): """ Fork a child nethack process into a pty and setup its stdin and stdout """ (self.pid, self.pipe) = os.forkpty() if self.pid == 0: # I'm the child process in a fake pty. I need to replace myself # with an instance of nethack. # # NOTE: The '--proxy' argument doesn't seem to do anything though # it's used by dgamelaunch which is a bit confusing. However, # without *some* argument execvp doesn't seem to like nethack and # launches a shell instead? It's quite confusing. if self.debug: os.execvpe("nethack", ["--proxy", "-D"], os.environ) else: os.execvpe("nethack", ["--proxy"], os.environ) else: # Before we do anything else, it's time to establish some boundries signal.siginterrupt(signal.SIGCHLD, True) signal.signal(signal.SIGCHLD, self._close) # When my tty resizes, the child's pty should resize too. signal.signal(signal.SIGWINCH, self.resize_child) # Setup out input/output proxies self.stdout = os.fdopen(self.pipe, "rb", 0) self.stdin = os.fdopen(self.pipe, "wb", 0) # Set the initial size of the child pty to my own size. self.resize_child()
def test_a110_one(self): pid, fd = os.forkpty() #cmd = [sys.executable] cmd = ['coverage', 'run'] cmd += [ inspect.getsourcefile(run), 'one', '-i', inspect.getsourcefile(data_sample_handler) ] if pid == 0: # child os.execvp(cmd[0], cmd) else: # parent def wait_text(timeout=1): import select text = [] while True: rl, wl, xl = select.select([fd], [], [], timeout) if not rl: break try: t = os.read(fd, 1024) except OSError: break if not t: break t = utils.text(t) text.append(t) print(t, end='') return ''.join(text) text = wait_text() self.assertIn('new task data_sample_handler:on_start', text) self.assertIn('pyspider shell', text) os.write(fd, utils.utf8('run()\n')) text = wait_text() self.assertIn('task done data_sample_handler:on_start', text) os.write(fd, utils.utf8('crawl("%s/pyspider/test.html")\n' % self.httpbin)) text = wait_text() self.assertIn('/robots.txt', text) os.write(fd, utils.utf8('crawl("%s/links/10/0")\n' % self.httpbin)) text = wait_text(2) self.assertIn('"title": "Links"', text) os.write(fd, utils.utf8('crawl("%s/404")\n' % self.httpbin)) text = wait_text() self.assertIn('task retry', text) os.write(fd, b'quit_pyspider()\n') text = wait_text() self.assertIn('scheduler exiting...', text) os.close(fd) os.kill(pid, signal.SIGINT)
def fork(self): '''return the pid and file descriptors''' pid,fd = os.forkpty() if pid == 0: self.execssh() else: success = self.authenticate(fd) return pid,fd,success
def startIOC(): # conf needs to be set pid, fd = os.forkpty() if pid == 0: os.chdir("../../../client/iocBoot/iocdemo") print os.curdir os.execv("st_test.cmd", ['']) return pid, fd
def start(self): # init the terminal emulator self.terminal = Terminal(self, self.prefs["term_width"], self.prefs["term_height"]) (pid, self.master) = os.forkpty() if(pid == 0): # ensure that the right terminal type is set os.environ['TERM'] = 'xterm' # launch the target os.execv(self.prefs["term_proc"], [self.prefs["term_proc"]] + shlex.split(self.prefs["term_args"])) # set the attributes of the terminal (size, for now) self.resize(self.prefs["term_width"], self.prefs["term_height"]) # open the psuedo terminal master file (this is what we read/write to) self.wstream = os.fdopen(self.master, "w") self.rstream = os.fdopen(self.master, "r") # this is passed locally so we can shut down only threads that were started by this invocation shutdown = threading.Event() # start a loop to accept incoming http sessions a = threading.Thread(target=self.sessionLoop, name="sessionLoop", args=(shutdown,)) a.daemon = True a.start() # start a thread to read output from the shell o = threading.Thread(target=self.handleOutput, name="oThread", args=(shutdown,)) o.daemon = True o.start() if(self.prefs["enable_http"]): # start the http listener s = threading.Thread(target=self.server.acceptLoop, name="httpThread", args=(self.prefs["http_port"], False)) s.daemon = True s.start() if(self.prefs["enable_https"]): # start the https listener s = threading.Thread(target=self.server.acceptLoop, name="httpsThread", args=(self.prefs["https_port"], True)) s.daemon = True s.start() # start a thread to push diff updates to the clients u = threading.Thread(target=self.updateLoop, name="updateThread", args=(shutdown,)) u.daemon = True u.start() # now wait for the subprocess to terminate, and for us to flush the last of it's output try: os.waitpid(pid, 0) except KeyboardInterrupt: os.kill(pid, signal.SIGKILL) os.waitpid(pid, 0) # wait on the process so we don't create a zombie finally: #signal the worker threads to shut down shutdown.set()
def start(self): self.pid, self._pty = os.forkpty() if self.pid == 0: os.chdir(self.workDir) try: os.execve(self.cmdLine[0], self.cmdLine, self.environ) except: sys.exit(99) self._poll.register(self._pty, select.POLLIN) self._started = 1
def __init__(self, readable, writable, *args): """ Start an interactive shell """ pid, _fd = os.forkpty() if pid == 0: os.execlp(*args) self.fromshell = os.fdopen(_fd, "r") self.toshell = os.fdopen(_fd, "w") self.fromfd = os.fdopen(readable, "r") self.tofd = os.fdopen(writable, "w") for fd in [_fd, readable]:#, writable]: fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def __init__(self, description, host, user, password): self.description = description self.host = host self.user = user self.password = password self.sendlock = thread.allocate_lock() try: (pid, fd) = os.forkpty() except BaseException, e: log("ERROR: forkpty for '" + description + "': " + e) (pid, fd) = (-1, -1)
def run(self): (pid, fd) = os.forkpty() # child process if pid == 0: try: #print 'exec:', self.cmd os.execvp(self.cmd[0], self.cmd) except OSError, e: print 'execution failed:', e print 'command was:', self.cmd sys.exit(os.EX_OSERR)
def test_forkpty(self): import sys os = self.posix childpid, master_fd = os.forkpty() assert isinstance(childpid, int) assert isinstance(master_fd, int) if childpid == 0: data = os.read(0, 100) if data.startswith('abc'): os._exit(42) else: os._exit(43) os.write(master_fd, 'abc\n') _, status = os.waitpid(childpid, 0) assert status >> 8 == 42
def start(self): # init the terminal emulator self.terminal = Terminal(self.connections, self.prefs["term_width"], self.prefs["term_height"]) (pid, master) = os.forkpty() if(pid == 0): # ensure that the right terminal type is set os.environ['TERM'] = 'xterm' # launch the target os.execv(self.prefs["term_proc"], [self.prefs["term_proc"]] + shlex.split(self.prefs["term_args"])) # set the attributes of the terminal (size, for now) # winsize is 4 unsigned shorts: (ws_row, ws_col, ws_xpixel, ws_ypixel) winsize = struct.pack('HHHH', self.prefs["term_height"], self.prefs["term_width"], 0, 0) fcntl.ioctl(master, termios.TIOCSWINSZ, winsize) # open the psuedo terminal master file (this is what we read/write to) wstream = os.fdopen(master, "w") rstream = os.fdopen(master, "r") # start a loop to accept incoming http sessions a = threading.Thread(target=self.sessionLoop, name="sessionLoop", args=(wstream,)) a.daemon = True a.start() # start a thread to read output from the shell o = threading.Thread(target=self.handleOutput, name="oThread", args=(rstream,)) o.daemon = True o.start() # start the http server s = threading.Thread(target=self.server.acceptLoop, name="httpThread", args=(self.prefs["http_port"],)) s.daemon = True s.start() # start a thrad to push diff updates to the clients u = threading.Thread(target=self.updateLoop, name="updateThread", args=()) u.daemon = True u.start() # now wait for the subprocess to terminate, and for us to flush the last of it's output try: os.waitpid(pid, 0) except KeyboardInterrupt: os.kill(pid, signal.SIGKILL) os.waitpid(pid, 0) # wait on the process so we don't create a zombie
def _run_forking_function(space, kind): run_fork_hooks('before', space) try: if kind == "F": pid = os.fork() master_fd = -1 elif kind == "P": pid, master_fd = os.forkpty() else: raise AssertionError except OSError, e: try: run_fork_hooks('parent', space) except: # Don't clobber the OSError if the fork failed pass raise wrap_oserror(space, e)
def test_forkpty(self): import sys if 'freebsd' in sys.platform: skip("hangs indifinitly on FreeBSD (also on CPython).") os = self.posix childpid, master_fd = os.forkpty() assert isinstance(childpid, int) assert isinstance(master_fd, int) if childpid == 0: data = os.read(0, 100) if data.startswith('abc'): os._exit(42) else: os._exit(43) os.write(master_fd, 'abc\n') _, status = os.waitpid(childpid, 0) assert status >> 8 == 42
def initialize(self): self.pid,self.fd = os.forkpty(); if self.pid == 0: # print "child begin" # os.execv(self.bash_path,[self.bash_path,"-l"]) try: os.system(self.bash_path) print "child will be closed in 3 seconds" time.sleep(3) except Exception as e: print "wrong with " + e.message os._exit(0); else: self.outd=self.fd self.ind=self.fd self.errd=self.fd
def rcmd(user, rhost, pw, cmd): pid, fd = os.forkpty() # If Child; execute external process if pid == 0: os.execv("/usr/bin/ssh", ["/usr/bin/ssh", "-l", user,"-o","StrictHostKeyChecking=no","-o","PubkeyAuthentication=no",rhost] +cmd) else: pause() k=os.read(fd, 1000) while k.find("password") < 0: pause() k=os.read(fd, 1000) os.write(fd, pw + "\n") pause() k=os.read(fd, 1000) pause() res = '' print k return res
def rcmd(pw, cmd): pid, fd = os.forkpty() # If Child; execute external process if pid == 0: # os.execv("/usr/bin/scp", ["scp","-o","StrictHostKeyChecking=no","-r","file1","user@host:file2"]) os.execv("/usr/bin/scp", ["scp","-o","StrictHostKeyChecking=no","-r","test",]+cmd) else: pause() k=os.read(fd, 1000) print k pause() os.write(fd, pw + "\n") pause() k=os.read(fd, 1000) pause() res = '' print k return res
def rcmde(self, user, rhost, pw, cmd): if (self.PRMPT == True): print cmd pid, fd = os.forkpty() # If Child; execute external process if pid == 0: os.execv("/usr/bin/ssh", ["/usr/bin/ssh", "-l", user,"-o","StrictHostKeyChecking=no","-o","PubkeyAuthentication=no",rhost,"source ~/.bash_profile;"] +cmd) else: self.pause() k=os.read(fd, 1000) while k.find("password") < 0: self.pause() k=os.read(fd, 1000) os.write(fd, pw + "\n") self.pause() k=os.read(fd, 1000) self.pause() res = '' print k return res
def sur(self, pw, cmd): pid, fd = os.forkpty() # This command is a string. Not a list. cmd=cmd.replace(';;',';') # If Child; execute external process if pid == 0: os.execv("/bin/su", ["/bin/su", "-c",] +[str(cmd)]) else: self.pause() k=os.read(fd, 1000) while k.find("assword") < 0: self.pause() k=os.read(fd, 1000) os.write(fd, pw + "\n") self.pause() k=os.read(fd, 1000) self.pause() res = '' print k return res
def Func_CopyWBMInfo(str_name): """ Func_CopyWBMInfo(str_name) Logs in on cmsusr0 and copies file from there """ pid, fd = os.forkpty() if pid == 0: os.execv('/usr/bin/scp', ['/usr/bin/scp', Str_userID+'@'+STR_p5+':~/'+str_name, '.']) else: time.sleep(1) os.read(fd, 1000) time.sleep(1) os.write(fd, Str_passwd) time.sleep(1) c = 0 s = os.read(fd, 1) while s: c += 1 s = os.read(fd, 1) if c >= 163: break
def Func_GetWBMInfo(str_name, str_path): """ Func_GetWBMInfo(str_name, str_path) Logs in on cmsusr0, retrieves WBM information and stores it locally """ pid, fd = os.forkpty() if pid == 0: os.execv('/usr/bin/ssh', ['/usr/bin/ssh', '-l', Str_userID, STR_p5] + ['rm', '-f', '\"'+str_name + '\" && ' + 'wget', '\"'+str_path+'/'+str_name+'\"']) else: time.sleep(1) os.read(fd, 1000) time.sleep(1) os.write(fd, Str_passwd) time.sleep(1) c = 0 s = os.read(fd, 1) while s: c += 1 s = os.read(fd, 1) if c >= 2: break
def test_a110_one(self): pid, fd = os.forkpty() #cmd = [sys.executable] cmd = ['coverage', 'run'] cmd += [ inspect.getsourcefile(run), 'one', '-i', inspect.getsourcefile(data_sample_handler) ] if pid == 0: # child os.execvp(cmd[0], cmd) else: # parent def wait_text(timeout=1): import select text = [] while True: rl, wl, xl = select.select([fd], [], [], timeout) if not rl: break try: t = os.read(fd, 1024) except OSError: break if not t: break t = utils.text(t) text.append(t) print(t, end='') return ''.join(text) text = wait_text(3) self.assertIn('new task data_sample_handler:on_start', text) self.assertIn('pyspider shell', text) os.write(fd, utils.utf8('run()\n')) text = wait_text() self.assertIn('task done data_sample_handler:on_start', text) os.write( fd, utils.utf8('crawl("%s/pyspider/test.html")\n' % self.httpbin)) text = wait_text() self.assertIn('/robots.txt', text) os.write(fd, utils.utf8('crawl("%s/links/10/0")\n' % self.httpbin)) text = wait_text() if '"title": "Links"' not in text: os.write(fd, utils.utf8('crawl("%s/links/10/1")\n' % self.httpbin)) text = wait_text() self.assertIn('"title": "Links"', text) os.write(fd, utils.utf8('crawl("%s/404")\n' % self.httpbin)) text = wait_text() self.assertIn('task retry', text) os.write(fd, b'quit_pyspider()\n') text = wait_text() self.assertIn('scheduler exiting...', text) os.close(fd) os.kill(pid, signal.SIGINT)
else: print(' - [%s/%s] exiting' % (i, pid)) os._exit(0) time.sleep(TIMEOUT * 10) elif test_name == 'test_auth_fail': manhole.get_peercred = lambda _: (-1, -1, -1) manhole.install() time.sleep(TIMEOUT * 10) else: manhole.install() time.sleep(0.3) # give the manhole a bit enough time to start if test_name == 'test_simple': time.sleep(TIMEOUT * 10) elif test_name == 'test_with_forkpty': time.sleep(1) pid, masterfd = os.forkpty() if pid: @atexit.register def cleanup(): try: os.kill(pid, signal.SIGINT) time.sleep(0.2) os.kill(pid, signal.SIGTERM) except OSError as e: if e.errno != errno.ESRCH: raise while not os.waitpid(pid, os.WNOHANG)[0]: try: os.write(2, os.read(masterfd, 1024))
def run(args, timeout=0, die=True, output=None): must_close = False if output: if type(output) == str: output = open(output, "a") must_close = True logger.info("running command %s" % args) sys.stdout.flush() start = time.time() # Use a pty so that commands which call isatty don't change behavior. pid, fd = os.forkpty() if pid == 0: try: os.execlp(args[0], *args) except OSError as e: print(e) sys.exit(1) else: t = termios.tcgetattr(fd) t[1] = t[1] & ~termios.ONLCR termios.tcsetattr(fd, termios.TCSANOW, t) buffer = b"" expired = False while True: # A pty master returns EIO when the slave is closed. try: rlist, wlist, xlist = select.select([fd], [], [], 5) if len(rlist): new = os.read(fd, 1024) else: if timeout and time.time() > start + timeout: expired = True else: continue except OSError: new = b"" if expired or len(new) == 0: break sys.stdout.buffer.write(new) sys.stdout.flush() if output: output.buffer.write(new) output.flush() buffer = buffer + new if expired: logger.error(f"time limit of {timeout} expired") # This will also send SIGHUP to the child process. os.close(fd) pid, status = os.waitpid(pid, 0) end = time.time() final_time = end - start if os.WIFEXITED(status): status = os.WEXITSTATUS(status) logger.info(f"process returned {status} after {final_time} seconds") else: status = os.WTERMSIG(status) logger.error( f"process died from signal {status} after {final_time} seconds") if die and (status != 0 or expired): sys.exit(1) elif not die and (status != 0 or expired): fail = True else: fail = False buffer = buffer.decode() if must_close: output.close() return buffer, fail
def _fork(self): """Fork and create a master/slave pty pair by which the forked process can be controlled. """ pid, self.master_fd = os.forkpty() return pid