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:
POLLIN
terjadi saat input tersediaPOLLHUP
terjadi ketika file ditutup olehprintf
close(pfd.fd);
danpfd.fd *= -1;
bersihkan semuanya, dan kami berhenti menerimaPOLLHUP
poll
hang 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:
POLLIN
danPOLLHUP
danclose
terjadi seperti sebelumnya- karena kami tidak menyetel
pfd.fd
ke angka negatif,poll
terus mencoba menggunakanfd
yang kami tutup - ini terus menampilkan
POLLNVAL
selamanya
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.