chiark / gitweb /
regress: playback fuzzraw generator: Get errno and result generation right
[adns.git] / regress / hplayback.c.m4
index 2f961f749a52609e782966ed5c344ff0ae375fc2..46554d6d47ae305148352ea5e03d86b91494c048 100644 (file)
@@ -3,7 +3,8 @@ m4_dnl (part of complex test harness, not of the library)
 m4_dnl - playback routines
 
 m4_dnl  This file is part of adns, which is
-m4_dnl    Copyright (C) 1997-2000,2003,2006,2014  Ian Jackson
+m4_dnl    Copyright (C) 1997-2000,2003,2006,2014-2016,2020  Ian Jackson
+m4_dnl    Copyright (C) 2014  Mark Wooding
 m4_dnl    Copyright (C) 1999-2000,2003,2006  Tony Finch
 m4_dnl    Copyright (C) 1991 Massachusetts Institute of Technology
 m4_dnl  (See the file INSTALL for full details.)
@@ -36,16 +37,14 @@ m4_include(hmacros.i4)
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <limits.h>
+
 
 #include "harness.h"
 
-static FILE *Tinputfile, *Treportfile;
+static FILE *Tinputfile, *Tfuzzrawfile, *Treportfile;
 static vbuf vb2;
 
-extern void Tshutdown(void) {
-  adns__vbuf_free(&vb2);
-}
-
 static void Tensurereportfile(void) {
   const char *fdstr;
   int fd;
@@ -57,6 +56,36 @@ static void Tensurereportfile(void) {
   Treportfile= fdopen(fd,"a"); if (!Treportfile) Tfailed("fdopen ADNS_TEST_REPORT_FD");
 }
 
+static void Tensurefuzzrawfile(void) {
+  static int done;
+
+  if (done) return;
+  done++;
+
+  const char *fdstr= getenv("ADNS_TEST_FUZZRAW_DUMP_FD");
+  if (!fdstr) return;
+
+  int fd= atoi(fdstr);
+  Tfuzzrawfile= fdopen(fd,"ab");
+  if (!Tfuzzrawfile) Tfailed("fdopen ADNS_TEST_FUZZRAW_DUMP_FD");
+}
+
+static void FR_write(void *p, size_t sz) {
+  if (!Tfuzzrawfile) return;
+  ssize_t got = fwrite(p,1,sz,Tfuzzrawfile);
+  if (ferror(Tfuzzrawfile)) Tfailed("write fuzzraw output file");
+  assert(got==sz);
+}
+
+#define FR_WRITE(x) (FR_write(&(x), sizeof((x))))
+
+extern void Tshutdown(void) {
+  adns__vbuf_free(&vb2);
+  if (Tfuzzrawfile) {
+    if (fclose(Tfuzzrawfile)) Tfailed("close fuzzraw output file");
+  }
+}
+
 static void Psyntax(const char *where) {
   fprintf(stderr,"adns test harness: syntax error in test log input file: %s\n",where);
   exit(-1);
@@ -67,17 +96,23 @@ static void Pcheckinput(void) {
   if (feof(Tinputfile)) Psyntax("eof at syscall reply");
 }
 
+void T_gettimeofday_hook(void) {
+  static struct timeval previously;
+  struct timeval delta;
+  memset(&delta,0,sizeof(delta));
+  timersub(&currenttime, &previously, &delta);
+  FR_WRITE(delta);
+}
+
 void Tensurerecordfile(void) {
-  const char *fdstr;
   int fd;
   int chars;
   unsigned long sec, usec;
 
   if (Tinputfile) return;
   Tinputfile= stdin;
-  fdstr= getenv("ADNS_TEST_IN_FD");
-  if (fdstr) {
-    fd= atoi(fdstr);
+  fd = Ttestinputfd();
+  if (fd >= 0) {
     Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD");
   }
   setvbuf(Tinputfile,0,_IONBF,0);
@@ -125,6 +160,7 @@ static int Perrno(const char *stuff) {
   if (te->n) return te->v;
   r= strtoul(stuff+2,&ep,10);
   if (*ep) Psyntax("errno value not recognised, not numeric");
+  if (r==0 || r>255) Psyntax("numeric errno out of range 1..255");
   return r;
 }
 
@@ -147,17 +183,23 @@ static void P_updatetime(void) {
 }
 
 static void Pfdset(fd_set *set, int max) {
-  int r, c;
+  int c;
+  unsigned long ul;
   char *ep;
+
+  if (!set) {
+    Pstring("null","null fdset pointer");
+    return;
+  }
   
   if (vb2.buf[vb2.used++] != hm_squote[hm_squote) Psyntax("fd set start not [");
   FD_ZERO(set);
   if (vb2.buf[vb2.used] == hm_squote]hm_squote) { vb2.used++; return; }
   for (;;) {
-    r= strtoul(vb2.buf+vb2.used,&ep,10);
-    if (r>=max) Psyntax("fd set member > max");
+    ul= strtoul(vb2.buf+vb2.used,&ep,10);
+    if (ul>=max) Psyntax("fd set member > max");
     if (ep == (char*)vb2.buf+vb2.used) Psyntax("empty entry in fd set");
-    FD_SET(r,set);
+    FD_SET(ul,set);
     vb2.used= ep - (char*)vb2.buf;
     c= vb2.buf[vb2.used++];
     if (c == hm_squote]hm_squote) break;
@@ -319,6 +361,7 @@ int H$1(hm_args_massage($3,void)) {
  fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
 
  Tensurereportfile();
+ Tensurefuzzrawfile();
  fprintf(Treportfile,"%s",vb2.buf);
  amtread= strlen(vb2.buf);
  if (amtread<=0 || vb2.buf[--amtread]!=hm_squote\nhm_squote)
@@ -326,26 +369,48 @@ int H$1(hm_args_massage($3,void)) {
  vb2.buf[amtread]= 0;
  if (memcmp(vb2.buf," $1=",hm_r_offset)) Psyntax("syscall reply mismatch");
 
+ m4_define(`hm_rv_check_errno',`
  if (vb2.buf[hm_r_offset] == hm_squoteEhm_squote) {
   int e;
   e= Perrno(vb2.buf+hm_r_offset);
   P_updatetime();
   errno= e;
+  FR_WRITE(e);
   return -1;
  }
-
- m4_define(`hm_rv_succfail',`
+ r= 0;
+ FR_WRITE(r);
+ ')
+ m4_define(`hm_rv_check_success',`
   if (memcmp(vb2.buf+hm_r_offset,"OK",2)) Psyntax("success/fail not E* or OK");
   vb2.used= hm_r_offset+2;
   r= 0;
  ')
- m4_define(`hm_rv_len',`hm_rv_succfail')
- m4_define(`hm_rv_must',`hm_rv_succfail')
- m4_define(`hm_rv_any',`
-  r= strtoul(vb2.buf+hm_r_offset,&ep,10);
-  if (*ep && *ep!=hm_squote hm_squote) Psyntax("return value not E* or positive number");
+ m4_define(`hm_rv_any_nowrite',`
+  hm_rv_check_errno
+  unsigned long ul_r= strtoul(vb2.buf+hm_r_offset,&ep,10);
+  if (ul_r < 0 || ul_r > INT_MAX ||
+      (*ep && *ep!=hm_squote hm_squote))
+    Psyntax("return value not E* or positive number");
+  r= ul_r;
   vb2.used= ep - (char*)vb2.buf;
  ')
+
+ m4_define(`hm_rv_succfail',`
+  hm_rv_check_errno
+  hm_rv_check_success
+ ')
+ m4_define(`hm_rv_len',`
+  hm_rv_check_errno
+  hm_rv_check_success
+ ')
+ m4_define(`hm_rv_must',`
+  hm_rv_check_success
+ ')
+ m4_define(`hm_rv_any',`
+  hm_rv_any_nowrite
+  FR_WRITE(r);
+ ')
  m4_define(`hm_rv_fd',`hm_rv_any')
  m4_define(`hm_rv_fcntl',`
   r= 0;
@@ -375,7 +440,11 @@ int H$1(hm_args_massage($3,void)) {
  if (vb2.used != amtread) Psyntax("junk at end of line");
 
  hm_create_nothing
- m4_define(`hm_arg_bytes_out',`r= Pbytes($'`2,$'`4);')
+ m4_define(`hm_arg_bytes_out',`
+  r= Pbytes($'`2,$'`4);
+  FR_WRITE(r);
+  FR_write(buf,r);
+ ')
  $3
 
  P_updatetime();
@@ -386,3 +455,5 @@ int H$1(hm_args_massage($3,void)) {
 m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
+
+hm_stdsyscall_close