source: zzuf/trunk/src/libzzuf/lib-fd.c @ 4373

Last change on this file since 4373 was 4373, checked in by Sam Hocevar, 10 years ago

Revert any potential overriding macro before declaring a new function.

  • Property svn:keywords set to Id
File size: 19.4 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
4 *                2007 Rémi Denis-Courmont <rdenis#simphalempin:com>
5 *                2007 Clément Stenac <zorglub#diwi:org>
6 *                2007 Dominik Kuhlen <dominik.kuhlen#gmit-gmbh:de>
7 *                2009 Corentin Delorme <codelorme@gmail.com>
8 *                All Rights Reserved
9 *
10 *  This program is free software. It comes without any warranty, to
11 *  the extent permitted by applicable law. You can redistribute it
12 *  and/or modify it under the terms of the Do What The Fuck You Want
13 *  To Public License, Version 2, as published by Sam Hocevar. See
14 *  http://sam.zoy.org/wtfpl/COPYING for more details.
15 */
16
17/*
18 *  load-fd.c: loaded file descriptor functions
19 */
20
21#include "config.h"
22
23/* Need this for RTLD_NEXT */
24#define _GNU_SOURCE
25/* Use this to get lseek64() on glibc systems */
26#define _LARGEFILE64_SOURCE
27/* Use this to get off64_t() on Solaris systems */
28#define _LARGEFILE_SOURCE
29/* Use this to get proper prototypes on HP-UX systems */
30#define _XOPEN_SOURCE_EXTENDED
31#define _INCLUDE_POSIX_SOURCE
32
33#if defined HAVE_STDINT_H
34#   include <stdint.h>
35#elif defined HAVE_INTTYPES_H
36#   include <inttypes.h>
37#endif
38#include <stdlib.h>
39#include <string.h>
40#include <stdio.h>
41#include <errno.h>
42
43#if defined HAVE_WINSOCK2_H
44#   include <winsock2.h>
45#endif
46#include <sys/types.h>
47#if defined HAVE_SYS_SOCKET_H
48#   include <sys/socket.h>
49#endif
50#if defined HAVE_NETINET_IN_H
51#   include <netinet/in.h>
52#endif
53#if defined HAVE_ARPA_INET_H
54#   include <arpa/inet.h>
55#endif
56#if defined HAVE_SYS_UIO_H
57#   include <sys/uio.h>
58#endif
59#if defined HAVE_UNISTD_H
60#   include <unistd.h>
61#endif
62#include <fcntl.h>
63#include <stdarg.h>
64#if defined HAVE_AIO_H
65#   include <aio.h>
66#endif
67
68#include "libzzuf.h"
69#include "lib-load.h"
70#include "debug.h"
71#include "network.h"
72#include "fuzz.h"
73#include "fd.h"
74
75#if defined HAVE_SOCKLEN_T
76#   define SOCKLEN_T socklen_t
77#else
78#   define SOCKLEN_T int
79#endif
80
81#if defined CONNECT_USES_STRUCT_SOCKADDR
82#   define SOCKADDR_T struct sockaddr
83#else
84#   define SOCKADDR_T void
85#endif
86
87/* Local prototypes */
88#if defined HAVE_READV || defined HAVE_RECVMSG
89static void fuzz_iovec   (int fd, const struct iovec *iov, ssize_t ret);
90#endif
91static void offset_check (int fd);
92
93/* Library functions that we divert */
94static int     (*ORIG(open))    (const char *file, int oflag, ...);
95#if defined HAVE_OPEN64
96static int     (*ORIG(open64))  (const char *file, int oflag, ...);
97#endif
98#if defined HAVE___OPEN64
99static int     (*ORIG(__open64))(const char *file, int oflag, ...);
100#endif
101#if defined HAVE_DUP
102static int     (*ORIG(dup))     (int oldfd);
103#endif
104#if defined HAVE_DUP2
105static int     (*ORIG(dup2))    (int oldfd, int newfd);
106#endif
107#if defined HAVE_ACCEPT
108static int     (*ORIG(accept))  (int sockfd, SOCKADDR_T *addr,
109                                 SOCKLEN_T *addrlen);
110#endif
111#if defined HAVE_BIND
112static int     (*ORIG(bind))    (int sockfd, const SOCKADDR_T *my_addr,
113                                 SOCKLEN_T addrlen);
114#endif
115#if defined HAVE_CONNECT
116static int     (*ORIG(connect)) (int sockfd, const SOCKADDR_T *serv_addr,
117                                 SOCKLEN_T addrlen);
118#endif
119#if defined HAVE_SOCKET
120static int     (*ORIG(socket))  (int domain, int type, int protocol);
121#endif
122#if defined HAVE_RECV
123static RECV_T  (*ORIG(recv))    (int s, void *buf, size_t len, int flags);
124#endif
125#if defined HAVE___RECV_CHK
126static RECV_T  (*ORIG(__recv_chk)) (int s, void *buf, size_t len, int flags);
127#endif
128#if defined HAVE_RECVFROM
129static RECV_T  (*ORIG(recvfrom))(int s, void *buf, size_t len, int flags,
130                                 SOCKADDR_T *from, SOCKLEN_T *fromlen);
131#endif
132#if defined HAVE___RECVFROM_CHK
133static RECV_T  (*ORIG(__recvfrom_chk))(int s, void *buf, size_t len, int flags,
134                                       SOCKADDR_T *from, SOCKLEN_T *fromlen);
135#endif
136#if defined HAVE_RECVMSG
137static RECV_T  (*ORIG(recvmsg)) (int s,  struct msghdr *hdr, int flags);
138#endif
139#if defined READ_USES_SSIZE_T
140static ssize_t (*ORIG(read))    (int fd, void *buf, size_t count);
141#else
142static int     (*ORIG(read))    (int fd, void *buf, unsigned int count);
143#endif
144#if defined HAVE___READ_CHK
145static ssize_t (*ORIG(__read_chk)) (int fd, void *buf, size_t count);
146#endif
147#if defined HAVE_READV
148static ssize_t (*ORIG(readv))   (int fd, const struct iovec *iov, int count);
149#endif
150#if defined HAVE_PREAD
151static ssize_t (*ORIG(pread))   (int fd, void *buf, size_t count, off_t offset);
152#endif
153#if defined HAVE_AIO_READ
154static int     (*ORIG(aio_read))   (struct aiocb *aiocbp);
155static ssize_t (*ORIG(aio_return)) (struct aiocb *aiocbp);
156#endif
157static off_t   (*ORIG(lseek))   (int fd, off_t offset, int whence);
158#if defined HAVE_LSEEK64
159static off64_t (*ORIG(lseek64)) (int fd, off64_t offset, int whence);
160#endif
161#if defined HAVE___LSEEK64
162static off64_t (*ORIG(__lseek64)) (int fd, off64_t offset, int whence);
163#endif
164static int     (*ORIG(close))   (int fd);
165
166#define ZZ_OPEN(myopen) \
167    do \
168    { \
169        int mode = 0; \
170        LOADSYM(myopen); \
171        if(oflag & O_CREAT) \
172        { \
173            va_list va; \
174            va_start(va, oflag); \
175            mode = va_arg(va, int); \
176            va_end(va); \
177            ret = ORIG(myopen)(file, oflag, mode); \
178        } \
179        else \
180        { \
181            ret = ORIG(myopen)(file, oflag); \
182        } \
183        if(!_zz_ready || _zz_islocked(-1)) \
184            return ret; \
185        if(ret >= 0 \
186            && ((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY) \
187            && _zz_mustwatch(file)) \
188        { \
189            if(oflag & O_CREAT) \
190                debug("%s(\"%s\", %i, %i) = %i", \
191                      __func__, file, oflag, mode, ret); \
192            else \
193                debug("%s(\"%s\", %i) = %i", __func__, file, oflag, ret); \
194            _zz_register(ret); \
195        } \
196    } while(0)
197
198#undef open
199int NEW(open)(const char *file, int oflag, ...)
200{
201    int ret; ZZ_OPEN(open); return ret;
202}
203
204#if defined HAVE_OPEN64
205#undef open64
206int NEW(open64)(const char *file, int oflag, ...)
207{
208    int ret; ZZ_OPEN(open64); return ret;
209}
210#endif
211
212#if defined HAVE___OPEN64
213#undef __open64
214int NEW(__open64)(const char *file, int oflag, ...)
215{
216    int ret; ZZ_OPEN(__open64); return ret;
217}
218#endif
219
220#if defined HAVE_DUP
221#undef dup
222int NEW(dup)(int oldfd)
223{
224    int ret;
225
226    LOADSYM(dup);
227    ret = ORIG(dup)(oldfd);
228    if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd)
229         || !_zz_isactive(oldfd))
230        return ret;
231
232    if(ret >= 0)
233    {
234        debug("%s(%i) = %i", __func__, oldfd, ret);
235        _zz_register(ret);
236    }
237
238    return ret;
239}
240#endif
241
242#if defined HAVE_DUP2
243#undef dup2
244int NEW(dup2)(int oldfd, int newfd)
245{
246    int ret;
247
248    LOADSYM(dup2);
249    ret = ORIG(dup2)(oldfd, newfd);
250    if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd)
251         || !_zz_isactive(oldfd))
252        return ret;
253
254    if(ret >= 0)
255    {
256        /* We must close newfd if it was open, but only if oldfd != newfd
257         * and if dup2() suceeded. */
258        if(oldfd != newfd && _zz_iswatched(newfd) && _zz_isactive(newfd))
259            _zz_unregister(newfd);
260
261        debug("%s(%i, %i) = %i", __func__, oldfd, newfd, ret);
262        _zz_register(ret);
263    }
264
265    return ret;
266}
267#endif
268
269#if defined HAVE_ACCEPT
270#undef accept
271int NEW(accept)(int sockfd, SOCKADDR_T *addr, SOCKLEN_T *addrlen)
272{
273    int ret;
274
275    LOADSYM(accept);
276    ret = ORIG(accept)(sockfd, addr, addrlen);
277    if(!_zz_ready || _zz_islocked(-1) || !_zz_network
278         || !_zz_iswatched(sockfd) || !_zz_isactive(sockfd))
279        return ret;
280
281    if(ret >= 0)
282    {
283        if(addrlen)
284            debug("%s(%i, %p, &%i) = %i", __func__,
285                  sockfd, addr, (int)*addrlen, ret);
286        else
287            debug("%s(%i, %p, NULL) = %i", __func__, sockfd, addr, ret);
288        _zz_register(ret);
289    }
290
291    return ret;
292}
293#endif
294
295#if defined AF_INET6
296#   define case_AF_INET6 case AF_INET6:
297#else
298#   define case_AF_INET6
299#endif
300
301#define ZZ_CONNECT(myconnect, addr) \
302    do \
303    { \
304        LOADSYM(myconnect); \
305        ret = ORIG(myconnect)(sockfd, addr, addrlen); \
306        if(!_zz_ready || _zz_islocked(-1) || !_zz_network) \
307            return ret; \
308        if(ret >= 0) \
309        { \
310            struct sockaddr_in in; \
311            long int port; \
312            switch(addr->sa_family) \
313            { \
314            case AF_INET: \
315            case_AF_INET6 \
316                /* We need to copy rather than cast sockaddr* to sockaddr_in* \
317                 * because sockaddr_in* has actually _larger_ alignment on \
318                 * eg. Linux alpha. And we only need sin_port so we only copy \
319                 * this member. */ \
320                memcpy(&in.sin_port, \
321                   (char const *)addr + ((char *)&in.sin_port - (char *)&in), \
322                   sizeof(in.sin_port)); \
323                port = ntohs(in.sin_port); \
324                if(_zz_portwatched(port)) \
325                    break; \
326                /* Fall through */ \
327            default: \
328                _zz_unregister(sockfd); \
329                return ret; \
330            } \
331            debug("%s(%i, %p, %i) = %i", __func__, \
332                  sockfd, addr, (int)addrlen, ret); \
333        } \
334    } while(0);
335
336#if defined HAVE_BIND
337#undef bind
338int NEW(bind)(int sockfd, const SOCKADDR_T *my_addr, SOCKLEN_T addrlen)
339{
340    int ret; ZZ_CONNECT(bind, my_addr); return ret;
341}
342#endif
343
344#if defined HAVE_CONNECT
345#undef connect
346int NEW(connect)(int sockfd, const SOCKADDR_T *serv_addr,
347                 SOCKLEN_T addrlen)
348{
349    int ret; ZZ_CONNECT(connect, serv_addr); return ret;
350}
351#endif
352
353#if defined HAVE_SOCKET
354#undef socket
355int NEW(socket)(int domain, int type, int protocol)
356{
357    int ret;
358
359    LOADSYM(socket);
360    ret = ORIG(socket)(domain, type, protocol);
361    if(!_zz_ready || _zz_islocked(-1) || !_zz_network)
362        return ret;
363
364    if(ret >= 0)
365    {
366        debug("%s(%i, %i, %i) = %i", __func__, domain, type, protocol, ret);
367        _zz_register(ret);
368    }
369
370    return ret;
371}
372#endif
373
374#define ZZ_RECV(myrecv) \
375    do \
376    { \
377        LOADSYM(myrecv); \
378        ret = ORIG(myrecv)(s, buf, len, flags); \
379        if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \
380             || _zz_islocked(s) || !_zz_isactive(s)) \
381            return ret; \
382        if(ret > 0) \
383        { \
384            char *b = buf; \
385            _zz_fuzz(s, buf, ret); \
386            _zz_addpos(s, ret); \
387            if(ret >= 4) \
388                debug("%s(%i, %p, %li, 0x%x) = %i \"%c%c%c%c...", __func__, \
389                      s, buf, (long int)len, flags, ret, \
390                      b[0], b[1], b[2], b[3]); \
391            else \
392                debug("%s(%i, %p, %li, 0x%x) = %i \"%c...", __func__, \
393                      s, buf, (long int)len, flags, ret, b[0]); \
394        } \
395        else \
396            debug("%s(%i, %p, %li, 0x%x) = %i", __func__, \
397                  s, buf, (long int)len, flags, ret); \
398    } while(0);
399
400#if defined HAVE_RECV
401#undef recv
402RECV_T NEW(recv)(int s, void *buf, size_t len, int flags)
403{
404    int ret; ZZ_RECV(recv); return ret;
405}
406#endif
407
408#if defined HAVE___RECV_CHK
409#undef __recv_chk
410RECV_T NEW(__recv_chk)(int s, void *buf, size_t len, int flags)
411{
412    int ret; ZZ_RECV(__recv_chk); return ret;
413}
414#endif
415
416#define ZZ_RECVFROM(myrecvfrom) \
417    do \
418    { \
419        LOADSYM(myrecvfrom); \
420        ret = ORIG(myrecvfrom)(s, buf, len, flags, from, fromlen); \
421        if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \
422             || _zz_islocked(s) || !_zz_isactive(s)) \
423            return ret; \
424        if(ret > 0) \
425        { \
426            char tmp[128]; \
427            char *b = buf; \
428            _zz_fuzz(s, buf, ret); \
429            _zz_addpos(s, ret); \
430            if (fromlen) \
431                sprintf(tmp, "&%i", (int)*fromlen); \
432            else \
433                strcpy(tmp, "NULL"); \
434            if (ret >= 4) \
435                debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c%c%c%c...", \
436                      __func__, s, buf, (long int)len, flags, from, tmp, \
437                      ret, b[0], b[1], b[2], b[3]); \
438            else \
439                debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c...", \
440                      __func__, s, buf, (long int)len, flags, from, tmp, \
441                      ret, b[0]); \
442        } \
443        else \
444            debug("%s(%i, %p, %li, 0x%x, %p, %p) = %i", __func__, \
445                  s, buf, (long int)len, flags, from, fromlen, ret); \
446    } while(0)
447
448#if defined HAVE_RECVFROM
449#undef recvfrom
450RECV_T NEW(recvfrom)(int s, void *buf, size_t len, int flags,
451                     SOCKADDR_T *from, SOCKLEN_T *fromlen)
452{
453    int ret; ZZ_RECVFROM(recvfrom); return ret;
454}
455#endif
456
457#if defined HAVE___RECVFROM_CHK
458#undef __recvfrom_chk
459RECV_T NEW(__recvfrom_chk)(int s, void *buf, size_t len, int flags,
460                           SOCKADDR_T *from, SOCKLEN_T *fromlen)
461{
462    int ret; ZZ_RECVFROM(__recvfrom_chk); return ret;
463}
464#endif
465
466#if defined HAVE_RECVMSG
467#undef recvmsg
468RECV_T NEW(recvmsg)(int s, struct msghdr *hdr, int flags)
469{
470    ssize_t ret;
471
472    LOADSYM(recvmsg);
473    ret = ORIG(recvmsg)(s, hdr, flags);
474    if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s)
475         || _zz_islocked(s) || !_zz_isactive(s))
476        return ret;
477
478    fuzz_iovec(s, hdr->msg_iov, ret);
479    debug("%s(%i, %p, %x) = %li", __func__, s, hdr, flags, (long int)ret);
480
481    return ret;
482}
483#endif
484
485#define ZZ_READ(myread) \
486    do \
487    { \
488        LOADSYM(myread); \
489        ret = ORIG(read)(fd, buf, count); \
490        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_hostwatched(fd) \
491             || _zz_islocked(fd) || !_zz_isactive(fd)) \
492            return ret; \
493        if(ret > 0) \
494        { \
495            char *b = buf; \
496            _zz_fuzz(fd, buf, ret); \
497            _zz_addpos(fd, ret); \
498            if(ret >= 4) \
499                debug("%s(%i, %p, %li) = %i \"%c%c%c%c...", __func__, fd, \
500                      buf, (long int)count, ret, b[0], b[1], b[2], b[3]); \
501            else \
502                debug("%s(%i, %p, %li) = %i \"%c...", __func__, fd, \
503                      buf, (long int)count, ret, b[0]); \
504        } \
505        else \
506            debug("%s(%i, %p, %li) = %i", __func__, fd, \
507                  buf, (long int)count, ret); \
508        offset_check(fd); \
509    } while(0)
510
511#if defined READ_USES_SSIZE_T
512#undef read
513ssize_t NEW(read)(int fd, void *buf, size_t count)
514{
515    int ret; ZZ_READ(read); return (ssize_t)ret;
516}
517#else
518#undef read
519int NEW(read)(int fd, void *buf, unsigned int count)
520{
521    int ret; ZZ_READ(read); return ret;
522}
523#endif
524
525#if defined HAVE___READ_CHK
526#undef __read_chk
527ssize_t NEW(__read_chk)(int fd, void *buf, size_t count)
528{
529    int ret; ZZ_READ(__read_chk); return (ssize_t)ret;
530}
531#endif
532
533#if defined HAVE_READV
534#undef readv
535ssize_t NEW(readv)(int fd, const struct iovec *iov, int count)
536{
537    ssize_t ret;
538
539    LOADSYM(readv);
540    ret = ORIG(readv)(fd, iov, count);
541    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd)
542         || !_zz_isactive(fd))
543        return ret;
544
545    fuzz_iovec(fd, iov, ret);
546    debug("%s(%i, %p, %i) = %li", __func__, fd, iov, count, (long int)ret);
547
548    offset_check(fd);
549    return ret;
550}
551#endif
552
553#if defined HAVE_PREAD
554#undef pread
555ssize_t NEW(pread)(int fd, void *buf, size_t count, off_t offset)
556{
557    int ret;
558
559    LOADSYM(pread);
560    ret = ORIG(pread)(fd, buf, count, offset);
561    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd)
562         || !_zz_isactive(fd))
563        return ret;
564
565    if(ret > 0)
566    {
567        long int curoff = _zz_getpos(fd);
568        char *b = buf;
569
570        _zz_setpos(fd, offset);
571        _zz_fuzz(fd, buf, ret);
572        _zz_setpos(fd, curoff);
573
574        if(ret >= 4)
575            debug("%s(%i, %p, %li, %li) = %i \"%c%c%c%c...", __func__, fd, buf,
576                  (long int)count, (long int)offset, ret,
577                  b[0], b[1], b[2], b[3]);
578        else
579            debug("%s(%i, %p, %li, %li) = %i \"%c...", __func__, fd, buf,
580                  (long int)count, (long int)offset, ret, b[0]);
581    }
582    else
583        debug("%s(%i, %p, %li, %li) = %i", __func__, fd, buf,
584              (long int)count, (long int)offset, ret);
585
586    return ret;
587}
588#endif
589
590#define ZZ_LSEEK(mylseek, off_t) \
591    do \
592    { \
593        LOADSYM(mylseek); \
594        ret = ORIG(mylseek)(fd, offset, whence); \
595        if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd) \
596             || !_zz_isactive(fd)) \
597            return ret; \
598        debug("%s(%i, %lli, %i) = %lli", __func__, fd, \
599              (long long int)offset, whence, (long long int)ret); \
600        if(ret != (off_t)-1) \
601            _zz_setpos(fd, ret); \
602    } while(0)
603
604#undef lseek
605off_t NEW(lseek)(int fd, off_t offset, int whence)
606{
607    off_t ret;
608    ZZ_LSEEK(lseek, off_t);
609    return ret;
610}
611
612#if defined HAVE_LSEEK64
613#undef lseek64
614off64_t NEW(lseek64)(int fd, off64_t offset, int whence)
615{
616    off64_t ret; ZZ_LSEEK(lseek64, off64_t); return ret;
617}
618#endif
619
620#if defined HAVE___LSEEK64
621#undef __lseek64
622off64_t NEW(__lseek64)(int fd, off64_t offset, int whence)
623{
624    off64_t ret; ZZ_LSEEK(__lseek64, off64_t); return ret;
625}
626#endif
627
628#if defined HAVE_AIO_READ
629#undef aio_read
630int NEW(aio_read)(struct aiocb *aiocbp)
631{
632    int ret;
633    int fd = aiocbp->aio_fildes;
634
635    LOADSYM(aio_read);
636    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
637        return ORIG(aio_read)(aiocbp);
638
639    _zz_lock(fd);
640    ret = ORIG(aio_read)(aiocbp);
641
642    debug("%s({%i, %i, %i, %p, %li, ..., %li}) = %i", __func__,
643          fd, aiocbp->aio_lio_opcode, aiocbp->aio_reqprio, aiocbp->aio_buf,
644          (long int)aiocbp->aio_nbytes, (long int)aiocbp->aio_offset, ret);
645
646    return ret;
647}
648
649#undef aio_return
650ssize_t NEW(aio_return)(struct aiocb *aiocbp)
651{
652    ssize_t ret;
653    int fd = aiocbp->aio_fildes;
654
655    LOADSYM(aio_return);
656    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
657        return ORIG(aio_return)(aiocbp);
658
659    ret = ORIG(aio_return)(aiocbp);
660    _zz_unlock(fd);
661
662    /* FIXME: make sure we’re actually *reading* */
663    if(ret > 0)
664    {
665        _zz_setpos(fd, aiocbp->aio_offset);
666        _zz_fuzz(fd, aiocbp->aio_buf, ret);
667        _zz_addpos(fd, ret);
668    }
669
670    debug("%s({%i, %i, %i, %p, %li, ..., %li}) = %li", __func__,
671          fd, aiocbp->aio_lio_opcode, aiocbp->aio_reqprio, aiocbp->aio_buf,
672          (long int)aiocbp->aio_nbytes, (long int)aiocbp->aio_offset,
673          (long int)ret);
674
675    return ret;
676}
677#endif
678
679#undef close
680int NEW(close)(int fd)
681{
682    int ret;
683
684    /* Hey, it’s our debug channel! Silently pretend we closed it. */
685    if(fd == _zz_debugfd)
686        return 0;
687
688    LOADSYM(close);
689    ret = ORIG(close)(fd);
690    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd))
691        return ret;
692
693    debug("%s(%i) = %i", __func__, fd, ret);
694    _zz_unregister(fd);
695
696    return ret;
697}
698
699/* XXX: the following functions are local */
700
701#if defined HAVE_READV || defined HAVE_RECVMSG
702static void fuzz_iovec(int fd, const struct iovec *iov, ssize_t ret)
703{
704    /* NOTE: We assume that iov countains at least <ret> bytes. */
705    while(ret > 0)
706    {
707        void *b = iov->iov_base;
708        size_t len = iov->iov_len;
709
710        if(len > (size_t)ret)
711            len = ret;
712
713        _zz_fuzz(fd, b, len);
714        _zz_addpos(fd, len);
715
716        iov++;
717        ret -= len;
718    }
719}
720#endif
721
722/* Sanity check, can be OK though (for instance with a character device) */
723static void offset_check(int fd)
724{
725    int orig_errno = errno;
726#if defined HAVE_LSEEK64
727    off64_t ret;
728    LOADSYM(lseek64);
729    ret = ORIG(lseek64)(fd, 0, SEEK_CUR);
730#else
731    off_t ret;
732    LOADSYM(lseek);
733    ret = ORIG(lseek)(fd, 0, SEEK_CUR);
734#endif
735    if(ret != -1 && ret != _zz_getpos(fd))
736        debug("warning: offset inconsistency");
737    errno = orig_errno;
738}
739
Note: See TracBrowser for help on using the repository browser.