2

Is it possible to programmatically capture stdout (and stdin) of an already running process on Linux? (Maybe redirect it to a pipe?)

It would be best if the solution worked in userspace (meaning without needing root privileges).

I've seen an answer apparently using gdb, but I'd like to do it without gdb.

EDIT: To clarify: no, I don't have access to the code, neither do I want to change the binary, I want the solution to work from a separate process. The target process is already running anyway.

Community
  • 1
  • 1
akavel
  • 4,789
  • 1
  • 35
  • 66
  • You will probably get a faster and better answer on unix.stackexchange.com – Muhammad Gelbana Oct 25 '13 at 08:29
  • Doesn't the question that you've pointed to contain options using `strace`? – devnull Oct 25 '13 at 08:30
  • Hmmm... the suggestion with strace seems interesting, although I'd strongly prefer if I could actually _redirect_ the output (as stated in the subject line), so that the original target gets disconnected, and IIUC, strace allows me only to "eavesdrop" on the communication. (Specifically, my preferred solution would seem more general and to allow the strace-like one as a special case.) – akavel Oct 25 '13 at 08:42

3 Answers3

5

From inside the process itself (assuming you can change its code in C) you might try freopen(3), perhaps as

 FILE*newout = freopen("/some/path", "w", stdout);
 if (!newout) { perror("freopen"); exit (EXIT_FAILURE); } 
 stdout = newout;

See also stdio(3). (Otherwise dup2 the STDOUT_FILENO).

From outside of the process you might perhaps play with /proc/$PID/fd/ that is dup2(2), or redirecting, or tee(1), the /proc/$PID/fd/0 for the stdin of your process $PID, the /proc/$PID/fd/1 for the stdout of your process $PID etc. See proc(5) for more.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • To clarify: no, I don't have access to the code, neither do I want to change the binary, I want the solution to work from a separate process. Assume that the target process is already running. – akavel Oct 25 '13 at 08:38
2

Hmmm, note to self: after reading some other similar questions, here are some promising projects which might (?) help me find the answer:

Community
  • 1
  • 1
akavel
  • 4,789
  • 1
  • 35
  • 66
1

If you've already started the process you can use gdb to actually redirect stdout or strace to just intercept the calls to write et.al.

If you don't want to use gdb or strace you would probably need to basically do the same thing as these do. The magic they're doing is to use the ptrace function to trace the other process. This will require that you have the right to trace the program (which also gdb and strace requires), as a normal user you can't trace programs of other users.

Linux Journal has an article about playing with ptrace that shows how you do it. One thing to note is that this will be platform dependent: you have to write the code specifically for the platform you're using, the article seems to have examples for the (32 bit) x86 platform.

skyking
  • 13,817
  • 1
  • 35
  • 57