17db96d56Sopenharmony_ci:mod:`pty` --- Pseudo-terminal utilities 27db96d56Sopenharmony_ci======================================== 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci.. module:: pty 57db96d56Sopenharmony_ci :platform: Unix 67db96d56Sopenharmony_ci :synopsis: Pseudo-Terminal Handling for Unix. 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci.. moduleauthor:: Steen Lumholt 97db96d56Sopenharmony_ci.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il> 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci**Source code:** :source:`Lib/pty.py` 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci-------------- 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciThe :mod:`pty` module defines operations for handling the pseudo-terminal 167db96d56Sopenharmony_ciconcept: starting another process and being able to write to and read from its 177db96d56Sopenharmony_cicontrolling terminal programmatically. 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ciPseudo-terminal handling is highly platform dependent. This code is mainly 207db96d56Sopenharmony_citested on Linux, FreeBSD, and macOS (it is supposed to work on other POSIX 217db96d56Sopenharmony_ciplatforms but it's not been thoroughly tested). 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ciThe :mod:`pty` module defines the following functions: 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci.. function:: fork() 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci Fork. Connect the child's controlling terminal to a pseudo-terminal. Return 297db96d56Sopenharmony_ci value is ``(pid, fd)``. Note that the child gets *pid* 0, and the *fd* is 307db96d56Sopenharmony_ci *invalid*. The parent's return value is the *pid* of the child, and *fd* is a 317db96d56Sopenharmony_ci file descriptor connected to the child's controlling terminal (and also to the 327db96d56Sopenharmony_ci child's standard input and output). 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci.. function:: openpty() 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci Open a new pseudo-terminal pair, using :func:`os.openpty` if possible, or 387db96d56Sopenharmony_ci emulation code for generic Unix systems. Return a pair of file descriptors 397db96d56Sopenharmony_ci ``(master, slave)``, for the master and the slave end, respectively. 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci.. function:: spawn(argv[, master_read[, stdin_read]]) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci Spawn a process, and connect its controlling terminal with the current 457db96d56Sopenharmony_ci process's standard io. This is often used to baffle programs which insist on 467db96d56Sopenharmony_ci reading from the controlling terminal. It is expected that the process 477db96d56Sopenharmony_ci spawned behind the pty will eventually terminate, and when it does *spawn* 487db96d56Sopenharmony_ci will return. 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci A loop copies STDIN of the current process to the child and data received 517db96d56Sopenharmony_ci from the child to STDOUT of the current process. It is not signaled to the 527db96d56Sopenharmony_ci child if STDIN of the current process closes down. 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci The functions *master_read* and *stdin_read* are passed a file descriptor 557db96d56Sopenharmony_ci which they should read from, and they should always return a byte string. In 567db96d56Sopenharmony_ci order to force spawn to return before the child process exits an 577db96d56Sopenharmony_ci empty byte array should be returned to signal end of file. 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci The default implementation for both functions will read and return up to 1024 607db96d56Sopenharmony_ci bytes each time the function is called. The *master_read* callback is passed 617db96d56Sopenharmony_ci the pseudoterminal’s master file descriptor to read output from the child 627db96d56Sopenharmony_ci process, and *stdin_read* is passed file descriptor 0, to read from the 637db96d56Sopenharmony_ci parent process's standard input. 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci Returning an empty byte string from either callback is interpreted as an 667db96d56Sopenharmony_ci end-of-file (EOF) condition, and that callback will not be called after 677db96d56Sopenharmony_ci that. If *stdin_read* signals EOF the controlling terminal can no longer 687db96d56Sopenharmony_ci communicate with the parent process OR the child process. Unless the child 697db96d56Sopenharmony_ci process will quit without any input, *spawn* will then loop forever. If 707db96d56Sopenharmony_ci *master_read* signals EOF the same behavior results (on linux at least). 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci Return the exit status value from :func:`os.waitpid` on the child process. 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci :func:`waitstatus_to_exitcode` can be used to convert the exit status into 757db96d56Sopenharmony_ci an exit code. 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci .. audit-event:: pty.spawn argv pty.spawn 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci .. versionchanged:: 3.4 807db96d56Sopenharmony_ci :func:`spawn` now returns the status value from :func:`os.waitpid` 817db96d56Sopenharmony_ci on the child process. 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ciExample 847db96d56Sopenharmony_ci------- 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci.. sectionauthor:: Steen Lumholt 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ciThe following program acts like the Unix command :manpage:`script(1)`, using a 897db96d56Sopenharmony_cipseudo-terminal to record all input and output of a terminal session in a 907db96d56Sopenharmony_ci"typescript". :: 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci import argparse 937db96d56Sopenharmony_ci import os 947db96d56Sopenharmony_ci import pty 957db96d56Sopenharmony_ci import sys 967db96d56Sopenharmony_ci import time 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci parser = argparse.ArgumentParser() 997db96d56Sopenharmony_ci parser.add_argument('-a', dest='append', action='store_true') 1007db96d56Sopenharmony_ci parser.add_argument('-p', dest='use_python', action='store_true') 1017db96d56Sopenharmony_ci parser.add_argument('filename', nargs='?', default='typescript') 1027db96d56Sopenharmony_ci options = parser.parse_args() 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci shell = sys.executable if options.use_python else os.environ.get('SHELL', 'sh') 1057db96d56Sopenharmony_ci filename = options.filename 1067db96d56Sopenharmony_ci mode = 'ab' if options.append else 'wb' 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci with open(filename, mode) as script: 1097db96d56Sopenharmony_ci def read(fd): 1107db96d56Sopenharmony_ci data = os.read(fd, 1024) 1117db96d56Sopenharmony_ci script.write(data) 1127db96d56Sopenharmony_ci return data 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci print('Script started, file is', filename) 1157db96d56Sopenharmony_ci script.write(('Script started on %s\n' % time.asctime()).encode()) 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci pty.spawn(shell, read) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci script.write(('Script done on %s\n' % time.asctime()).encode()) 1207db96d56Sopenharmony_ci print('Script done, file is', filename) 121