| 1 | #include <assert.h> |
| 2 | #include <string.h> |
| 3 | #include <errno.h> |
| 4 | #include <stdlib.h> |
| 5 | #include <sys/types.h> |
| 6 | #include <unistd.h> |
| 7 | #include <fcntl.h> |
| 8 | #include "harness.h" |
| 9 | static FILE *Toutputfile; |
| 10 | void Tshutdown(void) { |
| 11 | } |
| 12 | static void R_recordtime(void) { |
| 13 | int r; |
| 14 | struct timeval tv, tvrel; |
| 15 | Tensurerecordfile(); |
| 16 | r= gettimeofday(&tv,0); if (r) Tfailed("gettimeofday syscallbegin"); |
| 17 | tvrel.tv_sec= tv.tv_sec - currenttime.tv_sec; |
| 18 | tvrel.tv_usec= tv.tv_usec - currenttime.tv_usec; |
| 19 | if (tv.tv_usec < 0) { tvrel.tv_usec += 1000000; tvrel.tv_sec--; } |
| 20 | Tvbf("\n +%ld.%06ld",(long)tvrel.tv_sec,(long)tvrel.tv_usec); |
| 21 | currenttime= tv; |
| 22 | } |
| 23 | void Tensurerecordfile(void) { |
| 24 | const char *fdstr; |
| 25 | int fd, r; |
| 26 | if (Toutputfile) return; |
| 27 | Toutputfile= stdout; |
| 28 | fdstr= getenv("ADNS_TEST_OUT_FD"); |
| 29 | if (fdstr) { |
| 30 | fd= atoi(fdstr); |
| 31 | Toutputfile= fdopen(fd,"a"); if (!Toutputfile) Tfailed("fdopen ADNS_TEST_OUT_FD"); |
| 32 | } |
| 33 | r= gettimeofday(¤ttime,0); if (r) Tfailed("gettimeofday syscallbegin"); |
| 34 | if (fprintf(Toutputfile," start %ld.%06ld\n", |
| 35 | (long)currenttime.tv_sec,(long)currenttime.tv_usec) == EOF) Toutputerr(); |
| 36 | } |
| 37 | void Q_vb(void) { |
| 38 | if (!adns__vbuf_append(&vb,"",1)) Tnomem(); |
| 39 | Tensurerecordfile(); |
| 40 | if (fprintf(Toutputfile," %s\n",vb.buf) == EOF) Toutputerr(); |
| 41 | if (fflush(Toutputfile)) Toutputerr(); |
| 42 | } |
| 43 | static void R_vb(void) { |
| 44 | Q_vb(); |
| 45 | } |
| 46 | int Hselect( int max , fd_set *rfds , fd_set *wfds , fd_set *efds , struct timeval *to ) { |
| 47 | int r, e; |
| 48 | Qselect( max , rfds , wfds , efds , to ); |
| 49 | r= select( max , rfds , wfds , efds , to ); |
| 50 | e= errno; |
| 51 | vb.used= 0; |
| 52 | Tvba("select="); |
| 53 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 54 | Tvbf("%d",r); |
| 55 | Tvba(" rfds="); Tvbfdset(max,rfds); |
| 56 | Tvba(" wfds="); Tvbfdset(max,wfds); |
| 57 | Tvba(" efds="); Tvbfdset(max,efds); |
| 58 | x_error: |
| 59 | R_recordtime(); |
| 60 | R_vb(); |
| 61 | errno= e; |
| 62 | return r; |
| 63 | } |
| 64 | #ifdef HAVE_POLL |
| 65 | int Hpoll( struct pollfd *fds , int nfds , int timeout ) { |
| 66 | int r, e; |
| 67 | Qpoll( fds , nfds , timeout ); |
| 68 | r= poll( fds , nfds , timeout ); |
| 69 | e= errno; |
| 70 | vb.used= 0; |
| 71 | Tvba("poll="); |
| 72 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 73 | Tvbf("%d",r); |
| 74 | Tvba(" fds="); Tvbpollfds(fds,nfds); |
| 75 | x_error: |
| 76 | R_recordtime(); |
| 77 | R_vb(); |
| 78 | errno= e; |
| 79 | return r; |
| 80 | } |
| 81 | #endif |
| 82 | int Hsocket( int domain , int type , int protocol ) { |
| 83 | int r, e; |
| 84 | Tmust("socket","domain",domain==AF_INET || domain==AF_INET6); |
| 85 | Tmust("socket","type",type==SOCK_STREAM || type==SOCK_DGRAM); |
| 86 | Qsocket( domain , type ); |
| 87 | r= socket( domain , type , protocol ); |
| 88 | e= errno; |
| 89 | vb.used= 0; |
| 90 | Tvba("socket="); |
| 91 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 92 | Tvbf("%d",r); |
| 93 | x_error: |
| 94 | R_recordtime(); |
| 95 | R_vb(); |
| 96 | errno= e; |
| 97 | return r; |
| 98 | } |
| 99 | int Hfcntl( int fd , int cmd , ... ) { |
| 100 | int r, e; |
| 101 | va_list al; long arg; |
| 102 | Tmust("fcntl","cmd",cmd==F_SETFL || cmd==F_GETFL); |
| 103 | if (cmd == F_SETFL) { |
| 104 | va_start(al,cmd); arg= va_arg(al,long); va_end(al); |
| 105 | } else { |
| 106 | arg= 0; |
| 107 | } |
| 108 | Qfcntl( fd , cmd , arg ); |
| 109 | r= fcntl( fd , cmd , arg ); |
| 110 | e= errno; |
| 111 | vb.used= 0; |
| 112 | Tvba("fcntl="); |
| 113 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 114 | if (cmd == F_GETFL) { |
| 115 | Tvbf(r & O_NONBLOCK ? "O_NONBLOCK|..." : "~O_NONBLOCK&..."); |
| 116 | } else { |
| 117 | if (cmd == F_SETFL) { |
| 118 | Tmust("fcntl","return",!r); |
| 119 | } else { |
| 120 | Tmust("cmd","F_GETFL/F_SETFL",0); |
| 121 | } |
| 122 | Tvba("OK"); |
| 123 | } |
| 124 | x_error: |
| 125 | R_recordtime(); |
| 126 | R_vb(); |
| 127 | errno= e; |
| 128 | return r; |
| 129 | } |
| 130 | int Hconnect( int fd , const struct sockaddr *addr , int addrlen ) { |
| 131 | int r, e; |
| 132 | Qconnect( fd , addr , addrlen ); |
| 133 | r= connect( fd , addr , addrlen ); |
| 134 | e= errno; |
| 135 | vb.used= 0; |
| 136 | Tvba("connect="); |
| 137 | if (r) { Tvberrno(e); goto x_error; } |
| 138 | Tvba("OK"); |
| 139 | x_error: |
| 140 | R_recordtime(); |
| 141 | R_vb(); |
| 142 | errno= e; |
| 143 | return r; |
| 144 | } |
| 145 | int Hbind( int fd , const struct sockaddr *addr , int addrlen ) { |
| 146 | int r, e; |
| 147 | Qbind( fd , addr , addrlen ); |
| 148 | r= bind( fd , addr , addrlen ); |
| 149 | e= errno; |
| 150 | vb.used= 0; |
| 151 | Tvba("bind="); |
| 152 | if (r) { Tvberrno(e); goto x_error; } |
| 153 | Tvba("OK"); |
| 154 | x_error: |
| 155 | R_recordtime(); |
| 156 | R_vb(); |
| 157 | errno= e; |
| 158 | return r; |
| 159 | } |
| 160 | int Hlisten( int fd , int backlog ) { |
| 161 | int r, e; |
| 162 | Qlisten( fd , backlog ); |
| 163 | r= listen( fd , backlog ); |
| 164 | e= errno; |
| 165 | vb.used= 0; |
| 166 | Tvba("listen="); |
| 167 | if (r) { Tvberrno(e); goto x_error; } |
| 168 | Tvba("OK"); |
| 169 | x_error: |
| 170 | R_recordtime(); |
| 171 | R_vb(); |
| 172 | errno= e; |
| 173 | return r; |
| 174 | } |
| 175 | int Hclose( int fd ) { |
| 176 | int r, e; |
| 177 | Qclose( fd ); |
| 178 | r= close( fd ); |
| 179 | e= errno; |
| 180 | vb.used= 0; |
| 181 | Tvba("close="); |
| 182 | if (r) { Tvberrno(e); goto x_error; } |
| 183 | Tvba("OK"); |
| 184 | x_error: |
| 185 | R_recordtime(); |
| 186 | R_vb(); |
| 187 | errno= e; |
| 188 | return r; |
| 189 | } |
| 190 | int Hsendto( int fd , const void *msg , int msglen , unsigned int flags , const struct sockaddr *addr , int addrlen ) { |
| 191 | int r, e; |
| 192 | Tmust("sendto","flags",flags==0); |
| 193 | Qsendto( fd , msg , msglen , addr , addrlen ); |
| 194 | r= sendto( fd , msg , msglen , flags , addr , addrlen ); |
| 195 | e= errno; |
| 196 | vb.used= 0; |
| 197 | Tvba("sendto="); |
| 198 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 199 | Tvbf("%d",r); |
| 200 | x_error: |
| 201 | R_recordtime(); |
| 202 | R_vb(); |
| 203 | errno= e; |
| 204 | return r; |
| 205 | } |
| 206 | int Hrecvfrom( int fd , void *buf , int buflen , unsigned int flags , struct sockaddr *addr , int *addrlen ) { |
| 207 | int r, e; |
| 208 | Tmust("recvfrom","flags",flags==0); |
| 209 | Tmust("recvfrom","*addrlen",*addrlen>=sizeof(struct sockaddr_in)); |
| 210 | Qrecvfrom( fd , buflen , *addrlen ); |
| 211 | r= recvfrom( fd , buf , buflen , flags , addr , addrlen ); |
| 212 | e= errno; |
| 213 | vb.used= 0; |
| 214 | Tvba("recvfrom="); |
| 215 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 216 | Tmust("recvfrom","return",r<=buflen); |
| 217 | Tvba("OK"); |
| 218 | Tvba(" addr="); Tvbaddr(addr,*addrlen); |
| 219 | Tvbbytes(buf,r); |
| 220 | x_error: |
| 221 | R_recordtime(); |
| 222 | R_vb(); |
| 223 | errno= e; |
| 224 | return r; |
| 225 | } |
| 226 | int Hread( int fd , void *buf , size_t buflen ) { |
| 227 | int r, e; |
| 228 | Qread( fd , buflen ); |
| 229 | r= read( fd , buf , buflen ); |
| 230 | e= errno; |
| 231 | vb.used= 0; |
| 232 | Tvba("read="); |
| 233 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 234 | Tmust("read","return",r<=buflen); |
| 235 | Tvba("OK"); |
| 236 | Tvbbytes(buf,r); |
| 237 | x_error: |
| 238 | R_recordtime(); |
| 239 | R_vb(); |
| 240 | errno= e; |
| 241 | return r; |
| 242 | } |
| 243 | int Hwrite( int fd , const void *buf , size_t len ) { |
| 244 | int r, e; |
| 245 | Qwrite( fd , buf , len ); |
| 246 | r= write( fd , buf , len ); |
| 247 | e= errno; |
| 248 | vb.used= 0; |
| 249 | Tvba("write="); |
| 250 | if (r==-1) { Tvberrno(e); goto x_error; } |
| 251 | Tvbf("%d",r); |
| 252 | x_error: |
| 253 | R_recordtime(); |
| 254 | R_vb(); |
| 255 | errno= e; |
| 256 | return r; |
| 257 | } |