xref: /inferno-os/utils/acid/os-Posix.c (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
1 #include <lib9.h>
2 #include <bio.h>
3 #include <sys/types.h>
4 #include <termios.h>
5 #undef getwd
6 #undef getwd
7 #include <unistd.h>
8 #include "mach.h"
9 #define	Extern extern
10 #include "acid.h"
11 #include <signal.h>
12 #include <sys/wait.h>
13 
14 static void
15 setraw(int fd, int baud)
16 {
17 	struct termios sg;
18 
19 	switch(baud){
20 	case 1200:	baud = B1200; break;
21 	case 2400:	baud = B2400; break;
22 	case 4800:	baud = B4800; break;
23 	case 9600:	baud = B9600; break;
24 	case 19200:	baud = B19200; break;
25 	case 38400:	baud = B38400; break;
26 	default:
27 		werrstr("unknown speed %d", baud);
28 		return;
29 	}
30 	if(tcgetattr(fd, &sg) >= 0) {
31 		sg.c_iflag = sg.c_oflag = sg.c_lflag = 0;
32 		sg.c_cflag &= ~CSIZE;
33 		sg.c_cflag |= CS8 | CREAD;
34 		sg.c_cflag &= ~(PARENB|PARODD);
35 		sg.c_cc[VMIN] = 1;
36 		sg.c_cc[VTIME] = 0;
37 		if(baud) {
38 			cfsetispeed(&sg, baud);
39 			cfsetospeed(&sg, baud);
40 		}
41 		tcsetattr(fd, TCSANOW, &sg);
42 	}
43 }
44 
45 int
46 opentty(char *tty, int baud)
47 {
48 	int fd;
49 
50 	if(baud == 0)
51 		baud = 19200;
52 	fd = open(tty, 2);
53 	if(fd < 0)
54 		return -1;
55 	setraw(fd, baud);
56 	return fd;
57 }
58 
59 void
60 detach(void)
61 {
62 	setpgid(0, 0);
63 }
64 
65 char *
66 waitfor(int pid)
67 {
68 	int n, status;
69 	static char buf[32];
70 
71 	for(;;) {
72 		n = wait(&status);
73 		if(n < 0)
74 			error("wait %r");
75 		if(n == pid) {
76 			sprint(buf, "%d", status);
77 			return buf;
78 		}
79 	}
80 }
81 
82 char *
83 runcmd(char *cmd)
84 {
85 	char *argv[4];
86 	int pid;
87 
88 	argv[0] = "/bin/sh";
89 	argv[1] = "-c";
90 	argv[2] = cmd;
91 	argv[3] = 0;
92 
93 	pid = fork();
94 	switch(pid) {
95 	case -1:
96 		error("fork %r");
97 	case 0:
98 		execv("/bin/sh", argv);
99 		exits(0);
100 	default:
101 		return waitfor(pid);
102 	}
103 	return 0;
104 }
105 
106 void (*notefunc)(int);
107 
108 void
109 os_notify(void (*func)(int))
110 {
111 	notefunc = func;
112 	signal(SIGINT, func);
113 }
114 
115 void
116 catcher(int sig)
117 {
118 	if(sig==SIGINT) {
119 		gotint = 1;
120 		signal(SIGINT, notefunc);
121 	}
122 }
123 
124 void
125 setup_os_notify(void)
126 {
127 	os_notify(catcher);
128 }
129 
130 int
131 nproc(char **argv)
132 {
133 	char buf[128];
134 	int pid, i, fd;
135 
136 	if(rdebug)
137 		error("can't newproc in remote mode");
138 
139 	pid = fork();
140 	switch(pid) {
141 	case -1:
142 		error("new: fork %r");
143 	case 0:
144 		detach();
145 
146 		sprint(buf, "/proc/%d/ctl", getpid());
147 		fd = open(buf, ORDWR);
148 		if(fd < 0)
149 			fatal("new: open %s: %r", buf);
150 		write(fd, "hang", 4);
151 		close(fd);
152 
153 		close(0);
154 		close(1);
155 		close(2);
156 		for(i = 3; i < NFD; i++)
157 			close(i);
158 
159 		open("/dev/cons", OREAD);
160 		open("/dev/cons", OWRITE);
161 		open("/dev/cons", OWRITE);
162 		execvp(argv[0], argv);
163 		fatal("new: execvp %s: %r");
164 	default:
165 		install(pid);
166 		msg(pid, "waitstop");
167 		notes(pid);
168 		sproc(pid);
169 		dostop(pid);
170 		break;
171 	}
172 
173 	return pid;
174 }
175 
176 int
177 remote_read(int fd, char *buf, int bytes)
178 {
179 	return read(fd, buf, bytes);
180 }
181 
182 int remote_write(int fd, char *buf, int bytes)
183 {
184 	return write(fd, buf, bytes);
185 }
186