mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +00:00
Check return value of a few write calls and retry on EINTR, and fix a few other warnings, mostly by printing error messages before giving up.
darcs-hash:20090222202852-ac50b-b0e79142af5b7a99e55271d4001fa252d9684a1d.gz
This commit is contained in:
parent
f71c6f3f0e
commit
14c84ffbcb
13 changed files with 122 additions and 30 deletions
|
@ -2849,7 +2849,7 @@ static int builtin_source( wchar_t ** argv )
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_( L"%ls: Error while reading file '%ls'\n" ),
|
_( L"%ls: Error while reading file '%ls'\n" ),
|
||||||
argv[0],
|
argv[0],
|
||||||
fn_intern == L"-" ? L"<stdin>" : fn_intern );
|
fn_intern == intern_static(L"-") ? L"<stdin>" : fn_intern );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
39
common.c
39
common.c
|
@ -578,6 +578,36 @@ int read_blocked(int fd, void *buf, size_t count)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t write_loop(int fd, char *buff, size_t count)
|
||||||
|
{
|
||||||
|
ssize_t out=0;
|
||||||
|
ssize_t out_cum=0;
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
out = write( fd,
|
||||||
|
&buff[out_cum],
|
||||||
|
count - out_cum );
|
||||||
|
if (out == -1)
|
||||||
|
{
|
||||||
|
if( errno != EAGAIN &&
|
||||||
|
errno != EINTR )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
out_cum += out;
|
||||||
|
}
|
||||||
|
if( out_cum >= count )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out_cum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void debug( int level, const wchar_t *msg, ... )
|
void debug( int level, const wchar_t *msg, ... )
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
|
@ -1815,7 +1845,14 @@ double timef()
|
||||||
|
|
||||||
if( time_res )
|
if( time_res )
|
||||||
{
|
{
|
||||||
return nan(0);
|
/*
|
||||||
|
Fixme: What on earth is the correct parameter value for NaN?
|
||||||
|
The man pages and the standard helpfully state that this
|
||||||
|
parameter is implementation defined. Gcc gives a warning if
|
||||||
|
a null pointer is used. But not even all mighty Google gives
|
||||||
|
a hint to what value should actually be returned.
|
||||||
|
*/
|
||||||
|
return nan("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (double)tv.tv_sec + 0.000001*tv.tv_usec;
|
return (double)tv.tv_sec + 0.000001*tv.tv_usec;
|
||||||
|
|
6
common.h
6
common.h
|
@ -331,6 +331,12 @@ __sentinel int contains_internal( const wchar_t *needle, ... );
|
||||||
*/
|
*/
|
||||||
int read_blocked(int fd, void *buf, size_t count);
|
int read_blocked(int fd, void *buf, size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Loop a write request while failiure is non-critical. Return -1 and set errno
|
||||||
|
in case of critical error.
|
||||||
|
*/
|
||||||
|
ssize_t write_loop(int fd, char *buff, size_t count);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Issue a debug message with printf-style string formating and
|
Issue a debug message with printf-style string formating and
|
||||||
|
|
35
exec.c
35
exec.c
|
@ -53,6 +53,11 @@
|
||||||
*/
|
*/
|
||||||
#define FD_ERROR _( L"An error occurred while redirecting file descriptor %d" )
|
#define FD_ERROR _( L"An error occurred while redirecting file descriptor %d" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
file descriptor redirection error message
|
||||||
|
*/
|
||||||
|
#define WRITE_ERROR _( L"An error occurred while writing output" )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
file redirection error message
|
file redirection error message
|
||||||
*/
|
*/
|
||||||
|
@ -92,6 +97,18 @@ static array_list_t *open_fds=0;
|
||||||
|
|
||||||
static int set_child_group( job_t *j, process_t *p, int print_errors );
|
static int set_child_group( job_t *j, process_t *p, int print_errors );
|
||||||
|
|
||||||
|
static void exec_write_and_exit( int fd, char *buff, size_t count, int status )
|
||||||
|
{
|
||||||
|
if( write_loop(fd, buff, count) == -1 )
|
||||||
|
{
|
||||||
|
debug( 0, WRITE_ERROR);
|
||||||
|
wperror( L"write" );
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
exit( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void exec_close( int fd )
|
void exec_close( int fd )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1426,15 +1443,17 @@ void exec( job_t *j )
|
||||||
|
|
||||||
if( pid == 0 )
|
if( pid == 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the child process. Write out the contents of the pipeline.
|
This is the child process. Write out the contents of the pipeline.
|
||||||
*/
|
*/
|
||||||
p->pid = getpid();
|
p->pid = getpid();
|
||||||
setup_child_process( j, p );
|
setup_child_process( j, p );
|
||||||
write( io_buffer->fd,
|
|
||||||
io_buffer->param2.out_buffer->buff,
|
exec_write_and_exit(io_buffer->fd,
|
||||||
io_buffer->param2.out_buffer->used );
|
io_buffer->param2.out_buffer->buff,
|
||||||
exit( status );
|
io_buffer->param2.out_buffer->used,
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1480,10 +1499,10 @@ void exec( job_t *j )
|
||||||
p->pid = getpid();
|
p->pid = getpid();
|
||||||
setup_child_process( j, p );
|
setup_child_process( j, p );
|
||||||
|
|
||||||
write( 1,
|
exec_write_and_exit( 1,
|
||||||
input_redirect->param2.out_buffer->buff,
|
input_redirect->param2.out_buffer->buff,
|
||||||
input_redirect->param2.out_buffer->used );
|
input_redirect->param2.out_buffer->used,
|
||||||
exit( 0 );
|
0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -351,7 +351,7 @@ static int pager_buffered_writer( char c)
|
||||||
*/
|
*/
|
||||||
static void pager_flush()
|
static void pager_flush()
|
||||||
{
|
{
|
||||||
write( 1, pager_buffer->buff, pager_buffer->used );
|
write_loop( 1, pager_buffer->buff, pager_buffer->used );
|
||||||
pager_buffer->used = 0;
|
pager_buffer->used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
fishd.c
2
fishd.c
|
@ -521,7 +521,7 @@ static void load_or_save( int save)
|
||||||
if( save )
|
if( save )
|
||||||
{
|
{
|
||||||
|
|
||||||
write( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
write_loop( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
||||||
enqueue_all( &c );
|
enqueue_all( &c );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
19
mimedb.c
19
mimedb.c
|
@ -94,6 +94,17 @@ license. Read the source code of the library for more information.
|
||||||
*/
|
*/
|
||||||
#define GETOPT_STRING "tfimdalhv"
|
#define GETOPT_STRING "tfimdalhv"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Error message if system call goes wrong.
|
||||||
|
*/
|
||||||
|
#define ERROR_SYSTEM "%s: Could not execute command \"%s\"\n"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Exit code if system call goes wrong.
|
||||||
|
*/
|
||||||
|
#define STATUS_ERROR_SYSTEM 1
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
All types of input and output possible
|
All types of input and output possible
|
||||||
*/
|
*/
|
||||||
|
@ -1127,8 +1138,12 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
||||||
writer( '&' );
|
writer( '&' );
|
||||||
writer( '\0' );
|
writer( '\0' );
|
||||||
|
|
||||||
// fprintf( stderr, "mimedb: %s\n", launch_buff );
|
if( system( launch_buff ) == -1 )
|
||||||
system( launch_buff );
|
{
|
||||||
|
fprintf( stderr, _( ERROR_SYSTEM ), MIMEDB, launch_buff );
|
||||||
|
exit(STATUS_ERROR_SYSTEM);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
output.c
2
output.c
|
@ -362,7 +362,7 @@ void set_color( int c, int c2 )
|
||||||
*/
|
*/
|
||||||
static int writeb_internal( char c )
|
static int writeb_internal( char c )
|
||||||
{
|
{
|
||||||
write( 1, &c, 1 );
|
write_loop( 1, &c, 1 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
parser.c
3
parser.c
|
@ -436,6 +436,7 @@ typedef struct
|
||||||
/**
|
/**
|
||||||
Return the current number of block nestings
|
Return the current number of block nestings
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
static int block_count( block_t *b )
|
static int block_count( block_t *b )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -443,7 +444,7 @@ static int block_count( block_t *b )
|
||||||
return 0;
|
return 0;
|
||||||
return( block_count(b->outer)+1);
|
return( block_count(b->outer)+1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void parser_push_block( int type )
|
void parser_push_block( int type )
|
||||||
{
|
{
|
||||||
|
|
12
print_help.c
12
print_help.c
|
@ -5,18 +5,26 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "print_help.h"
|
#include "print_help.h"
|
||||||
|
|
||||||
#define CMD_LEN 1024
|
#define CMD_LEN 1024
|
||||||
|
|
||||||
|
#define HELP_ERR "Could not show help message\n"
|
||||||
|
|
||||||
void print_help( char *c, int fd )
|
void print_help( char *c, int fd )
|
||||||
{
|
{
|
||||||
char cmd[ CMD_LEN];
|
char cmd[ CMD_LEN];
|
||||||
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
|
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
|
||||||
|
|
||||||
if( printed < CMD_LEN )
|
if( printed < CMD_LEN )
|
||||||
system( cmd );
|
{
|
||||||
|
if( (system( cmd ) == -1) )
|
||||||
|
{
|
||||||
|
write_loop(2, HELP_ERR, strlen(HELP_ERR));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
10
proc.c
10
proc.c
|
@ -356,6 +356,8 @@ static void mark_process_status( job_t *j,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ssize_t ignore;
|
||||||
|
|
||||||
/* This should never be reached */
|
/* This should never be reached */
|
||||||
p->completed = 1;
|
p->completed = 1;
|
||||||
|
|
||||||
|
@ -364,8 +366,12 @@ static void mark_process_status( job_t *j,
|
||||||
MESS_SIZE,
|
MESS_SIZE,
|
||||||
"Process %d exited abnormally\n",
|
"Process %d exited abnormally\n",
|
||||||
(int) p->pid );
|
(int) p->pid );
|
||||||
|
/*
|
||||||
write( 2, mess, strlen(mess) );
|
If write fails, do nothing. We're in a signal handlers error
|
||||||
|
handler. If things aren't working properly, it's safer to
|
||||||
|
give up.
|
||||||
|
*/
|
||||||
|
ignore = write( 2, mess, strlen(mess) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
reader.c
8
reader.c
|
@ -1577,9 +1577,9 @@ static int handle_completions( array_list_t *comp )
|
||||||
wchar_t quote;
|
wchar_t quote;
|
||||||
get_param( data->buff, data->buff_pos, "e, 0, 0, 0 );
|
get_param( data->buff, data->buff_pos, "e, 0, 0, 0 );
|
||||||
is_quoted = (quote != L'\0');
|
is_quoted = (quote != L'\0');
|
||||||
|
|
||||||
write(1, "\n", 1 );
|
write_loop(1, "\n", 1 );
|
||||||
|
|
||||||
run_pager( prefix, is_quoted, comp );
|
run_pager( prefix, is_quoted, comp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2650,7 +2650,7 @@ wchar_t *reader_readline()
|
||||||
case R_REPAINT:
|
case R_REPAINT:
|
||||||
{
|
{
|
||||||
exec_prompt();
|
exec_prompt();
|
||||||
write( 1, "\r", 1 );
|
write_loop( 1, "\r", 1 );
|
||||||
s_reset( &data->screen, 0 );
|
s_reset( &data->screen, 0 );
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
break;
|
break;
|
||||||
|
|
12
screen.c
12
screen.c
|
@ -337,7 +337,7 @@ static void s_check_status( screen_t *s)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int prev_line = s->actual_cursor[1];
|
int prev_line = s->actual_cursor[1];
|
||||||
write( 1, "\r", 1 );
|
write_loop( 1, "\r", 1 );
|
||||||
s_reset( s, 0 );
|
s_reset( s, 0 );
|
||||||
s->actual_cursor[1] = prev_line;
|
s->actual_cursor[1] = prev_line;
|
||||||
}
|
}
|
||||||
|
@ -756,7 +756,7 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
||||||
|
|
||||||
if( output.used )
|
if( output.used )
|
||||||
{
|
{
|
||||||
write( 1, output.buff, output.used );
|
write_loop( 1, output.buff, output.used );
|
||||||
}
|
}
|
||||||
|
|
||||||
b_destroy( &output );
|
b_destroy( &output );
|
||||||
|
@ -804,9 +804,9 @@ void s_write( screen_t *s,
|
||||||
char *prompt_narrow = wcs2str( prompt );
|
char *prompt_narrow = wcs2str( prompt );
|
||||||
char *buffer_narrow = wcs2str( b );
|
char *buffer_narrow = wcs2str( b );
|
||||||
|
|
||||||
write( 1, "\r", 1 );
|
write_loop( 1, "\r", 1 );
|
||||||
write( 1, prompt_narrow, strlen( prompt_narrow ) );
|
write_loop( 1, prompt_narrow, strlen( prompt_narrow ) );
|
||||||
write( 1, buffer_narrow, strlen( buffer_narrow ) );
|
write_loop( 1, buffer_narrow, strlen( buffer_narrow ) );
|
||||||
|
|
||||||
free( prompt_narrow );
|
free( prompt_narrow );
|
||||||
free( buffer_narrow );
|
free( buffer_narrow );
|
||||||
|
@ -938,7 +938,7 @@ void s_reset( screen_t *s, int reset_cursor )
|
||||||
This should prevent reseting the cursor position during the
|
This should prevent reseting the cursor position during the
|
||||||
next repaint.
|
next repaint.
|
||||||
*/
|
*/
|
||||||
write( 1, "\r", 1 );
|
write_loop( 1, "\r", 1 );
|
||||||
s->actual_cursor[1] = prev_line;
|
s->actual_cursor[1] = prev_line;
|
||||||
}
|
}
|
||||||
fstat( 1, &s->prev_buff_1 );
|
fstat( 1, &s->prev_buff_1 );
|
||||||
|
|
Loading…
Reference in a new issue