mirror of git://sourceware.org/git/glibc.git
(exec_comm): Add a few TEMP_FAILURE_RETRY. Reorganize code to avoid multiple calls to exec_comm_child. (exec_comm_child): Can now be inlined.
This commit is contained in:
parent
8d33466fca
commit
f89c41c116
|
|
@ -1,5 +1,5 @@
|
||||||
/* POSIX.2 wordexp implementation.
|
/* POSIX.2 wordexp implementation.
|
||||||
Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
|
Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
|
Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
|
||||||
|
|
||||||
|
|
@ -810,7 +810,7 @@ parse_arith (char **word, size_t *word_length, size_t *max_length,
|
||||||
|
|
||||||
/* Function called by child process in exec_comm() */
|
/* Function called by child process in exec_comm() */
|
||||||
static void
|
static void
|
||||||
internal_function
|
internal_function __attribute__ ((always_inline))
|
||||||
exec_comm_child (char *comm, int *fildes, int showerr, int noexec)
|
exec_comm_child (char *comm, int *fildes, int showerr, int noexec)
|
||||||
{
|
{
|
||||||
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
|
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
|
||||||
|
|
@ -868,13 +868,14 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
||||||
const char *ifs_white)
|
const char *ifs_white)
|
||||||
{
|
{
|
||||||
int fildes[2];
|
int fildes[2];
|
||||||
int bufsize = 128;
|
#define bufsize 128
|
||||||
int buflen;
|
int buflen;
|
||||||
int i;
|
int i;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
size_t maxnewlines = 0;
|
size_t maxnewlines = 0;
|
||||||
char *buffer;
|
char buffer[bufsize];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
int noexec = 0;
|
||||||
|
|
||||||
/* Don't fork() unless necessary */
|
/* Don't fork() unless necessary */
|
||||||
if (!comm || !*comm)
|
if (!comm || !*comm)
|
||||||
|
|
@ -884,32 +885,42 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
||||||
/* Bad */
|
/* Bad */
|
||||||
return WRDE_NOSPACE;
|
return WRDE_NOSPACE;
|
||||||
|
|
||||||
|
again:
|
||||||
if ((pid = __fork ()) < 0)
|
if ((pid = __fork ()) < 0)
|
||||||
{
|
{
|
||||||
/* Bad */
|
/* Bad */
|
||||||
__close (fildes[0]);
|
if (fildes[0] != -1)
|
||||||
__close (fildes[1]);
|
__close (fildes[0]);
|
||||||
|
if (fildes[1] != -1)
|
||||||
|
__close (fildes[1]);
|
||||||
return WRDE_NOSPACE;
|
return WRDE_NOSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
exec_comm_child (comm, fildes, flags & WRDE_SHOWERR, 0);
|
exec_comm_child (comm, fildes, noexec ? 0 : flags & WRDE_SHOWERR, noexec);
|
||||||
|
|
||||||
/* Parent */
|
/* Parent */
|
||||||
|
|
||||||
|
/* If we are just testing the syntax, only wait. */
|
||||||
|
if (noexec)
|
||||||
|
return (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) == pid
|
||||||
|
&& status != 0) ? WRDE_SYNTAX : 0;
|
||||||
|
|
||||||
__close (fildes[1]);
|
__close (fildes[1]);
|
||||||
buffer = __alloca (bufsize);
|
fildes[1] = -1;
|
||||||
|
|
||||||
if (!pwordexp)
|
if (!pwordexp)
|
||||||
/* Quoted - no field splitting */
|
/* Quoted - no field splitting */
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if ((buflen = __read (fildes[0], buffer, bufsize)) < 1)
|
if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
|
||||||
|
bufsize))) < 1)
|
||||||
{
|
{
|
||||||
if (__waitpid (pid, &status, WNOHANG) == 0)
|
if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((buflen = __read (fildes[0], buffer, bufsize)) < 1)
|
if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
|
||||||
|
bufsize))) < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -933,11 +944,13 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if ((buflen = __read (fildes[0], buffer, bufsize)) < 1)
|
if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
|
||||||
|
bufsize))) < 1)
|
||||||
{
|
{
|
||||||
if (__waitpid (pid, &status, WNOHANG) == 0)
|
if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((buflen = __read (fildes[0], buffer, bufsize)) < 1)
|
if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
|
||||||
|
bufsize))) < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1053,31 +1066,20 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
__close (fildes[0]);
|
__close (fildes[0]);
|
||||||
|
fildes[0] = -1;
|
||||||
|
|
||||||
/* Check for syntax error (re-execute but with "-n" flag) */
|
/* Check for syntax error (re-execute but with "-n" flag) */
|
||||||
if (buflen < 1 && status != 0)
|
if (buflen < 1 && status != 0)
|
||||||
{
|
{
|
||||||
if ((pid = __fork ()) < 0)
|
noexec = 1;
|
||||||
{
|
goto again;
|
||||||
/* Bad */
|
|
||||||
return WRDE_NOSPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
fildes[0] = fildes[1] = -1;
|
|
||||||
exec_comm_child (comm, fildes, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__waitpid (pid, &status, 0) == pid && status != 0)
|
|
||||||
return WRDE_SYNTAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
no_space:
|
no_space:
|
||||||
__kill (pid, SIGKILL);
|
__kill (pid, SIGKILL);
|
||||||
__waitpid (pid, NULL, 0);
|
TEMP_FAILURE_RETRY (__waitpid (pid, NULL, 0));
|
||||||
__close (fildes[0]);
|
__close (fildes[0]);
|
||||||
return WRDE_NOSPACE;
|
return WRDE_NOSPACE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue