【问题标题】:Inappropriate ioctl using Ubuntu and pty使用 Ubuntu 和 pty 不合适的 ioctl
【发布时间】:2019-03-25 14:12:31
【问题描述】:

我正在开发一个用 python 编写的终端多路复用器。 在基于 Ubuntu 的发行版上,我看到了错误:

bash: cannot set terminal process group (9862): Inappropriate ioctl for device
bash: no job control in this shell
tmp@tmp-VirtualBox:

在 openSuSE 和 Fedora 上,我没有看到 ioctl 错误,并且作业控制工作正常。

示例问题:

#!/usr/bin/python3

import subprocess
import sys
import pty
import os

master, slave = pty.openpty()

bashCMD = "bash".split()
p = subprocess.Popen(bashCMD, preexec_fn=os.setsid, stdin=slave, stdout=slave, stderr=slave, universal_newlines=True, shell=True)


while p.poll() is None:
  data = os.read(master, 1026)
  print(str(data))


完整项目:https://bitbucket.org/hackersgame/janit/src/master/

【问题讨论】:

    标签: python ubuntu opensuse ioctl pty


    【解决方案1】:

    好的,pty.fork() 适用于所有平台。

    但它不允许我们像 pty.openpty() slave 那样写入 TTY

    为了解决这个问题,我使用了 mmap

    #write tty device info to memory the child and parent process can read
    slaveFd, tmpfile = tempfile.mkstemp()
    os.write(slaveFd, b'\x00' * mmap.PAGESIZE)
    os.lseek(slaveFd, 0, os.SEEK_SET)
    def getSlaves():
      raw = getSlavesRaw()
      returnData = []
      for lessRaw in raw.strip('/').split('/'):
        returnData.append("/dev/pts/" + str(lessRaw))
      return returnData
    
    def getSlavesRaw():
      os.lseek(slaveFd, 0, os.SEEK_SET)
      buf = mmap.mmap(slaveFd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_READ)
      msg = str(buf.readline())
      msg = ':'.join(msg.split(':')[:-1]).split("'")[-1]
      return(msg)
    
    def addSlave(PID):
      offset = getSlavesRaw()
      offset = len(offset)
      os.lseek(slaveFd, offset, os.SEEK_SET)
      buf = mmap.mmap(slaveFd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_WRITE)
      TTY = subprocess.check_output(['ps', 'hotty', str(PID)]).strip().decode()
      TTY = TTY.split("pts")[-1] + ":" # cut off pts and add a : for spacing
      for index in range(offset, offset + len(TTY)):
        buf[index] = ord(TTY[index - offset])
    
    
    #Thanks! https://stackoverflow.com/a/52157066/5282272
    # fork this script such that a child process writes to a pty that is
    # controlled or "spied on" by the parent process
    
    (child_pid, newMasterHandle) = pty.fork()
    masters.append(newMasterHandle)
    # A new child process has been spawned and is continuing from here.
    # The original parent process is also continuing from here.
    # They have "forked".
    
    if child_pid == 0:
      debug("This is the child process fork, pid %s" % os.getpid())
      addSlave(os.getpid())
      bashProcessList.append(subprocess.run("bash"))
    else:
      debug("This is the parent process fork, pid %s" % os.getpid())
      debug(getSlaves())
    
      while True:
        try:
          data = os.read(masters[myScreen], 1026)
        except Exception:
          #time.sleep(.2)
          continue
        yield data
    
    

    【讨论】:

      猜你喜欢
      • 2015-10-30
      • 2010-12-08
      • 1970-01-01
      • 2014-09-17
      • 2015-02-03
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2022-06-27
      相关资源
      最近更新 更多