Changeset 4013 for zzuf/trunk


Ignore:
Timestamp:
Nov 23, 2009, 2:35:23 AM (11 years ago)
Author:
Sam Hocevar
Message:

More fread() behaviour improvements, with documentation.

Location:
zzuf/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/src/lib-fd.c

    r3635 r4013  
    147147static int     (*ORIG(close))   (int fd);
    148148
    149 #define OPEN(fn) \
     149#define OPEN(myopen) \
    150150    do \
    151151    { \
    152152        int mode = 0; \
    153         LOADSYM(fn); \
     153        LOADSYM(myopen); \
    154154        if(oflag & O_CREAT) \
    155155        { \
     
    158158            mode = va_arg(va, int); \
    159159            va_end(va); \
    160             ret = ORIG(fn)(file, oflag, mode); \
     160            ret = ORIG(myopen)(file, oflag, mode); \
    161161        } \
    162162        else \
    163163        { \
    164             ret = ORIG(fn)(file, oflag); \
     164            ret = ORIG(myopen)(file, oflag); \
    165165        } \
    166166        if(!_zz_ready || _zz_islocked(-1)) \
     
    276276#endif
    277277
    278 #define CONNECTION(fn, addr) \
     278#define CONNECTION(myconnect, addr) \
    279279    do \
    280280    { \
    281         LOADSYM(fn); \
    282         ret = ORIG(fn)(sockfd, addr, addrlen); \
     281        LOADSYM(myconnect); \
     282        ret = ORIG(myconnect)(sockfd, addr, addrlen); \
    283283        if(!_zz_ready || _zz_islocked(-1) || !_zz_network) \
    284284            return ret; \
     
    529529#endif
    530530
    531 #define LSEEK(fn, off_t) \
     531#define LSEEK(mylseek, off_t) \
    532532    do \
    533533    { \
    534         LOADSYM(fn); \
    535         ret = ORIG(fn)(fd, offset, whence); \
     534        LOADSYM(mylseek); \
     535        ret = ORIG(mylseek)(fd, offset, whence); \
    536536        if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd) \
    537537             || !_zz_isactive(fd)) \
  • zzuf/trunk/src/lib-mem.c

    r4005 r4013  
    249249int nbmaps = 0;
    250250
    251 #define MMAP(fn, off_t) \
     251#define MMAP(mymmap, off_t) \
    252252    do { \
    253253        char *b = MAP_FAILED; \
    254         LOADSYM(fn); \
     254        LOADSYM(mymmap); \
    255255        if(!_zz_ready || !_zz_iswatched(fd) || _zz_islocked(fd) \
    256256             || !_zz_isactive(fd)) \
    257             return ORIG(fn)(start, length, prot, flags, fd, offset); \
    258         ret = ORIG(fn)(NULL, length, prot, flags, fd, offset); \
     257            return ORIG(mymmap)(start, length, prot, flags, fd, offset); \
     258        ret = ORIG(mymmap)(NULL, length, prot, flags, fd, offset); \
    259259        if(ret != MAP_FAILED && length) \
    260260        { \
    261             b = ORIG(fn)(start, length, PROT_READ | PROT_WRITE, \
    262                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
     261            b = ORIG(mymmap)(start, length, PROT_READ | PROT_WRITE, \
     262                             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
    263263            if(b == MAP_FAILED) \
    264264            { \
  • zzuf/trunk/src/lib-stream.c

    r4012 r4013  
    160160
    161161/* Helper functions for refill-like functions */
     162static inline uint8_t *get_stream_ptr(FILE *stream)
     163{
    162164#if defined HAVE___FILBUF || defined HAVE___SRGET || defined HAVE___UFLOW
    163 static inline uint8_t *get_stream_ptr(FILE *stream)
    164 {
    165165    return (uint8_t *)stream->FILE_PTR;
     166#else
     167    return NULL;
     168#endif
    166169}
    167170
    168171static inline int get_stream_cnt(FILE *stream)
    169172{
    170 #   if defined HAVE_GLIBC_FP
     173#if defined HAVE_GLIBC_FP
    171174    return (int)((uint8_t *)stream->FILE_CNT - (uint8_t *)stream->FILE_PTR);
    172 #   else
     175#elif defined HAVE___FILBUF || defined HAVE___SRGET || defined HAVE___UFLOW
    173176    return stream->FILE_CNT;
    174 #   endif
    175 }
    176 #endif
    177 
    178 /* Our function wrappers */
     177#else
     178    return 0;
     179#endif
     180}
     181
     182#define DEBUG_STREAM(prefix, fp) \
     183    debug2(prefix "stream([%i], %p, %i)", fileno(fp), \
     184           get_stream_ptr(fp), get_stream_cnt(fp));
     185
     186/*
     187 * fopen, fopen64 etc.
     188 */
     189
    179190#if defined REFILL_ONLY_STDIO /* Fuzz fp if we have __srefill() */
    180191#   define FOPEN_FUZZ() \
     
    184195#endif
    185196
    186 #define BEGIN_STREAM(fp) \
    187     debug2("oldstream([%i], %p, %i)", fileno(fp), \
    188            get_stream_ptr(fp), get_stream_cnt(fp));
    189 
    190 #define END_STREAM(fp) \
    191     debug2("newstream([%i], %p, %i)", fileno(fp), \
    192            get_stream_ptr(fp), get_stream_cnt(fp));
    193 
    194 #define FOPEN(fn) \
     197#define FOPEN(myfopen) \
    195198    do \
    196199    { \
    197         LOADSYM(fn); \
     200        LOADSYM(myfopen); \
    198201        if(!_zz_ready) \
    199             return ORIG(fn)(path, mode); \
     202            return ORIG(myfopen)(path, mode); \
    200203        _zz_lock(-1); \
    201         ret = ORIG(fn)(path, mode); \
     204        ret = ORIG(myfopen)(path, mode); \
    202205        _zz_unlock(-1); \
    203206        if(ret && _zz_mustwatch(path)) \
     
    206209            _zz_register(fd); \
    207210            debug("%s(\"%s\", \"%s\") = [%i]", __func__, path, mode, fd); \
    208             END_STREAM(ret); \
     211            DEBUG_STREAM("new", ret); \
    209212            FOPEN_FUZZ(); \
    210213        } \
     
    230233#endif
    231234
    232 #define FREOPEN(fn) \
     235/*
     236 * freopen, freopen64 etc.
     237 */
     238
     239#define FREOPEN(myfreopen) \
    233240    do \
    234241    { \
    235242        int fd0 = -1, fd1 = -1, disp = 0; \
    236         LOADSYM(fn); \
     243        LOADSYM(myfreopen); \
    237244        if(_zz_ready && (fd0 = fileno(stream)) >= 0 && _zz_iswatched(fd0)) \
    238245        { \
     
    241248        } \
    242249        _zz_lock(-1); \
    243         ret = ORIG(fn)(path, mode, stream); \
     250        ret = ORIG(myfreopen)(path, mode, stream); \
    244251        _zz_unlock(-1); \
    245252        if(ret && _zz_mustwatch(path)) \
     
    273280#endif
    274281
     282/*
     283 * fseek, fseeko etc.
     284 */
     285
    275286#if defined REFILL_ONLY_STDIO /* Don't fuzz or seek if we have __srefill() */
    276 #   define FSEEK_FUZZ(fn2)
    277 #else
    278 #   define FSEEK_FUZZ(fn2) \
     287#   define FSEEK_FUZZ(myftell)
     288#else
     289#   define FSEEK_FUZZ(myftell) \
    279290        if(ret == 0) \
    280291        { \
     
    283294            { \
    284295                case SEEK_END: \
    285                     offset = fn2(stream); \
     296                    offset = myftell(stream); \
    286297                    /* fall through */ \
    287298                case SEEK_SET: \
     
    295306#endif
    296307
    297 #define FSEEK(fn, fn2) \
     308#define FSEEK(myfseek, myftell) \
    298309    do \
    299310    { \
    300311        int fd; \
    301         LOADSYM(fn); \
     312        LOADSYM(myfseek); \
    302313        fd = fileno(stream); \
    303314        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    304             return ORIG(fn)(stream, offset, whence); \
    305         BEGIN_STREAM(stream); \
     315            return ORIG(myfseek)(stream, offset, whence); \
     316        DEBUG_STREAM("old", stream); \
    306317        _zz_lock(fd); \
    307         ret = ORIG(fn)(stream, offset, whence); \
     318        ret = ORIG(myfseek)(stream, offset, whence); \
    308319        _zz_unlock(fd); \
    309320        debug("%s([%i], %lli, %i) = %i", __func__, \
    310321              fd, (long long int)offset, whence, ret); \
    311         FSEEK_FUZZ(fn2) \
    312         END_STREAM(stream); \
     322        FSEEK_FUZZ(myftell) \
     323        DEBUG_STREAM("new", stream); \
    313324    } while(0)
    314325
     
    339350#endif
    340351
    341 #define FSETPOS(fn) \
     352/*
     353 * fsetpos64, __fsetpos64
     354 */
     355
     356#define FSETPOS(myfsetpos) \
    342357    do \
    343358    { \
    344359        int fd; \
    345         LOADSYM(fn); \
     360        LOADSYM(myfsetpos); \
    346361        fd = fileno(stream); \
    347362        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    348             return ORIG(fn)(stream, pos); \
    349         BEGIN_STREAM(stream); \
     363            return ORIG(myfsetpos)(stream, pos); \
     364        DEBUG_STREAM("old", stream); \
    350365        _zz_lock(fd); \
    351         ret = ORIG(fn)(stream, pos); \
     366        ret = ORIG(myfsetpos)(stream, pos); \
    352367        _zz_unlock(fd); \
    353368        debug("%s([%i], %lli) = %i", __func__, \
    354369              fd, (long long int)FPOS_CAST(*pos), ret); \
    355370        _zz_setpos(fd, (int64_t)FPOS_CAST(*pos)); \
    356         END_STREAM(stream); \
     371        DEBUG_STREAM("new", stream); \
    357372    } \
    358373    while(0)
     
    371386}
    372387#endif
     388
     389/*
     390 * rewind
     391 */
    373392
    374393void NEW(rewind)(FILE *stream)
     
    396415}
    397416
     417/*
     418 * fread, fread_unlocked
     419 */
     420
    398421/* Compute how many bytes from the stream were already fuzzed by __filbuf,
    399422 * __srget or __uflow, and store it in already_fuzzed. If these functions
    400423 * are not available, do nothing. */
    401424#if defined HAVE___FILBUF || defined HAVE___SRGET || defined HAVE___UFLOW
    402 #   define FREAD_PREFUZZ(fd, pos) \
     425#   define FREAD_PREFUZZ(fd, oldpos) \
    403426    do \
    404427    { \
    405428        int64_t tmp = _zz_getpos(fd); \
    406         _zz_setpos(fd, pos); \
     429        _zz_setpos(fd, oldpos); \
    407430        already_fuzzed = _zz_getfuzzed(fd); \
    408431        _zz_setpos(fd, tmp); \
     
    410433    while(0)
    411434#else
    412 #   define FREAD_PREFUZZ(fd, pos) do {} while(0)
     435#   define FREAD_PREFUZZ(fd, oldpos) do {} while(0)
    413436#endif
    414437
     
    418441 * one that actually fuzzes things. */
    419442#if defined REFILL_ONLY_STDIO
    420 #   define FREAD_FUZZ(fd, pos) \
     443#   define FREAD_FUZZ(fd, oldpos) \
    421444    do \
    422445    { \
     
    425448    } while(0)
    426449#else
    427 #   define FREAD_FUZZ(fd, pos) \
     450#   define FREAD_FUZZ(fd, oldpos) \
    428451    do \
    429452    { \
     
    435458        if(newpos <= 0) \
    436459        { \
    437             pos = _zz_getpos(fd); \
    438             newpos = pos + ret * size; \
     460            oldpos = _zz_getpos(fd); \
     461            newpos = oldpos + ret * size; \
    439462        } \
    440         if(newpos != pos) \
     463        if(newpos != oldpos) \
    441464        { \
    442465            char *b = ptr; \
    443466            /* Skip bytes that were already fuzzed by __filbuf or __srget */ \
    444             if(newpos > pos + already_fuzzed) \
     467            if(newpos > oldpos + already_fuzzed) \
    445468            { \
    446                 _zz_setpos(fd, pos + already_fuzzed); \
    447                 _zz_fuzz(fd, ptr, newpos - pos - already_fuzzed); \
     469                _zz_setpos(fd, oldpos + already_fuzzed); \
     470                _zz_fuzz(fd, ptr, newpos - oldpos - already_fuzzed); \
     471                /* FIXME: we need to fuzz the extra bytes that may have been \
     472                 * read by the fread call we just made, or subsequent calls \
     473                 * to getc_unlocked may miss them. */ \
     474                _zz_setpos(fd, newpos); \
     475                _zz_fuzz(fd, get_stream_ptr(stream), get_stream_cnt(stream)); \
     476                _zz_setfuzzed(fd, get_stream_cnt(stream)); \
     477                /* FIXME: *AND* we need to fuzz the buffer before the current \
     478                 * position, in case fseek() causes us to rewind. */ \
    448479            } \
    449             /* FIXME: we need to fuzz the extra bytes that may have been \
    450              * read by the fread call we just made, or subsequent calls \
    451              * to getc_unlocked may miss them. */ \
    452480            _zz_setpos(fd, newpos); \
    453             if(newpos >= pos + 4) \
     481            if(newpos >= oldpos + 4) \
    454482                debug("%s(%p, %li, %li, [%i]) = %li \"%c%c%c%c...", __func__, \
    455483                      ptr, (long int)size, (long int)nmemb, fd, \
     
    466494#endif
    467495
    468 #define FREAD(fn) \
     496#define FREAD(myfread) \
    469497    do \
    470498    { \
    471         int64_t pos; \
     499        int64_t oldpos; \
    472500        int fd, already_fuzzed = 0; \
    473         LOADSYM(fn); \
     501        LOADSYM(myfread); \
    474502        fd = fileno(stream); \
    475503        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    476             return ORIG(fn)(ptr, size, nmemb, stream); \
    477         BEGIN_STREAM(stream); \
    478         pos = ftell(stream); \
     504            return ORIG(myfread)(ptr, size, nmemb, stream); \
     505        DEBUG_STREAM("old", stream); \
     506        oldpos = ftell(stream); \
    479507        _zz_lock(fd); \
    480         ret = ORIG(fn)(ptr, size, nmemb, stream); \
     508        ret = ORIG(myfread)(ptr, size, nmemb, stream); \
    481509        _zz_unlock(fd); \
    482         FREAD_PREFUZZ(fd, pos); \
    483         FREAD_FUZZ(fd, pos); \
    484         END_STREAM(stream); \
     510        FREAD_PREFUZZ(fd, oldpos); \
     511        FREAD_FUZZ(fd, oldpos); \
     512        DEBUG_STREAM("new", stream); \
    485513    } while(0)
    486514
     
    497525}
    498526#endif
     527
     528/*
     529 * getc, getchar, fgetc etc.
     530 */
    499531
    500532#if defined HAVE___FILBUF || defined HAVE___SRGET || defined HAVE___UFLOW
     
    518550#endif
    519551
    520 #define FGETC(fn, s, arg) \
     552#define FGETC(myfgetc, s, arg) \
    521553    do { \
    522554        int fd, already_fuzzed = 0; \
    523         LOADSYM(fn); \
     555        LOADSYM(myfgetc); \
    524556        fd = fileno(s); \
    525557        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    526             return ORIG(fn)(arg); \
    527         BEGIN_STREAM(s); \
     558            return ORIG(myfgetc)(arg); \
     559        DEBUG_STREAM("old", s); \
    528560        _zz_lock(fd); \
    529         ret = ORIG(fn)(arg); \
     561        ret = ORIG(myfgetc)(arg); \
    530562        _zz_unlock(fd); \
    531563        FGETC_PREFUZZ \
     
    535567        else \
    536568            debug("%s([%i]) = '%c'", __func__, fd, ret); \
    537         END_STREAM(s); \
     569        DEBUG_STREAM("new", s); \
    538570    } while(0)
    539571
     
    586618#endif
    587619
     620/*
     621 * fgets, fgets_unlocked
     622 */
     623
    588624#if defined REFILL_ONLY_STDIO /* Don't fuzz or seek if we have __srefill() */
    589 #   define FGETS_FUZZ(fn, fn2) \
     625#   define FGETS_FUZZ(myfgets, myfgetc) \
    590626        _zz_lock(fd); \
    591         ret = ORIG(fn)(s, size, stream); \
     627        ret = ORIG(myfgets)(s, size, stream); \
    592628        _zz_unlock(fd);
    593629#else
    594 #   define FGETS_FUZZ(fn, fn2) \
     630#   define FGETS_FUZZ(myfgets, myfgetc) \
    595631        if(size <= 0) \
    596632            ret = NULL; \
     
    604640                int ch; \
    605641                _zz_lock(fd); \
    606                 ch = ORIG(fn2)(stream); \
     642                ch = ORIG(myfgetc)(stream); \
    607643                _zz_unlock(fd); \
    608644                if(ch == EOF) \
     
    625661#endif
    626662
    627 #define FGETS(fn, fn2) \
     663#define FGETS(myfgets, myfgetc) \
    628664    do \
    629665    { \
    630666        int fd; \
    631667        ret = s; \
    632         LOADSYM(fn); \
    633         LOADSYM(fn2); \
     668        LOADSYM(myfgets); \
     669        LOADSYM(myfgetc); \
    634670        fd = fileno(stream); \
    635671        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    636             return ORIG(fn)(s, size, stream); \
    637         BEGIN_STREAM(s); \
    638         FGETS_FUZZ(fn, fn2) \
     672            return ORIG(myfgets)(s, size, stream); \
     673        DEBUG_STREAM("old", s); \
     674        FGETS_FUZZ(myfgets, myfgetc) \
    639675        debug("%s(%p, %i, [%i]) = %p", __func__, s, size, fd, ret); \
    640         END_STREAM(s); \
     676        DEBUG_STREAM("new", s); \
    641677    } while(0)
    642678
     
    652688}
    653689#endif
     690
     691/*
     692 * ungetc
     693 */
    654694
    655695int NEW(ungetc)(int c, FILE *stream)
     
    662702        return ORIG(ungetc)(c, stream);
    663703
    664     BEGIN_STREAM(stream);
     704    DEBUG_STREAM("old", stream);
    665705    _zz_lock(fd);
    666706    ret = ORIG(ungetc)(c, stream);
     
    683723    else
    684724        debug("%s(0x%02x, [%i]) = '%c'", __func__, c, fd, ret);
    685     END_STREAM(stream);
     725    DEBUG_STREAM("new", stream);
    686726    return ret;
    687727}
     728
     729/*
     730 * fclose
     731 */
    688732
    689733int NEW(fclose)(FILE *fp)
     
    696740        return ORIG(fclose)(fp);
    697741
    698     BEGIN_STREAM(fp);
     742    DEBUG_STREAM("old", fp);
    699743    _zz_lock(fd);
    700744    ret = ORIG(fclose)(fp);
     
    706750}
    707751
    708 #define GETDELIM(fn, delim, need_delim) \
     752/*
     753 * getline, getdelim etc.
     754 */
     755
     756#define GETDELIM(mygetdelim, delim, need_delim) \
    709757    do { \
    710758        char *line; \
    711759        ssize_t done, size; \
    712760        int fd, already_fuzzed = 0, finished = 0; \
    713         LOADSYM(fn); \
     761        LOADSYM(mygetdelim); \
    714762        LOADSYM(getdelim); \
    715763        LOADSYM(fgetc); \
     
    720768            break; \
    721769        } \
    722         BEGIN_STREAM(stream); \
     770        DEBUG_STREAM("old", stream); \
    723771        line = *lineptr; \
    724772        size = line ? *n : 0; \
     
    763811            debug("%s(%p, %p, [%i]) = %li", __func__, \
    764812                  lineptr, n, fd, (long int)ret); \
    765         END_STREAM(stream); \
     813        DEBUG_STREAM("new", stream); \
    766814        break; \
    767815    } while(0)
     
    787835}
    788836#endif
     837
     838/*
     839 * fgetln
     840 */
    789841
    790842#if defined HAVE_FGETLN
     
    805857        return ORIG(fgetln)(stream, len);
    806858
    807     BEGIN_STREAM(stream);
     859    DEBUG_STREAM("old", stream);
    808860#if defined REFILL_ONLY_STDIO /* Don't fuzz or seek if we have __srefill() */
    809861    _zz_lock(fd);
     
    840892
    841893    debug("%s([%i], &%li) = %p", __func__, fd, (long int)*len, ret);
    842     END_STREAM(stream);
     894    DEBUG_STREAM("new", stream);
    843895    return ret;
    844896}
    845897#endif
    846898
    847 #if defined HAVE___FILBUF || defined HAVE___SRGET
     899/*
     900 * __srefill, __filbuf, __srget, __uflow
     901 */
     902
     903#if defined HAVE___SREFILL || defined HAVE___FILBUF || defined HAVE___SRGET
    848904#   define REFILL_RETURNS_INT 1
    849905#elif defined HAVE___UFLOW
     
    851907#endif
    852908
    853 #define REFILL(fn, fn_advances) \
     909#define REFILL(myrefill, fn_advances) \
    854910    do \
    855911    { \
     
    857913        off_t newpos; \
    858914        int fd; \
    859         LOADSYM(fn); \
     915        LOADSYM(myrefill); \
    860916        fd = fileno(fp); \
    861917        if(!_zz_ready || !_zz_iswatched(fd) || !_zz_isactive(fd)) \
    862             return ORIG(fn)(fp); \
    863         BEGIN_STREAM(fp); \
     918            return ORIG(myrefill)(fp); \
     919        DEBUG_STREAM("old", fp); \
    864920        pos = _zz_getpos(fd); \
    865921        _zz_lock(fd); \
    866         ret = ORIG(fn)(fp); \
     922        ret = ORIG(myrefill)(fp); \
    867923        newpos = lseek(fd, 0, SEEK_CUR); \
    868924        _zz_unlock(fd); \
     
    902958        else \
    903959            debug("%s([%i]) = '%c'", __func__, fd, ret); \
    904         END_STREAM(fp); \
     960        DEBUG_STREAM("new", fp); \
    905961    } \
    906962    while(0)
Note: See TracChangeset for help on using the changeset viewer.