1#undef _POSIX_C_SOURCE
2#define _POSIX_C_SOURCE 200809L
3
4#include <signal.h>
5#include <sys/stat.h>
6#include <sys/wait.h>
7#include <unistd.h>
8
9#include <errno.h>
10#include <stdio.h>
11#include <string.h>
12
13#include "make.h"
14
15static volatile pid_t pid;
16
17void
18killchild(void)
19{
20 if (pid != 0)
21 kill(pid, SIGTERM);
22 pid = 0;
23}
24
25int
26is_dir(char *fname)
27{
28 struct stat st;
29
30 if (stat(fname, &st) < 0)
31 return 0;
32 return S_ISDIR(st.st_mode);
33}
34
35void
36exportvar(char *var, char *value)
37{
38 int n;
39 char *buf;
40
41 n = snprintf(NULL, 0, "%s=%s", var, value);
42 buf = emalloc(n + 1);
43 snprintf(buf, n + 1, "%s=%s", var, value);
44 putenv(buf);
45}
46
47time_t
48stamp(char *name)
49{
50 struct stat st;
51
52 if (stat(name, &st) < 0)
53 return -1;
54
55 return st.st_mtime;
56}
57
58int
59launch(char *cmd, int ignore)
60{
61 int st;
62 sigset_t new, old;
63 char *name, *shell;
64 char *args[] = {NULL, "-ec", cmd, NULL};
65 static int initsignals;
66 extern char **environ;
67 extern void sighandler(int);
68
69 if (!initsignals) {
70 struct sigaction act = {.sa_handler = sighandler};
71
72 /* avoid BSD weirdness signal restart handling */
73 sigaction(SIGINT, &act, NULL);
74 sigaction(SIGHUP, &act, NULL);
75 sigaction(SIGTERM, &act, NULL);
76 sigaction(SIGQUIT, &act, NULL);
77 initsignals = 1;
78 }
79
80 sigfillset(&new);
81 sigprocmask(SIG_BLOCK, &new, &old);
82 if (stop)
83 goto unblock;
84
85 switch (pid = fork()) {
86 case -1:
87 perror("make");
88 unblock:
89 sigprocmask(SIG_SETMASK, &old, NULL);
90 return -1;
91 case 0:
92 signal(SIGINT, SIG_DFL);
93 signal(SIGHUP, SIG_DFL);
94 signal(SIGTERM, SIG_DFL);
95 signal(SIGQUIT, SIG_DFL);
96
97 sigprocmask(SIG_SETMASK, &old, NULL);
98
99 shell = getmacro("SHELL");
100
101 if (ignore)
102 args[1] = "-c";
103 if ((name = strrchr(shell, '/')) != NULL)
104 ++name;
105 else
106 name = shell;
107 args[0] = name;
108 execve(shell, args, environ);
109 _exit(127);
110 default:
111 sigprocmask(SIG_SETMASK, &old, NULL);
112 wait(&st);
113
114 return st;
115 }
116}