9 void eprint(const char *errstr
, ...) {
12 vfprintf(stderr
, errstr
, ap
);
16 void skip_until(char** str
, char c
) {
17 while (**str
&& **str
!= c
)
21 void skip_spaces(char **str
) {
22 while (isspace(**str
))
26 int fexecw(const char *path
, char *const argv
[], char *const envp
[]) {
28 struct sigaction ignore
, old_int
, old_quit
;
29 sigset_t masked
, oldmask
;
32 /* Block SIGCHLD and ignore SIGINT and SIGQUIT before forking
33 * restore the original signal handlers afterwards. */
35 ignore
.sa_handler
= SIG_IGN
;
36 sigemptyset(&ignore
.sa_mask
);
38 sigaction(SIGINT
, &ignore
, &old_int
);
39 sigaction(SIGQUIT
, &ignore
, &old_quit
);
42 sigaddset(&masked
, SIGCHLD
);
43 sigprocmask(SIG_BLOCK
, &masked
, &oldmask
);
48 return -1; /* can't fork */
49 else if (pid
== 0) { /* child process */
50 sigaction(SIGINT
, &old_int
, NULL
);
51 sigaction(SIGQUIT
, &old_quit
, NULL
);
52 sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
53 execve(path
, (char *const *)argv
, (char *const *)envp
);
57 /* wait for our child and store it's exit status */
58 waitpid(pid
, &status
, 0);
60 /* restore signal handlers */
61 sigaction(SIGINT
, &old_int
, NULL
);
62 sigaction(SIGQUIT
, &old_quit
, NULL
);
63 sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);