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

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

Fortify functions actually have extra arguments. Fix that.

  • Property svn:keywords set to Id
File size: 19.8 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,
127                                    size_t buflen, int flags);
128#endif
129#if defined HAVE_RECVFROM
130static RECV_T  (*ORIG(recvfrom))(int s, void *buf, size_t len, int flags,
131                                 SOCKADDR_T *from, SOCKLEN_T *fromlen);
132#endif
133#if defined HAVE___RECVFROM_CHK
134static RECV_T  (*ORIG(__recvfrom_chk))(int s, void *buf, size_t len,
135                                       size_t buflen, int flags,
136                                       SOCKADDR_T *from, SOCKLEN_T *fromlen);
137#endif
138#if defined HAVE_RECVMSG
139static RECV_T  (*ORIG(recvmsg)) (int s,  struct msghdr *hdr, int flags);
140#endif
141#if defined READ_USES_SSIZE_T
142static ssize_t (*ORIG(read))    (int fd, void *buf, size_t count);
143#else
144static int     (*ORIG(read))    (int fd, void *buf, unsigned int count);
145#endif
146#if defined HAVE___READ_CHK
147static ssize_t (*ORIG(__read_chk)) (int fd, void *buf, size_t count,
148                                    size_t buflen);
149#endif
150#if defined HAVE_READV
151static ssize_t (*ORIG(readv))   (int fd, const struct iovec *iov, int count);
152#endif
153#if defined HAVE_PREAD
154static ssize_t (*ORIG(pread))   (int fd, void *buf, size_t count, off_t offset);
155#endif
156#if defined HAVE_AIO_READ
157static int     (*ORIG(aio_read))   (struct aiocb *aiocbp);
158static ssize_t (*ORIG(aio_return)) (struct aiocb *aiocbp);
159#endif
160static off_t   (*ORIG(lseek))   (int fd, off_t offset, int whence);
161#if defined HAVE_LSEEK64
162static off64_t (*ORIG(lseek64)) (int fd, off64_t offset, int whence);
163#endif
164#if defined HAVE___LSEEK64
165static off64_t (*ORIG(__lseek64)) (int fd, off64_t offset, int whence);
166#endif
167static int     (*ORIG(close))   (int fd);
168
169#define ZZ_OPEN(myopen) \
170    do \
171    { \
172        int mode = 0; \
173        LOADSYM(myopen); \
174        if(oflag & O_CREAT) \
175        { \
176            va_list va; \
177            va_start(va, oflag); \
178            mode = va_arg(va, int); \
179            va_end(va); \
180            ret = ORIG(myopen)(file, oflag, mode); \
181        } \
182        else \
183        { \
184            ret = ORIG(myopen)(file, oflag); \
185        } \
186        if(!_zz_ready || _zz_islocked(-1)) \
187            return ret; \
188        if(ret >= 0 \
189            && ((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY) \
190            && _zz_mustwatch(file)) \
191        { \
192            if(oflag & O_CREAT) \
193                debug("%s(\"%s\", %i, %i) = %i", \
194                      __func__, file, oflag, mode, ret); \
195            else \
196                debug("%s(\"%s\", %i) = %i", __func__, file, oflag, ret); \
197            _zz_register(ret); \
198        } \
199    } while(0)
200
201#undef open
202int NEW(open)(const char *file, int oflag, ...)
203{
204    int ret; ZZ_OPEN(open); return ret;
205}
206
207#if defined HAVE_OPEN64
208#undef open64
209int NEW(open64)(const char *file, int oflag, ...)
210{
211    int ret; ZZ_OPEN(open64); return ret;
212}
213#endif
214
215#if defined HAVE___OPEN64
216#undef __open64
217int NEW(__open64)(const char *file, int oflag, ...)
218{
219    int ret; ZZ_OPEN(__open64); return ret;
220}
221#endif
222
223#if defined HAVE_DUP
224#undef dup
225int NEW(dup)(int oldfd)
226{
227    int ret;
228
229    LOADSYM(dup);
230    ret = ORIG(dup)(oldfd);
231    if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd)
232         || !_zz_isactive(oldfd))
233        return ret;
234
235    if(ret >= 0)
236    {
237        debug("%s(%i) = %i", __func__, oldfd, ret);
238        _zz_register(ret);
239    }
240
241    return ret;
242}
243#endif
244
245#if defined HAVE_DUP2
246#undef dup2
247int NEW(dup2)(int oldfd, int newfd)
248{
249    int ret;
250
251    LOADSYM(dup2);
252    ret = ORIG(dup2)(oldfd, newfd);
253    if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd)
254         || !_zz_isactive(oldfd))
255        return ret;
256
257    if(ret >= 0)
258    {
259        /* We must close newfd if it was open, but only if oldfd != newfd
260         * and if dup2() suceeded. */
261        if(oldfd != newfd && _zz_iswatched(newfd) && _zz_isactive(newfd))
262            _zz_unregister(newfd);
263
264        debug("%s(%i, %i) = %i", __func__, oldfd, newfd, ret);
265        _zz_register(ret);
266    }
267
268    return ret;
269}
270#endif
271
272#if defined HAVE_ACCEPT
273#undef accept
274int NEW(accept)(int sockfd, SOCKADDR_T *addr, SOCKLEN_T *addrlen)
275{
276    int ret;
277
278    LOADSYM(accept);
279    ret = ORIG(accept)(sockfd, addr, addrlen);
280    if(!_zz_ready || _zz_islocked(-1) || !_zz_network
281         || !_zz_iswatched(sockfd) || !_zz_isactive(sockfd))
282        return ret;
283
284    if(ret >= 0)
285    {
286        if(addrlen)
287            debug("%s(%i, %p, &%i) = %i", __func__,
288                  sockfd, addr, (int)*addrlen, ret);
289        else
290            debug("%s(%i, %p, NULL) = %i", __func__, sockfd, addr, ret);
291        _zz_register(ret);
292    }
293
294    return ret;
295}
296#endif
297
298#if defined AF_INET6
299#   define case_AF_INET6 case AF_INET6:
300#else
301#   define case_AF_INET6
302#endif
303
304#define ZZ_CONNECT(myconnect, addr) \
305    do \
306    { \
307        LOADSYM(myconnect); \
308        ret = ORIG(myconnect)(sockfd, addr, addrlen); \
309        if(!_zz_ready || _zz_islocked(-1) || !_zz_network) \
310            return ret; \
311        if(ret >= 0) \
312        { \
313            struct sockaddr_in in; \
314            long int port; \
315            switch(addr->sa_family) \
316            { \
317            case AF_INET: \
318            case_AF_INET6 \
319                /* We need to copy rather than cast sockaddr* to sockaddr_in* \
320                 * because sockaddr_in* has actually _larger_ alignment on \
321                 * eg. Linux alpha. And we only need sin_port so we only copy \
322                 * this member. */ \
323                memcpy(&in.sin_port, \
324                   (char const *)addr + ((char *)&in.sin_port - (char *)&in), \
325                   sizeof(in.sin_port)); \
326                port = ntohs(in.sin_port); \
327                if(_zz_portwatched(port)) \
328                    break; \
329                /* Fall through */ \
330            default: \
331                _zz_unregister(sockfd); \
332                return ret; \
333            } \
334            debug("%s(%i, %p, %i) = %i", __func__, \
335                  sockfd, addr, (int)addrlen, ret); \
336        } \
337    } while(0);
338
339#if defined HAVE_BIND
340#undef bind
341int NEW(bind)(int sockfd, const SOCKADDR_T *my_addr, SOCKLEN_T addrlen)
342{
343    int ret; ZZ_CONNECT(bind, my_addr); return ret;
344}
345#endif
346
347#if defined HAVE_CONNECT
348#undef connect
349int NEW(connect)(int sockfd, const SOCKADDR_T *serv_addr,
350                 SOCKLEN_T addrlen)
351{
352    int ret; ZZ_CONNECT(connect, serv_addr); return ret;
353}
354#endif
355
356#if defined HAVE_SOCKET
357#undef socket
358int NEW(socket)(int domain, int type, int protocol)
359{
360    int ret;
361
362    LOADSYM(socket);
363    ret = ORIG(socket)(domain, type, protocol);
364    if(!_zz_ready || _zz_islocked(-1) || !_zz_network)
365        return ret;
366
367    if(ret >= 0)
368    {
369        debug("%s(%i, %i, %i) = %i", __func__, domain, type, protocol, ret);
370        _zz_register(ret);
371    }
372
373    return ret;
374}
375#endif
376
377#define ZZ_RECV(myrecv, myargs) \
378    do \
379    { \
380        LOADSYM(myrecv); \
381        ret = ORIG(myrecv) myargs; \
382        if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \
383             || _zz_islocked(s) || !_zz_isactive(s)) \
384            return ret; \
385        if(ret > 0) \
386        { \
387            char *b = buf; \
388            _zz_fuzz(s, buf, ret); \
389            _zz_addpos(s, ret); \
390            if(ret >= 4) \
391                debug("%s(%i, %p, %li, 0x%x) = %i \"%c%c%c%c...", __func__, \
392                      s, buf, (long int)len, flags, ret, \
393                      b[0], b[1], b[2], b[3]); \
394            else \
395                debug("%s(%i, %p, %li, 0x%x) = %i \"%c...", __func__, \
396                      s, buf, (long int)len, flags, ret, b[0]); \
397        } \
398        else \
399            debug("%s(%i, %p, %li, 0x%x) = %i", __func__, \
400                  s, buf, (long int)len, flags, ret); \
401    } while(0);
402
403#if defined HAVE_RECV
404#undef recv
405RECV_T NEW(recv)(int s, void *buf, size_t len, int flags)
406{
407    int ret; ZZ_RECV(recv, (s, buf, len, flags)); return ret;
408}
409#endif
410
411#if defined HAVE___RECV_CHK
412#undef __recv_chk
413RECV_T NEW(__recv_chk)(int s, void *buf, size_t len, size_t buflen, int flags)
414{
415    int ret; ZZ_RECV(__recv_chk, (s, buf, len, buflen, flags)); return ret;
416}
417#endif
418
419#define ZZ_RECVFROM(myrecvfrom, myargs) \
420    do \
421    { \
422        LOADSYM(myrecvfrom); \
423        ret = ORIG(myrecvfrom) myargs; \
424        if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s) \
425             || _zz_islocked(s) || !_zz_isactive(s)) \
426            return ret; \
427        if(ret > 0) \
428        { \
429            char tmp[128]; \
430            char *b = buf; \
431            _zz_fuzz(s, buf, ret); \
432            _zz_addpos(s, ret); \
433            if (fromlen) \
434                sprintf(tmp, "&%i", (int)*fromlen); \
435            else \
436                strcpy(tmp, "NULL"); \
437            if (ret >= 4) \
438                debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c%c%c%c...", \
439                      __func__, s, buf, (long int)len, flags, from, tmp, \
440                      ret, b[0], b[1], b[2], b[3]); \
441            else \
442                debug("%s(%i, %p, %li, 0x%x, %p, %s) = %i \"%c...", \
443                      __func__, s, buf, (long int)len, flags, from, tmp, \
444                      ret, b[0]); \
445        } \
446        else \
447            debug("%s(%i, %p, %li, 0x%x, %p, %p) = %i", __func__, \
448                  s, buf, (long int)len, flags, from, fromlen, ret); \
449    } while(0)
450
451#if defined HAVE_RECVFROM
452#undef recvfrom
453RECV_T NEW(recvfrom)(int s, void *buf, size_t len, int flags,
454                     SOCKADDR_T *from, SOCKLEN_T *fromlen)
455{
456    int ret;
457    ZZ_RECVFROM(recvfrom, (s, buf, len, flags, from, fromlen));
458    return ret;
459}
460#endif
461
462#if defined HAVE___RECVFROM_CHK
463#undef __recvfrom_chk
464RECV_T NEW(__recvfrom_chk)(int s, void *buf, size_t len, size_t buflen,
465                           int flags, SOCKADDR_T *from, SOCKLEN_T *fromlen)
466{
467    int ret;
468    ZZ_RECVFROM(__recvfrom_chk, (s, buf, len, buflen, flags, from, fromlen));
469    return ret;
470}
471#endif
472
473#if defined HAVE_RECVMSG
474#undef recvmsg
475RECV_T NEW(recvmsg)(int s, struct msghdr *hdr, int flags)
476{
477    ssize_t ret;
478
479    LOADSYM(recvmsg);
480    ret = ORIG(recvmsg)(s, hdr, flags);
481    if(!_zz_ready || !_zz_iswatched(s) || !_zz_hostwatched(s)
482         || _zz_islocked(s) || !_zz_isactive(s))
483        return ret;
484
485    fuzz_iovec(s, hdr->msg_iov, ret);
486    debug("%s(%i, %p, %x) = %li", __func__, s, hdr, flags, (long int)ret);
487
488    return ret;
489}
490#endif
491
492#define ZZ_READ(myread, myargs) \
493    do \
494    { \
495        LOADSYM(myread); \
496        ret = ORIG(myread) myargs; \
497        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_hostwatched(fd) \
498             || _zz_islocked(fd) || !_zz_isactive(fd)) \
499            return ret; \
500        if(ret > 0) \
501        { \
502            char *b = buf; \
503            _zz_fuzz(fd, buf, ret); \
504            _zz_addpos(fd, ret); \
505            if(ret >= 4) \
506                debug("%s(%i, %p, %li) = %i \"%c%c%c%c...", __func__, fd, \
507                      buf, (long int)count, ret, b[0], b[1], b[2], b[3]); \
508            else \
509                debug("%s(%i, %p, %li) = %i \"%c...", __func__, fd, \
510                      buf, (long int)count, ret, b[0]); \
511        } \
512        else \
513            debug("%s(%i, %p, %li) = %i", __func__, fd, \
514                  buf, (long int)count, ret); \
515        offset_check(fd); \
516    } while(0)
517
518#if defined READ_USES_SSIZE_T
519#undef read
520ssize_t NEW(read)(int fd, void *buf, size_t count)
521{
522    int ret; ZZ_READ(read, (fd, buf, count)); return (ssize_t)ret;
523}
524#else
525#undef read
526int NEW(read)(int fd, void *buf, unsigned int count)
527{
528    int ret; ZZ_READ(read, (fd, buf, count)); return ret;
529}
530#endif
531
532#if defined HAVE___READ_CHK
533#undef __read_chk
534ssize_t NEW(__read_chk)(int fd, void *buf, size_t count, size_t buflen)
535{
536    int ret; ZZ_READ(__read_chk, (fd, buf, count, buflen)); return (ssize_t)ret;
537}
538#endif
539
540#if defined HAVE_READV
541#undef readv
542ssize_t NEW(readv)(int fd, const struct iovec *iov, int count)
543{
544    ssize_t ret;
545
546    LOADSYM(readv);
547    ret = ORIG(readv)(fd, iov, count);
548    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd)
549         || !_zz_isactive(fd))
550        return ret;
551
552    fuzz_iovec(fd, iov, ret);
553    debug("%s(%i, %p, %i) = %li", __func__, fd, iov, count, (long int)ret);
554
555    offset_check(fd);
556    return ret;
557}
558#endif
559
560#if defined HAVE_PREAD
561#undef pread
562ssize_t NEW(pread)(int fd, void *buf, size_t count, off_t offset)
563{
564    int ret;
565
566    LOADSYM(pread);
567    ret = ORIG(pread)(fd, buf, count, offset);
568    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd)
569         || !_zz_isactive(fd))
570        return ret;
571
572    if(ret > 0)
573    {
574        long int curoff = _zz_getpos(fd);
575        char *b = buf;
576
577        _zz_setpos(fd, offset);
578        _zz_fuzz(fd, buf, ret);
579        _zz_setpos(fd, curoff);
580
581        if(ret >= 4)
582            debug("%s(%i, %p, %li, %li) = %i \"%c%c%c%c...", __func__, fd, buf,
583                  (long int)count, (long int)offset, ret,
584                  b[0], b[1], b[2], b[3]);
585        else
586            debug("%s(%i, %p, %li, %li) = %i \"%c...", __func__, fd, buf,
587                  (long int)count, (long int)offset, ret, b[0]);
588    }
589    else
590        debug("%s(%i, %p, %li, %li) = %i", __func__, fd, buf,
591              (long int)count, (long int)offset, ret);
592
593    return ret;
594}
595#endif
596
597#define ZZ_LSEEK(mylseek, off_t) \
598    do \
599    { \
600        LOADSYM(mylseek); \
601        ret = ORIG(mylseek)(fd, offset, whence); \
602        if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd) \
603             || !_zz_isactive(fd)) \
604            return ret; \
605        debug("%s(%i, %lli, %i) = %lli", __func__, fd, \
606              (long long int)offset, whence, (long long int)ret); \
607        if(ret != (off_t)-1) \
608            _zz_setpos(fd, ret); \
609    } while(0)
610
611#undef lseek
612off_t NEW(lseek)(int fd, off_t offset, int whence)
613{
614    off_t ret;
615    ZZ_LSEEK(lseek, off_t);
616    return ret;
617}
618
619#if defined HAVE_LSEEK64
620#undef lseek64
621off64_t NEW(lseek64)(int fd, off64_t offset, int whence)
622{
623    off64_t ret; ZZ_LSEEK(lseek64, off64_t); return ret;
624}
625#endif
626
627#if defined HAVE___LSEEK64
628#undef __lseek64
629off64_t NEW(__lseek64)(int fd, off64_t offset, int whence)
630{
631    off64_t ret; ZZ_LSEEK(__lseek64, off64_t); return ret;
632}
633#endif
634
635#if defined HAVE_AIO_READ
636#undef aio_read
637int NEW(aio_read)(struct aiocb *aiocbp)
638{
639    int ret;
640    int fd = aiocbp->aio_fildes;
641
642    LOADSYM(aio_read);
643    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
644        return ORIG(aio_read)(aiocbp);
645
646    _zz_lock(fd);
647    ret = ORIG(aio_read)(aiocbp);
648
649    debug("%s({%i, %i, %i, %p, %li, ..., %li}) = %i", __func__,
650          fd, aiocbp->aio_lio_opcode, aiocbp->aio_reqprio, aiocbp->aio_buf,
651          (long int)aiocbp->aio_nbytes, (long int)aiocbp->aio_offset, ret);
652
653    return ret;
654}
655
656#undef aio_return
657ssize_t NEW(aio_return)(struct aiocb *aiocbp)
658{
659    ssize_t ret;
660    int fd = aiocbp->aio_fildes;
661
662    LOADSYM(aio_return);
663    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
664        return ORIG(aio_return)(aiocbp);
665
666    ret = ORIG(aio_return)(aiocbp);
667    _zz_unlock(fd);
668
669    /* FIXME: make sure we’re actually *reading* */
670    if(ret > 0)
671    {
672        _zz_setpos(fd, aiocbp->aio_offset);
673        _zz_fuzz(fd, aiocbp->aio_buf, ret);
674        _zz_addpos(fd, ret);
675    }
676
677    debug("%s({%i, %i, %i, %p, %li, ..., %li}) = %li", __func__,
678          fd, aiocbp->aio_lio_opcode, aiocbp->aio_reqprio, aiocbp->aio_buf,
679          (long int)aiocbp->aio_nbytes, (long int)aiocbp->aio_offset,
680          (long int)ret);
681
682    return ret;
683}
684#endif
685
686#undef close
687int NEW(close)(int fd)
688{
689    int ret;
690
691    /* Hey, it’s our debug channel! Silently pretend we closed it. */
692    if(fd == _zz_debugfd)
693        return 0;
694
695    LOADSYM(close);
696    ret = ORIG(close)(fd);
697    if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd))
698        return ret;
699
700    debug("%s(%i) = %i", __func__, fd, ret);
701    _zz_unregister(fd);
702
703    return ret;
704}
705
706/* XXX: the following functions are local */
707
708#if defined HAVE_READV || defined HAVE_RECVMSG
709static void fuzz_iovec(int fd, const struct iovec *iov, ssize_t ret)
710{
711    /* NOTE: We assume that iov countains at least <ret> bytes. */
712    while(ret > 0)
713    {
714        void *b = iov->iov_base;
715        size_t len = iov->iov_len;
716
717        if(len > (size_t)ret)
718            len = ret;
719
720        _zz_fuzz(fd, b, len);
721        _zz_addpos(fd, len);
722
723        iov++;
724        ret -= len;
725    }
726}
727#endif
728
729/* Sanity check, can be OK though (for instance with a character device) */
730static void offset_check(int fd)
731{
732    int orig_errno = errno;
733#if defined HAVE_LSEEK64
734    off64_t ret;
735    LOADSYM(lseek64);
736    ret = ORIG(lseek64)(fd, 0, SEEK_CUR);
737#else
738    off_t ret;
739    LOADSYM(lseek);
740    ret = ORIG(lseek)(fd, 0, SEEK_CUR);
741#endif
742    if(ret != -1 && ret != _zz_getpos(fd))
743        debug("warning: offset inconsistency");
744    errno = orig_errno;
745}
746
Note: See TracBrowser for help on using the repository browser.