Eu tenho um dispositivo que envia informações via USB para o meu computador. Arch Linux configura este dispositivo através da criação de um arquivo chamado ttyUSB0
no /dev/
. Eu tenho usado GTKterm
para receber essas informações e exibi-las em uma janela de terminal emulada.
Minha pergunta é: como exatamente GTKterm
lê / grava neste ttyUSB0
arquivo e onde posso começar a aprender a implementar funcionalidades semelhantes? Ou seja, da forma mais básica, como posso escrever um caractere ttyUSB0
ou, em contraste, receber um byte e gravá-lo em um arquivo?
screen
pode fazer isso eminiterm
screen
e / ouminiterm
programaticamente.Respostas:
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. Vou cobrir alguns dos casos especiais no final, mas primeiro, um experimento.
Uma coisa interessante que você pode fazer diretamente de um terminal regular. Execute
tty
e ele imprimirá uma linha como:Esse é o dispositivo TTY em que seu terminal está sendo executado. Você pode escrever algo nesse terminal:
Você pode até ler:
(o
read X
comando sh é "ler uma linha da entrada padrão para a variável X"; <é usar / dev / pts / 2 como entrada padrão para o comando read; o primeiro "olá" que eu digitei e o segundo foi impresso) .Se você abrir outro shell, digamos, usando
screen
ouxterm
, poderá executar runecho spooky > /dev/pts/2
nesse shell para fazer com que o texto apareça no seu terminal original e o mesmo para os outros comandos. Tudo isso é apenas o shell que abre um arquivo sem saber que é um TTY.Aqui está um programa C muito simples que faz exatamente o que você pediu e grava um único caractere em / dev / pts / 3, e depois lê um único byte:
Um dispositivo TTY real conectado a um emulador de terminal ou shell terá um comportamento interessante, mas você deve receber algo em troca.
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ê
ls -l
e definechmod
: você precisa de permissão de leitura para abrir o arquivo e lê-lo, e permissão de gravação para escrever nele. Os TTYs que suportam seu terminal pertencem a você, 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 maneira como sempre.Quanto a escrever um programa para trabalhar com ele, você não precisa fazer muita coisa especial. Você pode ver no exemplo que uma coisa que você não precisa fazer é fechar o arquivo toda vez para que seus dados sejam lidos pela outra extremidade: os arquivos TTY agem como pipelines, apenas empurrando os dados nas duas direções à medida que entram. Quando escrevi um texto para o TTY, ele apareceu imediatamente, e quando o li depois não havia mais nada esperando por mim. É não como escrever para um arquivo regular, onde os dados são salvos no disco - que é transmitido imediatamente para o outro lado, ou armazenados na memória até que alguém lê-lo.
Você pode usar a função de seleção para poder fazer outras coisas enquanto espera o dispositivo dizer alguma coisa, mas se estiver feliz em esperar a chegada dos dados, basta usar o bloqueio de leituras e deixar o sistema operacional funcionar. o levantamento.
Uma coisa a ter em mente é que existe um tamanho de buffer limitado no kernel, e se você escrever muitos dados de uma só vez, poderá acabar bloqueando sem querer. Se isso for um problema, use E / S sem bloqueio
open("/dev/...", O_RDWR | O_NONBLOCK)
. O princípio será o mesmo de qualquer maneira.fonte
sudo echo Hello > /dev/tty4
quando estou no ambiente de área de trabalho, mas recebobash: /dev/tty4: Permission denied
se não estiver conectado ao tty4. No entanto, se eu estiver logado no tty4, tudo funcionará bem. Qual é a razão para isto?ls -l /dev/tty4
> /dev/tty4
parte não faz parte doecho
subprocesso iniciado,sudo
mas parte dosudo
próprio processo, que é executado pelo usuário atual. as permissões de arquivo para o usuário atual se aplicam em vez da raiz.