Como ler / escrever no dispositivo tty *?

20

Eu tenho um dispositivo que envia informações via USB para o meu computador. O Arch Linux configura esse dispositivo criando um arquivo chamado ttyUSB0 in /dev/ . Eu tenho usado GTKterm para receber essa informação de entrada e exibi-la em uma janela de terminal emulada.

A minha pergunta é: como exatamente GTKterm lê / escreve para este arquivo ttyUSB0 , e onde posso começar a aprender como implementar uma funcionalidade semelhante? Ou seja, na forma mais básica, como posso escrever um caractere para ttyUSB0 ou, em contraste, receber um byte e gravá-lo em um arquivo?

    
por sherrellbc 20.06.2014 / 20:23

1 resposta

31

TTYs são arquivos que você pode usar como qualquer outro. Você pode abri-los com as ferramentas padrão de abertura de arquivos do seu idioma e ler ou escrever a partir deles. Eles têm um comportamento especial diferente dos arquivos "comuns", mas o básico é o mesmo. Eu cobrirei alguns dos casos especiais no final, mas primeiro, um experimento.

Uma coisa interessante que você pode fazer direto de um terminal comum. Execute tty e imprima uma linha como:

/dev/pts/2

Esse é o dispositivo TTY que seu terminal está executando. Você pode escrever algo para esse terminal:

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

Você pode até ler:

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

( read X é sh's "lê uma linha de entrada padrão na variável X" comando; o < é usar / dev / pts / 2 como entrada padrão para o comando de leitura; o primeiro "hello" eu digitei, e o segundo foi impresso).

Se você abrir outro shell, digamos, usando screen ou xterm , poderá executar echo spooky > /dev/pts/2 nesse shell para que o texto apareça no terminal original e o mesmo para os outros comandos. Tudo isso é apenas o seu shell abrindo um arquivo sem saber que é um TTY.

Aqui está um programa em C muito simples que faz exatamente o que você pediu, e escreve um único caractere em / dev / pts / 3, e então lê um único 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;
}

Um dispositivo TTY real que esteja conectado a um shell ou emulador de terminal terá um comportamento interessante, mas você deve receber algo de volta.

Para acessar um terminal, você precisa ter permissão para usá-lo. Essas são apenas as permissões de arquivo padrão que você vê com ls -l e configuradas com chmod : você precisa de permissão de leitura para abrir o arquivo, lê-lo e gravar permissão para gravar nele. Os TTYs que suportam o seu terminal serão de sua propriedade, mas o TTY de outro usuário não, e os TTYs para dispositivos USB podem ou não ser, dependendo da sua configuração. Você pode alterar as permissões da mesma forma que sempre.

No que diz respeito a escrever um programa para trabalhar com ele, você não precisa fazer muito especial. Você pode ver no exemplo que uma coisa que você não precisa fazer é fechar o arquivo toda vez para ter seus dados lidos pelo outro lado: os arquivos TTY agem como pipelines, apenas empurrando dados para dentro. Ambas as direções quando elas chegam. Quando eu escrevi o texto para o TTY, ele apareceu imediatamente, e quando eu li dele depois, não havia mais nada esperando por mim. Não é não como gravar em um arquivo regular onde os dados são salvos no disco - eles são passados imediatamente para o outro lado ou armazenados na memória até que alguém os leia.

Você pode usar a função selecione para poder fazer outras coisas enquanto aguarda o dispositivo para dizer alguma coisa, mas se você está feliz em apenas esperar que os dados cheguem, basta usar as leituras de bloqueio e deixar o SO fazer o levantamento.

Uma coisa a ter em mente é que pode haver um tamanho de buffer limitado no kernel, e se você escrever muitos dados de uma só vez, pode acabar bloqueando sem querer. Se isso for um problema, use IO sem bloqueio com open("/dev/...", O_RDWR | O_NONBLOCK) . O princípio será o mesmo em ambos os sentidos.

    
por 21.06.2014 / 05:16

Tags