1

I tried to develop a remote app that launches sh and resends an incoming data there, and found that some special sequences don't work.

So, for testing purposes, I launched on my desktop sh, then executed there a command ping localhost, next trying to interrupt the ping by executing echo -e "\003" > /proc/$shPID/fd/0 from the other shell. The byte 0x3 is the one that produced by Ctrl+C combination. No matter what I tried (adding a newline, adding a CSI at the beginning), it didn't work — characters just shows up in stdout of the sh (I mean e.g. newline), but does not interrupt the ping running.

How do I interrupt that ping via stdin of the sh?

1 Answer 1

3

That ^C handling is done by the terminal device driver, not the shell.

It's when that character is received on the wire that connects to a tty device (or written on the master side of the master side of a pseudo-terminal pair (like xterm does when you press Ctrl+C)) that the tty line discipline (a driver in the kernel) sends the SIGINT signal to the foreground process group of the terminal.

So you'd need to send that character on the fd that xterm has open on the master side.

$ eval "$(xprop -notype -id $WINDOWID 32i '=$0\n' _NET_WM_PID)"; lsof -ap "$_NET_WM_PID" /dev/ptmx
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xterm   21123 stephane    4u   CHR    5,2      0t0 1460 /dev/ptmx

Writing it to /proc/21123/fd/4 on Linux would not work as that would just reopen /dev/ptmx so not refer to the same pseudo-terminal. You'd need to convince that xterm to write that ^C to its fd 4.

So not really an option.

You could start your own pseudo-terminal pair and run sh and ping` in it. Then you could write ^C on the master side for that SIGINT to be sent to the foreground process group, but easier here would be to send a signal directly (SIGTERM would be prefered).

Also note that trying to write a character on /proc/$pid/fd/0, doesn't really make sense. The file descriptor is usually open for reading. On Linux, doing an open() on that /proc/$pid/fd/0 actually reopens the resource that that fd points to.

So for instance if sh was started with sh < /some/file, doing echo something > "/proc/$shpid/fd/0" would replace the content of /some/file with something\n. If it was a tty, then that would just display something on that terminal. The only case where writing something would have that something read by sh would be when that sh stding is a pipe. On Linux (and Linux only), if you do an open() in write mode to /proc/$shpid/fd/0 (where that is a pipe), then that opens the writing end of that pipe (while that fd 0 actually points to the reading end).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .