diff --git a/builtin.c b/builtin.c index 6c343ae8e..d6ab7db0a 100644 --- a/builtin.c +++ b/builtin.c @@ -335,7 +335,7 @@ static int builtin_bind( wchar_t **argv ) long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'M': input_set_mode( woptarg ); @@ -348,7 +348,7 @@ static int builtin_bind( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -430,7 +430,7 @@ static int builtin_block( wchar_t **argv ) long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'h': builtin_print_help( argv[0], sb_out ); return 0; @@ -450,7 +450,7 @@ static int builtin_block( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -461,13 +461,13 @@ static int builtin_block( wchar_t **argv ) if( scope != UNSET ) { sb_printf( sb_err, _( L"%ls: Can not specify scope when removing block\n" ), argv[0] ); - return 1; + return STATUS_BUILTIN_ERROR; } if( !global_event_block ) { sb_printf( sb_err, _( L"%ls: No blocks defined\n" ), argv[0] ); - return 1; + return STATUS_BUILTIN_ERROR; } event_block_t *eb = global_event_block; @@ -571,7 +571,7 @@ static int builtin_builtin( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'h': builtin_print_help( argv[0], sb_out ); return 0; @@ -583,7 +583,7 @@ static int builtin_builtin( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -660,7 +660,7 @@ static int builtin_generic( wchar_t **argv ) argv[0], long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'h': builtin_print_help( argv[0], sb_out ); @@ -669,12 +669,12 @@ static int builtin_generic( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } } - return 1; + return STATUS_BUILTIN_ERROR; } /** @@ -835,7 +835,7 @@ static int builtin_functions( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'e': erase=1; @@ -864,7 +864,7 @@ static int builtin_functions( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -882,7 +882,7 @@ static int builtin_functions( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } if( erase ) @@ -903,7 +903,7 @@ static int builtin_functions( wchar_t **argv ) argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } func = argv[woptind]; if( !function_exists( func ) ) @@ -915,7 +915,7 @@ static int builtin_functions( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } function_set_desc( func, desc ); @@ -1410,7 +1410,7 @@ static int builtin_random( wchar_t **argv ) long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'h': builtin_print_help( argv[0], sb_out ); @@ -1419,7 +1419,7 @@ static int builtin_random( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -1457,7 +1457,7 @@ static int builtin_random( wchar_t **argv ) argv[0], argv[woptind] ); - return 1; + return STATUS_BUILTIN_ERROR; } seeded=1; srand48_r( foo, &seed_buffer); @@ -1471,7 +1471,7 @@ static int builtin_random( wchar_t **argv ) argv[0], argc-woptind ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } } return 0; @@ -1558,7 +1558,7 @@ static int builtin_read( wchar_t **argv ) long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case L'x': place |= ENV_EXPORT; @@ -1589,7 +1589,7 @@ static int builtin_read( wchar_t **argv ) case L'?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } } @@ -1603,7 +1603,7 @@ static int builtin_read( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } if( (place&ENV_LOCAL?1:0) + (place & ENV_GLOBAL?1:0) + (place & ENV_UNIVERSAL?1:0) > 1) @@ -1614,7 +1614,7 @@ static int builtin_read( wchar_t **argv ) parser_current_line() ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } /* @@ -1627,7 +1627,7 @@ static int builtin_read( wchar_t **argv ) if( !wcslen( argv[i] ) ) { sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); - return 1; + return STATUS_BUILTIN_ERROR; } for( src=argv[i]; *src; src++ ) @@ -1636,7 +1636,7 @@ static int builtin_read( wchar_t **argv ) { sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *src ); sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 ); - return 1; + return STATUS_BUILTIN_ERROR; } } @@ -1859,7 +1859,7 @@ static int builtin_status( wchar_t **argv ) long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; case 'h': builtin_print_help( argv[0], sb_out ); @@ -1885,7 +1885,7 @@ static int builtin_status( wchar_t **argv ) case '?': builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -2013,7 +2013,7 @@ static int builtin_exit( wchar_t **argv ) argv[0], argv[1] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } break; } @@ -2025,7 +2025,7 @@ static int builtin_exit( wchar_t **argv ) argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } } @@ -2137,13 +2137,13 @@ static int builtin_source( wchar_t ** argv ) { sb_printf( sb_err, _( L"%ls: Expected at least one argument, got %d\n" ), argv[0], argc ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } if( wstat(argv[1], &buf) == -1 ) { builtin_wperror( L"stat" ); - return 1; + return STATUS_BUILTIN_ERROR; } if( !S_ISREG(buf.st_mode) ) @@ -2151,7 +2151,7 @@ static int builtin_source( wchar_t ** argv ) sb_printf( sb_err, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 ) { @@ -2388,7 +2388,7 @@ static int send_to_bg( job_t *j, const wchar_t *name ) L"bg", name ); builtin_print_help( L"bg", sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } else if( !j->job_control ) { @@ -2398,7 +2398,7 @@ static int send_to_bg( job_t *j, const wchar_t *name ) j->job_id, j->command ); builtin_print_help( L"bg", sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } else { @@ -2749,7 +2749,7 @@ static int builtin_end( wchar_t **argv ) argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } else { @@ -2859,7 +2859,7 @@ static int builtin_else( wchar_t **argv ) _( L"%ls: Not inside of 'if' block\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } else { @@ -2894,7 +2894,7 @@ static int builtin_break_continue( wchar_t **argv ) argv[1] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -2911,7 +2911,7 @@ static int builtin_break_continue( wchar_t **argv ) _( L"%ls: Not inside of loop\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } b = current_block; @@ -2952,7 +2952,7 @@ static int builtin_return( wchar_t **argv ) argv[0], argv[1] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } break; } @@ -2961,7 +2961,7 @@ static int builtin_return( wchar_t **argv ) _( L"%ls: Too many arguments\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } @@ -2977,7 +2977,7 @@ static int builtin_return( wchar_t **argv ) _( L"%ls: Not inside of function\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } b = current_block; @@ -3039,7 +3039,7 @@ static int builtin_case( wchar_t **argv ) _( L"%ls: 'case' command while not in switch block\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); - return 1; + return STATUS_BUILTIN_ERROR; } current_block->skip = 1; diff --git a/doc_src/doc.hdr b/doc_src/doc.hdr index ef2e37d19..98f5c40cb 100644 --- a/doc_src/doc.hdr +++ b/doc_src/doc.hdr @@ -790,7 +790,7 @@ values of most of these variables. - \c history, which is an array containing the last commands that where entered. - \c HOME, which is the users home directory. This variable can only be changed by the root user. - \c PWD, which is the current working directory. -- \c status, which is the exit status of the last foreground job to exit. If a job contains pipelines, the status of the last command in the pipeline is the status for the job. +- \c status, which is the exit status of the last foreground job to exit. - \c USER, which is the username. This variable can only be changed by the root user. Variables whose name are in uppercase are exported to the commands @@ -800,6 +800,26 @@ distinguish between exported and unexported variables. \c fish also uses several variables internally. Such variables are prefixed with the string __FISH or __fish. These should be ignored by the user. +\subsection variables-status The status variable + +Whenever a process exits, an exit status is returned to the program +that started it. This exit status is an integer number, which tells +the calling application how the execution of the command went. In +general, a zero exit status means that the command executed without +problem, but a non-zero exit status means there was some form of +problem. + +Fish stores the exit status of the last process in the last job to +exit in the \c status variable. + +If fish encounters a problem while executing a command, the status +variable may also be set to a specific value: + +- 1 is the generally the exit status from fish builtins if they where supplied with invalid arguments +- 125 means an unknown error occured while trying to execute the command +- 126 means that the command was not executed because none of the wildcards in the command produced any matches +- 127 means that no command with the given name could be located + \subsection variables-color Variables for changing highlighting colors The colors used by fish for syntax highlighting can be configured by diff --git a/exec.c b/exec.c index 842722d1f..bd4440bd9 100644 --- a/exec.c +++ b/exec.c @@ -578,7 +578,7 @@ static void internal_exec_helper( const wchar_t *def, */ if( io && !io_internal ) { - proc_set_last_status( 1 ); + proc_set_last_status( STATUS_EXEC_FAIL ); return; } @@ -1041,7 +1041,7 @@ void exec( job_t *j ) */ if( p->next == 0 ) { - proc_set_last_status( j->negate?(status?0:1):status); + proc_set_last_status( j->negate?(!status):status); } p->completed = 1; break; @@ -1091,7 +1091,7 @@ void exec( job_t *j ) { if( p->next == 0 ) { - proc_set_last_status( j->negate?(status?0:1):status); + proc_set_last_status( j->negate?(!status):status); } p->completed = 1; } @@ -1182,7 +1182,7 @@ void exec( job_t *j ) { debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status ); - proc_set_last_status( j->negate?(p->status?0:1):p->status ); + proc_set_last_status( j->negate?(!p->status):p->status ); } break; diff --git a/parser.c b/parser.c index 84c9a9e43..4d5589797 100644 --- a/parser.c +++ b/parser.c @@ -1816,7 +1816,7 @@ static void parse_job_main_loop( process_t *p, if( unmatched_wildcard && !matched_wildcard ) { j->wildcard_error = 1; - proc_set_last_status( 1 ); + proc_set_last_status( STATUS_UNMATCHED_WILDCARD ); if( is_interactive && !is_block ) { int tmp; diff --git a/proc.h b/proc.h index b44d024a2..baf7af536 100644 --- a/proc.h +++ b/proc.h @@ -24,6 +24,21 @@ */ #define STATUS_UNKNOWN_COMMAND 127 +/** + The status code use when a wildcard had no matches +*/ +#define STATUS_UNMATCHED_WILDCARD 126 + +/** + The status code use when an unknown error occured during execution of a command +*/ +#define STATUS_EXEC_FAIL 125 + +/** + The status code use for erroneous argument combinations in a builtin +*/ +#define STATUS_BUILTIN_ERROR 1 + /** Types of processes */