nano.c:do_int_speller - Change all child error checks to use one goto (gasp) called close_pipes_and_exit, so we don't leak FDs

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1344 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2003-01-12 23:54:05 +00:00
parent ed4fb2cf0f
commit 3f1b6851cb
2 changed files with 36 additions and 54 deletions

View File

@ -100,6 +100,8 @@ Changes
redundant word list. [The only reason this is going in during redundant word list. [The only reason this is going in during
feature freeze is because the int speller is useless as is and should feature freeze is because the int speller is useless as is and should
either be improved or removed. I chose improved]. either be improved or removed. I chose improved].
- Change all child error checks to use one goto (gasp!) called
close_pipes_and_exit, so we don't leak FDs.
do_int_speller(), do_alt_speller() do_int_speller(), do_alt_speller()
- Programs now return char *, NULL for successful completion, - Programs now return char *, NULL for successful completion,
otherwise the error string to display. This allows us to give otherwise the error string to display. This allows us to give

88
nano.c
View File

@ -1695,15 +1695,14 @@ char *do_int_speller(char *tempfile_name)
{ {
char *read_buff, *read_buff_ptr, *read_buff_word; char *read_buff, *read_buff_ptr, *read_buff_word;
size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread; size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread;
int spell_fd[2], sort_fd[2], uniq_fd[2], tempfile_fd; int spell_fd[2], sort_fd[2], uniq_fd[2], tempfile_fd = -1;
pid_t pid_spell, pid_sort, pid_uniq; pid_t pid_spell, pid_sort, pid_uniq;
int spell_status, sort_status, uniq_status; int spell_status, sort_status, uniq_status;
char *pipe_msg = _("Could not create pipe"); /* Create all three pipes up front */
/* Create a pipe to spell program */
if (pipe(spell_fd) == -1) if (pipe(spell_fd) == -1 || pipe(sort_fd) == -1 || pipe(uniq_fd) == -1)
return pipe_msg; return _("Could not create pipe");
statusbar(_("Creating misspelled word list, please wait...")); statusbar(_("Creating misspelled word list, please wait..."));
/* A new process to run spell in */ /* A new process to run spell in */
@ -1715,59 +1714,44 @@ char *do_int_speller(char *tempfile_name)
close(spell_fd[0]); close(spell_fd[0]);
/* replace the standard in with the tempfile */ /* replace the standard in with the tempfile */
if ((tempfile_fd = open(tempfile_name, O_RDONLY)) == -1) { if ((tempfile_fd = open(tempfile_name, O_RDONLY)) == -1)
close(spell_fd[1]); goto close_pipes_and_exit;
exit(1);
} if (dup2(tempfile_fd, STDIN_FILENO) != STDIN_FILENO)
if (dup2(tempfile_fd, STDIN_FILENO) != STDIN_FILENO) { goto close_pipes_and_exit;
close(tempfile_fd);
close(spell_fd[1]);
exit(1);
}
close(tempfile_fd); close(tempfile_fd);
/* send spell's standard out to the pipe */ /* send spell's standard out to the pipe */
if (dup2(spell_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
if (dup2(spell_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
close(spell_fd[1]);
exit(1);
}
close(spell_fd[1]); close(spell_fd[1]);
/* Start spell program, we are using the PATH here!?!? */ /* Start spell program, we are using the PATH here!?!? */
execlp("spell", "spell", NULL); execlp("spell", "spell", NULL);
/* Should not be reached, if spell is found!!! */ /* Should not be reached, if spell is found!!! */
exit(1); exit(1);
} }
/* Parent continues here */ /* Parent continues here */
close(spell_fd[1]); close(spell_fd[1]);
if (pipe(sort_fd) == -1)
return pipe_msg;
/* A new process to run sort in */ /* A new process to run sort in */
if ((pid_sort = fork()) == 0) { if ((pid_sort = fork()) == 0) {
/* Child continues, (i.e. future spell process) */ /* Child continues, (i.e. future spell process) */
/* replace the standard in with output of the old pipe */ /* replace the standard in with output of the old pipe */
if (dup2(spell_fd[0], STDIN_FILENO) != STDIN_FILENO) { if (dup2(spell_fd[0], STDIN_FILENO) != STDIN_FILENO)
close(spell_fd[0]); goto close_pipes_and_exit;
close(sort_fd[1]);
exit(1);
}
close(spell_fd[0]); close(spell_fd[0]);
/* send sort's standard out to the new pipe */ /* send sort's standard out to the new pipe */
if (dup2(sort_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
if (dup2(sort_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
close(sort_fd[1]);
exit(1);
}
close(sort_fd[1]); close(sort_fd[1]);
/* Start sort program. Use -f to remove mixed case without having /* Start sort program. Use -f to remove mixed case without having
@ -1775,64 +1759,49 @@ char *do_int_speller(char *tempfile_name)
execlp("sort", "sort", "-f", NULL); execlp("sort", "sort", "-f", NULL);
/* Should not be reached, if sort is found */ /* Should not be reached, if sort is found */
exit(1); exit(1);
} }
close(sort_fd[1]); close(sort_fd[1]);
/* And one more for uniq! */
if (pipe(uniq_fd) == -1)
return pipe_msg;
/* A new process to run uniq in */ /* A new process to run uniq in */
if ((pid_uniq = fork()) == 0) { if ((pid_uniq = fork()) == 0) {
/* Child continues, (i.e. future uniq process) */ /* Child continues, (i.e. future uniq process) */
/* replace the standard in with output of the old pipe */ /* replace the standard in with output of the old pipe */
if (dup2(sort_fd[0], STDIN_FILENO) != STDIN_FILENO) { if (dup2(sort_fd[0], STDIN_FILENO) != STDIN_FILENO)
close(sort_fd[0]); goto close_pipes_and_exit;
close(uniq_fd[1]);
exit(1);
}
close(sort_fd[0]); close(sort_fd[0]);
/* send uniq's standard out to the new pipe */ /* send uniq's standard out to the new pipe */
if (dup2(uniq_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
if (dup2(uniq_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
close(uniq_fd[1]);
exit(1);
}
close(uniq_fd[1]); close(uniq_fd[1]);
/* Start uniq program, we are using PATH */ /* Start uniq program, we are using PATH */
execlp("uniq", "uniq", NULL); execlp("uniq", "uniq", NULL);
/* Should not be reached, if uniq is found */ /* Should not be reached, if uniq is found */
exit(1); exit(1);
} }
close(uniq_fd[1]); close(uniq_fd[1]);
/* Child process was not forked successfully */ /* Child process was not forked successfully */
if (pid_spell < 0 || pid_sort < 0 || pid_uniq < 0) { if (pid_spell < 0 || pid_sort < 0 || pid_uniq < 0) {
close(uniq_fd[0]); close(uniq_fd[0]);
return _("Could not fork"); return _("Could not fork");
} }
/* Get system pipe buffer size */ /* Get system pipe buffer size */
if ((pipe_buff_size = fpathconf(uniq_fd[0], _PC_PIPE_BUF)) < 1) { if ((pipe_buff_size = fpathconf(uniq_fd[0], _PC_PIPE_BUF)) < 1) {
close(uniq_fd[0]); close(uniq_fd[0]);
return _("Could not get size of pipe buffer"); return _("Could not get size of pipe buffer");
} }
/* Read-in the returned spelling errors */ /* Read-in the returned spelling errors */
read_buff_read = 0; read_buff_read = 0;
read_buff_size = pipe_buff_size + 1; read_buff_size = pipe_buff_size + 1;
read_buff = read_buff_ptr = charalloc(read_buff_size); read_buff = read_buff_ptr = charalloc(read_buff_size);
@ -1849,7 +1818,6 @@ char *do_int_speller(char *tempfile_name)
close(uniq_fd[0]); close(uniq_fd[0]);
/* Process the spelling errors */ /* Process the spelling errors */
read_buff_word = read_buff_ptr = read_buff; read_buff_word = read_buff_ptr = read_buff;
while (*read_buff_ptr != '\0') { while (*read_buff_ptr != '\0') {
@ -1892,6 +1860,18 @@ char *do_int_speller(char *tempfile_name)
/* Otherwise... */ /* Otherwise... */
return NULL; return NULL;
close_pipes_and_exit:
/* Don't leak any handles */
close(tempfile_fd);
close(spell_fd[0]);
close(spell_fd[1]);
close(sort_fd[0]);
close(sort_fd[1]);
close(uniq_fd[0]);
close(uniq_fd[1]);
exit(1);
} }
/* External spell checking. Return value: NULL for normal termination, /* External spell checking. Return value: NULL for normal termination,