posix.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       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 }