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