posix.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
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 }