scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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 }