* Execute a script, breaking it up into individual commands and passing them * sequentially into DDB's input processing. Use the KDB jump buffer to * restore control to the main script loop if things get too wonky when * processing a command -- i.e., traps, etc. Also, make sure we don't exceed * practical limits on recursion. * * XXXRW: If any individual command is too long, it will be tru
| 268 | * before configuring it to avoid this scenario. |
| 269 | */ |
| 270 | static int |
| 271 | db_script_exec(const char *scriptname, int warnifnotfound) |
| 272 | { |
| 273 | struct db_recursion_data *drd; |
| 274 | struct ddb_script *dsp; |
| 275 | char *buffer, *command; |
| 276 | void *prev_jb; |
| 277 | jmp_buf jb; |
| 278 | |
| 279 | dsp = db_script_lookup(scriptname); |
| 280 | if (dsp == NULL) { |
| 281 | if (warnifnotfound) |
| 282 | db_printf("script '%s' not found\n", scriptname); |
| 283 | return (ENOENT); |
| 284 | } |
| 285 | |
| 286 | if (db_recursion >= DB_MAXSCRIPTRECURSION) { |
| 287 | db_printf("Script stack too deep\n"); |
| 288 | return (E2BIG); |
| 289 | } |
| 290 | db_recursion++; |
| 291 | drd = &db_recursion_data[db_recursion]; |
| 292 | |
| 293 | /* |
| 294 | * Parse script in temporary buffer, since strsep() is destructive. |
| 295 | */ |
| 296 | buffer = drd->drd_buffer; |
| 297 | strcpy(buffer, dsp->ds_script); |
| 298 | while ((command = strsep(&buffer, ";")) != NULL) { |
| 299 | db_printf("db:%d:%s> %s\n", db_recursion, dsp->ds_scriptname, |
| 300 | command); |
| 301 | db_command_trim(&command); |
| 302 | prev_jb = kdb_jmpbuf(jb); |
| 303 | if (setjmp(jb) == 0) |
| 304 | db_command_script(command); |
| 305 | else |
| 306 | db_printf("Script command '%s' returned error\n", |
| 307 | command); |
| 308 | kdb_jmpbuf(prev_jb); |
| 309 | } |
| 310 | db_recursion--; |
| 311 | return (0); |
| 312 | } |
| 313 | |
| 314 | /* |
| 315 | * Wrapper for exec path that is called on KDB enter. Map reason for KDB |
no test coverage detected