[PATCH] setproctitle cleanup

Roy Marples roy at marples.name
Fri Oct 9 19:41:03 UTC 2020


Hi!

I had issues with an alternative setproctitle implementation in dhcpcd, so gave 
the one from libbsd a spin. Seems to work fine!

I need to embed this in my binary though - I enjoy building it without any 
libraries and libbsd isn't always installed into /lib by some distros.
As such, I tidied up a lot of compile warnings due to signedness and added a 
setproctitle_fini() function to free any malloced memory used to make debugging 
with valgrind easier.

Patch attached.

Roy
-------------- next part --------------
--- setproctitle.c.orig	2020-10-09 19:52:18.163869323 +0100
+++ setproctitle.c	2020-10-09 20:19:35.553275107 +0100
@@ -35,7 +35,7 @@
 
 static struct {
 	/* Original value. */
-	const char *arg0;
+	char *arg0;
 
 	/* Title space available. */
 	char *base, *end;
@@ -46,6 +46,11 @@
 	bool warned;
 	bool reset;
 	int error;
+
+	/* Our copy of args and environent to free. */
+	int argc;
+	char **argv;
+	char **tmp_environ;
 } SPT;
 
 
@@ -65,14 +70,12 @@
 #ifdef HAVE_CLEARENV
 	return clearenv();
 #else
-	char **tmp;
-
-	tmp = malloc(sizeof(*tmp));
-	if (tmp == NULL)
+	SPT.tmp_environ = malloc(sizeof(*SPT.tmp_environ));
+	if (SPT.tmp_environ == NULL)
 		return errno;
 
-	tmp[0] = NULL;
-	environ = tmp;
+	SPT.tmp_environ[0] = NULL;
+	environ = SPT.tmp_environ;
 
 	return 0;
 #endif
@@ -83,7 +86,7 @@
 {
 	char **envcopy;
 	char *eq;
-	int envsize;
+	size_t envsize;
 	int i, error;
 
 	if (environ != envp)
@@ -93,7 +96,7 @@
 	 * clearenv() or setenv() is implemented to free the internal
 	 * environ array, because we will need to access the old environ
 	 * contents to make the new copy. */
-	envsize = (envc + 1) * sizeof(char *);
+	envsize = (size_t)(envc + 1) * sizeof(char *);
 	envcopy = malloc(envsize);
 	if (envcopy == NULL)
 		return errno;
@@ -213,23 +216,45 @@
 		return;
 	}
 
+	SPT.argc = argc;
+	SPT.argv = argv;
+
 	SPT.nul  = nul;
 	SPT.base = base;
 	SPT.end  = end;
 }
 
+void
+setproctitle_fini(void)
+{
+	int i;
+
+	free(SPT.arg0);
+	SPT.arg0 = NULL;
+
+	for (i = 1; i < SPT.argc; i++) {
+		if (SPT.argv[i] != NULL)
+			free(SPT.argv[i]);
+	}
+	SPT.argc = 0;
+
+	free(SPT.tmp_environ);
+	SPT.tmp_environ = NULL;
+}
+
 #ifndef SPT_MAXTITLE
 #define SPT_MAXTITLE 255
 #endif
 
-void
+__printflike(1, 2) static void
 setproctitle_impl(const char *fmt, ...)
 {
 	/* Use buffer in case argv[0] is passed. */
 	char buf[SPT_MAXTITLE + 1];
 	va_list ap;
 	char *nul;
-	int len;
+	int l;
+	size_t len, base_len;
 
 	if (SPT.base == NULL) {
 		if (!SPT.warned) {
@@ -247,30 +272,35 @@
 			len = 0;
 		} else {
 			/* Print program name heading for grep. */
-			snprintf(buf, sizeof(buf), "%s: ", getprogname());
-			len = strlen(buf);
+			l = snprintf(buf, sizeof(buf), "%s: ", getprogname());
+			if (l <= 0)
+				return;
+			len = (size_t)l;
 		}
 
 		va_start(ap, fmt);
-		len += vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
+		l = vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
 		va_end(ap);
 	} else {
-		len = snprintf(buf, sizeof(buf), "%s", SPT.arg0);
+		len = 0;
+		l = snprintf(buf, sizeof(buf), "%s", SPT.arg0);
 	}
 
-	if (len <= 0) {
+	if (l <= 0) {
 		SPT.error = errno;
 		return;
 	}
+	len += (size_t)l;
 
+	base_len = (size_t)(SPT.end - SPT.base);
 	if (!SPT.reset) {
-		memset(SPT.base, 0, SPT.end - SPT.base);
+		memset(SPT.base, 0, base_len);
 		SPT.reset = true;
 	} else {
-		memset(SPT.base, 0, spt_min(sizeof(buf), SPT.end - SPT.base));
+		memset(SPT.base, 0, spt_min(sizeof(buf), base_len));
 	}
 
-	len = spt_min(len, spt_min(sizeof(buf), SPT.end - SPT.base) - 1);
+	len = spt_min(len, spt_min(sizeof(buf), base_len) - 1);
 	memcpy(SPT.base, buf, len);
 	nul = &SPT.base[len];
 


More information about the libbsd mailing list