我正在尝试重新编写UNIX命令script(因为它在OSX上).这是学校帮助学生学习UNIX API的练习的一部分.我们只允许使用系统调用,更具体地说,只允许使用Mac OSX上的MAN(2)页面上的那些(因为那是我们在学校的操作系统).
我有一个'第一版'那种作品.运行程序,例如ls将正确的输出打印到屏幕和输出文件中.
问题场景
我bash从script-clone中运行.第一个问题是我收到以下错误:
bash: no job control in this shell
我试图迫使bash过程分为前台与setpgrp和setpgid但din't改变什么,所以我的结论是没有问题的.
我也试图理解为什么真正的script命令使用cfmakeraw(至少在Linux上),因为看到这里,但我不明白这一点.MAN页面不是很有帮助.
真正script还dup2ŠSTDIN上slave,因为看到这里,但是当我这样做,好像输入不再阅读.
但是,bash仍然运行,我可以在其中执行命令.
但是如果我在vim里面跑,然后点击Ctrl-Z放到vim后台,终端就搞砸了(当我在常规终端时不会发生这种情况).
所以我想我一定做错了.我很感激任何建议/帮助.
这是源代码:https: //github.com/conradkleinespel/unix-command-script/tree/2587b07e7a36dc74bf6dff0e82c9fdd33cb40411
您可以通过执行以下操作进行编译:( make它建立在OSX 10.9上,希望在Linux上也是如此)
并通过做: ./ft_script
不知道在StackOverflow中拥有所有源代码更有意义,因为它会使页面占用它.如果需要,我可以用源替换Git链接.
我不使用 OS X,所以我不能直接测试你的代码,但我目前正在编写一个玩具终端模拟器,并且遇到了类似的麻烦。
\n\n关于“bash:此 shell 中没有作业控制”
\n\n为了执行作业控制,shell 需要成为会话领导者及其终端的控制进程。默认情况下,您的程序继承您自己的 shell 的控制终端,该终端运行您的script程序,并且也是会话领导者。以下是如何使您的新从属进程成为会话领导者fork:
/* we don\'t need the inherited master fd */\nclose(master);\n/* discard the previous controlling tty */\nioctl(0, TIOCNOTTY, 0);\n/* replace existing stdin/out/err with the slave pts */\ndup2(slave, 0);\ndup2(slave, 1);\ndup2(slave, 2);\n/* discard the extra file descriptor for the slave pts */\nclose(slave);\n/* make the pts our controlling terminal */\nioctl(0, TIOCSCTTY, 0);\n/* make a new session */\nsetsid()\nRun Code Online (Sandbox Code Playgroud)\n\n此时,分叉进程已将 stdin/out/err 绑定到新的 pts,pts 成为其控制终端,并且该进程是会话领导者。作业控制现在应该可以工作了。
\n\n关于原始 tty
\n\n当您在普通终端中运行程序时,它看起来像这样:
\n\n(term emulator, master side) <=> /dev/pts/42 <=> (program, slave side)\nRun Code Online (Sandbox Code Playgroud)\n\n如果按^Z,终端仿真器会将 ascii 字符写入0x1Apts。它是一个控制字符,因此不会发送给程序,而是内核会发送SIGSTP给程序并挂起它。将字符转换为其他内容的过程称为“线路烹饪”,并且具有可以针对每个 tty 进行调整的各种设置。
现在让我们看看情况script:
term emulator <=> /dev/pts/42 <=> script <=> /dev/pts/43 <=> program\nRun Code Online (Sandbox Code Playgroud)\n\n使用正常线路设置时,按 会发生什么^Z?它将转变为由SIGSTP并将/dev/pts/42暂停script。但这不是我们想要的,相反,我们希望0x1A我们生成的字符^Z按原样通过,然后由\xc2\xa0to/dev/pts/42传递,然后才被转换为来挂起程序。script/dev/pts/43SIGSTP
这就是为什么终端和脚本之间的点必须配置为“原始”的原因,以便所有控制字符到达程序之间的点script,就像您直接使用它一样。
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |