Tty * cihazına nasıl okunur / yazılır?


29

Bilgisayarıma USB üzerinden bilgi gönderen bir aygıtım var. Arch Linux, bu aygıtı ttyUSB0içinde adlı bir dosya oluşturarak ayarlar /dev/. Ben kullanıyorum GTKtermbu gelen bilgileri almak ve bir taklit terminal penceresinde görüntülemek için.

Sorum şu, GTKtermbu ttyUSB0dosyayı tam olarak nasıl okuyor / yazıyor ve benzer işlevleri nasıl uygulayabileceğimi nereden öğrenebilirim? Bu, en temel haliyle, nasıl bir karakter yazabilirim ttyUSB0, ya da tam tersine, bir bayt alabilir ve onu bir dosyaya yazabilirim?


1
Kediyi okumaya ve yazmaya yankı vermeye çalışın. "Her şey bir dosyadır" unix :)
dchirikov

Üzerinde seri konsol açmayı deneyebilirsiniz. screenbunu yapabilir veminiterm
mikeserv

Programatik bir yaklaşım açısından düşünüyordum. Bu doğruysa ve gerçekten bu kadar kolaysa (dosyayı açıp okuyabilmek için), önceki zamandan beri yeni veriler bulunduğunda dosyayı sürekli açmak, okumak, kapatmak ve güncellemek için sonsuz bir döngü yazar mıydınız? Eğer 'tty' cihazı programınızda açıksa dosyaya yazmaya çalışırsa ne olur?
sherrellbc

Yardımcı olabilir: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () ve select (). Özel bir şey yok, öyle görünüyor.
dchirikov

@sherrellbc - Sen screenve / veya minitermprogramatik olarak komut dosyası olabilir .
mikeserv

Yanıtlar:


38

TTY'ler, tıpkı diğerleri gibi kullanabileceğiniz dosyalardır. Bunları, dilinizin standart dosya açma araçlarıyla açabilir ve onlardan okuyabilir veya yazabilirsiniz. "Sıradan" dosyalardan farklı bazı özel davranışları var, ancak temelleri aynı. Sonunda bazı özel durumları ele alacağım, ama önce bir deney.

Normal bir terminalden yapabileceğiniz ilginç bir şey. Çalıştırın ttyve şöyle bir satır yazdıracak:

/dev/pts/2

Bu, terminalinizin çalıştığı TTY cihazı. Bu terminale bir şeyler yazabilirsiniz:

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

Hatta ondan okuyabilirsiniz:

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

( read Xsh'ın "standart girdiden X değişkenine bir satır oku" komutudur; <okuma komutu için / dev / pts / 2 komutunu standart girdi olarak kullanmaktır; ilk "merhaba" yazdım ve ikincisi yazdırıldı) .

Başka bir kabuk açarsanız, screenya da ' yı kullanarak söyleyin , metnin orijinal terminalinizde görünmesini sağlamak için o kabukta xtermkoşabilirsiniz echo spooky > /dev/pts/2, diğer komutlarda da aynıdır. Bütün bunlar sadece bir kabuğun bir TTY olduğunu bilmeden bir dosyayı açmasıdır.


İstediğiniz şeyi yapan ve / dev / pts / 3'e tek bir karakter yazan, sonra ondan tek bir bayt okuyan çok basit bir C programı:

#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;
}

Bir kabuk veya terminal emülatörüne bağlanan gerçek bir TTY cihazı, burada ilginç davranış sergileyecektir, ancak bir şeyi geri almalısınız.


Bir terminale erişmek için kullanmak için izniniz olması gerekir. Bunlar sadece gördüğünüz ls -lve birlikte ayarladığınız standart dosya izinleridir chmod: dosyayı açmak ve okumak için okuma iznine ve yazmak için izin yazmanız gerekir. Terminalinizi destekleyen TTY'ler size ait olacak, ancak başka bir kullanıcının TTY'si olmayacak ve yapılandırmanıza bağlı olarak USB aygıtları için TTY'ler olabilir veya olmayabilir. İzinleri her zaman olduğu gibi değiştirebilirsiniz.

Onunla çalışmak için bir program yazarken, çok özel bir şey yapmanıza gerek kalmaz. Örnekte, yapmanız gerekmeyen bir şeyin , verilerinizin diğer ucundan okunması için her seferinde dosyayı kapatması olduğunu görebilirsiniz: TTY dosyaları, her iki yönde de olduğu gibi veri ileterek boru hatları gibi davranır. TTY'ye metin yazdığımda hemen belirdi ve daha sonra okuduğumda beni bekleyen hiçbir şey yoktu. O var olmayan veri diske kurtulur düzenli dosyaya yazmak gibi - bu diğer tarafa hemen geçti, ya da birisi onu okuyana kadar hafızada depolanır.

Seçim işlevini kullanmak isteyebilirsiniz, böylece cihazın bir şey söylemesini beklerken başka şeyler yapabilirsiniz, ancak verilerin gelmesini beklediğinizden memnunsanız, sadece blok okuyanları kullanabilir ve işletim sisteminin yapmasına izin verebilirsiniz. kaldırma.

Akılda tutulması gereken bir şey, çekirdekte sınırlı arabellek boyutu olabileceği ve bir kerede çok fazla veri yazarsanız, anlamsız bir şekilde engellemeye son verebileceğinizdir. Bu bir sorun olma ihtimali varsa, kullanmak IO olmayan engelleme ile open("/dev/...", O_RDWR | O_NONBLOCK). Prensip aynı şekilde olacaktır.


sudo echo Hello > /dev/tty4Masaüstü ortamındayken deniyorum , ancak bash: /dev/tty4: Permission deniedtty4'te oturum açmamışsam alıyorum. Ancak, tty4'te oturum açtıysam, her şey yolunda gider. Bunun sebebi nedir?
Utku

@Utku, Bu kesinlikle sanal terminal ile yapılan onaylamadan sonra kaldırılan bir nevi izin problemi. Oturum açmadan önce ve sonra dosya izinlerini kontrol edin.ls -l /dev/tty4
sherrellbc

1
Bu > /dev/tty4kısım, echobaşlatılan alt işlemin bir sudoparçası değil sudo, mevcut kullanıcı tarafından yürütülen işlemin bir parçasıdır . geçerli kullanıcı için dosya izinleri root yerine uygulanır.
Robin479
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.