Skip to content

Commit

Permalink
Check return value of a few write calls and retry on EINTR, and fix a…
Browse files Browse the repository at this point in the history
… few other warnings, mostly by printing error messages before giving up.

darcs-hash:20090222202852-ac50b-b0e79142af5b7a99e55271d4001fa252d9684a1d.gz
  • Loading branch information
liljencrantz committed Feb 22, 2009
1 parent f71c6f3 commit 14c84ff
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 30 deletions.
2 changes: 1 addition & 1 deletion builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
39 changes: 38 additions & 1 deletion common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 27 additions & 8 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion fish_pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion fishd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 17 additions & 2 deletions mimedb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
3 changes: 2 additions & 1 deletion parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,14 +436,15 @@ typedef struct
/**
Return the current number of block nestings
*/
/*
static int block_count( block_t *b )
{
if( b==0)
return 0;
return( block_count(b->outer)+1);
}

*/

void parser_push_block( int type )
{
Expand Down
12 changes: 10 additions & 2 deletions print_help.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 8 additions & 2 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ static void mark_process_status( job_t *j,
}
else
{
ssize_t ignore;

/* This should never be reached */
p->completed = 1;

Expand All @@ -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) );
}
}

Expand Down
8 changes: 4 additions & 4 deletions reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1577,9 +1577,9 @@ static int handle_completions( array_list_t *comp )
wchar_t quote;
get_param( data->buff, data->buff_pos, &quote, 0, 0, 0 );
is_quoted = (quote != L'\0');
write(1, "\n", 1 );


write_loop(1, "\n", 1 );
run_pager( prefix, is_quoted, comp );
}

Expand Down Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down

0 comments on commit 14c84ff

Please sign in to comment.