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 }