diff options
| -rw-r--r-- | src/misc/wordexp.c | 27 | 
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; | 
