ref: 11fecde6d0ba873506a6c89f12518b18e87e16a4
parent: f502310ba1b242cab4646cb71cd00944d471f1f1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Dec 2 20:12:00 EST 2019
devcmd: on posix, use execvp() and handle chdir(), format better status line code is mostly taken from os-inferno's Linux/cmd.c, tho failure is currently signaled by perror() in the child instead of oscmd() erroring.
--- a/kern/posix.c
+++ b/kern/posix.c
@@ -168,13 +168,10 @@
pthread_mutex_unlock(&op->mutex);
}
+#undef chdir
#undef pipe
#undef fork
#undef close
-#undef dup2
-#undef execv
-#undef setsid
-#undef exit
void*
oscmd(char **argv, int nice, char *dir, Chan **fd)
{
@@ -207,8 +204,13 @@
dup2(p[2][1], 2);
for(i = 3; i < 1000; i++)
close(i);
- execv(argv[0], argv);
- exit(0);
+ if(chdir(dir) < 0){
+ perror("chdir");
+ _exit(1);
+ }
+ execvp(argv[0], argv);
+ perror("exec");
+ _exit(1);
}
poperror();
close(p[0][0]);
@@ -222,21 +224,30 @@
return (void*)(uintptr)pid;
}
-#undef waitpid
int
oscmdwait(void *c, char *status, int nstatus)
{
int pid = (int)(uintptr)c;
- int wstatus = -1;
+ int s = -1;
- if(waitpid(pid, &wstatus, 0) < 0)
+ if(waitpid(pid, &s, 0) < 0)
return -1;
- if(wstatus == 0)
- return snprint(status, nstatus, "0 0 0 0 ''");
- return snprint(status, nstatus, "0 0 0 0 %d", (int)wstatus);
+ if(WIFEXITED(s)){
+ if((s = WEXITSTATUS(s)) == 0)
+ return snprint(status, nstatus, "%d 0 0 0 ''", pid);
+ return snprint(status, nstatus, "%d 0 0 0 'exit: %d'", pid, s);
+ }
+ if(WIFSIGNALED(s)){
+ switch(s = WTERMSIG(s)){
+ case SIGTERM:
+ case SIGKILL:
+ return snprint(status, nstatus, "%d 0 0 0 killed", pid);
+ }
+ return snprint(status, nstatus, "%d 0 0 0 'signal: %d'", pid, s);
+ }
+ return snprint(status, nstatus, "%d 0 0 0 'odd status: 0x%x'", pid, s);
}
-#undef kill
int
oscmdkill(void *c)
{