Come leggere / scrivere sul dispositivo tty *?


29

Ho un dispositivo che invia informazioni tramite USB al mio computer. Arch Linux configura questo dispositivo per la creazione di un file chiamato ttyUSB0in /dev/. Ho usato GTKtermper ricevere queste informazioni in arrivo e visualizzarle in una finestra del terminale emulato.

La mia domanda è: come GTKtermlegge / scrive esattamente questo ttyUSB0file e dove posso iniziare a imparare come implementare funzionalità simili? Cioè, nella forma più semplice, come potrei scrivere un carattere ttyUSB0o, al contrario, ricevere un byte e scriverlo su un file?


1
Prova a usare cat per leggere ed eco per scrivere. "Tutto è un file" in unix :)
dchirikov

Puoi provare ad aprire una console seriale su di essa. screenposso farlo, eminiterm
mikeserv il

Stavo pensando in termini di un approccio programmatico. Se questo è vero ed è davvero così semplice (essendo solo aprire e leggere il file), scriveresti semplicemente un ciclo infinito per aprire, leggere, chiudere il file e aggiornarlo continuamente quando sono presenti nuovi dati dalla volta precedente? Cosa succede se il dispositivo 'tty' tenta di scrivere sul file se è aperto nel programma?
Sherrellbc,

Può essere utile: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () e select (). Niente di speciale, a quanto pare.
dchirikov,

@sherrellbc - puoi scrivere script screene / o minitermprogrammaticamente.
Mikeserv,

Risposte:


38

I TTY sono file che puoi usare come qualsiasi altro. Puoi aprirli con gli strumenti standard di apertura dei file della tua lingua e leggere o scrivere da essi. Hanno un comportamento speciale diverso dai file "ordinari", ma le basi sono le stesse. Tratterò alcuni dei casi speciali alla fine, ma prima, un esperimento.

Una cosa interessante che puoi fare direttamente da un terminale normale. Esegui ttye stamperà una riga come:

/dev/pts/2

Questo è il dispositivo TTY in cui è in esecuzione il tuo terminale. Puoi scrivere qualcosa su quel terminale:

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

Puoi persino leggere da esso:

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

( read Xè il comando "leggi una riga dall'input standard nella variabile X" di sh; il <deve usare / dev / pts / 2 come input standard per il comando read; il primo "ciao" ho digitato e il secondo è stato stampato) .

Se apri un'altra shell, ad esempio usando screeno xterm, puoi eseguire run echo spooky > /dev/pts/2in quella shell per far apparire il testo sul tuo terminale originale, e lo stesso per gli altri comandi. Tutto questo è solo la tua shell che apre un file senza sapere che è un TTY.


Ecco un programma C molto semplice che fa esattamente quello che hai chiesto e scrive un singolo carattere in / dev / pts / 3, quindi legge un singolo byte indietro da esso:

#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 vero dispositivo TTY collegato a una shell o un emulatore di terminale avrà un comportamento interessante lì, ma dovresti ottenere qualcosa in cambio.


Per accedere a un terminale è necessario disporre dell'autorizzazione per utilizzarlo. Queste sono solo le autorizzazioni standard per i file visualizzate ls -le impostate chmod: è necessario disporre dell'autorizzazione in lettura per aprire il file e leggerlo e per scrivere in esso. I TTY che supportano il tuo terminale saranno di tua proprietà, ma i TTY di un altro utente non lo faranno e i TTY per i dispositivi USB potrebbero essere o meno, a seconda della configurazione. È possibile modificare le autorizzazioni come sempre.

Per quanto riguarda la scrittura di un programma per lavorare con esso, non è necessario fare molto speciale. Nell'esempio puoi vedere che una cosa che non devi fare è chiudere il file ogni volta che i tuoi dati vengono letti dall'altra parte: i file TTY si comportano come pipeline, semplicemente spingendo i dati in entrambe le direzioni quando arrivano. Quando ho scritto un messaggio sul TTY, è apparso immediatamente e dopo averlo letto da lì non c'era più nulla che mi aspettasse. E ' non è come scrivere su un file normale in cui i dati vengono salvati su disco - ottiene trasmesso subito dall'altra parte, o memorizzati nella memoria fino a quando qualcuno lo legge.

Potresti voler utilizzare la funzione di selezione in modo da poter fare altre cose mentre aspetti che il dispositivo dica qualcosa, ma se sei felice di aspettare solo il passaggio dei dati, puoi semplicemente usare le letture di blocco e lasciare che il sistema operativo faccia il sollevamento.

Una cosa da tenere a mente è che esiste una dimensione del buffer limitata nel kernel e se si scrivono molti dati contemporaneamente si potrebbe finire per bloccare senza significato. Se è probabile che si tratti di un problema, utilizzare IO non bloccante con open("/dev/...", O_RDWR | O_NONBLOCK). Il principio sarà lo stesso in entrambi i modi.


Sto provando sudo echo Hello > /dev/tty4quando mi trovo nell'ambiente desktop ma ottengo bash: /dev/tty4: Permission deniedse non ho effettuato l'accesso a tty4. Tuttavia, se ho effettuato l'accesso a tty4, tutto funziona correttamente. Qual è la ragione di ciò?
Utku,

@Utku, Questo è certamente una sorta di problema di autorizzazioni che vengono rimosse dopo l'autenticazione con il terminale virtuale. Controlla i permessi dei file prima e dopo aver effettuato l'accesso.ls -l /dev/tty4
Sherherell

1
la > /dev/tty4parte non fa parte del echosottoprocesso avviato da sudoma parte del sudoprocesso stesso, che viene eseguito dall'utente corrente. si applicano le autorizzazioni di file per l'utente corrente anziché root.
Robin479,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.