mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +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,
|
||||
_( L"%ls: Error while reading file '%ls'\n" ),
|
||||
argv[0],
|
||||
fn_intern == L"-" ? L"<stdin>" : fn_intern );
|
||||
fn_intern == intern_static(L"-") ? L"<stdin>" : fn_intern );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
39
common.c
39
common.c
|
@ -578,6 +578,36 @@ int read_blocked(int fd, void *buf, size_t count)
|
|||
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, ... )
|
||||
{
|
||||
va_list va;
|
||||
|
@ -1815,7 +1845,14 @@ double timef()
|
|||
|
||||
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;
|
||||
|
|
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);
|
||||
|
||||
/**
|
||||
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
|
||||
|
|
35
exec.c
35
exec.c
|
@ -53,6 +53,11 @@
|
|||
*/
|
||||
#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
|
||||
*/
|
||||
|
@ -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 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 )
|
||||
{
|
||||
int i;
|
||||
|
@ -1426,15 +1443,17 @@ void exec( job_t *j )
|
|||
|
||||
if( pid == 0 )
|
||||
{
|
||||
|
||||
/*
|
||||
This is the child process. Write out the contents of the pipeline.
|
||||
*/
|
||||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
write( io_buffer->fd,
|
||||
io_buffer->param2.out_buffer->buff,
|
||||
io_buffer->param2.out_buffer->used );
|
||||
exit( status );
|
||||
|
||||
exec_write_and_exit(io_buffer->fd,
|
||||
io_buffer->param2.out_buffer->buff,
|
||||
io_buffer->param2.out_buffer->used,
|
||||
status);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1480,10 +1499,10 @@ void exec( job_t *j )
|
|||
p->pid = getpid();
|
||||
setup_child_process( j, p );
|
||||
|
||||
write( 1,
|
||||
input_redirect->param2.out_buffer->buff,
|
||||
input_redirect->param2.out_buffer->used );
|
||||
exit( 0 );
|
||||
exec_write_and_exit( 1,
|
||||
input_redirect->param2.out_buffer->buff,
|
||||
input_redirect->param2.out_buffer->used,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -351,7 +351,7 @@ static int pager_buffered_writer( char c)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
2
fishd.c
2
fishd.c
|
@ -521,7 +521,7 @@ static void load_or_save( int save)
|
|||
if( save )
|
||||
{
|
||||
|
||||
write( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
||||
write_loop( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
|
||||
enqueue_all( &c );
|
||||
}
|
||||
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"
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
|
@ -1127,8 +1138,12 @@ static void launch( char *filter, array_list_t *files, int fileno )
|
|||
writer( '&' );
|
||||
writer( '\0' );
|
||||
|
||||
// fprintf( stderr, "mimedb: %s\n", launch_buff );
|
||||
system( launch_buff );
|
||||
if( system( launch_buff ) == -1 )
|
||||
{
|
||||
fprintf( stderr, _( ERROR_SYSTEM ), MIMEDB, launch_buff );
|
||||
exit(STATUS_ERROR_SYSTEM);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
2
output.c
2
output.c
|
@ -362,7 +362,7 @@ void set_color( int c, int c2 )
|
|||
*/
|
||||
static int writeb_internal( char c )
|
||||
{
|
||||
write( 1, &c, 1 );
|
||||
write_loop( 1, &c, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
3
parser.c
3
parser.c
|
@ -436,6 +436,7 @@ typedef struct
|
|||
/**
|
||||
Return the current number of block nestings
|
||||
*/
|
||||
/*
|
||||
static int block_count( block_t *b )
|
||||
{
|
||||
|
||||
|
@ -443,7 +444,7 @@ static int block_count( block_t *b )
|
|||
return 0;
|
||||
return( block_count(b->outer)+1);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void parser_push_block( int type )
|
||||
{
|
||||
|
|
12
print_help.c
12
print_help.c
|
@ -5,18 +5,26 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "print_help.h"
|
||||
|
||||
#define CMD_LEN 1024
|
||||
|
||||
#define HELP_ERR "Could not show help message\n"
|
||||
|
||||
void print_help( char *c, int fd )
|
||||
{
|
||||
char cmd[ CMD_LEN];
|
||||
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
|
||||
|
||||
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
|
||||
{
|
||||
ssize_t ignore;
|
||||
|
||||
/* This should never be reached */
|
||||
p->completed = 1;
|
||||
|
||||
|
@ -364,8 +366,12 @@ static void mark_process_status( job_t *j,
|
|||
MESS_SIZE,
|
||||
"Process %d exited abnormally\n",
|
||||
(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;
|
||||
get_param( data->buff, data->buff_pos, "e, 0, 0, 0 );
|
||||
is_quoted = (quote != L'\0');
|
||||
|
||||
write(1, "\n", 1 );
|
||||
|
||||
|
||||
write_loop(1, "\n", 1 );
|
||||
|
||||
run_pager( prefix, is_quoted, comp );
|
||||
}
|
||||
|
||||
|
@ -2650,7 +2650,7 @@ wchar_t *reader_readline()
|
|||
case R_REPAINT:
|
||||
{
|
||||
exec_prompt();
|
||||
write( 1, "\r", 1 );
|
||||
write_loop( 1, "\r", 1 );
|
||||
s_reset( &data->screen, 0 );
|
||||
reader_repaint();
|
||||
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];
|
||||
write( 1, "\r", 1 );
|
||||
write_loop( 1, "\r", 1 );
|
||||
s_reset( s, 0 );
|
||||
s->actual_cursor[1] = prev_line;
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
|
||||
if( output.used )
|
||||
{
|
||||
write( 1, output.buff, output.used );
|
||||
write_loop( 1, output.buff, output.used );
|
||||
}
|
||||
|
||||
b_destroy( &output );
|
||||
|
@ -804,9 +804,9 @@ void s_write( screen_t *s,
|
|||
char *prompt_narrow = wcs2str( prompt );
|
||||
char *buffer_narrow = wcs2str( b );
|
||||
|
||||
write( 1, "\r", 1 );
|
||||
write( 1, prompt_narrow, strlen( prompt_narrow ) );
|
||||
write( 1, buffer_narrow, strlen( buffer_narrow ) );
|
||||
write_loop( 1, "\r", 1 );
|
||||
write_loop( 1, prompt_narrow, strlen( prompt_narrow ) );
|
||||
write_loop( 1, buffer_narrow, strlen( buffer_narrow ) );
|
||||
|
||||
free( prompt_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
|
||||
next repaint.
|
||||
*/
|
||||
write( 1, "\r", 1 );
|
||||
write_loop( 1, "\r", 1 );
|
||||
s->actual_cursor[1] = prev_line;
|
||||
}
|
||||
fstat( 1, &s->prev_buff_1 );
|
||||
|
|
Loading…
Reference in a new issue