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