Contanto que você queira apenas ler e gravar streams (um caractere após o outro), você pode usar um pseudoterminal . Isso basicamente funciona como um pipe de dois lados, onde apenas um lado ("escravo") é visível no sistema de arquivos (como /dev/pts/X ), e o outro lado ("mestre") é visível para o programa que o criou. Tem algumas coisas adicionais, como disciplina de linha e parâmetros seriais no topo, que você pode simplesmente ignorar.
Existem duas maneiras de criar pseudo-terminais, o mais moderno é usar openpty e, em seguida, select no lado mestre. Veja man openpty para detalhes. O Google deve mostrar alguns programas de exemplo.