1
1

* subshell.c: restart write() calls interrupted by sigchld which lead

to some bytes being swallowed from the subshell's output.
Этот коммит содержится в:
Andrew V. Samoilov 2006-01-23 18:55:36 +00:00
родитель 8de760e37b
Коммит ee404fbebe
2 изменённых файлов: 42 добавлений и 13 удалений

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

@ -1,3 +1,8 @@
2006-01-23 Egmont Koblinger <egmont@uhulinux.hu>
* subshell.c: restart write() calls interrupted by sigchld which lead
to some bytes being swallowed from the subshell's output.
2006-01-07 Roland Illig <roland.illig@gmx.de> 2006-01-07 Roland Illig <roland.illig@gmx.de>
* view.c: Replaced calls to printw() with tty_printf() to get * view.c: Replaced calls to printw() with tty_printf() to get

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

@ -149,6 +149,30 @@ static struct termios raw_mode;
static int prompt_pos; static int prompt_pos;
/*
* Write all data, even if the write() call is interrupted.
*/
static ssize_t
write_all (int fd, const void *buf, size_t count)
{
ssize_t ret;
ssize_t written = 0;
while (count > 0) {
ret = write (fd, buf, count);
if (ret < 0) {
if (errno == EINTR) {
continue;
} else {
return written > 0 ? written : ret;
}
}
buf += ret;
count -= ret;
written += ret;
}
return written;
}
/* /*
* Prepare child process to running the shell and run it. * Prepare child process to running the shell and run it.
* *
@ -476,7 +500,7 @@ init_subshell (void)
tcsh_fifo); tcsh_fifo);
break; break;
} }
write (subshell_pty, precmd, strlen (precmd)); write_all (subshell_pty, precmd, strlen (precmd));
/* Wait until the subshell has started up and processed the command */ /* Wait until the subshell has started up and processed the command */
@ -533,16 +557,16 @@ int invoke_subshell (const char *command, int how, char **new_dir)
subshell_state = ACTIVE; subshell_state = ACTIVE;
/* FIXME: possibly take out this hack; the user can /* FIXME: possibly take out this hack; the user can
re-play it by hitting C-hyphen a few times! */ re-play it by hitting C-hyphen a few times! */
write (subshell_pty, " \b", 2); /* Hack to make prompt reappear */ write_all (subshell_pty, " \b", 2); /* Hack to make prompt reappear */
} }
} }
else /* MC has passed us a user command */ else /* MC has passed us a user command */
{ {
if (how == QUIETLY) if (how == QUIETLY)
write (subshell_pty, " ", 1); write_all (subshell_pty, " ", 1);
/* FIXME: if command is long (>8KB ?) we go comma */ /* FIXME: if command is long (>8KB ?) we go comma */
write (subshell_pty, command, strlen (command)); write_all (subshell_pty, command, strlen (command));
write (subshell_pty, "\n", 1); write_all (subshell_pty, "\n", 1);
subshell_state = RUNNING_COMMAND; subshell_state = RUNNING_COMMAND;
subshell_ready = FALSE; subshell_ready = FALSE;
} }
@ -767,21 +791,21 @@ do_subshell_chdir (const char *directory, int do_update, int reset_prompt)
/* The initial space keeps this out of the command history (in bash /* The initial space keeps this out of the command history (in bash
because we set "HISTCONTROL=ignorespace") */ because we set "HISTCONTROL=ignorespace") */
write (subshell_pty, " cd ", 4); write_all (subshell_pty, " cd ", 4);
if (*directory) { if (*directory) {
char *temp = subshell_name_quote (directory); char *temp = subshell_name_quote (directory);
if (temp) { if (temp) {
write (subshell_pty, temp, strlen (temp)); write_all (subshell_pty, temp, strlen (temp));
g_free (temp); g_free (temp);
} else { } else {
/* Should not happen unless the directory name is so long /* Should not happen unless the directory name is so long
that we don't have memory to quote it. */ that we don't have memory to quote it. */
write (subshell_pty, ".", 1); write_all (subshell_pty, ".", 1);
} }
} else { } else {
write (subshell_pty, "/", 1); write_all (subshell_pty, "/", 1);
} }
write (subshell_pty, "\n", 1); write_all (subshell_pty, "\n", 1);
subshell_state = RUNNING_COMMAND; subshell_state = RUNNING_COMMAND;
feed_subshell (QUIETLY, FALSE); feed_subshell (QUIETLY, FALSE);
@ -954,7 +978,7 @@ feed_subshell (int how, int fail_on_error)
} }
if (how == VISIBLY) if (how == VISIBLY)
write (STDOUT_FILENO, pty_buffer, bytes); write_all (STDOUT_FILENO, pty_buffer, bytes);
} }
else if (FD_ISSET (subshell_pipe[READ], &read_set)) else if (FD_ISSET (subshell_pipe[READ], &read_set))
@ -996,13 +1020,13 @@ feed_subshell (int how, int fail_on_error)
for (i = 0; i < bytes; ++i) for (i = 0; i < bytes; ++i)
if (pty_buffer[i] == subshell_switch_key) { if (pty_buffer[i] == subshell_switch_key) {
write (subshell_pty, pty_buffer, i); write_all (subshell_pty, pty_buffer, i);
if (subshell_ready) if (subshell_ready)
subshell_state = INACTIVE; subshell_state = INACTIVE;
return TRUE; return TRUE;
} }
write (subshell_pty, pty_buffer, bytes); write_all (subshell_pty, pty_buffer, bytes);
subshell_ready = FALSE; subshell_ready = FALSE;
} else { } else {
return FALSE; return FALSE;