Skip to content

Instantly share code, notes, and snippets.

@calaveraInfo
Last active January 27, 2021 05:29
Show Gist options
  • Save calaveraInfo/73cd438c3d65dba4228f4b1985177e6a to your computer and use it in GitHub Desktop.
Save calaveraInfo/73cd438c3d65dba4228f4b1985177e6a to your computer and use it in GitHub Desktop.
Simple tool that redirects it's standard input to input buffer of a terminal (i.e. fake input to some terminal)

About

It is possible to redirect some input to TTY device by standard IO redirection.

echo ahoj > /dev/tty1

Such redirection will however end in the output buffer of the TTY device so the characters will be ghosts - visible on the terminal, but not effective. It is, in fact, not possible by standard tools to redirect input to terminal as if it is a real input from keyboard. It is possible to do it by using Linux specific ioctl(), but I haven't found any user space tool that would allow me to simply redirect keyboard input from one terminal to another.

The only tool I've found is openvt, part of console-tools package, but it reads the input from the command line parameter so it's not suitable for permanent IO redirection which is what I needed.

Build

make termpipe

Usage

With this tool it's possible to do this:

sudo kill -stop <pid> # Stop agetty or whatewer process may be reading the source terminal to prevent race condition
sudo stty -F /dev/tty1 raw # set the source terminal to raw mode so that it's not line buffered among other things
sudo cat /dev/tty1 | sudo termpipe /dev/ttyUSB0 & # this effectively redirects local keyboard input as if it is an input from the serial interface
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char **argv) {
int fd, argi;
char *term = NULL;
char ch;
if (argc > 1) {
term = argv[1];
} else {
fprintf(stderr, "no tty specified\n");
return 1;
}
fd = open(term, O_RDONLY);
if (fd < 0) {
perror(term);
fprintf(stderr, "could not open tty\n");
return 1;
}
while(read(STDIN_FILENO, &ch, 1) > 0) {
if (ioctl(fd, TIOCSTI, &ch)) {
perror("ioctl");
return 1;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment