如何用openpty实现Ctrl-C和Ctrl-D?

all*_*tom 11 shell cocoa objective-c nstask pty

我正在使用NSTask和NSTextView编写一个简单的终端.如何和应该实施?openptyCtrlCCtrlD

我开始像这样的shell:

int amaster = 0, aslave = 0;
if (openpty(&amaster, &aslave, NULL, NULL, NULL) == -1) {
    NSLog(@"openpty failed");
    return;
}

masterHandle = [[NSFileHandle alloc] initWithFileDescriptor:amaster closeOnDealloc:YES];
NSFileHandle *slaveHandle = [[NSFileHandle alloc] initWithFileDescriptor:aslave closeOnDealloc:YES];

NSTask *task = [NSTask new];
task.launchPath = @"/bin/bash";
task.arguments = @[@"-i", @"-l"];
task.standardInput = slaveHandle;
task.standardOutput = slaveHandle;
task.standardError = errorOutputPipe = [NSPipe pipe];
[task launch];
Run Code Online (Sandbox Code Playgroud)

然后我拦截CtrlC并发-[interrupt]送到NSTask这样的:

- (void)keyDown:(NSEvent *)theEvent
{
    NSUInteger flags = theEvent.modifierFlags;
    unsigned short keyCode = theEvent.keyCode;

    if ((flags & NSControlKeyMask) && keyCode == 8) { // ctrl-c
        [task interrupt]; // ???
    } else if ((flags & NSControlKeyMask) && keyCode == 2) { // ctrl-d
        // ???
    } else {
        [super keyDown:theEvent];
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,中断似乎不会杀死shell正在执行的任何程序.如果shell没有子进程,则中断会取消当前输入行.

我不知道如何实施CtrlD.

all*_*tom 5

我在 Linux 上的 gdb 中遍历了st(无油终端,其代码实际上很小而且很容易理解),发现当您按下Ctrl-C和 时Ctrl-D,它分别写入\003\004到进程。我在我的项目中在 OS X 上尝试过这个,它也能正常工作。

所以在我上面代码的上下文中,处理每个热键的解决方案是:

  • Ctrl-C: [masterHandle writeData:[NSData dataWithBytes:"\003" length:1]];
  • Ctrl-D: [masterHandle writeData:[NSData dataWithBytes:"\004" length:1]];