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 }