从haskell程序中运行vi(处理ptys)

 向日葵渴望 发布于 2023-02-09 19:32

我正在尝试编写一个日志记录shell; 例如,捕获有关以结构化格式运行的命令的数据.为此,我正在使用readline读取命令,然后在子shell中执行它们,同时捕获诸如所花费的时间,环境,退出状态等内容.

到现在为止还挺好.然而,最初的尝试运行的东西,如viless从内部此日志壳失败.调查表明要做的事情是建立一个伪tty并将子壳连接到那个而不是普通管道.这会阻止vi抱怨没有连接到终端,但仍然失败 - 我在屏幕上打印了一些废话并且命令在编辑器中作为字符打印 - 例如"ESC"只显示^[.

认为我需要做的是将pty置于原始模式.为此,我尝试了以下方法:

  pty <- do
    parentTerminal <- getControllingTerminalName >>= 
                      \a -> openFd a ReadWrite Nothing defaultFileFlags
    sttyp <- getTerminalAttributes parentTerminal
    (a, b) <- openPseudoTerminal
    let rawModes = [ProcessInput, KeyboardInterrupts, ExtendedFunctions, 
                    EnableEcho, InterruptOnBreak, MapCRtoLF, IgnoreBreak, 
                    IgnoreCR, MapLFtoCR, CheckParity, StripHighBit, 
                    StartStopOutput, MarkParityErrors, ProcessOutput]
        sttym = withoutModes rawModes sttyp
        withoutModes modes tty = foldl withoutMode tty modes
    setTerminalAttributes b sttym Immediately
    setTerminalAttributes a sttym Immediately
    a' <- fdToHandle a
    b' <- fdToHandle b
    return (a',b')

例如,我们获取父终端的属性,删除我认为对应于将tty设置为原始模式的各种标志(基于此代码和haddockSystem.Posix.Terminal),然后在pty的两侧设置这些.

然后我在shell中启动一个进程,使用createProcess并使用waitForProcess它连接到它,为子进程的stdin和stdout句柄提供pty的slave端:

eval :: (Handle, Handle) -> String -> IO ()
eval pty command = do
    let (ptym, ptys) = pty
    (_, _, hErr, ph) <- createProcess $ (shell command) { 
          delegate_ctlc = True
        , std_err = CreatePipe
        , std_out = UseHandle ptys
        , std_in = UseHandle ptys
      }
    snipOut <- tee ptym stdout
    snipErr <- sequence $ fmap (\h -> tee h stderr) hErr
    exitCode <- waitForProcess ph
    return ()
  where tee :: Handle -> Handle -> IO B.ByteString
        tee from to = DCB.sourceHandle from
            $= DCB.conduitHandle to -- Sink contents to out Handle
            $$ DCB.take 256 -- Pull off the start of the stream

这肯定会更改终端设置(已确认stty),但无法解决问题.我错过了什么吗?我需要设置属性的其他设备吗?

编辑:完整的可运行代码可以在https://github.com/nc6/tabula上找到 - 我简化了这篇文章的一些内容.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有