DragonFly bugs List (threaded) for 2007-12
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
[issue895] pselect(2) implementation
Nicolas Thery <nthery@gmail.com> added the comment:
Attached test suite.
----------
status: unread -> chatting
_____________________________________________________
DragonFly issue tracker <bugs@lists.dragonflybsd.org>
<http://bugs.dragonflybsd.org/issue895>
_____________________________________________________
/*
* Rudimentary test suite used while implementing pselect(2).
*/
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static int alarm_flag = 0;
static void
nop(int signo)
{
}
static void
set_alarm_flag(int signo)
{
alarm_flag = 1;
}
/*
* Try to detect regressions in select(2).
*/
static void
test_select()
{
fd_set rset;
fd_set wset;
struct timeval timeout;
int des[2];
int r;
char buf[1];
printf("test_select\n");
/*
* It is always possible to write to stdout (if not redirected).
*/
FD_ZERO(&wset);
FD_SET(1, &wset);
r = select(2, NULL, &wset, NULL, NULL);
assert(r == 1);
assert(FD_ISSET(1, &wset));
/*
* Write to a pipe and check a select on the read end does not block.
*/
r = pipe(des);
assert(r == 0);
FD_ZERO(&rset);
FD_SET(des[0], &rset);
buf[0] = 'f';
r = write(des[1], buf, 1);
assert(r == 1);
r = select(des[0]+1, &rset, NULL, NULL, NULL);
assert(r == 1);
assert(FD_ISSET(des[0], &rset));
r = read(des[0], buf, 1);
assert(r == 1);
assert(buf[0] == 'f');
/*
* Block until signal reception.
*/
signal(SIGALRM, nop);
alarm(1);
FD_ZERO(&rset);
FD_SET(des[0], &rset);
r = select(des[0]+1, &rset, NULL, NULL, NULL);
assert(r == -1);
assert(errno == EINTR);
/*
* Block until timeout.
*/
FD_ZERO(&rset);
FD_SET(des[0], &rset);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
r = select(des[0]+1, &rset, NULL, NULL, &timeout);
assert(r == 0);
/*
* When the timeout is zero, the call should not block.
*/
timeout.tv_sec = 0;
timeout.tv_usec = 0;
FD_ZERO(&rset);
FD_SET(des[0], &rset);
r = select(des[0]+1, &rset, NULL, NULL, &timeout);
assert(r == 0);
close(des[0]);
close(des[1]);
}
/*
* Very roughly exercise pselect(2).
*/
static void
test_pselect()
{
fd_set rset;
fd_set wset;
sigset_t blockset;
struct timespec timeout;
int des[2];
int r;
char buf[1];
printf("test_pselect\n");
/*
* It is always possible to write to stdout (if not redirected).
*/
FD_ZERO(&wset);
FD_SET(1, &wset);
r = pselect(2, NULL, &wset, NULL, NULL, NULL);
assert(r == 1);
assert(FD_ISSET(1, &wset));
/*
* Write to a pipe and check a select on the read end does not block.
*/
r = pipe(des);
assert(r == 0);
FD_ZERO(&rset);
FD_SET(des[0], &rset);
buf[0] = 'f';
r = write(des[1], buf, 1);
assert(r == 1);
r = pselect(des[0]+1, &rset, NULL, NULL, NULL, NULL);
assert(r == 1);
assert(FD_ISSET(des[0], &rset));
r = read(des[0], buf, 1);
assert(r == 1);
assert(buf[0] == 'f');
/*
* Block until signal reception.
*/
signal(SIGALRM, nop);
alarm(1);
FD_ZERO(&rset);
FD_SET(des[0], &rset);
r = pselect(des[0]+1, &rset, NULL, NULL, NULL, NULL);
assert(r == -1);
assert(errno == EINTR);
/*
* Block until timeout.
*/
FD_ZERO(&rset);
FD_SET(des[0], &rset);
timeout.tv_sec = 1;
timeout.tv_nsec = 0;
r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, NULL);
assert(r == 0);
/*
* When the timeout is zero, the call should not block.
*/
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
FD_ZERO(&rset);
FD_SET(des[0], &rset);
r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, NULL);
assert(r == 0);
/*
* When a signal is masked, the syscall is not interrupted and the
* signal is received on completion.
*/
sigemptyset(&blockset);
sigaddset(&blockset, SIGALRM);
signal(SIGALRM, set_alarm_flag);
alarm(1);
timeout.tv_sec = 2;
timeout.tv_nsec = 0;
r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, &blockset);
assert(r == 0);
assert(alarm_flag);
close(des[0]);
close(des[1]);
}
int
main(void)
{
test_select();
test_pselect();
return (0);
}
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]