Added note to UNIX Tips page explaining how to connect a process' STDIO to a TCP...
[website_subgeniuskitty.com] / data / notes / unix_misc.md
CommitLineData
a8f095b0
AT
1# Redirect File Descriptor of Running Process #
2
3This note explains how to redirect `stdin` (or any other file descriptor) of a
4pre-existing process using the GNU debugger (`gdb`) and a FIFO. It was tested
5on FreeBSD 11.
6
7An example of use would be saving the contents of remote `vi` sessions after
8they are detached due to a dropped connection.
9
10First, make a FIFO:
11
12 $ mkfifo /tmp/vififo
13
14Assuming there is a pre-existing `vi` session with PID `91266`, connect
15with `gdb`, close file descriptor `0` and reopen it as a connection to the
16FIFO 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
26At 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
29Special characters may be escaped by pressing `Ctrl-V` followed by the
30character. For example, to send an `Escape`, press `Ctrl-V` followed by
31`Escape` which results in an `Escape` code, or `^[`.
32
33Continuing the example, tell `vi` to save the current buffer to a file.
34
35 $ echo "^[:w /tmp/vi_recover.txt" > /tmp/vififo
36
37After this command the `gdb` session should start responding again, returning
38to 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
50The characters have now been received by `vi` and a file should be waiting at
51`/tmp/vi_recover.txt`.
08f3fbf9
AT
52
53
54# Expose Process STDIO on TCP Port #
55
56This note explains how to launch a process and connect its
57`stdin`/`stdout`/`stderr` directly to a TCP port. It was tested on FreeBSD 12.
58
59As an example, we will launch a `bash` process running on a Debian 10 machine
60and connect it to TCP port `4242`. Then, from a FreeBSD machine we will connect
61and utilize the `bash` session remotely.
62
63First, on the Debian machine, we use
64[`socat`](http://www.dest-unreach.org/socat/), a program which establishes two
65bidirectional byte streams and transfers data between them. In our case, we
66tell `socat` to build a PTY at `/tmp/pty_test` and connect it to TCP port
67`4242`.
68
69 socat PTY,link=/tmp/pty_test,raw TCP-LISTEN:4242,reuseaddr,fork
70
71Note that the `PTY` argument to `socat` must precede the `TCP-LISTEN` argument.
72Despite the bidirectional nature, the endpoint definition order is not
73interchangeable.
74
75Now we use `setsid` to start a new `bash` process and attach it to the PTY at
76`/tmp/pty_test`. Note that we collapse `stdout` and `stderr` into a single
77combined stream.
78
79 setsid sh -c 'exec bash --login <> /tmp/pty_test >&0 2>&1'
80
81Replace `bash --login` with whatever other command you desire to execute.
82
83Now, from the FreeBSD machine, connect the remote TCP port to your local STDIO
84with `socat`. Assuming the Debian machine running `bash` is at `192.168.1.107`,
85execute the following command.
86
87 socat STDIO,raw TCP:192.168.1.107:4242
88
89At this point you have a fully interative `bash` session running on the Debian
90machine, controlled from the FreeBSD machine.