| 269 | */ |
| 270 | |
| 271 | void exec_cmd |
| 272 | ( |
| 273 | string const * cmd_orig, |
| 274 | ExecCmdCallback func, |
| 275 | void * closure, |
| 276 | LIST * shell |
| 277 | ) |
| 278 | { |
| 279 | int const slot = get_free_cmdtab_slot(); |
| 280 | int const is_raw_cmd = is_raw_command_request( shell ); |
| 281 | string cmd_local[ 1 ]; |
| 282 | |
| 283 | /* Initialize default shell - anything more than /Q/C is non-portable. */ |
| 284 | static LIST * default_shell; |
| 285 | if ( !default_shell ) |
| 286 | default_shell = list_new( object_new( "cmd.exe /Q/C" ) ); |
| 287 | |
| 288 | /* Specifying no shell means requesting the default shell. */ |
| 289 | if ( list_empty( shell ) ) |
| 290 | shell = default_shell; |
| 291 | |
| 292 | if ( DEBUG_EXECCMD ) |
| 293 | if ( is_raw_cmd ) |
| 294 | out_printf( "Executing raw command directly\n" ); |
| 295 | else |
| 296 | { |
| 297 | out_printf( "Executing using a command file and the shell: " ); |
| 298 | list_print( shell ); |
| 299 | out_printf( "\n" ); |
| 300 | } |
| 301 | |
| 302 | /* If we are running a raw command directly - trim its leading whitespaces |
| 303 | * as well as any trailing all-whitespace lines but keep any trailing |
| 304 | * whitespace in the final/only line containing something other than |
| 305 | * whitespace). |
| 306 | */ |
| 307 | if ( is_raw_cmd ) |
| 308 | { |
| 309 | char const * start = cmd_orig->value; |
| 310 | char const * p = cmd_orig->value + cmd_orig->size; |
| 311 | char const * end = p; |
| 312 | while ( isspace( *start ) ) ++start; |
| 313 | while ( p > start && isspace( p[ -1 ] ) ) |
| 314 | if ( *--p == '\n' ) |
| 315 | end = p; |
| 316 | string_new( cmd_local ); |
| 317 | string_append_range( cmd_local, start, end ); |
| 318 | assert( cmd_local->size == raw_command_length( cmd_orig->value ) ); |
| 319 | } |
| 320 | /* If we are not running a raw command directly, prepare a command file to |
| 321 | * be executed using an external shell and the actual command string using |
| 322 | * that command file. |
| 323 | */ |
| 324 | else |
| 325 | { |
| 326 | char const * const cmd_file = prepare_command_file( cmd_orig, slot ); |
| 327 | char const * argv[ MAXARGC + 1 ]; /* +1 for NULL */ |
| 328 | argv_from_shell( argv, shell, cmd_file, slot ); |
no test coverage detected