]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
compat: Add setproctitle from LXC
authorRoy Marples <roy@marples.name>
Mon, 14 Oct 2019 20:49:31 +0000 (21:49 +0100)
committerRoy Marples <roy@marples.name>
Mon, 14 Oct 2019 20:49:31 +0000 (21:49 +0100)
compat/setproctitle.c [new file with mode: 0644]
compat/setproctitle.h [new file with mode: 0644]
configure
src/dhcpcd.c

diff --git a/compat/setproctitle.c b/compat/setproctitle.c
new file mode 100644 (file)
index 0000000..f5ff0ac
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "config.h"
+
+#define prctl_arg(x) ((unsigned long)x)
+
+/*
+ * Sets the process title to the specified title. Note that this may fail if
+ * the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
+ */
+int setproctitle(const char *fmt, ...)
+{
+       char title[1024], *tp, *progname;
+       va_list args;
+       int fd, i;
+       char *buf_ptr, *tmp_proctitle;
+       char buf[BUFSIZ];
+       int ret = 0;
+       ssize_t bytes_read = 0;
+       size_t len;
+       static char *proctitle = NULL;
+
+#if 0
+       progname = getprogname();
+#else
+       progname = "dhcpcd";
+#endif
+       tp = title;
+       tp += snprintf(title, sizeof(title), "%s: ", progname);
+
+       va_start(args, fmt);
+       vsnprintf(tp, sizeof(title) - strlen(progname), fmt, args);
+       va_end(args);
+
+       /*
+        * We don't really need to know all of this stuff, but unfortunately
+        * PR_SET_MM_MAP requires us to set it all at once, so we have to
+        * figure it out anyway.
+        */
+       unsigned long start_data, end_data, start_brk, start_code, end_code,
+           start_stack, arg_start, arg_end, env_start, env_end;
+       long brk_val;
+       struct prctl_mm_map prctl_map;
+
+       fd = open("/proc/self/stat", O_RDONLY);
+       if (fd == -1)
+               return -1;
+       bytes_read = read(fd, buf, sizeof(buf) - 1);
+       close(fd);
+       if (bytes_read == -1)
+               return -1;
+
+       buf[bytes_read] = '\0';
+
+       /* Skip the first 25 fields, column 26-28 are start_code, end_code,
+        * and start_stack */
+       buf_ptr = strchr(buf, ' ');
+       for (i = 0; i < 24; i++) {
+               if (!buf_ptr)
+                       return -1;
+               buf_ptr = strchr(buf_ptr + 1, ' ');
+       }
+       if (!buf_ptr)
+               return -1;
+
+       i = sscanf(buf_ptr, "%lu %lu %lu", &start_code, &end_code, &start_stack);
+       if (i != 3)
+               return -1;
+
+       /* Skip the next 19 fields, column 45-51 are start_data to arg_end */
+       for (i = 0; i < 19; i++) {
+               if (!buf_ptr)
+                       return -1;
+               buf_ptr = strchr(buf_ptr + 1, ' ');
+       }
+
+       if (!buf_ptr)
+               return -1;
+
+       i = sscanf(buf_ptr, "%lu %lu %lu %*u %*u %lu %lu", &start_data,
+                  &end_data, &start_brk, &env_start, &env_end);
+       if (i != 5)
+               return -1;
+
+       /* Include the null byte here, because in the calculations below we
+        * want to have room for it. */
+       len = strlen(title) + 1;
+
+       tmp_proctitle = realloc(proctitle, len);
+       if (!tmp_proctitle)
+               return -1;
+
+       proctitle = tmp_proctitle;
+
+       arg_start = (unsigned long)proctitle;
+       arg_end = arg_start + len;
+
+       brk_val = syscall(__NR_brk, 0);
+
+       prctl_map = (struct prctl_mm_map){
+           .start_code = start_code,
+           .end_code = end_code,
+           .start_stack = start_stack,
+           .start_data = start_data,
+           .end_data = end_data,
+           .start_brk = start_brk,
+           .brk = (unsigned long long)brk_val,
+           .arg_start = arg_start,
+           .arg_end = arg_end,
+           .env_start = env_start,
+           .env_end = env_end,
+           .auxv = NULL,
+           .auxv_size = 0,
+           .exe_fd = (unsigned int)-1,
+       };
+
+       ret = prctl(PR_SET_MM, prctl_arg(PR_SET_MM_MAP), prctl_arg(&prctl_map),
+                   prctl_arg(sizeof(prctl_map)), prctl_arg(0));
+       if (ret == 0)
+               (void)strlcpy((char *)arg_start, title, len);
+       return ret;
+}
diff --git a/compat/setproctitle.h b/compat/setproctitle.h
new file mode 100644 (file)
index 0000000..2fe685f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SETPROCTITLE_H
+#define SETPROCTITLE_H
+
+#ifndef __printflike
+#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
+#define        __printflike(a, b) __attribute__((format(printf, a, b)))
+#else
+#define        __printflike(a, b)
+#endif
+#endif /* !__printflike */
+
+__printflike(1, 2) int setproctitle(const char *, ...);
+#endif
index 6b29444a082a0d13909301f2787d8ba5129e4a93..f17712830b6b247921ae025a58aff584c0e9f164 100755 (executable)
--- a/configure
+++ b/configure
@@ -818,8 +818,9 @@ EOF
        echo "$SETPROCTITLE"
        rm -f _setproctitle.c _setproctitle
 fi
-if [ "$SETPROCTITLE" = yes ]; then
-       echo "#define   HAVE_SETPROCTITLE" >>$CONFIG_H
+if [ "$SETPROCTITLE" = no ]; then
+       echo "COMPAT_SRCS+=     compat/setproctitle.c" >>$CONFIG_MK
+       echo "#include                  \"compat/setproctitle.h\"" >>$CONFIG_H
 fi
 
 if [ -z "$STRLCPY" ]; then
index e9b8a0234183857ce857ad95a4c822b7325b83a1..193414ed67bbd6fb867bf14e3abd61c18b0633a9 100644 (file)
@@ -1984,12 +1984,10 @@ printpidfile:
        logdebugx(PACKAGE "-" VERSION " starting");
        ctx.options |= DHCPCD_STARTED;
 
-#ifdef HAVE_SETPROCTITLE
        setproctitle("%s%s%s",
            ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind],
            ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
            ctx.options & DHCPCD_IPV6 ? " [ip6]" : "");
-#endif
 
        if (if_opensockets(&ctx) == -1) {
                logerr("%s: if_opensockets", __func__);