| 2397 | |
| 2398 | |
| 2399 | LIST * builtin_shell( FRAME * frame, int flags ) |
| 2400 | { |
| 2401 | LIST * command = lol_get( frame->args, 0 ); |
| 2402 | LIST * result = L0; |
| 2403 | string s; |
| 2404 | int32_t ret; |
| 2405 | char buffer[ 1024 ]; |
| 2406 | FILE * p = NULL; |
| 2407 | int exit_status = -1; |
| 2408 | int exit_status_opt = 0; |
| 2409 | int no_output_opt = 0; |
| 2410 | int strip_eol_opt = 0; |
| 2411 | |
| 2412 | /* Process the variable args options. */ |
| 2413 | { |
| 2414 | int a = 1; |
| 2415 | LIST * arg = lol_get( frame->args, a ); |
| 2416 | for ( ; !list_empty( arg ); arg = lol_get( frame->args, ++a ) ) |
| 2417 | { |
| 2418 | if ( !strcmp( "exit-status", object_str( list_front( arg ) ) ) ) |
| 2419 | exit_status_opt = 1; |
| 2420 | else if ( !strcmp( "no-output", object_str( list_front( arg ) ) ) ) |
| 2421 | no_output_opt = 1; |
| 2422 | else if ( !strcmp("strip-eol", object_str( list_front( arg ) ) ) ) |
| 2423 | strip_eol_opt = 1; |
| 2424 | } |
| 2425 | } |
| 2426 | |
| 2427 | /* The following fflush() call seems to be indicated as a workaround for a |
| 2428 | * popen() bug on POSIX implementations related to synhronizing input |
| 2429 | * stream positions for the called and the calling process. |
| 2430 | */ |
| 2431 | fflush( NULL ); |
| 2432 | |
| 2433 | p = popen( object_str( list_front( command ) ), "r" ); |
| 2434 | if ( p == NULL ) |
| 2435 | return L0; |
| 2436 | |
| 2437 | string_new( &s ); |
| 2438 | |
| 2439 | while ( ( ret = int32_t(fread( buffer, sizeof( char ), sizeof( buffer ) - 1, p )) ) > |
| 2440 | 0 ) |
| 2441 | { |
| 2442 | buffer[ ret ] = 0; |
| 2443 | if ( !no_output_opt ) |
| 2444 | { |
| 2445 | string_append( &s, buffer ); |
| 2446 | } |
| 2447 | |
| 2448 | /* Explicit EOF check for systems with broken fread */ |
| 2449 | if ( feof( p ) ) break; |
| 2450 | } |
| 2451 | |
| 2452 | if ( strip_eol_opt ) |
| 2453 | string_rtrim( &s ); |
| 2454 | |
| 2455 | exit_status = pclose( p ); |
| 2456 |
nothing calls this directly
no test coverage detected