3
votes

I have an NSTask that's executing another program I wrote. In that command line program, it expects the ETX (control-C, or ASCII value 3) to pause one of its processes and call another function. How can I send this? I know I'm sending commands correctly because the program interacts with every command I've sent it so far except ETX. I'm using the following code but it does not work:

NSString *cmdScan = [NSString stringWithFormat:@"%c", 3];
[inputHandle writeData: [cmdScan dataUsingEncoding:NSUTF8StringEncoding]];
1

1 Answers

6
votes

(I'm assuming you want to emulate the behavior of the ctrl+c keystroke in a terminal window. If you really mean to send an ETX to the target process, this answer isn't going to help you.)

The ctrl+c keyboard combination doesn't send an ETX to the standard input of the program. This can easily be verified as regular keyboard input can be ignored by a running program, but ctrl+c (usually) immediately takes effect. For instance, even programs that completely ignore the standard input (such as int main() { while (1); }) can be stopped by pressing ctrl+c.

This works because terminals catch the ctrl+c key combination and deliver a SIGINT signal to the process instead. Therefore, writing an ETX to the standard input of a program has no effect, because the keystroke is caught by the terminal and the resulting character isn't delivered to the running program's standard input.

You can send SIGINT signals to processes represented by a NSTask by using the -[NSTask interrupt] method.

[task interrupt];

Otherwise, you can also send arbitrary signals to processes by using the kill function (which, mind you, doesn't necessarily kills programs).

#include <signal.h>
kill(task.processIdentifier, SIGINT);