¿Cómo leer/escribir en un dispositivo tty*?

¿Cómo leer/escribir en un dispositivo tty*?

Tengo un dispositivo que envía información por USB a mi computadora. Arch Linux configura este dispositivo creando un archivo ttyUSB0llamado /dev/. He estado usando GTKtermpara recibir esta información entrante y mostrarla en una ventana de terminal emulada.

Mi pregunta es, ¿cómo se GTKtermlee/escribe exactamente en este ttyUSB0archivo y dónde podría empezar a aprender a implementar una funcionalidad similar? Es decir, en la forma más básica, ¿cómo podría escribir un carácter ttyUSB0o, por el contrario, recibir un byte y escribirlo en un archivo?

Respuesta1

Los TTY son archivos que puedes usar como cualquier otro. Puede abrirlos con las herramientas de apertura de archivos estándar de su idioma y leerlos o escribirlos. Tienen un comportamiento especial que los diferencia de los archivos "normales", pero los conceptos básicos son los mismos. Cubriré algunos de los casos especiales al final, pero primero, un experimento.

Una cosa interesante que puedes hacer directamente desde una terminal normal. Ejecute ttye imprimirá una línea como:

/dev/pts/2

Ese es el dispositivo TTY en el que se ejecuta su terminal. Puede escribir algo en ese terminal:

$ echo Hello > /dev/pts/2
Hello
$

Incluso puedes leerlo:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

( read Xes el comando "leer una línea de la entrada estándar a la variable X" de sh; el < es usar /dev/pts/2 como entrada estándar para el comando de lectura; el primer "hola" lo escribí y el segundo se imprimió) .

Si abre otro shell, digamos usando screeno xterm, puede ejecutar ejecutar echo spooky > /dev/pts/2en ese shell para que el texto aparezca en su terminal original, y lo mismo para los otros comandos. Todo esto es simplemente tu shell abriendo un archivo sin saber que es un TTY.


Aquí hay un programa en C muy simple que hace exactamente lo que usted pidió y escribe un solo carácter en /dev/pts/3, luego lee un solo byte:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>    
int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c\n", byte);
    return 0;
}

Un dispositivo TTY real que esté conectado a un shell o emulador de terminal tendrá un comportamiento interesante allí, pero debería recibir algo a cambio.


Para acceder a un terminal es necesario tener permiso para utilizarlo. Esos son solo los permisos de archivo estándar que ve ls -ly configura chmod: necesita permiso de lectura para abrir el archivo y leerlo, y permiso de escritura para escribir en él. Los TTY que respaldan su terminal serán de su propiedad, pero el TTY de otro usuario no, y los TTY para dispositivos USB pueden serlo o no, dependiendo de su configuración. Puedes cambiar los permisos de la misma forma que siempre.

En lo que respecta a escribir un programa para trabajar con él, no es necesario hacer mucho especial. Puedes ver en el ejemplo que una cosanoLo que tengo que hacer es cerrar el archivo cada vez para que el otro extremo lea los datos: los archivos TTY actúan como canalizaciones, simplemente empujando los datos en ambas direcciones a medida que llegan. Cuando escribí texto en el TTY, apareció inmediatamente, y cuando Leí después que ya no había nada esperándome. Esnocomo escribir en un archivo normal donde los datos se guardan en el disco: se pasan inmediatamente al otro lado o se almacenan en la memoria hasta que alguien los lee.

Es posible que desee utilizar elseleccionarfunciona para que pueda hacer otras cosas mientras espera que el dispositivo diga algo, pero si está contento de esperar a que lleguen los datos, puede usar lecturas de bloqueo y dejar que el sistema operativo haga el trabajo.

Una cosa a tener en cuenta es que puede haber un tamaño de búfer limitado en el kernel y, si escribe muchos datos a la vez, puede terminar bloqueándolos sin querer. Si es probable que eso sea un problema, utiliceE/S sin bloqueocon open("/dev/...", O_RDWR | O_NONBLOCK). El principio será el mismo en cualquier caso.

información relacionada