1#undef _POSIX_C_SOURCE2#define _POSIX_C_SOURCE 200809L34#include <signal.h>5#include <sys/stat.h>6#include <sys/wait.h>7#include <unistd.h>89#include <errno.h>10#include <stdio.h>11#include <string.h>1213#include "make.h"141516static volatile pid_t pid;1718void19killchild(void)20{21 if (pid != 0)22 kill(pid, SIGTERM);23 pid = 0;24}2526int27is_dir(char *fname)28{29 struct stat st;3031 if (stat(fname, &st) < 0)32 return 0;33 return S_ISDIR(st.st_mode);34}3536void37exportvar(char *var, char *value)38{39 int n;40 char *buf;4142 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}4748time_t49stamp(char *name)50{51 struct stat st;5253 if (stat(name, &st) < 0)54 return -1;5556 return st.st_mtime;57}5859int60launch(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);6970 if (!initsignals) {71 struct sigaction act = {72 .sa_handler = sighandler73 };7475 /* 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 }8283 sigfillset(&new);84 sigprocmask(SIG_BLOCK, &new, &old);85 if (stop)86 goto unblock;8788 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);99100 sigprocmask(SIG_SETMASK, &old, NULL);101102 shell = getmacro("SHELL");103104 if (ignore)105 args[1] = "-c";106 if ((name = strrchr(shell, '/')) != NULL)107 ++name;108 else109 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);116117 return st;118 }119}