diff options
author | Koushik Dutta <koushd@gmail.com> | 2012-12-12 17:15:18 -0800 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2012-12-12 17:15:18 -0800 |
commit | a4a854d68c979c076e3e1d7a27197b5652f3a362 (patch) | |
tree | a165d8a5f598fcd49a5f63ae346b8117d9d9459c | |
parent | ae4a2b2e0f0980c9d07dae2dd6e7d7a94bd6b3b8 (diff) | |
download | bootable_recovery-a4a854d68c979c076e3e1d7a27197b5652f3a362.zip bootable_recovery-a4a854d68c979c076e3e1d7a27197b5652f3a362.tar.gz bootable_recovery-a4a854d68c979c076e3e1d7a27197b5652f3a362.tar.bz2 |
Fix crash in recovery that occurs during backup.
Change-Id: I8d13646eede75c64878b50a8b6f4617a48e10b32
-rw-r--r-- | libcrecovery/popen.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/libcrecovery/popen.c b/libcrecovery/popen.c index 73d3c74..59a7bd4 100644 --- a/libcrecovery/popen.c +++ b/libcrecovery/popen.c @@ -50,6 +50,8 @@ static struct pid { pid_t pid; } *pidlist; +extern char **environ; + FILE * __popen(const char *program, const char *type) { @@ -57,6 +59,7 @@ __popen(const char *program, const char *type) FILE *iop; int pdes[2]; pid_t pid; + char *argp[] = {"sh", "-c", NULL, NULL}; if ((*type != 'r' && *type != 'w') || type[1] != '\0') { errno = EINVAL; @@ -71,7 +74,7 @@ __popen(const char *program, const char *type) return (NULL); } - switch (pid = vfork()) { + switch (pid = fork()) { case -1: /* Error. */ (void)close(pdes[0]); (void)close(pdes[1]); @@ -82,24 +85,17 @@ __popen(const char *program, const char *type) { struct pid *pcur; /* - * because vfork() instead of fork(), must leak FILE *, - * but luckily we are terminally headed for an execl() + * We fork()'d, we got our own copy of the list, no + * contention. */ for (pcur = pidlist; pcur; pcur = pcur->next) close(fileno(pcur->fp)); if (*type == 'r') { - int tpdes1 = pdes[1]; - (void) close(pdes[0]); - /* - * We must NOT modify pdes, due to the - * semantics of vfork. - */ - if (tpdes1 != STDOUT_FILENO) { - (void)dup2(tpdes1, STDOUT_FILENO); - (void)close(tpdes1); - tpdes1 = STDOUT_FILENO; + if (pdes[1] != STDOUT_FILENO) { + (void)dup2(pdes[1], STDOUT_FILENO); + (void)close(pdes[1]); } } else { (void)close(pdes[1]); @@ -108,7 +104,8 @@ __popen(const char *program, const char *type) (void)close(pdes[0]); } } - execl(_PATH_BSHELL, "sh", "-c", program, (char *)NULL); + argp[2] = (char *)program; + execve(_PATH_BSHELL, argp, environ); _exit(127); /* NOTREACHED */ } |