Changeset 1995

Show
Ignore:
Timestamp:
13/12/2007 00:21:38 (13 months ago)
Author:
chris
Message:

Restructure intercept_errornow() for clarity.

Move delay code out of macro and into intercept_errornow() to
simplify macro.

Clear hook functions in intercept_clear_setup().

Check that intercept_filename is not NULL before comparing it with
anything.

Change some TRACEx macros to BOX_TRACE.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • box/trunk/lib/intercept/intercept.cpp

    r1491 r1995  
    7575int intercept_delay_ms = 0; 
    7676 
     77static opendir_t*  opendir_real  = NULL; 
     78static readdir_t*  readdir_real  = NULL; 
     79static readdir_t*  readdir_hook  = NULL; 
     80static closedir_t* closedir_real = NULL; 
     81static lstat_t*    lstat_real    = NULL; 
     82static lstat_t*    lstat_hook    = NULL; 
     83static const char* lstat_file    = NULL; 
     84 
    7785#define SIZE_ALWAYS_ERROR       -773 
    7886 
     
    8694        intercept_filepos = 0; 
    8795        intercept_delay_ms = 0; 
     96        readdir_hook = NULL; 
     97        lstat_hook = NULL; 
    8898} 
    8999 
     
    95105void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror) 
    96106{ 
    97         TRACE4("Setup for error: %s, after %d, err %d, syscall %d\n", filename, errorafter, errortoreturn, syscalltoerror); 
     107        BOX_TRACE("Setup for error: " << filename <<  
     108                ", after " << errorafter << 
     109                ", err " << errortoreturn << 
     110                ", syscall " << syscalltoerror); 
     111 
    98112        intercept_count = 1; 
    99113        intercept_filename = filename; 
     
    109123        int delay_ms, int syscall_to_delay, int num_delays) 
    110124{ 
    111         TRACE5("Setup for delay: %s, after %d, wait %d ms, times %d, " 
    112                 "syscall %d\n", filename, delay_after, delay_ms,  
    113                 num_delays, syscall_to_delay); 
     125        BOX_TRACE("Setup for delay: " << filename << 
     126                ", after " << delay_after << 
     127                ", wait " << delay_ms << " ms" << 
     128                ", times " << num_delays << 
     129                ", syscall " << syscall_to_delay); 
     130 
    114131        intercept_count = num_delays; 
    115132        intercept_filename = filename; 
     
    121138        intercept_delay_ms = delay_ms; 
    122139} 
     140 
    123141bool intercept_errornow(int d, int size, int syscallnum) 
    124142{ 
    125         if(intercept_filedes != -1 && d == intercept_filedes && syscallnum == intercept_syscall) 
    126         { 
    127                 //printf("Checking for err, %d, %d, %d\n", d, size, syscallnum); 
    128                 if(size == SIZE_ALWAYS_ERROR) 
    129                 { 
    130                         // Looks good for an error! 
    131                         TRACE2("Returning error %d for syscall %d\n", intercept_errno, syscallnum); 
    132                         return true; 
    133                 } 
    134                 // where are we in the file? 
    135                 if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((off_t)intercept_errorafter - size)) 
    136                 { 
    137                         if (intercept_errno != 0) 
    138                         { 
    139                                 TRACE3("Returning error %d for syscall %d, " 
    140                                         "file pos %d\n", intercept_errno,  
    141                                         syscallnum, (int)intercept_filepos); 
    142                         } 
    143                         else if (intercept_delay_ms != 0) 
    144                         { 
    145                                 TRACE3("Delaying %d ms for syscall %d, " 
    146                                         "file pos %d\n", intercept_delay_ms,  
    147                                         syscallnum, (int)intercept_filepos); 
    148                         } 
    149  
    150                         return true; 
    151                 } 
    152         } 
    153         return false;   // no error please! 
     143        ASSERT(intercept_count > 0) 
     144 
     145        if (intercept_filedes == -1) 
     146        { 
     147                return false; // no error please! 
     148        } 
     149 
     150        if (d != intercept_filedes) 
     151        { 
     152                return false; // no error please! 
     153        } 
     154 
     155        if (syscallnum != intercept_syscall) 
     156        { 
     157                return false; // no error please! 
     158        } 
     159 
     160        bool ret = false; // no error unless one of the conditions matches 
     161 
     162        //printf("Checking for err, %d, %d, %d\n", d, size, syscallnum); 
     163 
     164        if (intercept_delay_ms != 0) 
     165        { 
     166                BOX_TRACE("Delaying " << intercept_delay_ms << " ms " << 
     167                        " for syscall " << syscallnum <<  
     168                        " at " << intercept_filepos); 
     169 
     170                struct timespec tm; 
     171                tm.tv_sec = intercept_delay_ms / 1000; 
     172                tm.tv_nsec = (intercept_delay_ms % 1000) * 1000000; 
     173                while (nanosleep(&tm, &tm) != 0 && 
     174                        errno == EINTR) { } 
     175        } 
     176 
     177        if (size == SIZE_ALWAYS_ERROR) 
     178        { 
     179                // Looks good for an error! 
     180                BOX_TRACE("Returning error " << intercept_errno << 
     181                        " for syscall " << syscallnum); 
     182                ret = true; 
     183        } 
     184        else if (intercept_filepos + size < intercept_errorafter) 
     185        { 
     186                return false; // no error please 
     187        } 
     188        else if (intercept_errno != 0) 
     189        { 
     190                BOX_TRACE("Returning error " << intercept_errno <<  
     191                        " for syscall " << syscallnum << 
     192                        " at " << intercept_filepos); 
     193                ret = true; 
     194        } 
     195 
     196        intercept_count--; 
     197        if (intercept_count == 0) 
     198        { 
     199                intercept_clear_setup(); 
     200        } 
     201 
     202        return ret; 
    154203} 
    155204 
     
    161210} 
    162211 
    163 #define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES)  \ 
     212#define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES) \ 
    164213        if(intercept_count > 0) \ 
    165         {                                                                               \ 
    166                 if(intercept_errornow(D, S, CALL))      \ 
    167                 {                                                                       \ 
    168                         if(intercept_delay_ms > 0) \ 
    169                         { \ 
    170                                 struct timespec tm; \ 
    171                                 tm.tv_sec = intercept_delay_ms / 1000; \ 
    172                                 tm.tv_nsec = (intercept_delay_ms % 1000) \ 
    173                                         * 1000000; \ 
    174                                 while (nanosleep(&tm, &tm) != 0 && \ 
    175                                         errno == EINTR) { } \ 
    176                                 intercept_count --; \ 
    177                                 if (intercept_count == 0) \ 
    178                                 { \ 
    179                                         intercept_clear_setup(); \ 
    180                                 } \ 
    181                         } \ 
    182                         else \ 
    183                         { \ 
    184                                 errno = intercept_reterr();             \ 
    185                                 return FAILRES;                                 \ 
    186                         } \ 
    187                 }                                                                       \ 
     214        { \ 
     215                if(intercept_errornow(D, S, CALL)) \ 
     216                { \ 
     217                        errno = intercept_reterr(); \ 
     218                        return FAILRES; \ 
     219                } \ 
    188220        } 
    189221 
     
    193225        if(intercept_count > 0) 
    194226        { 
    195                 if(intercept_syscall == SYS_open && strcmp(path, intercept_filename) == 0) 
     227                if(intercept_filename != NULL && 
     228                        intercept_syscall == SYS_open && 
     229                        strcmp(path, intercept_filename) == 0) 
    196230                { 
    197231                        errno = intercept_reterr(); 
     
    199233                } 
    200234        } 
     235 
    201236#ifdef PLATFORM_NO_SYSCALL 
    202237        int r = TEST_open(path, flags, mode); 
     
    204239        int r = syscall(SYS_open, path, flags, mode); 
    205240#endif 
    206         if(intercept_count > 0 && intercept_filedes == -1) 
     241 
     242        if(intercept_filename != NULL &&  
     243                intercept_count > 0 &&  
     244                intercept_filedes == -1) 
    207245        { 
    208246                // Right file? 
     
    213251                } 
    214252        } 
     253 
    215254        return r; 
    216255} 
     
    324363} 
    325364 
    326 static opendir_t*  opendir_real  = NULL; 
    327 static readdir_t*  readdir_real  = NULL; 
    328 static readdir_t*  readdir_hook  = NULL; 
    329 static closedir_t* closedir_real = NULL; 
    330 static lstat_t*    lstat_real    = NULL; 
    331 static lstat_t*    lstat_hook    = NULL; 
    332 static const char* lstat_file    = NULL; 
    333  
    334365void intercept_setup_readdir_hook(const char *dirname, readdir_t hookfn) 
    335366{ 
     
    337368        { 
    338369                dirname = intercept_filename; 
     370                ASSERT(dirname != NULL); 
    339371        } 
    340372 
     
    343375                TRACE2("readdir hooked to %p for %s\n", hookfn, dirname); 
    344376        } 
    345         else 
     377        else if (intercept_filename != NULL) 
    346378        { 
    347379                TRACE2("readdir unhooked from %p for %s\n", readdir_hook,  
     
    387419        DIR* r = opendir_real(dirname); 
    388420 
    389         if(readdir_hook != NULL && intercept_filedes == -1 &&  
     421        if (readdir_hook != NULL &&  
     422                intercept_filename != NULL &&  
     423                intercept_filedes == -1 &&  
    390424                strcmp(intercept_filename, dirname) == 0) 
    391425        {