Redirect File Descriptor of Running Process

This note explains how to redirect stdin (or any other file descriptor) of a pre-existing process using the GNU debugger (gdb) and a FIFO. It was tested on FreeBSD 11.

An example of use would be saving the contents of remote vi sessions after they are detached due to a dropped connection.

First, make a FIFO:

$ mkfifo /tmp/vififo

Assuming there is a pre-existing vi session with PID 91266, connect with gdb, close file descriptor 0 and reopen it as a connection to the FIFO with the call close and call open commands.

$ gdb -p 91266
<snip>
Attaching to process 91266
<snip>
(gdb) call close (0)
$1 = 0
(gdb) call open ("/tmp/vififo", 0600)

At this point gdb will appear to hang. Leave it and open a new terminal. Use echo to send characters to the process through the FIFO.

Special characters may be escaped by pressing Ctrl-V followed by the character. For example, to send an Escape, press Ctrl-V followed by Escape which results in an Escape code, or ^[.

Continuing the example, tell vi to save the current buffer to a file.

$ echo "^[:w /tmp/vi_recover.txt" > /tmp/vififo

After this command the gdb session should start responding again, returning to a (gdb) prompt. Exit gdb.

$2 = 0
(gdb) quit
A debugging session is active.

    Inferior 1 [process 91266] will be detached.

Quit anyway? (y or n) Y
Detaching from program: /hh/bin/vi, process 91266
[Inferior 1 (process 91266) detached]

The characters have now been received by vi and a file should be waiting at /tmp/vi_recover.txt.