6 #include <sys/socket.h>
7 #include <netinet/in.h>
15 struct timeval currenttime
;
16 const struct Terrno Terrnos
[]= {
19 { "EINPROGRESS", EINPROGRESS
},
22 { "EMSGSIZE", EMSGSIZE
},
23 { "ENOBUFS", ENOBUFS
},
25 { "ENOPROTOOPT", ENOPROTOOPT
},
27 { "EWOULDBLOCK", EWOULDBLOCK
},
28 { "EHOSTUNREACH", EHOSTUNREACH
},
29 { "ECONNRESET", ECONNRESET
},
30 { "ECONNREFUSED", ECONNREFUSED
},
32 { "ENOTSOCK", ENOTSOCK
},
36 int Hgettimeofday(struct timeval
*tv
, struct timezone
*tz
) {
38 Tmust("gettimeofday","tz",!tz
);
42 int Hwritev(int fd
, const struct iovec
*vector
, size_t count
) {
45 for (i
=0; i
<count
; i
++, vector
++) {
46 if (!adns__vbuf_append(&vbw
,vector
->iov_base
,vector
->iov_len
)) Tnomem();
48 return Hwrite(fd
,vbw
.buf
,vbw
.used
);
50 void Qselect( int max
, const fd_set
*rfds
, const fd_set
*wfds
, const fd_set
*efds
, struct timeval
*to
) {
54 Tvbf(" rfds="); Tvbfdset(max
,rfds
);
55 Tvbf(" wfds="); Tvbfdset(max
,wfds
);
56 Tvbf(" efds="); Tvbfdset(max
,efds
);
57 if (to
) Tvbf(" to=%ld.%06ld",(long)to
->tv_sec
,(long)to
->tv_usec
);
58 else Tvba(" to=null");
62 void Qpoll( const struct pollfd
*fds
, int nfds
, int timeout
) {
65 Tvbf(" fds="); Tvbpollfds(fds
,nfds
);
66 Tvbf(" timeout=%d",timeout
);
70 void Qsocket( int domain
, int type
) {
73 Tvbf(domain
==PF_INET ?
" domain=PF_INET" :
74 domain
==PF_INET6 ?
" domain=PF_INET6" :
76 Tvbf(type
==SOCK_STREAM ?
" type=SOCK_STREAM" : " type=SOCK_DGRAM");
79 void Qfcntl( int fd
, int cmd
, long arg
) {
84 Tvbf(" cmd=F_SETFL %s",arg
& O_NONBLOCK ?
"O_NONBLOCK|..." : "~O_NONBLOCK&...");
85 } else if (cmd
== F_GETFL
) {
88 Tmust("cmd","F_GETFL/F_SETFL",0);
92 void Qconnect( int fd
, const struct sockaddr
*addr
, int addrlen
) {
96 Tvba(" addr="); Tvbaddr(addr
,addrlen
);
99 void Qbind( int fd
, const struct sockaddr
*addr
, int addrlen
) {
103 Tvba(" addr="); Tvbaddr(addr
,addrlen
);
106 void Qlisten( int fd
, int backlog
) {
110 Tvbf(" backlog=%d",backlog
);
113 void Qclose( int fd
) {
119 void Qsendto( int fd
, const void *msg
, int msglen
, const struct sockaddr
*addr
, int addrlen
) {
123 Tvba(" addr="); Tvbaddr(addr
,addrlen
);
124 Tvbbytes(msg
,msglen
);
127 void Qrecvfrom( int fd
, int buflen
, int addrlen
) {
131 Tvbf(" buflen=%lu",(unsigned long)buflen
);
134 void Qread( int fd
, size_t buflen
) {
138 Tvbf(" buflen=%lu",(unsigned long)buflen
);
141 void Qwrite( int fd
, const void *buf
, size_t len
) {
148 void Tvbaddr(const struct sockaddr
*addr
, int len
) {
149 char buf
[ADNS_ADDR2TEXT_BUFLEN
];
152 err
= adns_addr2text(addr
, 0, buf
,&sz
, &port
);
154 Tvbf(strchr(buf
, ':') ?
"[%s]:%d" : "%s:%d", buf
,port
);
156 void Tvbbytes(const void *buf
, int len
) {
159 if (!len
) { Tvba("\n ."); return; }
160 for (i
=0, bp
=buf
; i
<len
; i
++, bp
++) {
161 if (!(i
&31)) Tvba("\n ");
162 else if (!(i
&3)) Tvba(" ");
167 void Tvbfdset(int max
, const fd_set
*fds
) {
169 const char *comma
= "";
171 for (i
=0; i
<max
; i
++) {
172 if (!FD_ISSET(i
,fds
)) continue;
179 static void Tvbpollevents(int events
) {
180 const char *delim
= "";
181 events
&= (POLLIN
|POLLOUT
|POLLPRI
);
182 if (!events
) { Tvba("0"); return; }
183 if (events
& POLLIN
) { Tvba("POLLIN"); delim
= "|"; }
184 if (events
& POLLOUT
) { Tvba(delim
); Tvba("POLLOUT"); delim
= "|"; }
185 if (events
& POLLPRI
) { Tvba(delim
); Tvba("POLLPRI"); }
187 void Tvbpollfds(const struct pollfd
*fds
, int nfds
) {
188 const char *comma
= "";
192 Tvbf("{fd=%d, events=",fds
->fd
);
193 Tvbpollevents(fds
->events
);
195 Tvbpollevents(fds
->revents
);
202 void Tvberrno(int e
) {
203 const struct Terrno
*te
;
204 for (te
= Terrnos
; te
->n
&& te
->v
!= e
; te
++);
208 void Tvba(const char *str
) {
209 if (!adns__vbuf_appendstr(&vb
,str
)) Tnomem();
211 void Tvbvf(const char *fmt
, va_list al
) {
213 buf
[sizeof(buf
)-2]= '\t';
214 vsnprintf(buf
,sizeof(buf
),fmt
,al
);
215 assert(buf
[sizeof(buf
)-2] == '\t');
218 void Tvbf(const char *fmt
, ...) {
224 void Tmust(const char *call
, const char *arg
, int cond
) {
226 fprintf(stderr
,"adns test harness: case not handled: system call %s, arg %s",call
,arg
);
229 void Tfailed(const char *why
) {
230 fprintf(stderr
,"adns test harness: failure: %s: %s\n",why
,strerror(errno
));
234 Tfailed("unable to malloc/realloc");
236 void Toutputerr(void) {
237 Tfailed("write error on test harness output");
240 struct malloced
*next
, *back
;
243 struct { double d
; long ul
; void *p
; void (*fp
)(void); } data
;
245 static unsigned long malloccount
, mallocfailat
;
246 static struct { struct malloced
*head
, *tail
; } mallocedlist
;
247 #define MALLOCHSZ ((char*)&mallocedlist.head->data - (char*)mallocedlist.head)
248 void *Hmalloc(size_t sz
) {
249 struct malloced
*newnode
;
253 newnode
= malloc(MALLOCHSZ
+ sz
); if (!newnode
) Tnomem();
254 LIST_LINK_TAIL(mallocedlist
,newnode
);
256 newnode
->count
= ++malloccount
;
258 mfavar
= getenv("ADNS_REGRESS_MALLOCFAILAT");
260 mallocfailat
= strtoul(mfavar
,&ep
,10);
261 if (!mallocfailat
|| *ep
) Tfailed("ADNS_REGRESS_MALLOCFAILAT bad value");
266 assert(newnode
->count
!= mallocfailat
);
267 memset(&newnode
->data
,0xc7,sz
);
268 return &newnode
->data
;
270 void Hfree(void *ptr
) {
271 struct malloced
*oldnode
;
273 oldnode
= (void*)((char*)ptr
- MALLOCHSZ
);
274 LIST_UNLINK(mallocedlist
,oldnode
);
275 memset(&oldnode
->data
,0x38,oldnode
->sz
);
278 void *Hrealloc(void *op
, size_t nsz
) {
279 struct malloced
*oldnode
;
282 if (op
) { oldnode
= (void*)((char*)op
- MALLOCHSZ
); osz
= oldnode
->sz
; } else { osz
= 0; }
284 memcpy(np
,op
, osz
>nsz ? nsz
: osz
);
289 struct malloced
*loopnode
;
291 adns__vbuf_free(&vb
);
292 adns__vbuf_free(&vbw
);
293 if (mallocedlist
.head
) {
294 fprintf(stderr
,"adns test harness: memory leaked:");
295 for (loopnode
=mallocedlist
.head
; loopnode
; loopnode
=loopnode
->next
)
296 fprintf(stderr
," %lu",loopnode
->count
);
298 if (ferror(stderr
)) exit(-1);
302 pid_t
Hgetpid(void) {
303 return 2264; /* just some number */