posix.c (1881B)
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 16 static volatile pid_t pid; 17 18 void 19 killchild(void) 20 { 21 if (pid != 0) 22 kill(pid, SIGTERM); 23 pid = 0; 24 } 25 26 int 27 is_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 36 void 37 exportvar(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 48 time_t 49 stamp(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 59 int 60 launch(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 }