ref: 9080f94b2a14f931f9b2a74470c0e38bee194649
parent: b4fc8112b2c73cdd7dfe21b9b0172b19c5c7ea08
author: Jacob Moody <moody@posixcafe.org>
date: Wed Dec 17 20:28:31 EST 2025
libnpe: add system() wait() and kill()
--- a/include/npe/npe.h
+++ b/include/npe/npe.h
@@ -52,6 +52,12 @@
#pragma lib "libthread.a"
#endif
+typedef int pid_t;
+#define WNOHANG 0x1
+#define waitpid npe_waitpid
+int npe_waitpid(int wpid, int *status, int options);
+int kill(int pid, int sig);
extern void (*exit)(int);
+int system(const char *);
#endif
--- a/include/npe/signal.h
+++ b/include/npe/signal.h
@@ -9,6 +9,7 @@
/* all are treated as SIGSEGV */
SIGINT = 2,
SIGILL = 4,
+ SIGKILL = 7,
SIGABRT = 6,
SIGFPE = 8,
SIGSEGV = 11,
--- /dev/null
+++ b/include/npe/sys/wait.h
@@ -1,0 +1,1 @@
+#include <npe.h>
--- /dev/null
+++ b/libnpe/kill.c
@@ -1,0 +1,37 @@
+#include <npe.h>
+#include <signal.h>
+
+static
+char *killnotes[] = {+ [SIGKILL] = "exit",
+ [SIGTERM] = "term",
+};
+
+static int
+note(int pid, char *msg, char *fmt)
+{+ int f;
+ char pname[50];
+
+ sprintf(pname, fmt, pid);
+ f = open(pname, OWRITE);
+ if(f < 0){+ return -1;
+ }
+ if(write(f, msg, strlen(msg)) < 0){+ close(f);
+ return -1;
+ }
+ close(f);
+ return 0;
+}
+
+int
+kill(int pid, int sig)
+{+ if(sig < 0 || sig > SIGTERM || killnotes[sig] == nil)
+ return -1;
+ if(pid == 0)
+ return note(getpid(), killnotes[sig], "/proc/%d/notepg");
+ return note(pid, killnotes[sig], "/proc/%d/note");
+}
--- a/libnpe/mkfile
+++ b/libnpe/mkfile
@@ -43,6 +43,7 @@
isatty.$O\
isinf.$O\
isnormal.$O\
+ kill.$O\
ldexpf.$O\
log1p.$O\
localtime.$O\
@@ -68,10 +69,12 @@
strerror_r.$O\
strftime.$O\
strlcpy.$O\
+ system.$O\
trunc.$O\
unlink.$O\
usleep.$O\
utime.$O\
+ wait.$O\
UPDATE=\
mkfile\
--- /dev/null
+++ b/libnpe/system.c
@@ -1,0 +1,39 @@
+#include <npe.h>
+
+#undef waitpid
+
+int
+system(char *s)
+{+ int status;
+ Waitmsg *w;
+ pid_t pid;
+ char cmd[30], *oty;
+
+ if(!s)
+ return 1; /* a command interpreter is available */
+ pid = fork();
+ if(pid == 0){+ oty = getenv("cputype");+ if(!oty)
+ return -1;
+ snprintf(cmd, sizeof cmd, "/%s/bin/rc", oty);
+ execl(cmd, "rc", "-c", s, NULL);
+ exits(nil);
+ }
+ if(pid < 0){+ return -1;
+ }
+ for(;;){+ w = wait();
+ if(w == nil || w->pid == pid)
+ break;
+ }
+
+ status = -1;
+ if(w != nil){+ status = w->msg[0] != 0;
+ free(w);
+ }
+ return status;
+}
--- /dev/null
+++ b/libnpe/wait.c
@@ -1,0 +1,143 @@
+#include <npe.h>
+#include <signal.h>
+
+static struct {+ char *msg; /* just check prefix */
+ int num;
+} sigtab[] = {+ {"interrupt", SIGINT},+ {"sys: trap: illegal instruction", SIGILL},+ {"sys: trap: reserved instruction", SIGILL},+ {"sys: trap: reserved", SIGILL},+ {"sys: trap: arithmetic overflow", SIGFPE},+ {"abort", SIGABRT},+ {"sys: fp:", SIGFPE},+ {"exit", SIGKILL},+ {"die", SIGKILL},+ {"kill", SIGKILL},+ {"sys: trap: bus error", SIGSEGV},+ {"sys: trap: address error", SIGSEGV},+ {"sys: trap: TLB", SIGSEGV},+ {"term", SIGTERM},+};
+#define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0])))
+
+int
+_stringsig(char *nam)
+{+ int i;
+
+ for(i = 0; i<NSIGTAB; i++)
+ if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0)
+ return sigtab[i].num;
+ return 0;
+}
+
+
+/*
+ * status not yet collected for processes that have exited
+ */
+typedef struct Waited Waited;
+struct Waited {+ Waitmsg* msg;
+ Waited* next;
+};
+static Waited *wd;
+
+static Waitmsg *
+lookpid(int pid)
+{+ Waited **wl, *w;
+ Waitmsg *msg;
+
+ for(wl = &wd; (w = *wl) != nil; wl = &w->next)
+ if(pid <= 0 || w->msg->pid == pid){+ msg = w->msg;
+ *wl = w->next;
+ free(w);
+ return msg;
+ }
+ return 0;
+}
+
+static void
+addpid(Waitmsg *msg)
+{+ Waited *w;
+
+ w = malloc(sizeof(*w));
+ if(w == nil){+ /* lost it; what can we do? */
+ free(msg);
+ return;
+ }
+ w->msg = msg;
+ w->next = wd;
+ wd = w;
+}
+
+static int
+waitstatus(Waitmsg *w)
+{+ int r, t;
+ char *bp, *ep;
+
+ r = 0;
+ t = 0;
+ if(w->msg[0]){+ /* message is 'prog pid:string' */
+ bp = w->msg;
+ while(*bp){+ if(*bp++ == ':')
+ break;
+ }
+ if(*bp == 0)
+ bp = w->msg;
+ r = strtol(bp, &ep, 10);
+ if(*ep == 0){+ if(r < 0 || r >= 256)
+ r = 1;
+ }else{+ t = _stringsig(bp);
+ if(t == 0)
+ r = 1;
+ }
+ }
+ return (r<<8) | t;
+}
+
+int
+npe_waitpid(int wpid, int *status, int options)
+{+ char pname[50];
+ Dir *d;
+ Waitmsg *w;
+
+ w = lookpid(wpid);
+ if(w == nil){+ if(options & WNOHANG){+ snprintf(pname, sizeof(pname), "/proc/%d/wait", getpid());
+ d = dirstat(pname);
+ if(d != nil && d->length == 0){+ free(d);
+ return 0;
+ }
+ free(d);
+ }
+ for(;;){+ w = wait();
+ if(w == nil){+ return -1;
+ }
+ if(wpid <= 0 || w->pid == wpid)
+ break;
+ addpid(w);
+ }
+ }
+ if(status != nil)
+ *status = waitstatus(w);
+ wpid = w->pid;
+ free(w);
+ return wpid;
+
+}
--- a/libnpe_sdl2/_sdl.h
+++ b/libnpe_sdl2/_sdl.h
@@ -10,6 +10,7 @@
#include <cursor.h>
#include <plumb.h>
#include "_npe.h"
+#undef waitpid
struct npe_sdl {Mousectl *mctl;
--
⑨