chiark / gitweb /
Bugfixes; adnstest has ability to use poll(2), and user can set initflags;
authorian <ian>
Sun, 11 Jul 1999 18:15:10 +0000 (18:15 +0000)
committerian <ian>
Sun, 11 Jul 1999 18:15:10 +0000 (18:15 +0000)
checkall prints passed list as well as failed list, if any failed.

changelog
client/adnstest.c
regress/checkall
src/adns.h
src/event.c
src/poll.c

index 207c322f1d0f1277c81f4ff8624a0538456bf43d..2944a038f7b4f58b500acf1cddf187521daee155 100644 (file)
--- a/changelog
+++ b/changelog
@@ -9,6 +9,8 @@ adns (0.3) unstable; urgency=low
   * New adns_errabbrev() for getting status abbreviation strings.
   * regress/checkall prints summary list of failed tests, if any.
   * Event loop functions for poll(2), and some raw variants.
+  * adnstest has ability to use poll(2), and user can set initflags.
+  * checkall prints passed list as well as failed list, if any failed.
   
   Bugfixes:
   * Non-RFC822 mailbox `domain' formatting now works, and clarified.
index 52344d1475a5a4c0118049022bdb2bbc433ada4e..a293d3b1eb6e6102c3af028c352f242f2f3fd550 100644 (file)
@@ -26,6 +26,8 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+#include <sys/poll.h>
 
 #ifndef OUTPUTSTREAM
 # define OUTPUTSTREAM stdout
@@ -91,6 +93,10 @@ static void fdom_split(const char *fdom, const char **dom_r, int *qf_r,
   *ownflags= 0;
 }
 
+static int consistsof(const char *string, const char *accept) {
+  return strspn(string,accept) == strlen(string);
+}
+
 int main(int argc, char *const *argv) {
   adns_state ads;
   adns_query *qus, qu;
@@ -98,19 +104,42 @@ int main(int argc, char *const *argv) {
   const char *initstring, *rrtn, *fmtn;
   const char *const *fdomlist, *domain;
   char *show, *cp;
-  int len, i, qc, qi, tc, ti, ch, qflags;
+  int len, i, qc, qi, tc, ti, ch, qflags, initflagsnum, npollfds, npollfdsavail, timeout;
+  struct pollfd *pollfds;
   adns_status r, ri;
   const adns_rrtype *types;
   struct timeval now;
   adns_rrtype *types_a;
   char ownflags[10];
+  char *ep;
+  const char *initflags, *owninitflags;
 
+  if (argv[0] && argv[1] && argv[1][0] == '-') {
+    initflags= argv[1]+1;
+    argv++;
+  } else {
+    initflags= "";
+  }
   if (argv[0] && argv[1] && argv[1][0] == '/') {
     initstring= argv[1]+1;
     argv++;
   } else {
     initstring= 0;
   }
+
+  initflagsnum= strtoul(initflags,&ep,0);
+  if (*ep == ',') {
+    owninitflags= ep+1;
+    if (!consistsof(owninitflags,"p")) {
+      fputs("unknown owninitflag\n",stderr);
+      exit(4);
+    }
+  } else if (!*ep) {
+    owninitflags= "";
+  } else {
+    fputs("bad <initflagsnum>[,<owninitflags>]\n",stderr);
+    exit(4);
+  }
   
   if (argv[0] && argv[1] && argv[1][0] == ':') {
     for (cp= argv[1]+1, tc=1; (ch= *cp); cp++)
@@ -121,7 +150,12 @@ int main(int argc, char *const *argv) {
       types_a[ti]= strtoul(cp,&cp,10);
       if ((ch= *cp)) {
        if (ch != ',') {
-         fputs("usage: dtest [/<initstring>] [:<typenum>,...] [<domain> ...]\n",stderr);
+         fputs("usage: adnstest [-<initflagsnum>[,<owninitflags>]] [/<initstring>]\n"
+               "              [ :<typenum>,... ]\n"
+               "              [ [<queryflagsnum>[,<ownqueryflags>]/]<domain> ... ]\n"
+               "initflags:   p  use poll(2) instead of select(2)\n"
+               "queryflags:  a  print status abbrevs instead of strings\n",
+               stderr);
          exit(4);
        }
        cp++;
@@ -143,14 +177,25 @@ int main(int argc, char *const *argv) {
   if (!qus) { perror("malloc qus"); exit(3); }
 
   if (initstring) {
-    r= adns_init_strcfg(&ads,adns_if_debug|adns_if_noautosys,stdout,initstring);
+    r= adns_init_strcfg(&ads,
+                       (adns_if_debug|adns_if_noautosys)^initflagsnum,
+                       stdout,initstring);
   } else {
-    r= adns_init(&ads,adns_if_debug|adns_if_noautosys,0);
+    r= adns_init(&ads,
+                (adns_if_debug|adns_if_noautosys)^initflagsnum,
+                0);
   }
   if (r) failure_errno("init",r);
 
+  npollfdsavail= 0;
+  pollfds= 0;
+  
   for (qi=0; qi<qc; qi++) {
     fdom_split(fdomlist[qi],&domain,&qflags,ownflags,sizeof(ownflags));
+    if (!consistsof(ownflags,"a")) {
+      fputs("unknown ownqueryflag\n",stderr);
+      exit(4);
+    }
     for (ti=0; ti<tc; ti++) {
       fprintf(stdout,"%s flags %d type %d",domain,qflags,types[ti]);
       r= adns_submit(ads,domain,types[ti],qflags,0,&qus[qi*tc+ti]);
@@ -174,9 +219,29 @@ int main(int argc, char *const *argv) {
     for (ti=0; ti<tc; ti++) {
       qu= qus[qi*tc+ti];
       if (!qu) continue;
-      
-      r= adns_wait(ads,&qu,&ans,0);
-      if (r) failure_errno("wait",r);
+
+      if (strchr(owninitflags,'p')) {
+       for (;;) {
+         r= adns_check(ads,&qu,&ans,0);
+         if (r != EWOULDBLOCK) break;
+         for (;;) {
+           npollfds= npollfdsavail;
+           timeout= -1;
+           r= adns_beforepoll(ads, pollfds, &npollfds, &timeout, 0);
+           if (r != ERANGE) break;
+           pollfds= realloc(pollfds,sizeof(*pollfds)*npollfds);
+           if (!pollfds) failure_errno("realloc pollfds",errno);
+           npollfdsavail= npollfds;
+         }
+         if (r) failure_errno("beforepoll",r);
+         r= poll(pollfds,npollfds,timeout);
+         if (r == -1) failure_errno("poll",errno);
+         adns_afterpoll(ads,pollfds, r?npollfds:0, 0);
+       }
+      } else {
+       r= adns_wait(ads,&qu,&ans,0);
+      }
+      if (r) failure_errno("wait/check",r);
 
       if (gettimeofday(&now,0)) { perror("gettimeofday"); exit(3); }
       
@@ -185,7 +250,8 @@ int main(int argc, char *const *argv) {
       dumptype(ri,rrtn,fmtn);
       fprintf(stdout, "%s%s: %s; nrrs=%d; cname=%s; owner=%s; ttl=%ld\n",
              ownflags[0] ? " ownflags=" : "", ownflags,
-             strchr(ownflags,'a') ? adns_errabbrev(ans->status)
+             strchr(ownflags,'a')
+             ? adns_errabbrev(ans->status)
              : adns_strerror(ans->status),
              ans->nrrs,
              ans->cname ? ans->cname : "$",
index 9412247dd83a6207ace66b54e7e2d3cf03de4d25..0765eab89b9539d166e6dad083b866f50c658b2b 100755 (executable)
@@ -1,13 +1,14 @@
 #!/bin/sh
 
 failed=''
+passed=''
 
 for f in case-*.sys
 do
        case="`echo \"$f\" | sed -e 's/^case-//; s/\.sys$//'`"
        if ./r1test $case
        then
-               :
+               passed="$passed $case"
        else
                echo
                failed="$failed $case"
@@ -24,7 +25,8 @@ fi
 
 echo >&2 "
 AT LEAST ONE TEST FAILED
-$failed
+passed tests:${passed:- NONE}
+failed tests:$failed
 "
 
 exit 1
index ce92c8b2d614da3ae6de048b9e9208a0e878504c..190142b75e539caeb44261932bcea76744d33e94 100644 (file)
@@ -479,30 +479,35 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo
  * listen for more structs then *nfds_io will be set to the number
  * required and _beforepoll will return ERANGE.
  *
- * NOTE that if now is 0, adns may acquire additional fds from one
- * call to the next, so you must put adns_beforepoll in a loop, rather
- * than assuming that the second call (with the buffer size requested
- * by the first) will not return ERANGE.
- *
  * You may call _beforepoll with fds==0 and *nfds_io 0, in which case
  * adns will fill in the number of fds that it might be interested in
- * in *nfds_io, and always return 0.
+ * in *nfds_io, and always return either 0 (if it is not interested in
+ * any fds) or ERANGE (if it is).
+ *
+ * NOTE that (unless timeout_io is 0) adns may acquire additional fds
+ * from one call to the next, so you must put adns_beforepoll in a
+ * loop, rather than assuming that the second call (with the buffer
+ * size requested by the first) will not return ERANGE.
  *
  * adns only ever sets POLLIN, POLLOUT and POLLPRI in its pollfd
  * structs, and only ever looks at those bits.  POLLPRI is required to
- * detect TCP Urgent Data, which should not be used by a DNS server,
+ * detect TCP Urgent Data (which should not be used by a DNS server)
  * so that adns can know that the TCP stream is now useless.
  *
  * In any case, *timeout_io should be a timeout value as for poll(2),
  * which adns will modify downwards as required.  If the caller does
- * not plan to block then *timeout_io should be 0 on entry.
+ * not plan to block then *timeout_io should be 0 on entry, or
+ * alternatively, timeout_io may be 0.  (Alternatively, the caller may
+ * use _beforeselect with timeout_io==0 to find out about file
+ * descriptors, and use _firsttimeout is used to find out when adns
+ * might want to time something out.)
  *
  * adns_beforepoll will return 0 on success, and will not fail for any
  * reason other than the fds buffer being too small (ERANGE).
  *
- * If *now is not 0 then this call will never actually do any I/O, or
- * change the fds that adns is using or the timeouts it wants.  In any
- * case it won't block.
+ * This call will never actually do any I/O, or change the fds that
+ * adns is using or the timeouts it wants; and in any case it won't
+ * block.
  */
 
 #define ADNS_POLLFDS_RECOMMENDED 2
index d54d8479c38151b36e914f298b99e99af1922491..1b527a2fff26a414aa5cc4a5cdc2bc04a23572b8 100644 (file)
@@ -454,12 +454,16 @@ void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io,
 void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds,
                      const fd_set *writefds, const fd_set *exceptfds,
                      const struct timeval *now) {
+  struct timeval tv_buf;
   struct pollfd pollfds[MAX_POLLFDS];
-  int npollfds;
+  int npollfds, i;
 
+  adns__must_gettimeofday(ads,&now,&tv_buf);
+  if (!now) return;
   adns_processtimeouts(ads,now);
 
   npollfds= adns__pollfds(ads,pollfds);
+  for (i=0; i<npollfds; i++) pollfds[i].revents= POLLIN|POLLOUT|POLLPRI;
   adns__fdevents(ads,
                 pollfds,npollfds,
                 maxfd,readfds,writefds,exceptfds,
index 03f153a0b3849612a0b427ee7d5b1063c794f3c7..f4b9e05590cdd5c4db69911a98b72d7a7f47c3d9 100644 (file)
@@ -32,29 +32,31 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo
   int space, found, timeout_ms;
   struct pollfd fds_tmp[MAX_POLLFDS];
 
-  adns__must_gettimeofday(ads,&now,&tv_nowbuf);
-  if (!now) { *nfds_io= 0; return 0; }
+  if (timeout_io) {
+    adns__must_gettimeofday(ads,&now,&tv_nowbuf);
+    if (!now) { *nfds_io= 0; return 0; }
 
-  timeout_ms= *timeout_io;
-  if (timeout_ms == -1) {
-    tv_to= 0;
-  } else {
-    tv_tobuf.tv_sec= timeout_ms / 1000;
-    tv_tobuf.tv_usec= (timeout_ms % 1000)*1000;
-    tv_to= &tv_tobuf;
-  }
+    timeout_ms= *timeout_io;
+    if (timeout_ms == -1) {
+      tv_to= 0;
+    } else {
+      tv_tobuf.tv_sec= timeout_ms / 1000;
+      tv_tobuf.tv_usec= (timeout_ms % 1000)*1000;
+      tv_to= &tv_tobuf;
+    }
 
-  adns__timeouts(ads, 1, &tv_to,&tv_tobuf, *now);
+    adns__timeouts(ads, 0, &tv_to,&tv_tobuf, *now);
 
-  if (tv_to) {
-    assert(tv_to == &tv_tobuf);
-    timeout_ms= (tv_tobuf.tv_usec+999)/1000;
-    assert(tv_tobuf.tv_sec < (INT_MAX-timeout_ms)/1000);
-    timeout_ms += tv_tobuf.tv_sec*1000;
-  } else {
-    timeout_ms= -1;
+    if (tv_to) {
+      assert(tv_to == &tv_tobuf);
+      timeout_ms= (tv_tobuf.tv_usec+999)/1000;
+      assert(tv_tobuf.tv_sec < (INT_MAX-timeout_ms)/1000);
+      timeout_ms += tv_tobuf.tv_sec*1000;
+    } else {
+      timeout_ms= -1;
+    }
+    *timeout_io= timeout_ms;
   }
-  *timeout_io= timeout_ms;
   
   space= *nfds_io;
   if (space >= MAX_POLLFDS) {
@@ -63,7 +65,7 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo
   } else {
     found= adns__pollfds(ads,fds_tmp);
     *nfds_io= found;
-    if (found < space) return space ? ERANGE : 0;
+    if (space < found) return ERANGE;
     memcpy(fds,fds_tmp,sizeof(struct pollfd)*found);
   }
   return 0;
@@ -76,7 +78,7 @@ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds,
   adns__must_gettimeofday(ads,&now,&tv_buf);
   if (!now) return;
 
-  adns__timeouts(ads,1, 0,0, *now);
+  adns__timeouts(ads, 1, 0,0, *now);
   adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0);
 }