POLLNVAL berarti nilai deskriptor file tidak valid. Ini biasanya menunjukkan kesalahan dalam program Anda, tetapi Anda dapat mengandalkan poll mengembalikan POLLNVAL jika Anda telah menutup deskriptor file dan belum membuka file apa pun sejak saat itu, file tersebut mungkin telah menggunakan kembali deskriptor tersebut.
POLLERR mirip dengan peristiwa kesalahan dari select . Ini menunjukkan bahwa read atau write panggilan akan mengembalikan kondisi kesalahan (misalnya kesalahan I/O). Ini tidak termasuk data out-of-band yang select sinyal melalui errorfds miliknya mask tapi poll sinyal melalui POLLPRI .
POLLHUP pada dasarnya berarti bahwa apa yang ada di ujung koneksi telah menutup ujung koneksinya. POSIX mendeskripsikannya sebagai
Perangkat telah terputus. Acara dan POLLOUT ini saling eksklusif; aliran tidak akan pernah dapat ditulis jika hangup telah terjadi.
Ini cukup jelas untuk sebuah terminal:terminal telah hilang (kejadian yang sama yang menghasilkan SIGHUP:sesi modem telah dihentikan, jendela emulator terminal telah ditutup, dll.). POLLHUP tidak pernah dikirim untuk file biasa. Untuk pipa dan soket, tergantung sistem operasinya. Linux menyetel POLLHUP ketika program di ujung tulisan pipa menutup pipa, dan menyetel POLLIN|POLLHUP ketika ujung soket yang lain menutup soket, tetapi POLLIN hanya untuk shutdown soket. *BSD terbaru mengatur POLLIN|POLLUP ketika ujung tulisan pipa menutup pipa, dan perilaku soket lebih bervariasi.
A POLLHUP berarti soket tidak lagi terhubung. Di TCP, ini berarti FIN telah diterima dan dikirim.
A POLLERR berarti soket mendapat kesalahan asinkron. Di TCP, ini biasanya berarti RST telah diterima atau dikirim. Jika deskriptor file bukan soket, POLLERR mungkin berarti perangkat tidak mendukung polling.
Untuk kedua kondisi di atas, deskriptor file soket masih terbuka, dan belum ditutup (tetapi shutdown() mungkin sudah dipanggil). A close() pada deskriptor file akan melepaskan sumber daya yang masih dicadangkan atas nama soket. Secara teori, soket dapat segera digunakan kembali (mis., dengan connect() lain panggilan).
A POLLNVAL berarti deskriptor file soket tidak terbuka. Ini akan menjadi kesalahan untuk close() itu.
Itu tergantung pada sifat kesalahan yang tepat. Gunakan getockopt() untuk melihat masalahnya:
int error = 0;
socklen_t errlen = sizeof(error);
getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
Nilai:http://www.xinotes.net/notes/note/1793/
Cara termudah adalah dengan mengasumsikan bahwa soket tidak lagi dapat digunakan dalam hal apa pun dan menutupnya.
Contoh FIFO minimal
Setelah Anda memahami kapan kondisi tersebut terjadi, seharusnya mudah untuk mengetahui apa yang harus dilakukan dengan kondisi tersebut.
poll.c
#define _XOPEN_SOURCE 700
#include <fcntl.h> /* creat, O_CREAT */
#include <poll.h> /* poll */
#include <stdio.h> /* printf, puts, snprintf */
#include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */
#include <unistd.h> /* read */
int main(void) {
char buf[1024];
int fd, n;
short revents;
struct pollfd pfd;
fd = open("poll0.tmp", O_RDONLY | O_NONBLOCK);
pfd.fd = fd;
pfd.events = POLLIN;
while (1) {
puts("loop");
poll(&pfd, 1, -1);
revents = pfd.revents;
if (revents & POLLIN) {
n = read(pfd.fd, buf, sizeof(buf));
printf("POLLIN n=%d buf=%.*s\n", n, n, buf);
}
if (revents & POLLHUP) {
printf("POLLHUP\n");
close(pfd.fd);
pfd.fd *= -1;
}
if (revents & POLLNVAL) {
printf("POLLNVAL\n");
}
if (revents & POLLERR) {
printf("POLLERR\n");
}
}
}
GitHub upstream.
Kompilasi dengan:
gcc -o poll.out -std=c99 poll.c
Penggunaan:
sudo mknod -m 666 poll0.tmp p
./poll.out
Di shell lain:
printf a >poll0.tmp
POLLHUP
Jika Anda tidak mengubah sumbernya:./poll.out keluaran:
loop
POLLIN n=1 buf=a
loop
POLLHUP
loop
Jadi:
POLLINterjadi saat input tersediaPOLLHUPterjadi ketika file ditutup olehprintfclose(pfd.fd);danpfd.fd *= -1;bersihkan semuanya, dan kami berhenti menerimaPOLLHUPpollhang selamanya
Ini adalah operasi normal.
Anda sekarang dapat mengembalikan FIFO untuk menunggu open berikutnya , atau keluar dari loop jika sudah selesai.
POLLNAL
Jika Anda berkomentar pfd.fd *= -1; :./poll.out cetakan:
POLLIN n=1 buf=a
loop
POLLHUP
loop
POLLNVAL
loop
POLLNVAL
...
dan berulang selamanya.
Jadi:
POLLINdanPOLLHUPdancloseterjadi seperti sebelumnya- karena kami tidak menyetel
pfd.fdke angka negatif,pollterus mencoba menggunakanfdyang kami tutup - ini terus menampilkan
POLLNVALselamanya
Jadi kami melihat bahwa ini seharusnya tidak terjadi, dan menunjukkan adanya bug dalam kode Anda.
POLLERR
Saya tidak tahu cara membuat POLLERR dengan FIFO. Beri tahu saya jika ada jalan. Tapi seharusnya bisa dengan file_operations driver perangkat.
Diuji di Ubuntu 14.04.