Last active
December 14, 2015 23:59
-
-
Save depressed-pho/5169980 to your computer and use it in GitHub Desktop.
kqueue-poll-select
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% uname -a | |
FreeBSD nem.cielonegro.org 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #0: Tue Jan 5 16:02:27 UTC 2010 [email protected]:/usr/obj/usr/src/sys/GENERIC i386 | |
% ./kqueue-poll-select | |
Testing stdin... | |
Type of stdin: tty | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdin. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: tty | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdout. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. | |
% touch empty | |
% ./kqueue-poll-select < /dev/random > empty | |
Testing stdin... | |
Type of stdin: device | |
Checking if kqueue(2) works... | |
kevent(2) ifself succeeded but delivered us an EV_ERROR. This is how the old I/O | |
manager was fooled because it wasn't (and the newer one still don't) check this situation: Operation not supported by device | |
kevent(2) expectedly failed now. This time we didn't pass a non-NULL incoming event buffer. This is how the new I/O manager fails on this platform: Operation not supported by device | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: regular | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdout. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This is a test program to see if kqueue/poll/select can handle your | |
* stdin. | |
* | |
* compile: | |
* % g++ -o kqueue-poll-select kqueue-poll-select.cpp | |
* | |
* run: | |
* % ./kqueue-poll-select < WHATEVER-FILE-YOU-WANT-TO-TEST | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <sys/types.h> | |
#if !defined(__gnu_linux__) | |
#include <sys/event.h> | |
#endif | |
#include <sys/time.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <poll.h> | |
#include <sys/select.h> | |
#include <err.h> | |
void test_fd(int fd, const char* name, bool reading) { | |
/* Determine the type of fd */ | |
struct stat st; | |
if (fstat(fd, &st) < 0) { | |
err(1, name); | |
} | |
const char* type; | |
switch (st.st_mode & S_IFMT) { | |
case S_IFIFO: | |
type = "fifo"; | |
break; | |
case S_IFCHR: | |
if (isatty(fd)) { | |
type = "tty"; | |
} | |
else { | |
type = "device"; | |
} | |
break; | |
case S_IFREG: | |
type = "regular"; | |
break; | |
case S_IFSOCK: | |
type = "socket"; | |
break; | |
default: | |
type = "unknown"; | |
break; | |
} | |
fprintf(stderr, "Type of %s: %s\n", name, type); | |
#if !defined(__gnu_linux__) | |
fprintf(stderr, "\nChecking if kqueue(2) works...\n"); | |
int kq = kqueue(); | |
if (kq < 0) { | |
fprintf(stderr, "kqueue(2) somehow failed. This should not happen: %s\n", strerror(errno)); | |
} | |
else { | |
struct kevent change; | |
EV_SET(&change, fd, (reading ? EVFILT_READ : EVFILT_WRITE), EV_ADD, 0, 0, NULL); | |
struct timespec timeout; | |
timeout.tv_sec = 0; | |
timeout.tv_nsec = 0; | |
struct kevent event; | |
if (kevent(kq, &change, 1, &event, 1, &timeout) < 0) { | |
fprintf(stderr, "kevent(2) somehow failed even though we passed a non-NULL" | |
" incoming event buffer. This should not happen: %s\n", strerror(errno)); | |
} | |
else if (event.flags & EV_ERROR) { | |
errno = event.data; | |
fprintf(stderr, "kevent(2) ifself succeeded but delivered us an EV_ERROR." | |
" This is how the old I/O manager was fooled because it wasn't" | |
" (and the newer one still don't) check this situation: %s\n", strerror(errno)); | |
if (kevent(kq, &change, 1, NULL, 0, &timeout) < 0) { | |
fprintf(stderr, "kevent(2) expectedly failed now. This time we didn't pass a" | |
" non-NULL incoming event buffer. This is how the new I/O" | |
" manager fails on this platform: %s\n", strerror(errno)); | |
} | |
else { | |
fprintf(stderr, "kevent(2) somehow succeeded now. Why?: %s\n", strerror(errno)); | |
} | |
} | |
else { | |
fprintf(stderr, "Great. kevent(2) successfully handled your %s.\n", name); | |
} | |
} | |
#endif | |
fprintf(stderr, "\nChecking if poll(2) works...\n"); | |
struct pollfd pfd; | |
pfd.fd = fd; | |
pfd.events = (reading ? POLLIN : POLLOUT); | |
if (poll(&pfd, 1, 0) < 0) { | |
fprintf(stderr, "poll(2) somehow failed. This should not happen: %s\n", strerror(errno)); | |
} | |
else if (pfd.revents == POLLIN || pfd.revents == POLLOUT || pfd.revents == 0) { | |
fprintf(stderr, "Good. poll(2) successfully handled your %s.\n", name); | |
} | |
else if (pfd.revents == POLLNVAL) { | |
fprintf(stderr, "poll(2) itself succeeded but delivered us a POLLNVAL event." | |
" It can't handle your %s.\n", name); | |
} | |
else { | |
fprintf(stderr, "poll(2) itself succeeded but delivered us an unknown event." | |
" It seems poll(2) can't handle your %s: %d\n", name, (int)pfd.revents); | |
} | |
fprintf(stderr, "\nChecking if select(2) works...\n"); | |
fd_set rfd; | |
fd_set wfd; | |
FD_ZERO(&rfd); | |
FD_ZERO(&wfd); | |
if (reading) { | |
FD_SET(fd, &rfd); | |
} | |
else { | |
FD_SET(fd, &wfd); | |
} | |
struct timeval timeout; | |
timeout.tv_sec = 0; | |
timeout.tv_usec = 0; | |
if (select(fd + 1, &rfd, &wfd, NULL, &timeout) < 0) { | |
fprintf(stderr, "select(2) can't handle your %s. This is terrible...:", name, strerror(errno)); | |
} | |
else { | |
fprintf(stderr, "OK. select(2) successfully handled your %s.\n", name); | |
} | |
} | |
int main() { | |
fprintf(stderr, "Testing stdin...\n"); | |
test_fd(STDIN_FILENO , "stdin" , true ); | |
fprintf(stderr, "\nTesting stdout...\n"); | |
test_fd(STDOUT_FILENO, "stdout", false); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% uname -a | |
Darwin aria.cielonegro.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:57:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_PPC Power Macintosh | |
% ./kqueue-poll-select | |
Testing stdin... | |
Type of stdin: tty | |
Checking if kqueue(2) works... | |
kevent(2) ifself succeeded but delivered us an EV_ERROR. This is how the old I/O | |
manager was fooled because it wasn't (and the newer one still don't) check this | |
situation: Operation not supported | |
kevent(2) expectedly failed now. This time we didn't pass a non-NULL incoming ev | |
ent buffer. This is how the new I/O manager fails on this platform: Operation no | |
t supported | |
Checking if poll(2) works... | |
poll(2) itself succeeded but delivered us a POLLNVAL event. It can't handle your | |
stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: tty | |
Checking if kqueue(2) works... | |
kevent(2) ifself succeeded but delivered us an EV_ERROR. This is how the old I/O manager was fooled because it wasn't (and the newer one still don't) check this situation: Operation not supported | |
kevent(2) expectedly failed now. This time we didn't pass a non-NULL incoming event buffer. This is how the new I/O manager fails on this platform: Operation not supported | |
Checking if poll(2) works... | |
poll(2) itself succeeded but delivered us a POLLNVAL event. It can't handle your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. | |
% touch empty | |
% ./kqueue-poll-select < empty > empty | |
Testing stdin... | |
Type of stdin: regular | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdin. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: regular | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdout. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% uname -a | |
Linux boss 2.6.16.27-0.6-smp #1 SMP Wed Dec 13 09:34:50 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux | |
% ./kqueue-poll-select | |
Testing stdin... | |
Type of stdin: tty | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: tty | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. | |
% touch empty | |
% ./kqueue-poll-select < /dev/random > empty | |
Testing stdin... | |
Type of stdin: device | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: regular | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% uname -a | |
NetBSD seras 6.99.17 NetBSD 6.99.17 (VMWARE) #1: Fri Feb 15 13:06:57 JST 2013 pho@seras:/usr/obj/sys/arch/amd64/compile/VMWARE amd64 | |
% ./kqueue-poll-select | |
Testing stdin... | |
Type of stdin: tty | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdin. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: tty | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdout. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. | |
% touch empty | |
% ./kqueue-poll-select < /dev/random > empty | |
Testing stdin... | |
Type of stdin: device | |
Checking if kqueue(2) works... | |
Great. kevent(2) successfully handled your stdin. | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdin. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdin. | |
Testing stdout... | |
Type of stdout: regular | |
Checking if kqueue(2) works... | |
kevent(2) ifself succeeded but delivered us an EV_ERROR. This is how the old I/O manager was fooled because it wasn't (and the newer one still don't) check this situation: Invalid argument | |
kevent(2) expectedly failed now. This time we didn't pass a non-NULL incoming event buffer. This is how the new I/O manager fails on this platform: Invalid argument | |
Checking if poll(2) works... | |
Good. poll(2) successfully handled your stdout. | |
Checking if select(2) works... | |
OK. select(2) successfully handled your stdout. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment