source: zzuf/trunk/src/lib-stream.c @ 2533

Last change on this file since 2533 was 2533, checked in by Sam Hocevar, 12 years ago
  • Implement srefill() for full HP-UX support on parisc-gcc.
  • Property svn:keywords set to Id
File size: 20.2 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: lib-stream.c 2533 2008-07-16 09:52:02Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  load-stream.c: loaded stream functions
17 */
18
19#include "config.h"
20
21#define _GNU_SOURCE /* for getline() and getdelim() */
22
23#if defined HAVE_STDINT_H
24#   include <stdint.h>
25#elif defined HAVE_INTTYPES_H
26#   include <inttypes.h>
27#endif
28#include <stdlib.h>
29
30#include <stdio.h>
31#include <sys/types.h>
32#if defined HAVE___SREFILL && defined HAVE_UNISTD_H
33#   include <unistd.h> /* Needed for __srefill’s lseek() call */
34#endif
35
36#include "libzzuf.h"
37#include "lib-load.h"
38#include "debug.h"
39#include "fuzz.h"
40#include "fd.h"
41
42#if defined HAVE___SREFILL || defined HAVE___FILBUF
43#   define HAVE_REFILL_STDIO
44#endif
45
46#if defined HAVE___SREFILL
47int NEW(__srefill)(FILE *fp);
48#endif
49
50#if defined HAVE___FILBUF
51int NEW(__filbuf)(FILE *fp);
52#endif
53
54/* Library functions that we divert */
55static FILE *  (*ORIG(fopen))    (const char *path, const char *mode);
56#if defined HAVE_FOPEN64
57static FILE *  (*ORIG(fopen64))  (const char *path, const char *mode);
58#endif
59#if defined HAVE___FOPEN64
60static FILE *  (*ORIG(__fopen64))(const char *path, const char *mode);
61#endif
62static FILE *  (*ORIG(freopen))  (const char *path, const char *mode,
63                                  FILE *stream);
64#if defined HAVE___FREOPEN64
65static FILE *  (*ORIG(__freopen64)) (const char *path, const char *mode,
66                                     FILE *stream);
67#endif
68static int     (*ORIG(fseek))    (FILE *stream, long offset, int whence);
69#if defined HAVE_FSEEKO
70static int     (*ORIG(fseeko))   (FILE *stream, off_t offset, int whence);
71#endif
72#if defined HAVE___FSEEKO64
73static int     (*ORIG(__fseeko64)) (FILE *stream, off_t offset, int whence);
74#endif
75#if defined HAVE___FSETPOS64
76static int     (*ORIG(__fsetpos64)) (FILE *stream, const fpos64_t *pos);
77#endif
78static void    (*ORIG(rewind))   (FILE *stream);
79static size_t  (*ORIG(fread))    (void *ptr, size_t size, size_t nmemb,
80                                  FILE *stream);
81#if defined HAVE_FREAD_UNLOCKED
82static size_t  (*ORIG(fread_unlocked))  (void *ptr, size_t size, size_t nmemb,
83                                         FILE *stream);
84#endif
85static int     (*ORIG(getc))     (FILE *stream);
86static int     (*ORIG(getchar))  (void);
87static int     (*ORIG(fgetc))    (FILE *stream);
88#if defined HAVE__IO_GETC
89static int     (*ORIG(_IO_getc)) (FILE *stream);
90#endif
91#if defined HAVE_GETC_UNLOCKED
92static int     (*ORIG(getc_unlocked))    (FILE *stream);
93#endif
94#if defined HAVE_GETCHAR_UNLOCKED
95static int     (*ORIG(getchar_unlocked)) (void);
96#endif
97#if defined HAVE_FGETC_UNLOCKED
98static int     (*ORIG(fgetc_unlocked))   (FILE *stream);
99#endif
100static char *  (*ORIG(fgets))    (char *s, int size, FILE *stream);
101#if defined HAVE_FGETS_UNLOCKED
102static char *  (*ORIG(fgets_unlocked))   (char *s, int size, FILE *stream);
103#endif
104static int     (*ORIG(ungetc))   (int c, FILE *stream);
105static int     (*ORIG(fclose))   (FILE *fp);
106
107/* Additional GNUisms */
108#if defined HAVE_GETLINE
109static ssize_t (*ORIG(getline))    (char **lineptr, size_t *n, FILE *stream);
110#endif
111#if defined HAVE_GETDELIM
112static ssize_t (*ORIG(getdelim))   (char **lineptr, size_t *n, int delim,
113                                    FILE *stream);
114#endif
115#if defined HAVE___GETDELIM
116static ssize_t (*ORIG(__getdelim)) (char **lineptr, size_t *n, int delim,
117                                    FILE *stream);
118#endif
119
120/* Additional BSDisms */
121#if defined HAVE_FGETLN
122static char *  (*ORIG(fgetln))    (FILE *stream, size_t *len);
123#endif
124#if defined HAVE___SREFILL
125int            (*ORIG(__srefill)) (FILE *fp);
126#endif
127
128/* Additional HP-UXisms */
129#if defined HAVE___FILBUF
130int            (*ORIG(__filbuf))  (FILE *fp);
131#endif
132
133/* Our function wrappers */
134#if defined HAVE_REFILL_STDIO /* Fuzz fp if we have __srefill() */
135#   define FOPEN_FUZZ() \
136    _zz_fuzz(fd, ret->__ptr, ret->__cnt)
137#else
138#   define FOPEN_FUZZ()
139#endif
140
141#define FOPEN(fn) \
142    do \
143    { \
144        LOADSYM(fn); \
145        if(!_zz_ready) \
146            return ORIG(fn)(path, mode); \
147        _zz_lock(-1); \
148        ret = ORIG(fn)(path, mode); \
149        _zz_unlock(-1); \
150        if(ret && _zz_mustwatch(path)) \
151        { \
152            int fd = fileno(ret); \
153            _zz_register(fd); \
154            debug("%s(\"%s\", \"%s\") = [%i]", __func__, path, mode, fd); \
155            FOPEN_FUZZ(); \
156        } \
157    } while(0)
158
159FILE *NEW(fopen)(const char *path, const char *mode)
160{
161    FILE *ret; FOPEN(fopen); return ret;
162}
163
164#if defined HAVE_FOPEN64
165FILE *NEW(fopen64)(const char *path, const char *mode)
166{
167    FILE *ret; FOPEN(fopen64); return ret;
168}
169#endif
170
171#if defined HAVE___FOPEN64
172FILE *NEW(__fopen64)(const char *path, const char *mode)
173{
174    FILE *ret; FOPEN(__fopen64); return ret;
175}
176#endif
177
178#define FREOPEN(fn) \
179    do \
180    { \
181        int fd0 = -1, fd1 = -1, disp = 0; \
182        LOADSYM(fn); \
183        if(_zz_ready && (fd0 = fileno(stream)) >= 0 && _zz_iswatched(fd0)) \
184        { \
185            _zz_unregister(fd0); \
186            disp = 1; \
187        } \
188        _zz_lock(-1); \
189        ret = ORIG(fn)(path, mode, stream); \
190        _zz_unlock(-1); \
191        if(ret && _zz_mustwatch(path)) \
192        { \
193            fd1 = fileno(ret); \
194            _zz_register(fd1); \
195            disp = 1; \
196        } \
197        if(disp) \
198            debug("%s(\"%s\", \"%s\", [%i]) = [%i]", __func__, \
199                  path, mode, fd0, fd1); \
200    } while(0)
201
202FILE *NEW(freopen)(const char *path, const char *mode, FILE *stream)
203{
204    FILE *ret; FREOPEN(freopen); return ret;
205}
206
207#if defined HAVE___FREOPEN64
208FILE *NEW(__freopen64)(const char *path, const char *mode, FILE *stream)
209{
210    FILE *ret; FREOPEN(__freopen64); return ret;
211}
212#endif
213
214#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
215#   define FSEEK_FUZZ(fn2)
216#else
217#   define FSEEK_FUZZ(fn2) \
218        if(ret == 0) \
219        { \
220            /* FIXME: check what happens when fseek()ing a pipe */ \
221            switch(whence) \
222            { \
223                case SEEK_END: \
224                    offset = fn2(stream); \
225                    /* fall through */ \
226                case SEEK_SET: \
227                    _zz_setpos(fd, offset); \
228                    break; \
229                case SEEK_CUR: \
230                    _zz_addpos(fd, offset); \
231                    break; \
232            } \
233        }
234#endif
235
236#define FSEEK(fn, fn2) \
237    do \
238    { \
239        int fd; \
240        LOADSYM(fn); \
241        fd = fileno(stream); \
242        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
243            return ORIG(fn)(stream, offset, whence); \
244        _zz_lock(fd); \
245        ret = ORIG(fn)(stream, offset, whence); \
246        _zz_unlock(fd); \
247        debug("%s([%i], %lli, %i) = %i", __func__, \
248              fd, (long long int)offset, whence, ret); \
249        FSEEK_FUZZ(fn2) \
250    } while(0)
251
252int NEW(fseek)(FILE *stream, long offset, int whence)
253{
254    int ret; FSEEK(fseek, ftell); return ret;
255}
256
257#if defined HAVE_FSEEKO
258int NEW(fseeko)(FILE *stream, off_t offset, int whence)
259{
260    int ret; FSEEK(fseeko, ftello); return ret;
261}
262#endif
263
264#if defined HAVE___FSEEKO64
265int NEW(__fseeko64)(FILE *stream, off64_t offset, int whence)
266{
267    int ret; FSEEK(__fseeko64, ftello); return ret;
268}
269#endif
270
271#if defined HAVE___FSETPOS64
272int NEW(__fsetpos64)(FILE *stream, const fpos64_t *pos)
273{
274    int ret, fd;
275
276    LOADSYM(__fsetpos64);
277    fd = fileno(stream);
278    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
279        return ORIG(__fsetpos64)(stream, pos);
280    _zz_lock(fd);
281    ret = ORIG(__fsetpos64)(stream, pos);
282    _zz_unlock(fd);
283    debug("%s([%i], %lli) = %i", __func__,
284          fd, (long long int)*pos, ret);
285    /* On HP-UX at least, fpos64_t == int64_t */
286    _zz_setpos(fd, (int64_t)*pos);
287
288    return ret;
289}
290#endif
291
292void NEW(rewind)(FILE *stream)
293{
294    int fd;
295
296    LOADSYM(rewind);
297    fd = fileno(stream);
298    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
299    {
300        ORIG(rewind)(stream);
301        return;
302    }
303
304    _zz_lock(fd);
305    ORIG(rewind)(stream);
306    _zz_unlock(fd);
307    debug("%s([%i])", __func__, fd);
308
309#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
310#else
311    /* FIXME: check what happens when rewind()ing a pipe */
312    _zz_setpos(fd, 0);
313#endif
314}
315
316#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
317#   define FREAD_FUZZ() \
318    do \
319    { \
320        debug("%s(%p, %li, %li, [%i]) = %li", __func__, ptr, \
321              (long int)size, (long int)nmemb, fd, (long int)ret); \
322    } while(0)
323#else
324#   define FREAD_FUZZ() \
325    do \
326    { \
327        int64_t newpos = ftell(stream); \
328        /* XXX: the number of bytes read is not ret * size, because \
329         * a partial read may have advanced the stream pointer. However, \
330         * when reading from a pipe ftell() will return 0, and ret * size \
331         * is then better than nothing. */ \
332        if(newpos <= 0) \
333        { \
334            pos = _zz_getpos(fd); \
335            newpos = pos + ret * size; \
336        } \
337        if(newpos != pos) \
338        { \
339            char *b = ptr; \
340            _zz_fuzz(fd, ptr, newpos - pos); \
341            _zz_setpos(fd, newpos); \
342            if(newpos >= pos + 4) \
343                debug("%s(%p, %li, %li, [%i]) = %li \"%c%c%c%c...", __func__, \
344                      ptr, (long int)size, (long int)nmemb, fd, \
345                      (long int)ret, b[0], b[1], b[2], b[3]); \
346            else \
347                debug("%s(%p, %li, %li, [%i]) = %li \"%c...", __func__, ptr, \
348                      (long int)size, (long int)nmemb, fd, \
349                      (long int)ret, b[0]); \
350        } \
351        else \
352            debug("%s(%p, %li, %li, [%i]) = %li", __func__, ptr, \
353                  (long int)size, (long int)nmemb, fd, (long int)ret); \
354    } while(0)
355#endif
356
357#define FREAD(fn) \
358    do \
359    { \
360        int64_t pos; \
361        int fd; \
362        LOADSYM(fn); \
363        fd = fileno(stream); \
364        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
365            return ORIG(fn)(ptr, size, nmemb, stream); \
366        pos = ftell(stream); \
367        _zz_lock(fd); \
368        ret = ORIG(fn)(ptr, size, nmemb, stream); \
369        _zz_unlock(fd); \
370        FREAD_FUZZ(); \
371    } while(0)
372
373size_t NEW(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
374{
375    size_t ret; FREAD(fread); return ret;
376}
377
378#if defined HAVE_FREAD_UNLOCKED
379#undef fread_unlocked /* can be a macro; we don’t want that */
380size_t NEW(fread_unlocked)(void *ptr, size_t size, size_t nmemb, FILE *stream)
381{
382    size_t ret; FREAD(fread_unlocked); return ret;
383}
384#endif
385
386#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
387#   define FGETC_FUZZ
388#else
389#   define FGETC_FUZZ \
390        if(ret != EOF) \
391        { \
392            uint8_t ch = ret; \
393            _zz_fuzz(fd, &ch, 1); \
394            _zz_addpos(fd, 1); \
395            ret = ch; \
396        }
397#endif
398
399#define FGETC(fn, s, arg) \
400    do { \
401        int fd; \
402        LOADSYM(fn); \
403        fd = fileno(s); \
404        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
405            return ORIG(fn)(arg); \
406        _zz_lock(fd); \
407        ret = ORIG(fn)(arg); \
408        _zz_unlock(fd); \
409        FGETC_FUZZ \
410        if(ret == EOF) \
411            debug("%s([%i]) = EOF", __func__, fd); \
412        else \
413            debug("%s([%i]) = '%c'", __func__, fd, ret); \
414    } while(0)
415
416#undef getc /* can be a macro; we don’t want that */
417int NEW(getc)(FILE *stream)
418{
419    int ret; FGETC(getc, stream, stream); return ret;
420}
421
422#undef getchar /* can be a macro; we don’t want that */
423int NEW(getchar)(void)
424{
425    int ret; FGETC(getchar, stdin, /* empty */); return ret;
426}
427
428int NEW(fgetc)(FILE *stream)
429{
430    int ret; FGETC(fgetc, stream, stream); return ret;
431}
432
433#if defined HAVE__IO_GETC
434int NEW(_IO_getc)(FILE *stream)
435{
436    int ret; FGETC(_IO_getc, stream, stream); return ret;
437}
438#endif
439
440#if defined HAVE_GETC_UNLOCKED
441#undef getc_unlocked /* can be a macro; we don’t want that */
442int NEW(getc_unlocked)(FILE *stream)
443{
444    int ret; FGETC(getc_unlocked, stream, stream); return ret;
445}
446#endif
447
448#if defined HAVE_GETCHAR_UNLOCKED
449#undef getchar_unlocked /* can be a macro; we don’t want that */
450int NEW(getchar_unlocked)(void)
451{
452    int ret; FGETC(getchar_unlocked, stdin, /* empty */); return ret;
453}
454#endif
455
456#if defined HAVE_FGETC_UNLOCKED
457#undef fgetc_unlocked /* can be a macro; we don’t want that */
458int NEW(fgetc_unlocked)(FILE *stream)
459{
460    int ret; FGETC(fgetc_unlocked, stream, stream); return ret;
461}
462#endif
463
464#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
465#   define FGETS_FUZZ(fn, fn2) \
466        _zz_lock(fd); \
467        ret = ORIG(fn)(s, size, stream); \
468        _zz_unlock(fd);
469#else
470#   define FGETS_FUZZ(fn, fn2) \
471        if(size <= 0) \
472            ret = NULL; \
473        else if(size == 1) \
474            s[0] = '\0'; \
475        else \
476        { \
477            int i; \
478            for(i = 0; i < size - 1; i++) \
479            { \
480                int ch; \
481                _zz_lock(fd); \
482                ch = ORIG(fn2)(stream); \
483                _zz_unlock(fd); \
484                if(ch == EOF) \
485                { \
486                    s[i] = '\0'; \
487                    if(!i) \
488                        ret = NULL; \
489                    break; \
490                } \
491                s[i] = (char)(unsigned char)ch; \
492                _zz_fuzz(fd, (uint8_t *)s + i, 1); /* rather inefficient */ \
493                _zz_addpos(fd, 1); \
494                if(s[i] == '\n') \
495                { \
496                    s[i + 1] = '\0'; \
497                    break; \
498                } \
499            } \
500        }
501#endif
502
503#define FGETS(fn, fn2) \
504    do \
505    { \
506        int fd; \
507        ret = s; \
508        LOADSYM(fn); \
509        LOADSYM(fn2); \
510        fd = fileno(stream); \
511        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
512            return ORIG(fn)(s, size, stream); \
513        FGETS_FUZZ(fn, fn2) \
514        debug("%s(%p, %i, [%i]) = %p", __func__, s, size, fd, ret); \
515    } while(0)
516
517char *NEW(fgets)(char *s, int size, FILE *stream)
518{
519    char *ret; FGETS(fgets, fgetc); return ret;
520}
521
522#if defined HAVE_FGETS_UNLOCKED
523char *NEW(fgets_unlocked)(char *s, int size, FILE *stream)
524{
525    char *ret; FGETS(fgets_unlocked, fgetc_unlocked); return ret;
526}
527#endif
528
529int NEW(ungetc)(int c, FILE *stream)
530{
531    int ret, fd;
532
533    LOADSYM(ungetc);
534    fd = fileno(stream);
535    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
536        return ORIG(ungetc)(c, stream);
537
538    _zz_lock(fd);
539    ret = ORIG(ungetc)(c, stream);
540    _zz_unlock(fd);
541
542    if(ret != EOF)
543    {
544        struct fuzz *fuzz = _zz_getfuzz(fd);
545        fuzz->uflag = 1;
546        fuzz->upos = _zz_getpos(fd) - 1;
547        fuzz->uchar = c;
548#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
549#else
550        _zz_addpos(fd, -1);
551#endif
552    }
553
554    if(ret == EOF)
555        debug("%s(0x%02x, [%i]) = EOF", __func__, c, fd);
556    else
557        debug("%s(0x%02x, [%i]) = '%c'", __func__, c, fd, ret);
558
559    return ret;
560}
561
562int NEW(fclose)(FILE *fp)
563{
564    int ret, fd;
565
566    LOADSYM(fclose);
567    fd = fileno(fp);
568    if(!_zz_ready || !_zz_iswatched(fd))
569        return ORIG(fclose)(fp);
570
571    _zz_lock(fd);
572    ret = ORIG(fclose)(fp);
573    _zz_unlock(fd);
574    debug("%s([%i]) = %i", __func__, fd, ret);
575    _zz_unregister(fd);
576
577    return ret;
578}
579
580#define GETDELIM(fn, delim, need_delim) \
581    do { \
582        char *line; \
583        ssize_t done, size; \
584        int fd, finished = 0; \
585        LOADSYM(fn); \
586        LOADSYM(getdelim); \
587        LOADSYM(fgetc); \
588        fd = fileno(stream); \
589        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
590            return ORIG(getdelim)(lineptr, n, delim, stream); \
591        line = *lineptr; \
592        size = line ? *n : 0; \
593        ret = done = finished = 0; \
594        for(;;) \
595        { \
596            int ch; \
597            if(done >= size) /* highly inefficient but I don't care */ \
598                line = realloc(line, size = done + 1); \
599            if(finished) \
600            { \
601                line[done] = '\0'; \
602                *n = size; \
603                *lineptr = line; \
604                break; \
605            } \
606            _zz_lock(fd); \
607            ch = ORIG(fgetc)(stream); \
608            _zz_unlock(fd); \
609            if(ch == EOF) \
610            { \
611                finished = 1; \
612                ret = done; \
613            } \
614            else \
615            { \
616                unsigned char c = ch; \
617                _zz_fuzz(fd, &c, 1); /* even more inefficient */ \
618                line[done++] = c; \
619                _zz_addpos(fd, 1); \
620                if(c == delim) \
621                { \
622                    finished = 1; \
623                    ret = done; \
624                } \
625            } \
626        } \
627        if(need_delim) \
628            debug("%s(%p, %p, '%c', [%i]) = %li", __func__, \
629                  lineptr, n, delim, fd, (long int)ret); \
630        else \
631            debug("%s(%p, %p, [%i]) = %li", __func__, \
632                  lineptr, n, fd, (long int)ret); \
633        return ret; \
634    } while(0)
635
636#if defined HAVE_GETLINE
637ssize_t NEW(getline)(char **lineptr, size_t *n, FILE *stream)
638{
639    ssize_t ret; GETDELIM(getline, '\n', 0); return ret;
640}
641#endif
642
643#if defined HAVE_GETDELIM
644ssize_t NEW(getdelim)(char **lineptr, size_t *n, int delim, FILE *stream)
645{
646    ssize_t ret; GETDELIM(getdelim, delim, 1); return ret;
647}
648#endif
649
650#if defined HAVE___GETDELIM
651ssize_t NEW(__getdelim)(char **lineptr, size_t *n, int delim, FILE *stream)
652{
653    ssize_t ret; GETDELIM(__getdelim, delim, 1); return ret;
654}
655#endif
656
657#if defined HAVE_FGETLN
658char *NEW(fgetln)(FILE *stream, size_t *len)
659{
660    char *ret;
661#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
662#else
663    struct fuzz *fuzz;
664    size_t i, size;
665#endif
666    int fd;
667
668    LOADSYM(fgetln);
669    LOADSYM(fgetc);
670    fd = fileno(stream);
671    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
672        return ORIG(fgetln)(stream, len);
673
674#if defined HAVE_REFILL_STDIO /* Don't fuzz or seek if we have __srefill() */
675    _zz_lock(fd);
676    ret = ORIG(fgetln)(stream, len);
677    _zz_unlock(fd);
678#else
679    fuzz = _zz_getfuzz(fd);
680
681    for(i = size = 0; ; /* i is incremented below */)
682    {
683        int ch;
684
685        _zz_lock(fd);
686        ch = ORIG(fgetc)(stream);
687        _zz_unlock(fd);
688
689        if(ch == EOF)
690            break;
691
692        if(i >= size)
693            fuzz->tmp = realloc(fuzz->tmp, (size += 80));
694
695        fuzz->tmp[i] = (char)(unsigned char)ch;
696        _zz_fuzz(fd, (uint8_t *)fuzz->tmp + i, 1); /* rather inefficient */
697        _zz_addpos(fd, 1);
698
699        if(fuzz->tmp[i++] == '\n')
700            break;
701    }
702
703    *len = i;
704    ret = fuzz->tmp;
705#endif
706
707    debug("%s([%i], &%li) = %p", __func__, fd, (long int)*len, ret);
708    return ret;
709}
710#endif
711
712#if defined HAVE___SREFILL
713int NEW(__srefill)(FILE *fp)
714{
715    off_t newpos;
716    int ret, fd;
717
718    LOADSYM(__srefill);
719    fd = fileno(fp);
720    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
721        return ORIG(__srefill)(fp);
722
723    _zz_lock(fd);
724    ret = ORIG(__srefill)(fp);
725    newpos = lseek(fd, 0, SEEK_CUR);
726    _zz_unlock(fd);
727    if(ret != EOF)
728    {
729        /* FIXME: do we have to fuzz ret, too, like in __filbuf? */
730        if(newpos != -1)
731            _zz_setpos(fd, newpos - fp->_r);
732        _zz_fuzz(fd, fp->_p, fp->_r);
733        _zz_addpos(fd, fp->_r);
734    }
735
736    if(!_zz_islocked(fd))
737        debug("%s([%i]) = %i", __func__, fd, ret);
738
739    return ret;
740}
741#endif
742
743#if defined HAVE___FILBUF
744int NEW(__filbuf)(FILE *fp)
745{
746    off_t newpos;
747    int ret, fd;
748
749    LOADSYM(__filbuf);
750    fd = fileno(fp);
751    if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd))
752        return ORIG(__filbuf)(fp);
753
754    _zz_lock(fd);
755    ret = ORIG(__filbuf)(fp);
756    newpos = lseek(fd, 0, SEEK_CUR);
757    _zz_unlock(fd);
758    if(ret != EOF)
759    {
760        if(newpos != -1)
761            _zz_setpos(fd, newpos - fp->__cnt - 1);
762        _zz_fuzz(fd, fp->__ptr - 1, fp->__cnt + 1);
763        ret = (uint8_t)fp->__ptr[-1];
764        _zz_addpos(fd, fp->__cnt + 1);
765    }
766
767    if(!_zz_islocked(fd))
768        debug("%s([%i]) = %i", __func__, fd, ret);
769
770    return ret;
771}
772#endif
773
Note: See TracBrowser for help on using the repository browser.