summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/misc/wordexp.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c
index 617706e5..7a358686 100644
--- a/src/misc/wordexp.c
+++ b/src/misc/wordexp.c
@@ -7,7 +7,8 @@
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
-#include <pthread.h>
+#include <errno.h>
+#include "pthread_impl.h"
static char *getword(FILE *f)
{
@@ -28,6 +29,7 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags)
char **wv = 0;
int p[2];
pid_t pid;
+ sigset_t set;
if (flags & WRDE_REUSE) wordfree(we);
@@ -87,7 +89,9 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags)
}
if (pipe(p) < 0) return WRDE_NOSPACE;
+ __block_all_sigs(&set);
pid = fork();
+ __restore_sigs(&set);
if (pid < 0) {
close(p[0]);
close(p[1]);
@@ -98,7 +102,7 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags)
close(p[0]);
close(p[1]);
execl("/bin/sh", "sh", "-c",
- "eval \"printf %s\\\\\\\\0 $1 $2\"",
+ "eval \"printf %s\\\\\\\\0 x $1 $2\"",
"sh", s, redir, (char *)0);
_exit(1);
}
@@ -114,6 +118,14 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags)
l = wv ? i+1 : 0;
+ free(getword(f));
+ if (feof(f)) {
+ fclose(f);
+ while ((waitpid(pid, &status, 0) < 0 && errno == EINTR)
+ || !WIFEXITED(status));
+ return WRDE_SYNTAX;
+ }
+
while ((w = getword(f))) {
if (i+1 >= l) {
l += l/2+10;
@@ -127,15 +139,8 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags)
if (!feof(f)) err = WRDE_NOSPACE;
fclose(f);
- waitpid(pid, &status, 0);
- if (WEXITSTATUS(status)) {
- if (!(flags & WRDE_APPEND)) {
- free(wv);
- return WRDE_SYNTAX;
- } else if (wv==we->we_wordv) {
- return WRDE_SYNTAX;
- }
- }
+ while ((waitpid(pid, &status, 0) < 0 && errno == EINTR)
+ || !WIFEXITED(status));
we->we_wordv = wv;
we->we_wordc = i;