| 1 | # Redirect File Descriptor of Running Process # |
| 2 | |
| 3 | This note explains how to redirect `stdin` (or any other file descriptor) of a |
| 4 | pre-existing process using the GNU debugger (`gdb`) and a FIFO. It was tested |
| 5 | on FreeBSD 11. |
| 6 | |
| 7 | An example of use would be saving the contents of remote `vi` sessions after |
| 8 | they are detached due to a dropped connection. |
| 9 | |
| 10 | First, make a FIFO: |
| 11 | |
| 12 | $ mkfifo /tmp/vififo |
| 13 | |
| 14 | Assuming there is a pre-existing `vi` session with PID `91266`, connect |
| 15 | with `gdb`, close file descriptor `0` and reopen it as a connection to the |
| 16 | FIFO with the `call close` and `call open` commands. |
| 17 | |
| 18 | $ gdb -p 91266 |
| 19 | <snip> |
| 20 | Attaching to process 91266 |
| 21 | <snip> |
| 22 | (gdb) call close (0) |
| 23 | $1 = 0 |
| 24 | (gdb) call open ("/tmp/vififo", 0600) |
| 25 | |
| 26 | At this point `gdb` will appear to hang. Leave it and open a new terminal. Use |
| 27 | `echo` to send characters to the process through the FIFO. |
| 28 | |
| 29 | Special characters may be escaped by pressing `Ctrl-V` followed by the |
| 30 | character. For example, to send an `Escape`, press `Ctrl-V` followed by |
| 31 | `Escape` which results in an `Escape` code, or `^[`. |
| 32 | |
| 33 | Continuing the example, tell `vi` to save the current buffer to a file. |
| 34 | |
| 35 | $ echo "^[:w /tmp/vi_recover.txt" > /tmp/vififo |
| 36 | |
| 37 | After this command the `gdb` session should start responding again, returning |
| 38 | to a `(gdb)` prompt. Exit `gdb`. |
| 39 | |
| 40 | $2 = 0 |
| 41 | (gdb) quit |
| 42 | A debugging session is active. |
| 43 | |
| 44 | Inferior 1 [process 91266] will be detached. |
| 45 | |
| 46 | Quit anyway? (y or n) Y |
| 47 | Detaching from program: /hh/bin/vi, process 91266 |
| 48 | [Inferior 1 (process 91266) detached] |
| 49 | |
| 50 | The characters have now been received by `vi` and a file should be waiting at |
| 51 | `/tmp/vi_recover.txt`. |