shithub: drawterm

Download patch

ref: 580a51496fffc7bf4a247189cebd17ad952001a3
parent: 9c784144093e204332660445eff074cdb88c6fb1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 23 20:08:45 EST 2019

cmd(3): implement command execution for posix

--- a/kern/devcmd.c	Sat Nov 23 19:04:21 2019
+++ b/kern/devcmd.c	Sat Nov 23 20:08:45 2019
@@ -343,7 +343,6 @@
 		if(cc->child != nil){
 			if(!cc->killed)
 			if(r == 0 || (cc->killonclose && TYPE(c->qid) == Qctl)){
-				iprint("cmdclose killing (killonclose %d)\n", cc->killonclose);
 				oscmdkill(cc->child);
 				cc->killed = 1;
 			}
--- a/kern/posix.c	Sat Nov 23 19:04:21 2019
+++ b/kern/posix.c	Sat Nov 23 20:08:45 2019
@@ -10,6 +10,7 @@
 
 #include <pthread.h>
 #include <time.h>
+#include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/select.h>
 #include <signal.h>
@@ -54,9 +55,10 @@
 {
 	if(pthread_key_create(&prdakey, 0))
 		panic("cannot pthread_key_create");
+
+	signal(SIGPIPE, SIG_IGN);
 }
 
-#undef pipe
 void
 osnewproc(Proc *p)
 {
@@ -166,33 +168,78 @@
 	pthread_mutex_unlock(&op->mutex);
 }
 
+#undef pipe
+#undef fork
+#undef close
+#undef dup2
+#undef execv
+#undef setsid
+#undef exit
 void*
 oscmd(char **argv, int nice, char *dir, Chan **fd)
 {
-	USED(argv);
-	USED(nice);
-	USED(dir);
-	USED(fd);
+	int p[3][2];
+	int i, pid;
+
+	for(i = 0; i<3; i++){
+		if(pipe(p[i]) < 0){
+			while(--i >= 0){
+				close(p[i][0]);
+				close(p[i][1]);
+			}
+			oserror();
+		}
+	}
+	if(waserror()){
+		for(i = 0; i < 3; i++){
+			close(p[i][0]);
+			close(p[i][1]);
+		}
+		nexterror();
+	}
+	pid = fork();
+	if(pid == -1)
+		oserror();
+	if(pid == 0){
+		setsid();
+		dup2(p[0][0], 0);
+		dup2(p[1][1], 1);
+		dup2(p[2][1], 2);
+		for(i = 3; i < 1000; i++)
+			close(i);
+		execv(argv[0], argv);
+		exit(0);
+	}
+	poperror();
+	close(p[0][0]);
+	close(p[1][1]);
+	close(p[2][1]);
+
+	fd[0] = lfdchan((void*)(uintptr)p[0][1]);
+	fd[1] = lfdchan((void*)(uintptr)p[1][0]);
+	fd[2] = lfdchan((void*)(uintptr)p[2][0]);
 
-	error("not implemented");
-	return nil;
+	return (void*)(uintptr)pid;
 }
 
+#undef waitpid
 int
 oscmdwait(void *c, char *status, int nstatus)
 {
-	USED(c);
-	USED(status);
-	USED(nstatus);
+	int pid = (int)(uintptr)c;
+	int wstatus = -1;
 
-	return -1;
+	if(waitpid(pid, &wstatus, 0) < 0)
+		return -1;
+	return snprint(status, nstatus, "%d", wstatus);
 }
 
+#undef kill
 int
 oscmdkill(void *c)
 {
-	USED(c);
-	return -1;
+	int pid = (int)(uintptr)c;
+	return kill(pid, SIGTERM);
 }
 
 void