commit 072f3aadb35dd9d20c2c1e39239c4fdd2632120c
parent 0e0ffdbe05a892771d4f3a5b57478e195c639bb0
Author: Claudio Alessi <smoppy@gmail.com>
Date:   Wed,  1 Apr 2020 14:55:29 +0200
Ignore SIGCHLD to prevent zombies.
Also move most of the logic from run() to a new serve() function which handle
the forked child.
Diffstat:
| M | beans.c | | | 67 | ++++++++++++++++++++++++++++++++++++++++--------------------------- | 
1 file changed, 40 insertions(+), 27 deletions(-)
diff --git a/beans.c b/beans.c
@@ -10,6 +10,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <signal.h>
 
 #include "arg.h"
 
@@ -21,6 +22,7 @@ int bindon(char *port);
 void *ecalloc(size_t nmemb, size_t size);
 char *readall(int sd, int *len);
 void run(void);
+void serve(int sd);
 void sout(int sd, char *fmt, ...);
 
 /* variables */
@@ -102,8 +104,8 @@ void
 run(void) {
 	struct sockaddr_storage conn;
 	socklen_t size;
-	int csd, len, tmpsd;
-	char tmpfn[64] = {0}, *buf, *code;
+	int csd;
+	pid_t pid;
 
 	while(1) {
 		size = sizeof conn;
@@ -112,40 +114,50 @@ run(void) {
 			fprintf(stderr, "accept(): %s", strerror(errno));
 			continue;
 		}
-		if(fork()) {
+		pid = fork();
+		if(pid) {
+			if(pid == -1)
+				fprintf(stderr, "fork(): %s\n", strerror(errno));
 			close(csd);
 			continue;
 		}
-		buf = readall(csd, &len);
-		if(!(buf && len)) {
-			sout(csd, "Nothing pasted.\n");
-			close(csd);
-			continue;
-		}
-		snprintf(tmpfn, sizeof tmpfn, "%s/beans.XXXXXX", path);
-		tmpsd = mkstemp(tmpfn);
-		if(tmpsd == -1) {
-			fprintf(stderr, "mkstemp()\n");
-			free(buf);
-			close(csd);
-			continue;
-		}
-		if(write(tmpsd, buf, len) == -1)
-			fprintf(stderr, "write(): %s\n", strerror(errno));
-		code = strchr(tmpfn, '.')+1;
-		if(*base)
-			sout(csd, "%s%s\n", base, code);
-		else
-			sout(csd, "%s\n", code);
-		fchmod(tmpsd, strtol(mode, 0, 8));
+		serve(csd);
 		close(csd);
-		close(tmpsd);
-		free(buf);
 		break;
 	}
 }
 
 void
+serve(int sd) {
+	int len, tmpsd;
+	char *buf, *code;
+	char tmpfn[64] = {0};
+
+	buf = readall(sd, &len);
+	if(!(buf && len)) {
+		sout(sd, "Nothing pasted.\n");
+		return;
+	}
+	snprintf(tmpfn, sizeof tmpfn, "%s/beans.XXXXXX", path);
+	tmpsd = mkstemp(tmpfn);
+	if(tmpsd == -1) {
+		fprintf(stderr, "mkstemp()\n");
+		free(buf);
+		return;
+	}
+	if(write(tmpsd, buf, len) == -1)
+		fprintf(stderr, "write(): %s\n", strerror(errno));
+	code = strchr(tmpfn, '.')+1;
+	if(*base)
+		sout(sd, "%s%s\n", base, code);
+	else
+		sout(sd, "%s\n", code);
+	fchmod(tmpsd, strtol(mode, 0, 8));
+	close(tmpsd);
+	free(buf);
+}
+
+void
 sout(int sd, char *fmt, ...) {
 	va_list ap;
 	char buf[4096];
@@ -168,6 +180,7 @@ main(int argc, char *argv[]) {
 	} ARGEND
 
 	sockd = bindon(port);
+	signal(SIGCHLD, SIG_IGN); /* cleanup zombies */
 	run();
 	close(sockd);
 	return 0;