scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }