12 #include "pthread_impl.h"
14 static void reap(pid_t pid
)
17 while (waitpid(pid
, &status
, 0) < 0 && errno
== EINTR
);
20 static char *getword(FILE *f
)
23 return getdelim(&s
, (size_t [1]){0}, 0, f
) < 0 ? 0 : s
;
26 static int do_wordexp(const char *s
, wordexp_t
*we
, int flags
)
32 char *redir
= (flags
& WRDE_SHOWERR
) ? "" : "2>/dev/null";
41 if (flags
& WRDE_REUSE
) wordfree(we
);
43 if (flags
& WRDE_NOCMD
) for (i
=0; s
[i
]; i
++) switch (s
[i
]) {
71 if (!(sq
|dq
|np
)) return WRDE_BADCHAR
;
75 if (s
[i
+1]=='(' && s
[i
+2]=='(') {
79 } else if (s
[i
+1] != '(') break;
85 if (flags
& WRDE_APPEND
) {
91 if (flags
& WRDE_DOOFFS
) {
92 if (we
->we_offs
> SIZE_MAX
/sizeof(void *)/4)
99 if (pipe2(p
, O_CLOEXEC
) < 0) goto nospace
;
100 __block_all_sigs(&set
);
102 __restore_sigs(&set
);
109 if (p
[1] == 1) fcntl(1, F_SETFD
, 0);
111 execl("/bin/sh", "sh", "-c",
112 "eval \"printf %s\\\\\\\\0 x $1 $2\"",
113 "sh", s
, redir
, (char *)0);
118 f
= fdopen(p
[0], "r");
135 while ((w
= getword(f
))) {
138 tmp
= realloc(wv
, l
*sizeof(char *));
145 if (!feof(f
)) err
= WRDE_NOSPACE
;
150 if (!wv
) wv
= calloc(i
+1, sizeof *wv
);
155 if (flags
& WRDE_DOOFFS
) {
156 if (wv
) for (i
=we
->we_offs
; i
; i
--)
157 we
->we_wordv
[i
-1] = 0;
158 we
->we_wordc
-= we
->we_offs
;
163 if (!(flags
& WRDE_APPEND
)) {
170 int wordexp(const char *restrict s
, wordexp_t
*restrict we
, int flags
)
173 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
174 r
= do_wordexp(s
, we
, flags
);
175 pthread_setcancelstate(cs
, 0);
179 void wordfree(wordexp_t
*we
)
182 if (!we
->we_wordv
) return;
183 for (i
=0; i
<we
->we_wordc
; i
++) free(we
->we_wordv
[we
->we_offs
+i
]);