X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fpoll.c;h=60ff6ecf26f2c5dacc465e013ef22bf03db381ac;hb=7b4b431450c6056f7d419d28951194517f0f0b03;hp=7b1054a9560e337c483e8d62395a110744079ae4;hpb=28de64428cfdb63ad07acfcfc254907b608d5137;p=adns.git diff --git a/src/poll.c b/src/poll.c index 7b1054a..60ff6ec 100644 --- a/src/poll.c +++ b/src/poll.c @@ -3,7 +3,11 @@ * - wrappers for poll(2) */ /* - * This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson + * This file is part of adns, which is + * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1999-2000,2003,2006 Tony Finch + * Copyright (C) 1991 Massachusetts Institute of Technology + * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,13 +25,14 @@ */ #include +#include #include "internal.h" #ifdef HAVE_POLL -int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeout_io, - const struct timeval *now) { +int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, + int *timeout_io, const struct timeval *now) { struct timeval tv_nowbuf, tv_tobuf, *tv_to; int space, found, timeout_ms, r; struct pollfd fds_tmp[MAX_POLLFDS]; @@ -72,7 +77,7 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo } r= 0; xit: - adns__consistency(ads,0,cc_entex); + adns__returning(ads,0); return r; } @@ -86,7 +91,40 @@ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds, adns__timeouts(ads, 1, 0,0, *now); adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0); } + adns__returning(ads,0); +} + +int adns_wait_poll(adns_state ads, + adns_query *query_io, + adns_answer **answer_r, + void **context_r) { + int r, nfds, to; + struct pollfd fds[MAX_POLLFDS]; + adns__consistency(ads,0,cc_entex); + + for (;;) { + r= adns__internal_check(ads,query_io,answer_r,context_r); + if (r != EAGAIN) goto xit; + nfds= MAX_POLLFDS; to= -1; + adns_beforepoll(ads,fds,&nfds,&to,0); + r= poll(fds,nfds,to); + if (r == -1) { + if (errno == EINTR) { + if (ads->iflags & adns_if_eintr) { r= EINTR; goto xit; } + } else { + adns__diag(ads,-1,0,"poll failed in wait: %s",strerror(errno)); + adns_globalsystemfailure(ads); + } + } else { + assert(r >= 0); + adns_afterpoll(ads,fds,nfds,0); + } + } + + xit: + adns__returning(ads,0); + return r; } #endif