Changeset 1995
- Timestamp:
- 13/12/2007 00:21:38 (13 months ago)
- Files:
-
- 1 modified
-
box/trunk/lib/intercept/intercept.cpp (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/lib/intercept/intercept.cpp
r1491 r1995 75 75 int intercept_delay_ms = 0; 76 76 77 static opendir_t* opendir_real = NULL; 78 static readdir_t* readdir_real = NULL; 79 static readdir_t* readdir_hook = NULL; 80 static closedir_t* closedir_real = NULL; 81 static lstat_t* lstat_real = NULL; 82 static lstat_t* lstat_hook = NULL; 83 static const char* lstat_file = NULL; 84 77 85 #define SIZE_ALWAYS_ERROR -773 78 86 … … 86 94 intercept_filepos = 0; 87 95 intercept_delay_ms = 0; 96 readdir_hook = NULL; 97 lstat_hook = NULL; 88 98 } 89 99 … … 95 105 void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror) 96 106 { 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 98 112 intercept_count = 1; 99 113 intercept_filename = filename; … … 109 123 int delay_ms, int syscall_to_delay, int num_delays) 110 124 { 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 114 131 intercept_count = num_delays; 115 132 intercept_filename = filename; … … 121 138 intercept_delay_ms = delay_ms; 122 139 } 140 123 141 bool intercept_errornow(int d, int size, int syscallnum) 124 142 { 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; 154 203 } 155 204 … … 161 210 } 162 211 163 #define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES) \212 #define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES) \ 164 213 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 } \ 188 220 } 189 221 … … 193 225 if(intercept_count > 0) 194 226 { 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) 196 230 { 197 231 errno = intercept_reterr(); … … 199 233 } 200 234 } 235 201 236 #ifdef PLATFORM_NO_SYSCALL 202 237 int r = TEST_open(path, flags, mode); … … 204 239 int r = syscall(SYS_open, path, flags, mode); 205 240 #endif 206 if(intercept_count > 0 && intercept_filedes == -1) 241 242 if(intercept_filename != NULL && 243 intercept_count > 0 && 244 intercept_filedes == -1) 207 245 { 208 246 // Right file? … … 213 251 } 214 252 } 253 215 254 return r; 216 255 } … … 324 363 } 325 364 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 334 365 void intercept_setup_readdir_hook(const char *dirname, readdir_t hookfn) 335 366 { … … 337 368 { 338 369 dirname = intercept_filename; 370 ASSERT(dirname != NULL); 339 371 } 340 372 … … 343 375 TRACE2("readdir hooked to %p for %s\n", hookfn, dirname); 344 376 } 345 else 377 else if (intercept_filename != NULL) 346 378 { 347 379 TRACE2("readdir unhooked from %p for %s\n", readdir_hook, … … 387 419 DIR* r = opendir_real(dirname); 388 420 389 if(readdir_hook != NULL && intercept_filedes == -1 && 421 if (readdir_hook != NULL && 422 intercept_filename != NULL && 423 intercept_filedes == -1 && 390 424 strcmp(intercept_filename, dirname) == 0) 391 425 {
