1
1

viewer: Ticket: #410 certain binary treated-as-roff files cause viewer hangup

Hangup state:
viewer executes program an checks whether it emits data from stdout
or stderr and receives them via UNIX pipes. Viewer reads stdout
synchronously (fread). Inferior program tries to write large chunk
to stderr when viewer is blocked on stdout read. We get a deadlock:

* viewer is blocked reading from empty nonclosed stdout
* inferior app is blocked by full stderr pipe

To prevent this we close stderr right after first read byte from stdout.

Signed-off-by: Sergei Trofimovich <slyfox@inbox.ru>
Этот коммит содержится в:
Sergei Trofimovich 2009-06-20 16:29:44 +03:00
родитель f5980a332d
Коммит 40438bfd0f
2 изменённых файлов: 18 добавлений и 1 удалений

Просмотреть файл

@ -351,10 +351,13 @@ void open_error_pipe (void)
old_error = dup (2);
if(old_error < 0 || close(2) || dup (error_pipe[1]) != 2){
message (D_NORMAL, _("Warning"), _(" Dup failed "));
close (error_pipe[0]);
close (error_pipe[1]);
error_pipe[0] = -1;
}
/* we never write there */
close (error_pipe[1]);
error_pipe[1] = -1;
}
/*
@ -369,6 +372,10 @@ close_error_pipe (int error, const char *text)
char msg[MAX_PIPE_SIZE];
int len = 0;
/* already closed */
if (error_pipe[0] == -1)
return;
if (error)
title = MSG_ERROR;
else
@ -382,6 +389,7 @@ close_error_pipe (int error, const char *text)
if (len >= 0)
msg[len] = 0;
close (error_pipe[0]);
error_pipe[0] = -1;
}
if (error < 0)
return 0; /* Just ignore error message */

Просмотреть файл

@ -1936,6 +1936,15 @@ view_load_command_output (WView *view, const char *command)
if (!close_error_pipe (view_is_in_panel (view) ? -1 : D_ERROR, NULL))
view_show_error (view, _("Empty output from child filter"));
return FALSE;
} else {
/*
* At least something was read correctly. Close stderr and let
* program die if it will try to write something there.
*
* Ideally stderr should be read asynchronously to prevent programs
* from blocking (poll/select multiplexor).
*/
close_error_pipe (D_NORMAL, NULL);
}
return TRUE;
}