Add a simple GUI
[qi-bootmenu/guyou.git] / util.c
blobd86fdb6abeb44845ccad59658644eadadaadb1aa
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <unistd.h>
4 #include <ctype.h>
5 #include <signal.h>
6 #include <sys/wait.h>
7 #include "util.h"
9 void eprint(const char *errstr, ...) {
10 va_list ap;
11 va_start(ap, errstr);
12 vfprintf(stderr, errstr, ap);
13 va_end(ap);
16 void skip_until(char** str, char c) {
17 while (**str && **str != c)
18 (*str)++;
21 void skip_spaces(char **str) {
22 while (isspace(**str))
23 (*str)++;
26 int fexecw(const char *path, char *const argv[], char *const envp[]) {
27 pid_t pid;
28 struct sigaction ignore, old_int, old_quit;
29 sigset_t masked, oldmask;
30 int status;
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);
37 ignore.sa_flags = 0;
38 sigaction(SIGINT, &ignore, &old_int);
39 sigaction(SIGQUIT, &ignore, &old_quit);
41 sigemptyset(&masked);
42 sigaddset(&masked, SIGCHLD);
43 sigprocmask(SIG_BLOCK, &masked, &oldmask);
45 pid = fork();
47 if (pid < 0)
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);
54 _exit(127);
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);
65 return status;