Reputation:
It's possible to redirect everything that is written in the terminal to a process?
For example, after I started the process, if I write "command" in the terminal, this should be redirected to a pipe from my process or something like this.
Upvotes: 0
Views: 268
Reputation: 3970
Yes, it should be practical to redirect all terminal output from your program (and all of its child processes) after your program has started. Unix programs usually write to the terminal by writing to standard output (stdout). Standard output is always on the file descriptor number 1 (the C constant is STDOUT_FILENO
), for all processes. You can use the dup2()
system call to replace any file descriptor number with another file descriptor.
So you can e.g. create a pipe using int fds[2]; pipe(fds);
. Then fds[1]
will be a file descriptor number that you can use to write to the pipe. If you do dup2(fds[1], STDOUT_FILENO);
then standard output will also write to the pipe. (You can close(fds[1]);
afterwards since you probably don't need it, now that you can use stdout instead.)
You can also open a file for writing with fd = open("filename", O_WRONLY);
and then dup2(fd, STDOUT_FILENO);
so everything written to stdout goes into your file.
Note that you need to redirect stdout at the very beginning of your program before doing anything that might write to stdout.
The above trick will make standard output go to your pipe instead of the terminal. If you want the output to go to the terminal, and also get a copy of the output in a pipe of file, that's more difficult but can also be done. You need to create an internal pipe, then dup2(that_pipe, STDOUT_FILENO);
so stdout writes to that pipe. Then you need to read from that pipe (probably using poll()
then read()
) and write everything you got to both 1) the terminal and 2) to another pipe or file that is going outside your program. So you need two pipes if you want to copy output.
The tee
command does this (copy stdout to files) from the shell.
This dup2()
approach is not bulletproof because a Unix terminal (even when using a GUI terminal emulator instead of a hardware console) is a device in /dev
. You can type tty
in a shell or use ttyname(STDOUT_FILENO)
in C to see which file in /dev
corresponds to the terminal that stdout is writing to. In principle, any program (under the same user account) could open the terminal device using that filename and write to it without asking for permission from any other program. You can easily try this from the shell using the write
program:
echo hello world | write $(whoami) /dev/ttys123
where /dev/ttys123
is whatever you got by typing tty
in some other terminal window (the name looks a bit different on different operating systems, e.g. Linux and MacOS). You should see hello world
appear in that other window.
Upvotes: 1
Reputation: 213648
From a child process, no. You must set this up in the parent preocess, and have it propagate downwards to children (barring some kind of crazy hack).
From the shell, you can redirect.
exec >file
This will redirect standard output to file
, and it will apply to all future commands run in the shell. You can make this into a function, if you like.
Upvotes: 0