Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/ptyprocess/_fork_pty.py: 5%

37 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-20 06:09 +0000

1"""Substitute for the forkpty system call, to support Solaris. 

2""" 

3import os 

4import errno 

5 

6from pty import (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CHILD) 

7from .util import PtyProcessError 

8 

9def fork_pty(): 

10 '''This implements a substitute for the forkpty system call. This 

11 should be more portable than the pty.fork() function. Specifically, 

12 this should work on Solaris. 

13 

14 Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to 

15 resolve the issue with Python's pty.fork() not supporting Solaris, 

16 particularly ssh. Based on patch to posixmodule.c authored by Noah 

17 Spurrier:: 

18 

19 http://mail.python.org/pipermail/python-dev/2003-May/035281.html 

20 

21 ''' 

22 

23 parent_fd, child_fd = os.openpty() 

24 if parent_fd < 0 or child_fd < 0: 

25 raise OSError("os.openpty() failed") 

26 

27 pid = os.fork() 

28 if pid == CHILD: 

29 # Child. 

30 os.close(parent_fd) 

31 pty_make_controlling_tty(child_fd) 

32 

33 os.dup2(child_fd, STDIN_FILENO) 

34 os.dup2(child_fd, STDOUT_FILENO) 

35 os.dup2(child_fd, STDERR_FILENO) 

36 

37 else: 

38 # Parent. 

39 os.close(child_fd) 

40 

41 return pid, parent_fd 

42 

43def pty_make_controlling_tty(tty_fd): 

44 '''This makes the pseudo-terminal the controlling tty. This should be 

45 more portable than the pty.fork() function. Specifically, this should 

46 work on Solaris. ''' 

47 

48 child_name = os.ttyname(tty_fd) 

49 

50 # Disconnect from controlling tty, if any. Raises OSError of ENXIO 

51 # if there was no controlling tty to begin with, such as when 

52 # executed by a cron(1) job. 

53 try: 

54 fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) 

55 os.close(fd) 

56 except OSError as err: 

57 if err.errno != errno.ENXIO: 

58 raise 

59 

60 os.setsid() 

61 

62 # Verify we are disconnected from controlling tty by attempting to open 

63 # it again. We expect that OSError of ENXIO should always be raised. 

64 try: 

65 fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) 

66 os.close(fd) 

67 raise PtyProcessError("OSError of errno.ENXIO should be raised.") 

68 except OSError as err: 

69 if err.errno != errno.ENXIO: 

70 raise 

71 

72 # Verify we can open child pty. 

73 fd = os.open(child_name, os.O_RDWR) 

74 os.close(fd) 

75 

76 # Verify we now have a controlling tty. 

77 fd = os.open("/dev/tty", os.O_WRONLY) 

78 os.close(fd)