10 void eprint(const char *errstr
, ...) {
13 vfprintf(stderr
, errstr
, ap
);
17 void skip_until(char** str
, char c
) {
18 while (**str
&& **str
!= c
)
22 void skip_spaces(char **str
) {
23 while (isspace(**str
))
27 int fexecw(const char *path
, char *const argv
[], char *const envp
[]) {
29 struct sigaction ignore
, old_int
, old_quit
;
30 sigset_t masked
, oldmask
;
33 /* Block SIGCHLD and ignore SIGINT and SIGQUIT before forking
34 * restore the original signal handlers afterwards. */
36 ignore
.sa_handler
= SIG_IGN
;
37 sigemptyset(&ignore
.sa_mask
);
39 sigaction(SIGINT
, &ignore
, &old_int
);
40 sigaction(SIGQUIT
, &ignore
, &old_quit
);
43 sigaddset(&masked
, SIGCHLD
);
44 sigprocmask(SIG_BLOCK
, &masked
, &oldmask
);
49 return -1; /* can't fork */
50 else if (pid
== 0) { /* child process */
51 sigaction(SIGINT
, &old_int
, NULL
);
52 sigaction(SIGQUIT
, &old_quit
, NULL
);
53 sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
54 execve(path
, (char *const *)argv
, (char *const *)envp
);
58 /* wait for our child and store it's exit status */
59 waitpid(pid
, &status
, 0);
61 /* restore signal handlers */
62 sigaction(SIGINT
, &old_int
, NULL
);
63 sigaction(SIGQUIT
, &old_quit
, NULL
);
64 sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);