first add files
This commit is contained in:
78
lib/ptyprocess/_fork_pty.py
Normal file
78
lib/ptyprocess/_fork_pty.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""Substitute for the forkpty system call, to support Solaris.
|
||||
"""
|
||||
import os
|
||||
import errno
|
||||
|
||||
from pty import (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CHILD)
|
||||
from .util import PtyProcessError
|
||||
|
||||
def fork_pty():
|
||||
'''This implements a substitute for the forkpty system call. This
|
||||
should be more portable than the pty.fork() function. Specifically,
|
||||
this should work on Solaris.
|
||||
|
||||
Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to
|
||||
resolve the issue with Python's pty.fork() not supporting Solaris,
|
||||
particularly ssh. Based on patch to posixmodule.c authored by Noah
|
||||
Spurrier::
|
||||
|
||||
http://mail.python.org/pipermail/python-dev/2003-May/035281.html
|
||||
|
||||
'''
|
||||
|
||||
parent_fd, child_fd = os.openpty()
|
||||
if parent_fd < 0 or child_fd < 0:
|
||||
raise OSError("os.openpty() failed")
|
||||
|
||||
pid = os.fork()
|
||||
if pid == CHILD:
|
||||
# Child.
|
||||
os.close(parent_fd)
|
||||
pty_make_controlling_tty(child_fd)
|
||||
|
||||
os.dup2(child_fd, STDIN_FILENO)
|
||||
os.dup2(child_fd, STDOUT_FILENO)
|
||||
os.dup2(child_fd, STDERR_FILENO)
|
||||
|
||||
else:
|
||||
# Parent.
|
||||
os.close(child_fd)
|
||||
|
||||
return pid, parent_fd
|
||||
|
||||
def pty_make_controlling_tty(tty_fd):
|
||||
'''This makes the pseudo-terminal the controlling tty. This should be
|
||||
more portable than the pty.fork() function. Specifically, this should
|
||||
work on Solaris. '''
|
||||
|
||||
child_name = os.ttyname(tty_fd)
|
||||
|
||||
# Disconnect from controlling tty, if any. Raises OSError of ENXIO
|
||||
# if there was no controlling tty to begin with, such as when
|
||||
# executed by a cron(1) job.
|
||||
try:
|
||||
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
|
||||
os.close(fd)
|
||||
except OSError as err:
|
||||
if err.errno != errno.ENXIO:
|
||||
raise
|
||||
|
||||
os.setsid()
|
||||
|
||||
# Verify we are disconnected from controlling tty by attempting to open
|
||||
# it again. We expect that OSError of ENXIO should always be raised.
|
||||
try:
|
||||
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
|
||||
os.close(fd)
|
||||
raise PtyProcessError("OSError of errno.ENXIO should be raised.")
|
||||
except OSError as err:
|
||||
if err.errno != errno.ENXIO:
|
||||
raise
|
||||
|
||||
# Verify we can open child pty.
|
||||
fd = os.open(child_name, os.O_RDWR)
|
||||
os.close(fd)
|
||||
|
||||
# Verify we now have a controlling tty.
|
||||
fd = os.open("/dev/tty", os.O_WRONLY)
|
||||
os.close(fd)
|
||||
Reference in New Issue
Block a user