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