Commit 832c74d9 by Nathan Sidwell Committed by Nathan Sidwell

[libiberty patch] Fix PGO bootstrap

https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01386.html
	PR driver/87056
	* pex-unix.c (pex_unix_exec_child): Duplicate bad_fn into local
	scopes to avoid potential clobber.

Co-Authored-By: Martin Liska <mliska@suse.cz>

From-SVN: r263807
parent ebdb6f23
2018-08-23 Nathan Sidwell <nathan@acm.org>
Martin Liska <mliska@suse.cz>
PR driver/87056
* pex-unix.c (pex_unix_exec_child): Duplicate bad_fn into local
scopes to avoid potential clobber.
2018-08-20 Nathan Sidwell <nathan@acm.org> 2018-08-20 Nathan Sidwell <nathan@acm.org>
* pex-unix.c (pex_child_error): Delete. * pex-unix.c (pex_child_error): Delete.
......
...@@ -582,8 +582,6 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, ...@@ -582,8 +582,6 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
issues. */ issues. */
char **save_environ = environ; char **save_environ = environ;
const char *bad_fn = NULL;
for (retries = 0; retries < 4; ++retries) for (retries = 0; retries < 4; ++retries)
{ {
pid = vfork (); pid = vfork ();
...@@ -602,62 +600,64 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, ...@@ -602,62 +600,64 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
case 0: case 0:
/* Child process. */ /* Child process. */
if (!bad_fn && in != STDIN_FILE_NO)
{
if (dup2 (in, STDIN_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (in) < 0)
bad_fn = "close";
}
if (!bad_fn && out != STDOUT_FILE_NO)
{
if (dup2 (out, STDOUT_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (out) < 0)
bad_fn = "close";
}
if (!bad_fn && errdes != STDERR_FILE_NO)
{
if (dup2 (errdes, STDERR_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (errdes) < 0)
bad_fn = "close";
}
if (!bad_fn && toclose >= 0)
{
if (close (toclose) < 0)
bad_fn = "close";
}
if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
{
if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
bad_fn = "dup2";
}
if (!bad_fn)
{
if (env)
/* NOTE: In a standard vfork implementation this clobbers
the parent's copy of environ "too" (in reality there's
only one copy). This is ok as we restore it below. */
environ = (char**) env;
if ((flags & PEX_SEARCH) != 0)
{
execvp (executable, to_ptr32 (argv));
bad_fn = "execvp";
}
else
{
execv (executable, to_ptr32 (argv));
bad_fn = "execv";
}
}
/* Something failed, report an error. We don't use stdio
routines, because we might be here due to a vfork call. */
{ {
const char *bad_fn = NULL;
if (!bad_fn && in != STDIN_FILE_NO)
{
if (dup2 (in, STDIN_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (in) < 0)
bad_fn = "close";
}
if (!bad_fn && out != STDOUT_FILE_NO)
{
if (dup2 (out, STDOUT_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (out) < 0)
bad_fn = "close";
}
if (!bad_fn && errdes != STDERR_FILE_NO)
{
if (dup2 (errdes, STDERR_FILE_NO) < 0)
bad_fn = "dup2";
else if (close (errdes) < 0)
bad_fn = "close";
}
if (!bad_fn && toclose >= 0)
{
if (close (toclose) < 0)
bad_fn = "close";
}
if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
{
if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
bad_fn = "dup2";
}
if (!bad_fn)
{
if (env)
/* NOTE: In a standard vfork implementation this clobbers
the parent's copy of environ "too" (in reality there's
only one copy). This is ok as we restore it below. */
environ = (char**) env;
if ((flags & PEX_SEARCH) != 0)
{
execvp (executable, to_ptr32 (argv));
bad_fn = "execvp";
}
else
{
execv (executable, to_ptr32 (argv));
bad_fn = "execv";
}
}
/* Something failed, report an error. We don't use stdio
routines, because we might be here due to a vfork call. */
ssize_t retval = 0; ssize_t retval = 0;
int err = errno; int eno = errno;
#define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s))) #define writeerr(s) (retval |= write (STDERR_FILE_NO, s, strlen (s)))
writeerr (obj->pname); writeerr (obj->pname);
writeerr (": error trying to exec '"); writeerr (": error trying to exec '");
...@@ -665,7 +665,7 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, ...@@ -665,7 +665,7 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
writeerr ("': "); writeerr ("': ");
writeerr (bad_fn); writeerr (bad_fn);
writeerr (": "); writeerr (": ");
writeerr (xstrerror (err)); writeerr (xstrerror (eno));
writeerr ("\n"); writeerr ("\n");
#undef writeerr #undef writeerr
...@@ -677,30 +677,33 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, ...@@ -677,30 +677,33 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
default: default:
/* Parent process. */ /* Parent process. */
{
const char *bad_fn = NULL;
/* Restore environ. Note that the parent either doesn't run
until the child execs/exits (standard vfork behaviour), or
if it does run then vfork is behaving more like fork. In
either case we needn't worry about clobbering the child's
copy of environ. */
environ = save_environ;
if (!bad_fn && in != STDIN_FILE_NO)
if (close (in) < 0)
bad_fn = "close";
if (!bad_fn && out != STDOUT_FILE_NO)
if (close (out) < 0)
bad_fn = "close";
if (!bad_fn && errdes != STDERR_FILE_NO)
if (close (errdes) < 0)
bad_fn = "close";
/* Restore environ. if (bad_fn)
Note that the parent either doesn't run until the child execs/exits {
(standard vfork behaviour), or if it does run then vfork is behaving *err = errno;
more like fork. In either case we needn't worry about clobbering *errmsg = bad_fn;
the child's copy of environ. */ return (pid_t) -1;
environ = save_environ; }
}
if (!bad_fn && in != STDIN_FILE_NO)
if (close (in) < 0)
bad_fn = "close";
if (!bad_fn && out != STDOUT_FILE_NO)
if (close (out) < 0)
bad_fn = "close";
if (!bad_fn && errdes != STDERR_FILE_NO)
if (close (errdes) < 0)
bad_fn = "close";
if (bad_fn)
{
*err = errno;
*errmsg = bad_fn;
return (pid_t) -1;
}
return pid; return pid;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment