2010-08-15 12 views
8

Bir seri aygıttan (/ dev/ttyXX) okunduğunda birden fazla işleme sahip olmak, her iki işlemin de tüm verileri alamamasını sağlar - veriler bir şekilde aralarında bölünür. Bir seri aygıttan okuyan, birkaç master/slave pty çifti yaratan bir program yazmak istiyorum ve daha sonra, tüm okuma işlemlerinin veriyi alması için seri aygıttan ptys'den okumak için okunan programlara izin verir. Seri cihazdan ve ptys'in, seri cihaz gibi hareket etmesini sağlayarak, pty'den okumaya başladıklarında, sadece en yeni verileri alırlar. Diğer bir deyişle, okumaya başlamadan önce yazdığınız herhangi bir veriyi almazsınız (bu benim/dev/ttyXX aygıtlarının nasıl çalıştığını veya en azından okuma yaptığım RS-232 anemometresi). Adlandırılmış borular, SIGPIPE'yi herhangi bir okuyucunun bulunmadığını belirlemek için bu semantiği taklit edebilir ve böylece söz konusu adlandırılmış boruya yazmamayı seçebiliriz. Ancak, terminalleri kullanmak için yazılan bazı ikili dosyalar isatty() için denetimler olarak adlandırılır ve tcsetattr() gibi çağrılarda errno koşulu başarısız koşullara neden olabilir. Buradaki anahtar, bir terminal için yazılan mevcut ikili dosyaları kullanabilmektir.Birisi Linux'ta bir pty'nin (pseudo-terminal) köle tarafını açtığında nasıl anlayabilirim?

Yani, eğer pty'nin köle tarafının okuma için açıldığını algılayabiliyorsam, bu, adlandırılmış yöneltme durumunda SIGPIPE bulunmadığı gibi bana aynı anlambilimsel bilgiyi vermelidir. HP-UX'in TIOCTRAP'ın tam olarak istediğimi yaptığım gibi görünen bir ioctl() komutu olduğunu görüyorum, ancak ne yazık ki Linux'ta mevcut değil.

Günler için referanslar okuyorum ve bu tür bir şey için seçeneklerin sayısı şaşırtıcı. Cevap, terminal ayarlarında, engelleme/engelleme davranışında, tampon boyutlarının bir yerde ayarlanmasında, (+)/select() öğelerinden veya bazı kombinasyonlardan raporlanan koşullarda bulunabilir. Yine de hiçbir şey bulamıyorum. Kendi aygıt sürücümü yazmamın mümkün olup olmadığını merak ediyorum, ama bu kadar ileri gitmeden bunu yapabilmem gerekiyor gibi görünüyor. açıklama Yani

:
- Asıl soru: Nasıl birisi Linux bir pty (uçbirimsiler) köle tarafını açtığında algılayabilir?
- Okuyucunun piti açılmasından sonra kesinlikle yazılan verileri almak için pty'nin bağımlı tarafını açan bir okuyucu istiyorum (eğer çoklu yazma işlemim okuyucuyu köle tarafını açmadan önce bir süre veri yazıyorsa, veriler arabelleğe alınacaktır yukarı ve sonunda yazar bloke olacak ve köle okuyucu, açıldıktan sonra, hemen tüm tamponlanmış verileri alacaktır - bu, yalnızca anlık geçici ortamda üretilen verileri almak istediğim kadar istenmez)
- gerekir pty değil, isatty() ve tcsetattr() olarak adlandırılmış bir boru, soket, vb, vb olması gerekir, böylece var olan ikili dosyalar çalışacak şekilde

cevap

9

Bulamamanız nedeni, belgelendirilmiş olmamasıdır arabirim belirt ically izin vermek için. Ancak, bunu yapmanıza izin veren bir hile var.

close(open(ptsname(ptm), O_RDWR | O_NOCTTY)); 

Bu tty yöneticisinde HUP bayrağını ayarlar: uçbirimsi usta açtıktan sonra, açmak ve hemen köle tarafını kapatmak (dosya tanıtıcı ptm olmak için burada varsayılır). (Veri, veri kaynağından geliyor zaman, diyelim ki) Artık poll() düzenli HUP bayrağı anket: okuyucu hiç uzağa gider

struct pollfd pfd = { .fd = ptm, .events = POLLHUP }; 
poll(&pfd, 1, 10 /* or other small timeout */); 

if (!(pfd.revents & POLLHUP)) 
{ 
    /* There is now a reader on the slave side */ 
} 

ise POLLHUP yeniden ayarlanacak.Senin durumunda

, muhtemelen hatta bir döngüden verilen bir Pty bir okuyucu olup olmadığını sonraki hatırlamak gerekmez - sadece veri kaynağını read() engelle, daha sonra veri aynı anda, tüm poll() kullanılabilir olduğunda senin ana ttys ve POLLHUP seti olmayan herhangi birine veri gönderin.

+0

Açıklama için teşekkürler. Bu hileyi kaynak kodunda "socat" olarak bulmuştum ama köle tarafını açıp kapatmam gerektiğini fark etmemiştim. Hile anladıktan sonra bile, hala bazı saç-çekme bölümleri vardı çünkü açık bir şekilde açılış/dev/ptmx yerine openpty() yerine pts için ayrı, açık bir fd verdim ve böylece bir HUP durumu alamadım. başlangıçta. Openpty() 'yi çağırmak ve ondan dönen slave fd'yi kapatmak yeterlidir. Yanıt için tekrar teşekkürler. Belgelenmemiş özellik hakkında nasıl bilgi edindiniz? –

+0

Ben sadece usenet üzerinde posta (lar) yoluyla buldum. Bu soru, gelecekte insanlar için daha fazla Google’a sahip olmalı! – caf

3

Köle topuğuna bir nötr bir saat ekleyin ve bunun üzerine anket yapın. Açıkta bir etkinlik belirten etkinlik alabilirsiniz. Daha sonra, inotify dosya tanımlayıcısını ve master pty dosya tanımlayıcısını yoklayabilirsiniz. Açık için bir inotify olayı alabilirsiniz (IN_OPEN). Bu, köle tarafı açıldığında anketi engelini kaldıracaktır.

İlgili konular