--- /dev/null
+m4_dnl harness.h.m4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - function and other declarations
+
+m4_dnl This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 2, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation,
+m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+m4_include(hmacros.i4)
+
+#ifndef HARNESS_H_INCLUDED
+#define HARNESS_H_INCLUDED
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+/* We override several system calls with #define's */
+
+hm_create_proto_h
+m4_define(`hm_syscall', `int H$1(hm_args_massage($3,void));')
+m4_include(`hsyscalls.i4')
+
+/* There is a Q function (Q for Question) for each such syscall;
+ * it constructs a string representing the call, and calls Q_str
+ * on it, or constructs it in vb and calls Q_vb;
+ */
+
+hm_create_proto_q
+m4_define(`hm_syscall', `void Q$1(hm_args_massage($3,void));')
+m4_include(`hsyscalls.i4')
+
+void Q_vb(void);
+
+/* General help functions */
+
+void Tfailed(const char *why);
+void Toutputerr(void);
+void Tnomem(void);
+void Tfsyscallr(const char *fmt, ...) PRINTFFORMAT(1,2);
+void Tensureoutputfile(void);
+void Tmust(const char *call, const char *arg, int cond);
+
+void Tvbf(const char *fmt, ...) PRINTFFORMAT(1,2);
+void Tvbvf(const char *fmt, va_list al);
+void Tvbfdset(int max, const fd_set *set);
+void Tvbaddr(const struct sockaddr *addr, int addrlen);
+void Tvbbytes(const void *buf, int len);
+void Tvberrno(int e);
+void Tvba(const char *str);
+
+/* Shared globals */
+
+extern vbuf vb;
+extern FILE *Toutputfile;
+
+extern const struct Terrno { const char *n; int v; } Terrnos[];
+
+#endif
-/*
- * hcommon.c
- * - complex test harness, routines used for both record and playback
- */
-/*
- * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
- *
- * 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
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
+m4_dnl hcommon.c
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - routines used for both record and playback
+
+m4_dnl This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 2, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation,
+m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+m4_include(hmacros.i4)
#include <fcntl.h>
#include <string.h>
{ 0, 0 }
};
-void Qgettimeofday(void) {
- Q_str("gettimeofday()");
-}
-
-void Qselect(int n, const fd_set *rfds, const fd_set *wfds, const fd_set *efds,
- const struct timeval *to) {
- vb.used= 0;
- Tvbf("select(%d,",n);
- Tvbfdset(n,rfds);
- Tvba(",");
- Tvbfdset(n,wfds);
- Tvba(",");
- Tvbfdset(n,efds);
- if (to) {
- Tvbf(", %ld.%06ld)",to->tv_sec,to->tv_usec);
- } else {
- Tvba(", NULL)");
- }
- Q_vb();
-}
-
-void Qsocket(int type) {
- switch (type) {
- case SOCK_STREAM: Q_str("socket(,SOCK_STREAM,)"); break;
- case SOCK_DGRAM: Q_str("socket(,SOCK_DGRAM,)"); break;
- default: abort();
- }
-}
-
-void Qfcntl_setfl(int fd, int cmd, long arg) {
- vb.used= 0;
- Tvbf("fcntl(%d, F_SETFL, %ld)",fd,arg);
- Q_vb();
-}
-
-void Qfcntl_other(int fd, int cmd) {
- assert(cmd==F_GETFL);
- vb.used= 0;
- Tvbf("fcntl(%d, F_GETFL)",fd);
- Q_vb();
-}
-void Qconnect(int fd, struct sockaddr *addr, int addrlen) {
- vb.used= 0;
- Tvbf("connect(%d, ",fd);
- Tvbaddr(addr,addrlen);
- Tvba(")");
- Q_vb();
-}
-void Qclose(int fd) {
- vb.used= 0;
- Tvbf("close(%d)",fd);
- Q_vb();
-}
-void Qsendto(int fd, const void *msg, int msglen,
- const struct sockaddr *addr, int addrlen) {
- vb.used= 0;
- Tvbf("sendto(%d,,,, ",fd);
- Tvbaddr(addr,addrlen);
- Tvba(")");
- Tvbbytes(msg,msglen);
- Q_vb();
-}
+m4_define(`hm_syscall', `
+ hm_create_proto_q
+void Q$1(hm_args_massage($3,void)) {
+
+ vb.used= 0;
+ Tvba("$1");
+ m4_define(`hm_na',`')
+ m4_define(`hm_arg_nullptr',`')
+ m4_define(`hm_arg_int', `Tvbf(" $'`1=%d",$'`1);')
+ m4_define(`hm_arg_fdset_io', `Tvbf(" $'`1="); Tvbfdset($'`2,$'`1);')
+ m4_define(`hm_arg_timeval_in_rel_null', `
+ if ($'`1) Tvbf(" $'`1=%ld.%06ld",(long)$'`1->tv_sec,(long)$'`1->tv_usec);
+ else Tvba(" $'`1=null");')
+ m4_define(`hm_arg_must', `')
+ m4_define(`hm_arg_socktype', `
+ Tvbf($'`1==SOCK_STREAM ? " $'`1=SOCK_STREAM" : " $'`1=SOCK_DGRAM");')
+ m4_define(`hm_arg_ign', `')
+ m4_define(`hm_arg_fd', `Tvbf(" $'`1=%d",$'`1);')
+ m4_define(`hm_arg_fcntl_cmd_arg', `
+ if ($'`1 == F_SETFL) {
+ Tvbf(" $'`1=F_SETFL %ld",arg);
+ } else {
+ Tvba(" $'`1=F_GETFL");
+ }')
+ m4_define(`hm_arg_addr_in', `Tvbaddr($'`1,$'`2);')
+ m4_define(`hm_arg_bytes_in', `Tvbbytes($'`2,$'`4);')
+ m4_define(`hm_arg_bytes_out', `Tvbf(" $'`4=%lu",(unsigned long)$'`4);')
+ m4_define(`hm_arg_addr_out', `Tvbf(" *$'`2=%d",$'`2);')
+ $3
-void Qrecvfrom(int fd, int buflen, int addrlen) {
- vb.used= 0;
- Tvbf("recvfrom(%d,,%d,,,%d)",fd,buflen,addrlen);
Q_vb();
}
+')
-void Qread(int fd, size_t len) {
- vb.used= 0;
- Tvbf("read(%d,,%lu)",fd,(unsigned long)len);
- Q_vb();
-}
-
-void Qwrite(int fd, const void *buf, size_t len) {
- vb.used= 0;
- Tvbf("write(%d,,)",fd);
- Tvbbytes(buf,len);
- Q_vb();
-}
+m4_include(`hsyscalls.i4')
void Tvbaddr(const struct sockaddr *addr, int len) {
assert(len==sizeof(struct sockaddr_in));
assert(ai->sin_family==AF_INET);
- Tvbf(" %s:%u",inet_ntoa(ai->sin_addr),htons(ai->sin_port));
+ Tvbf("%s:%u",inet_ntoa(ai->sin_addr),htons(ai->sin_port));
}
void Tvbbytes(const void *buf, int len) {
int i;
const char *comma= "";
- Tvba(" [");
+ Tvba("[");
for (i=0; i<max; i++) {
if (!FD_ISSET(i,fds)) continue;
Tvba(comma);
}
+void Tmust(const char *call, const char *arg, int cond) {
+ if (cond) return;
+ fprintf(stderr,"adns test harness: case not handled: system call %s, arg %s",call,arg);
+ exit(-1);
+}
+
void Tfailed(const char *why) {
fprintf(stderr,"adns test harness: failure: %s: %s\n",why,strerror(errno));
exit(-1);
--- /dev/null
+m4_dnl hmacros.h.m4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - common macros
+
+m4_dnl This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 2, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation,
+m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+m4_define(`hm_args_massage',
+ `m4_ifelse(
+ m4_patsubst(
+ $1,
+ `hm_comma\|[
+ ]+',
+ `'),
+ `',
+ `$2',
+ `
+ m4_patsubst(m4_patsubst(m4_patsubst(m4_translit($1, `
+ ',` '), `\(hm_comma *\)*$', `'), `^\( *hm_comma\)*', `'),
+ `\( *hm_comma *\)+',` hm_comma ')
+ ')')
+
+m4_define(`hm_create_nothing', `
+ m4_define(`hm_na',`')
+ m4_define(`hm_arg_timeval_out_abs', `')
+ m4_define(`hm_arg_nullptr', `')
+ m4_define(`hm_arg_int', `')
+ m4_define(`hm_arg_fdset_io', `')
+ m4_define(`hm_arg_timeval_in_rel_null',`')
+ m4_define(`hm_arg_must', `')
+ m4_define(`hm_arg_socktype',`')
+ m4_define(`hm_arg_ign', `')
+ m4_define(`hm_arg_fd', `')
+ m4_define(`hm_arg_fcntl_cmd_arg',`')
+ m4_define(`hm_arg_addr_in', `')
+ m4_define(`hm_arg_bytes_in', `')
+ m4_define(`hm_arg_bytes_out', `')
+ m4_define(`hm_arg_addr_out', `')
+')
+
+m4_define(`hm_create_proto_h',`
+ m4_define(`hm_na', `hm_comma')
+ m4_define(`hm_arg_timeval_out_abs', `struct timeval *$'`1')
+ m4_define(`hm_arg_nullptr', `$'`1 $'`2')
+ m4_define(`hm_arg_int', `int $'`1')
+ m4_define(`hm_arg_fdset_io', `fd_set *$'`1')
+ m4_define(`hm_arg_timeval_in_rel_null', `struct timeval *$'`1')
+ m4_define(`hm_arg_must', `$'`1 $'`2')
+ m4_define(`hm_arg_socktype', `int $'`1')
+ m4_define(`hm_arg_ign', `$'`1 $'`2')
+ m4_define(`hm_arg_fd', `int $'`1')
+ m4_define(`hm_arg_fcntl_cmd_arg', `int $'`1 hm_comma ...')
+ m4_define(`hm_arg_addr_in', `const struct sockaddr *$'`1 hm_comma int $'`2')
+ m4_define(`hm_arg_bytes_in', `const $'`1 *$'`2 hm_comma $'`3 $'`4')
+ m4_define(`hm_arg_bytes_out', `$'`1 *$'`2 hm_comma $'`3 $'`4')
+ m4_define(`hm_arg_addr_out', `struct sockaddr *$'`1 hm_comma int *$'`2')
+')
+
+m4_define(`hm_create_proto_q',`
+ hm_create_proto_h
+ m4_define(`hm_arg_timeval_out_abs', `')
+ m4_define(`hm_arg_nullptr', `')
+ m4_define(`hm_arg_fdset_io', `const fd_set *$'`1')
+ m4_define(`hm_arg_must', `')
+ m4_define(`hm_arg_ign', `')
+ m4_define(`hm_arg_fcntl_cmd_arg', `int $'`1 hm_comma long $'`2')
+ m4_define(`hm_arg_bytes_out', `$'`3 $'`4')
+ m4_define(`hm_arg_addr_out', `int $'`2')
+')
+
+m4_define(`hm_create_hqcall_vars',`
+ hm_create_nothing
+ m4_define(`hm_arg_fcntl_cmd_arg',`va_list al; long $'`2;')
+')
+
+m4_define(`hm_create_hqcall_init',`
+ hm_create_nothing
+ m4_define(`hm_arg_nullptr', `Tmust("$1","$'`2",!$'`2);')
+ m4_define(`hm_arg_must', `Tmust("$1","$'`2",$'`2==$'`3);')
+ m4_define(`hm_arg_socktype',`
+ Tmust("$1","$'`1",$'`1==SOCK_STREAM || $'`1==SOCK_DGRAM);')
+ m4_define(`hm_arg_fcntl_cmd_arg',`
+ Tmust("$1","$'`1",$'`1==F_SETFL || $'`1==F_GETFL);
+ if ($'`1 == F_SETFL) {
+ va_start(al,$'`1); $'`2= va_arg(al,long); va_end(al);
+ } else {
+ $'`2= 0;
+ }')
+')
+
+m4_define(`hm_create_realcall_args',`
+ m4_define(`hm_na',`hm_comma')
+ m4_define(`hm_arg_timeval_out_abs', `$'`1')
+ m4_define(`hm_arg_nullptr', `0')
+ m4_define(`hm_arg_int', `$'`1')
+ m4_define(`hm_arg_fdset_io', `$'`1')
+ m4_define(`hm_arg_timeval_in_rel_null', `$'`1')
+ m4_define(`hm_arg_must', `$'`2')
+ m4_define(`hm_arg_socktype', `$'`1')
+ m4_define(`hm_arg_ign', `$'`2')
+ m4_define(`hm_arg_fd', `$'`1')
+ m4_define(`hm_arg_fcntl_cmd_arg', `$'`1 hm_comma $'`2')
+ m4_define(`hm_arg_addr_in', `$'`1 hm_comma $'`2')
+ m4_define(`hm_arg_bytes_in', `$'`2 hm_comma $'`4')
+ m4_define(`hm_arg_bytes_out', `$'`2 hm_comma $'`4')
+ m4_define(`hm_arg_addr_out', `$'`1 hm_comma $'`2')
+')
+
+m4_define(`hm_create_hqcall_args',`
+ hm_create_realcall_args
+ m4_define(`hm_arg_timeval_out_abs', `')
+ m4_define(`hm_arg_nullptr', `')
+ m4_define(`hm_arg_must', `')
+ m4_define(`hm_arg_ign', `')
+ m4_define(`hm_arg_bytes_in', `$'`2 hm_comma $'`4')
+ m4_define(`hm_arg_bytes_out', `$'`4')
+ m4_define(`hm_arg_addr_out', `*$'`2')
+')
--- /dev/null
+m4_dnl hrecord.c.m4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - recording routines
+
+m4_dnl This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 2, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation,
+m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+m4_include(hmacros.i4)
+
+#include <assert.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "harness.h"
+
+static int begin_set;
+static struct timeval begin;
+
+void Q_vb(void) {
+ if (!adns__vbuf_append(&vb,"",1)) Tnomem();
+ Tensureoutputfile();
+ if (fprintf(Toutputfile," %s\n",vb.buf) == EOF) Toutputerr();
+ if (fflush(Toutputfile)) Toutputerr();
+}
+
+static void R_vb(void) {
+ Q_vb();
+}
+
+m4_define(`hm_syscall', `
+ hm_create_proto_h
+int H$1(hm_args_massage($3,void)) {
+ int r, e;
+
+ hm_create_hqcall_vars
+ $3
+
+ hm_create_hqcall_init($1)
+ $3
+
+ hm_create_hqcall_args
+ Q$1(hm_args_massage($3));
+
+ hm_create_realcall_args
+ r= $1(hm_args_massage($3));
+ e= errno;
+
+ vb.used= 0;
+ Tvba("$1=");
+ m4_define(`hm_rv_any',`
+ if (r==-1) { Tvberrno(e); goto x_error; }
+ Tvbf("%d",r);')
+ m4_define(`hm_rv_fd',`hm_rv_any($'`1)')
+ m4_define(`hm_rv_succfail',`
+ if (r) { Tvberrno(e); goto x_error; }
+ Tvba("OK");')
+ m4_define(`hm_rv_must',`Tmust("$1","return",!r);')
+ m4_define(`hm_rv_len',`
+ if (r==-1) { Tvberrno(e); goto x_error; }
+ Tmust("$1","return",r<=$'`1);
+ Tvbf("%d",r);')
+ $2
+
+ hm_create_nothing
+ m4_define(`hm_arg_fdset_io',`Tvba(" $'`1="); Tvbfdset($'`2,$'`1);')
+ m4_define(`hm_arg_addr_out',`Tvba(" $'`1="); Tvbaddr($'`1,*$'`2);')
+ m4_define(`hm_arg_timeval_out_abs',`
+ if (!begin_set) {
+ Tvbf(" $'`1=%ld.%06ld",$'`1->tv_sec,$'`1->tv_usec);
+ begin= *$'`1;
+ begin_set= 1;
+ } else {
+ struct timeval diff;
+ diff.tv_sec= $'`1->tv_sec - begin.tv_sec;
+ diff.tv_usec= $'`1->tv_usec - begin.tv_usec;
+ if (diff.tv_usec < 0) {
+ diff.tv_sec -= 1;
+ diff.tv_usec += 1000000;
+ }
+ assert(diff.tv_sec >= 0);
+ assert(diff.tv_usec >= 0);
+ Tvbf(" $'`1=+%ld.%06ld",diff.tv_sec,diff.tv_usec);
+ }')
+ $3
+
+ hm_create_nothing
+ m4_define(`hm_arg_bytes_out',`Tvbbytes($'`2,r);')
+ $3
+
+ m4_define(`hm_rv_any',`x_error:')
+ m4_define(`hm_rv_fd',`x_error:')
+ m4_define(`hm_rv_succfail',`x_error:')
+ m4_define(`hm_rv_len',`x_error:')
+ m4_define(`hm_rv_must',`')
+ $2
+
+ R_vb();
+ errno= e;
+ return r;
+}
+')
+
+m4_include(`hsyscalls.i4')
--- /dev/null
+m4_dnl hsyscalls.i4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - list of syscalls to override/log and their args
+
+m4_dnl This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 2, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation,
+m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+m4_dnl each system call has
+m4_dnl hm_syscall(<name>,<returnvalue>,<args>
+m4_dnl <returnvalue> is one of
+m4_dnl hm_rv_must must succeed and return 0
+m4_dnl hm_rv_any any nonnegative return allowed, -1 means see errno
+m4_dnl hm_rv_fd file descriptor is returned, -1 means see errno
+m4_dnl hm_rv_succfail returns 0 (ok) or -1 (see errno)
+m4_dnl hm_rv_len(<max>) returns length read/written, must be <=max, -1 => errno
+m4_dnl <args> is list of macros for arguments, each followed by hm_na
+m4_dnl hm_arg_timeval_out_abs(<arg>) struct timeval, absolute time is returned
+m4_dnl hm_arg_nullptr(<type>,<arg>) pointer of type type, must be null
+m4_dnl hm_arg_int(<arg>) signed integer
+m4_dnl hm_arg_fdset_io(<arg>,<max>) fd_set, max bit set is in max
+m4_dnl hm_arg_timeval_in_rel_null(<t>) struct timeval*, pass in, relative, may be null
+m4_dnl hm_arg_must(<type>,<arg>,<val>) must have correct value, or abort test
+m4_dnl hm_arg_socktype(<arg>) SOCK_STREAM or SOCK_DGRAM (an int)
+m4_dnl hm_arg_ign(<type>,<arg>) input parameter ignored
+m4_dnl hm_arg_fd(<arg>) fd
+m4_dnl hm_arg_fcntl_cmd_arg(<ca>,<aa>) syscall is fcntl, do special processing
+m4_dnl hm_arg_addr_in(<arg>,<len>) struct sockaddr*, length given by <len> (an int)
+m4_dnl hm_arg_bytes_in(<objtype>,<objarg>,<lentype>,<lenarg>)
+m4_dnl some data from caller; <objarg> is of type pointer to const <objtype>
+m4_dnl and points to <lenarg> bytes (<lenarg> is of type <lentype>)
+m4_dnl hm_arg_bytes_out(<objtype>,<objarg>,<lentype>,<buflenarg>)
+m4_dnl buffer for data from syscall; <objarg> is of type pointer to const <objtype>
+m4_dnl and points to at least <lenarg> bytes (<lenarg> is of type <lentype>)
+m4_dnl return value from syscall is supposed to be returned length
+m4_dnl hm_arg_addr_out(<arg>,<lenptr>) struct sockaddr*, length io at <lenptr> (an int*)
+
+hm_syscall(
+ gettimeofday, `hm_rv_must', `
+ hm_arg_timeval_out_abs(tv) hm_na
+ hm_arg_nullptr(struct timezone*, tz) hm_na
+')
+
+hm_syscall(
+ select, `hm_rv_any', `
+ hm_arg_int(max) hm_na
+ hm_arg_fdset_io(rfds,max) hm_na
+ hm_arg_fdset_io(wfds,max) hm_na
+ hm_arg_fdset_io(efds,max) hm_na
+ hm_arg_timeval_in_rel_null(to) hm_na
+')
+
+hm_syscall(
+ socket, `hm_rv_fd', `
+ hm_arg_must(int,domain,AF_INET) hm_na
+ hm_arg_socktype(type) hm_na
+ hm_arg_ign(int,protocol) hm_na
+')
+
+hm_syscall(
+ fcntl, `hm_rv_any', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_fcntl_cmd_arg(cmd,arg) hm_na
+')
+
+hm_syscall(
+ connect, `hm_rv_succfail', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_addr_in(addr,addrlen) hm_na
+')
+
+hm_syscall(
+ close, `hm_rv_succfail', `
+ hm_arg_fd(fd) hm_na
+')
+
+hm_syscall(
+ sendto, `hm_rv_any', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_bytes_in(void,msg,int,msglen) hm_na
+ hm_arg_must(unsigned int,flags,0) hm_na
+ hm_arg_addr_in(addr,addrlen) hm_na
+')
+
+hm_syscall(
+ recvfrom, `hm_rv_len(buflen)', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_bytes_out(void,buf,int,buflen) hm_na
+ hm_arg_must(unsigned int,flags,0) hm_na
+ hm_arg_addr_out(addr,addrlen) hm_na
+')
+
+hm_syscall(
+ read, `hm_rv_len(buflen)', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_bytes_out(void,buf,size_t,buflen) hm_na
+')
+
+hm_syscall(
+ write, `hm_rv_any', `
+ hm_arg_fd(fd) hm_na
+ hm_arg_bytes_in(void,buf,size_t,len) hm_na
+')
-/*
- * hrecord.c
- * - complex test harness, recording routines
- */
-/*
- * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
- *
- * 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
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <assert.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "harness.h"
-
-static int begin_set;
-static struct timeval begin;
-
-void Q_str(const char *str) {
- Tensureoutputfile();
- if (fprintf(Toutputfile," %s\n",str) == EOF) Toutputerr();
- if (fflush(Toutputfile)) Toutputerr();
-}
-void Q_vb(void) {
- if (!adns__vbuf_append(&vb,"",1)) Tnomem();
- Q_str(vb.buf);
-}
-static void Rvb(void) {
- Q_vb();
-}
-
-static void Rf(const char *fmt, ...) PRINTFFORMAT(1,2);
-static void Rf(const char *fmt, ...) {
- va_list al;
- va_start(al,fmt);
- Tvbvf(fmt,al);
- va_end(al);
- Rvb();
-}
+m4_define(`hm_arg_timeval_out_abs', `')
+m4_define(`hm_arg_nullptr', `')
+m4_define(`hm_arg_fdset_io', `const fd_set *$1 $3')
+m4_define(`hm_arg_must', `')
+m4_define(`hm_arg_ign', `')
+m4_define(`hm_arg_fcntl_arg', `long arg')
+m4_define(`hm_arg_bytes_out', `$3 $4 $6')
+m4_define(`hm_arg_addr_out', `int $2 $3')
+
+
+m4_define(`hm_syscall', `void Q$1(hm_args_checkvoid(`$3'));')
+
+
-static void Rerrno(const char *call) {
- int e;
- e= errno;
- Tvbf("%s ",call);
- Tvberrno(e);
- Rvb();
- errno= e;
-}
int Hgettimeofday(struct timeval *tv, struct timezone *tz) {
int r;
return r;
}
+
+
+
+
+
+
%_d.o: %.c
$(CC) $(HCPPFLAGS) -c -g -o $@ $<
+%:: %.m4 hmacros.i4 hsyscalls.i4
+ m4 -P $< >$@-a.new
+ sed -e 's/hm_comma/,/g; s/hm_squote/'\''/g; /^[ ]*$$/d' <$@-a.new >$@-b.new
+ @mv -f $@-b.new $@; rm -f $@-a.new
+
clean:
- rm -f dtest *.o
+ rm -f dtest *.o harness.h hrecord.c hcommon.c
-$(HARNLOBJS): adns.h internal.h
-$(LIBOBJS): adns.h internal.h
-dtest.o: adns.h
+hrecord.o hcommon.o: adns.h internal.h harness.h
+$(HARNLOBJS): adns.h internal.h
+$(LIBOBJS): adns.h internal.h
+dtest.o: adns.h
%_d.o: %.c
$(CC) $(HCPPFLAGS) -c -g -o $@ $<
+%:: %.m4 hmacros.i4 hsyscalls.i4
+ m4 -P $< >$@-a.new
+ sed -e 's/hm_comma/,/g; s/hm_squote/'\''/g; /^[ ]*$$/d' <$@-a.new >$@-b.new
+ @mv -f $@-b.new $@; rm -f $@-a.new
+
clean:
- rm -f dtest *.o
+ rm -f dtest *.o harness.h hrecord.c hcommon.c
-$(HARNLOBJS): adns.h internal.h
-$(LIBOBJS): adns.h internal.h
-dtest.o: adns.h
+hrecord.o hcommon.o: adns.h internal.h harness.h
+$(HARNLOBJS): adns.h internal.h
+$(LIBOBJS): adns.h internal.h
+dtest.o: adns.h
+++ /dev/null
-/*
- * harness.h
- * - complex test harness function declarations, not part of the library
- */
-/*
- * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
- *
- * 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
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef HARNESS_H_INCLUDED
-#define HARNESS_H_INCLUDED
-
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "internal.h"
-
-/* We override several system calls with #define's */
-
-int Hgettimeofday(struct timeval *tv, struct timezone *tz);
-int Hselect(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *to);
-
-int Hsocket(int domain, int type, int protocol);
-int Hfcntl(int fd, int cmd, ...);
-int Hconnect(int fd, struct sockaddr *addr, int addrlen);
-int Hclose(int fd);
-
-int Hsendto(int fd, const void *msg, int msglen, unsigned int flags,
- const struct sockaddr *addr, int addrlen);
-int Hrecvfrom(int fd, void *buf, int buflen, unsigned int flags,
- struct sockaddr *addr, int *addrlen);
-
-int Hread(int fd, void *buf, size_t len);
-int Hwrite(int fd, const void *buf, size_t len);
-
-/* There is a Q function (Q for Question) for each such syscall;
- * it constructs a string representing the call, and calls Q_str
- * on it, or constructs it in vb and calls Q_vb;
- */
-
-void Qgettimeofday(void);
-void Qselect(int n, const fd_set *rfds, const fd_set *wfds, const fd_set *efds,
- const struct timeval *to);
-
-void Qsocket(int type);
-void Qfcntl_setfl(int fd, int cmd, long arg);
-void Qfcntl_other(int fd, int cmd);
-void Qconnect(int fd, struct sockaddr *addr, int addrlen);
-void Qclose(int fd);
-
-void Qsendto(int fd, const void *msg, int msglen,
- const struct sockaddr *addr, int addrlen);
-void Qrecvfrom(int fd, int buflen, int addrlen);
-
-void Qread(int fd, size_t len);
-void Qwrite(int fd, const void *buf, size_t len);
-
-void Q_str(const char *str);
-void Q_vb(void);
-
-/* General help functions */
-
-void Tfailed(const char *why);
-void Toutputerr(void);
-void Tnomem(void);
-void Tfsyscallr(const char *fmt, ...) PRINTFFORMAT(1,2);
-void Tensureoutputfile(void);
-
-void Tvbf(const char *fmt, ...) PRINTFFORMAT(1,2);
-void Tvbvf(const char *fmt, va_list al);
-void Tvbfdset(int max, const fd_set *set);
-void Tvbaddr(const struct sockaddr *addr, int addrlen);
-void Tvbbytes(const void *buf, int len);
-void Tvberrno(int e);
-void Tvba(const char *str);
-
-/* Shared globals */
-
-extern vbuf vb;
-extern FILE *Toutputfile;
-
-extern const struct Terrno { const char *n; int v; } Terrnos[];
-
-#endif