/* | |
* Copyright 1993, 1995 Christopher Seiwald. | |
* Copyright 2007 Noel Belcourt. | |
* | |
* Utility functions shared between different exec*.c platform specific | |
* implementation modules. | |
* | |
* This file is part of Jam - see jam.c for Copyright information. | |
*/ | |
/* Internal interrupt counter. */ | |
static int intr; | |
/* Constructs a list of command-line elements using the format specified by the | |
* given shell list. | |
* | |
* Given argv array should have at least MAXARGC + 1 elements. | |
* Slot numbers may be between 0 and 998 (inclusive). | |
* | |
* Constructed argv list will be zero terminated. Character arrays referenced by | |
* the argv structure elements will be either elements from the give shell list, | |
* internal static buffers or the given command string and should thus not | |
* considered owned by or released via the argv structure and should be | |
* considered invalidated by the next argv_from_shell() call. | |
* | |
* Shell list elements: | |
* - Starting with '%' - represent the command string. | |
* - Starting with '!' - represent the slot number (increased by one). | |
* - Anything else - used as a literal. | |
* - If no '%' element is found, the command string is appended as an extra. | |
*/ | |
void argv_from_shell( char const * * argv, LIST * shell, char const * command, | |
int const slot ) | |
{ | |
static char jobno[ 4 ]; | |
int i; | |
int gotpercent = 0; | |
LISTITER iter = list_begin( shell ); | |
LISTITER end = list_end( shell ); | |
assert( 0 <= slot ); | |
assert( slot < 999 ); | |
sprintf( jobno, "%d", slot + 1 ); | |
for ( i = 0; iter != end && i < MAXARGC; ++i, iter = list_next( iter ) ) | |
{ | |
switch ( object_str( list_item( iter ) )[ 0 ] ) | |
{ | |
case '%': argv[ i ] = command; ++gotpercent; break; | |
case '!': argv[ i ] = jobno; break; | |
default : argv[ i ] = object_str( list_item( iter ) ); | |
} | |
} | |
if ( !gotpercent ) | |
argv[ i++ ] = command; | |
argv[ i ] = NULL; | |
} | |
/* Returns whether the given command string contains lines longer than the given | |
* maximum. | |
*/ | |
int check_cmd_for_too_long_lines( char const * command, int const max, | |
int * const error_length, int * const error_max_length ) | |
{ | |
while ( *command ) | |
{ | |
size_t const l = strcspn( command, "\n" ); | |
if ( l > max ) | |
{ | |
*error_length = l; | |
*error_max_length = max; | |
return EXEC_CHECK_LINE_TOO_LONG; | |
} | |
command += l; | |
if ( *command ) | |
++command; | |
} | |
return EXEC_CHECK_OK; | |
} | |
/* Checks whether the given shell list is actually a request to execute raw | |
* commands without an external shell. | |
*/ | |
int is_raw_command_request( LIST * shell ) | |
{ | |
return !list_empty( shell ) && | |
!strcmp( object_str( list_front( shell ) ), "%" ) && | |
list_next( list_begin( shell ) ) == list_end( shell ); | |
} | |
/* Returns whether an interrupt has been detected so far. */ | |
int interrupted( void ) | |
{ | |
return intr != 0; | |
} | |
/* Internal interrupt handler. */ | |
void onintr( int disp ) | |
{ | |
++intr; | |
printf( "...interrupted\n" ); | |
} | |