Re: [dev] [st] externalpipe on OpenBSD

2024-02-21 Thread Страхиња Радић
On 24/02/21 10:12AM, Страхиња Радић wrote:
> [...] (the program specified in openurlcmd doesn't get 
> executed).

I narrowed this down to adding "exec" to the second pledge:

+@@ -803,7 +809,7 @@ ttynew(const char *line, char *cmd, const char *out, char 
**args)
+   break;
+   default:
+ #ifdef __OpenBSD__
+-  if (pledge("stdio rpath tty proc", NULL) == -1)
++  if (pledge("stdio rpath tty proc exec", NULL) == -1)
+   die("pledge\n");
+ #endif

with the added "exec", the program in openurlcmd gets executed. What I don't 
know, however, is why is st not aborted if it is in violation of pledge, 
instead of silently failing. The changed pledge is in the parent, which 
continues execution.


> I also noticed that when I simply comment out the pledge, the program is 
> executed, but nothing is passed to openurlcmd.

Disregard this, it was due to having the debug version of script in openurlcmd 
still installed in the system.

* * *

Anyway, I have attached the proposed "0.8.5" diff with this message. Is it ok 
if I try to commit it to the wiki?
diff --git a/st.c b/st.c
index 034954d..98f2589 100644
--- a/st.c
+++ b/st.c
@@ -718,8 +718,14 @@ sigchld(int a)
 	if ((p = waitpid(pid, , WNOHANG)) < 0)
 		die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
 
-	if (pid != p)
+	if (pid != p) {
+		if (p == 0 && wait() < 0)
+			die("wait: %s\n", strerror(errno));
+
+		/* reinstall sigchld handler */
+		signal(SIGCHLD, sigchld);
 		return;
+	}
 
 	if (WIFEXITED(stat) && WEXITSTATUS(stat))
 		die("child exited with status %d\n", WEXITSTATUS(stat));
@@ -803,7 +809,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
 		break;
 	default:
 #ifdef __OpenBSD__
-		if (pledge("stdio rpath tty proc", NULL) == -1)
+		if (pledge("stdio rpath tty proc exec", NULL) == -1)
 			die("pledge\n");
 #endif
 		close(s);
@@ -1991,6 +1997,59 @@ strparse(void)
 	}
 }
 
+void
+externalpipe(const Arg *arg)
+{
+	int to[2];
+	char buf[UTF_SIZ];
+	void (*oldsigpipe)(int);
+	Glyph *bp, *end;
+	int lastpos, n, newline;
+
+	if (pipe(to) == -1)
+		return;
+
+	switch (fork()) {
+	case -1:
+		close(to[0]);
+		close(to[1]);
+		return;
+	case 0:
+		dup2(to[0], STDIN_FILENO);
+		close(to[0]);
+		close(to[1]);
+		execvp(((char **)arg->v)[0], (char **)arg->v);
+		fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
+		perror("failed");
+		exit(0);
+	}
+
+	close(to[0]);
+	/* ignore sigpipe for now, in case child exists early */
+	oldsigpipe = signal(SIGPIPE, SIG_IGN);
+	newline = 0;
+	for (n = 0; n < term.row; n++) {
+		bp = term.line[n];
+		lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
+		if (lastpos < 0)
+			break;
+		end = [lastpos + 1];
+		for (; bp < end; ++bp)
+			if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
+break;
+		if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
+			continue;
+		if (xwrite(to[1], "\n", 1) < 0)
+			break;
+		newline = 0;
+	}
+	if (newline)
+		(void)xwrite(to[1], "\n", 1);
+	close(to[1]);
+	/* restore */
+	signal(SIGPIPE, oldsigpipe);
+}
+
 void
 strdump(void)
 {
diff --git a/st.h b/st.h
index fd3b0d8..754cd08 100644
--- a/st.h
+++ b/st.h
@@ -81,6 +81,7 @@ void die(const char *, ...);
 void redraw(void);
 void draw(void);
 
+void externalpipe(const Arg *);
 void printscreen(const Arg *);
 void printsel(const Arg *);
 void sendbreak(const Arg *);
-- 
2.42.0



[dev] [st] externalpipe on OpenBSD

2024-02-21 Thread Страхиња Радић
Hello,

I recently installed OpenBSD for the first time and I noticed a few issues with 
externalpipe[1]. It seems this patch clashes with the parameters passed to 
pledge(2) in ttynew[2] (the program specified in openurlcmd doesn't get 
executed).

I also noticed that when I simply comment out the pledge, the program is 
executed, but nothing is passed to openurlcmd.

Since I am new to pledge, it will take some time for me to debug this, but I'm 
reporting this anyway in case there is someone more versed in the internals of 
OpenBSD who can take a look at this.


[1]: https://st.suckless.org/patches/externalpipe/
[2]: https://git.suckless.org/st/file/st.c.html#l799