xref: /netbsd-src/external/bsd/nsd/dist/compat/setproctitle.c (revision f3d63a561b22e5536a0779632985057ed3d766aa)
1*f3d63a56Schristos /*
2*f3d63a56Schristos  * setproctitle.c -- mimic setproctitle
3*f3d63a56Schristos  *
4*f3d63a56Schristos  * Copyright (c) 2020, NLnet Labs. All rights reserved.
5*f3d63a56Schristos  *
6*f3d63a56Schristos  * See LICENSE for the license.
7*f3d63a56Schristos  *
8*f3d63a56Schristos  */
9*f3d63a56Schristos #include "config.h"
10*f3d63a56Schristos 
11*f3d63a56Schristos #if defined(__linux)
12*f3d63a56Schristos #include <assert.h>
13*f3d63a56Schristos #include <errno.h>
14*f3d63a56Schristos #ifndef HAVE_CONFIG_H
15*f3d63a56Schristos #include <libgen.h>
16*f3d63a56Schristos #endif
17*f3d63a56Schristos #include <stdarg.h>
18*f3d63a56Schristos #include <stdio.h>
19*f3d63a56Schristos #include <stdlib.h>
20*f3d63a56Schristos #include <sys/prctl.h>
21*f3d63a56Schristos #include <unistd.h>
22*f3d63a56Schristos 
executable(void)23*f3d63a56Schristos static char *executable(void)
24*f3d63a56Schristos {
25*f3d63a56Schristos   char *ptr, *buf = NULL;
26*f3d63a56Schristos   size_t len = 0;
27*f3d63a56Schristos   ssize_t cnt = 0;
28*f3d63a56Schristos 
29*f3d63a56Schristos   buf = NULL;
30*f3d63a56Schristos   do {
31*f3d63a56Schristos     len += 32;
32*f3d63a56Schristos     ptr = realloc(buf, len);
33*f3d63a56Schristos     if (ptr == NULL) {
34*f3d63a56Schristos       if (buf != NULL) {
35*f3d63a56Schristos         free(buf);
36*f3d63a56Schristos       }
37*f3d63a56Schristos       return NULL;
38*f3d63a56Schristos     }
39*f3d63a56Schristos     buf = ptr;
40*f3d63a56Schristos     cnt = readlink("/proc/self/exe", buf, len);
41*f3d63a56Schristos   } while (cnt >= 0 && (size_t)cnt == len);
42*f3d63a56Schristos 
43*f3d63a56Schristos   if (cnt >= 0) {
44*f3d63a56Schristos     buf[cnt] = '\0';
45*f3d63a56Schristos     return buf;
46*f3d63a56Schristos   }
47*f3d63a56Schristos 
48*f3d63a56Schristos   free(buf);
49*f3d63a56Schristos 
50*f3d63a56Schristos   return NULL;
51*f3d63a56Schristos }
52*f3d63a56Schristos 
setproctitle(const char * fmt,...)53*f3d63a56Schristos void setproctitle(const char *fmt, ...)
54*f3d63a56Schristos {
55*f3d63a56Schristos   va_list ap;
56*f3d63a56Schristos   char buf[32];
57*f3d63a56Schristos   int cnt = 0, off = 0;
58*f3d63a56Schristos 
59*f3d63a56Schristos   /* prepend executable name if fmt does not start with '-' */
60*f3d63a56Schristos   if (fmt == NULL || fmt[0] != '-' || fmt[(off = 1)] == '\0') {
61*f3d63a56Schristos     char *exe;
62*f3d63a56Schristos     const char *sep = (fmt && fmt[off] != '\0') ? ": " : "";
63*f3d63a56Schristos     if ((exe = executable()) != NULL) {
64*f3d63a56Schristos       cnt = snprintf(buf, sizeof(buf), "%s%s", basename(exe), sep);
65*f3d63a56Schristos       if ((size_t)cnt >= sizeof(buf)) {
66*f3d63a56Schristos         cnt = 31; /* leave room for '\0' */
67*f3d63a56Schristos       }
68*f3d63a56Schristos       free(exe);
69*f3d63a56Schristos     }
70*f3d63a56Schristos   }
71*f3d63a56Schristos 
72*f3d63a56Schristos   if (fmt != NULL && fmt[off] != '\0') {
73*f3d63a56Schristos     va_start(ap, fmt);
74*f3d63a56Schristos     cnt = vsnprintf(
75*f3d63a56Schristos       buf+(size_t)cnt, sizeof(buf)-(size_t)cnt, fmt+(size_t)off, ap);
76*f3d63a56Schristos     va_end(ap);
77*f3d63a56Schristos   }
78*f3d63a56Schristos 
79*f3d63a56Schristos   if (cnt > 0) {
80*f3d63a56Schristos     assert(cnt > 0 && (size_t)cnt < sizeof(buf));
81*f3d63a56Schristos     (void)prctl(PR_SET_NAME, buf, 0, 0, 0);
82*f3d63a56Schristos   }
83*f3d63a56Schristos }
84*f3d63a56Schristos #endif /* __linux */
85