summaryrefslogtreecommitdiffstats
path: root/compat
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-10-15 13:40:32 +0100
committerRoy Marples <roy@marples.name>2019-10-15 13:40:32 +0100
commitb6f15b302ca72858f93406b41a4886cbad42b6ee (patch)
tree1c7396b44cfd1c96992e5860c7ff3e0b96f12748 /compat
parenta644b9e11971993d16beed3940cebd28fc243048 (diff)
downloaddhcpcd-b6f15b302ca72858f93406b41a4886cbad42b6ee.tar.xz
Revert "compat: Use more portable setproctitle from nginx"
This reverts commit cbcb352f10de5ba5185860f20e148509081f9d2f.
Diffstat (limited to 'compat')
-rw-r--r--compat/setproctitle.c238
-rw-r--r--compat/setproctitle.h44
2 files changed, 148 insertions, 134 deletions
diff --git a/compat/setproctitle.c b/compat/setproctitle.c
index 9350e5ee..f5ff0ac0 100644
--- a/compat/setproctitle.c
+++ b/compat/setproctitle.c
@@ -1,136 +1,156 @@
/*
- * Copyright (C) 2002-2019 Igor Sysoev
- * Copyright (C) 2011-2019 Nginx, Inc.
- * All rights reserved.
+ * lxc: linux Container library
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * (C) Copyright IBM Corp. 2007, 2008
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * 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"
-#ifdef __sun
-#define SETPROCTITLE_PAD ' '
+#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
-#define SETPROCTITLE_PAD '\0'
+ progname = "dhcpcd";
#endif
+ tp = title;
+ tp += snprintf(title, sizeof(title), "%s: ", progname);
-static int setproctitle_argc;
-static char *setproctitle_argv_last;
-static char **setproctitle_argv;
-static char *setproctitle_buf;
-
-int
-setproctitle_init(int argc, char **argv)
-{
- size_t i, len;
- char *p;
+ va_start(args, fmt);
+ vsnprintf(tp, sizeof(title) - strlen(progname), fmt, args);
+ va_end(args);
- len = 0;
- for (i = 0; environ[i] != NULL; i++)
- len += strlen(environ[i]) + 1;
- if ((setproctitle_buf = malloc(len)) == NULL)
+ /*
+ * 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;
- setproctitle_argc = argc;
- setproctitle_argv = argv;
- setproctitle_argv_last = setproctitle_argv[0];
- for (i = 0; setproctitle_argv[i] != NULL; i++) {
- if (setproctitle_argv_last == setproctitle_argv[i])
- setproctitle_argv_last = setproctitle_argv[i] +
- strlen(setproctitle_argv[i]) + 1;
- }
+ buf[bytes_read] = '\0';
- p = setproctitle_buf;
- for (i = 0; environ[i] != NULL; i++) {
- if (setproctitle_argv_last != environ[i])
- continue;
- len = strlen(environ[i]) + 1;
- setproctitle_argv_last = environ[i] + len;
- strlcpy(p, environ[i], len);
- environ[i] = p;
- p += len;
+ /* 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;
- setproctitle_argv_last--;
- return 0;
-}
-
-void
-setproctitle_free(void)
-{
-
- free(setproctitle_buf);
-}
+ i = sscanf(buf_ptr, "%lu %lu %lu", &start_code, &end_code, &start_stack);
+ if (i != 3)
+ return -1;
-void
-setproctitle(const char *fmt, ...)
-{
- const char *progname;
- char *p;
- int n;
- va_list args;
-#if 0
- progname = getprogname();
-#else
- progname = "dhcpcd";
-#endif
+ /* 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, ' ');
+ }
- setproctitle_argv[1] = NULL;
-#define LAST_SIZE (size_t)(setproctitle_argv_last - p)
+ if (!buf_ptr)
+ return -1;
- p = setproctitle_argv[0];
- n = snprintf(p, LAST_SIZE, "%s: ", progname);
- if (n == -1)
- return;
- p += n;
+ 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;
- va_start(args, fmt);
- n = vsnprintf(p, LAST_SIZE, fmt, args);
- va_end(args);
- if (n == -1)
- return;
- p += n;
+ /* Include the null byte here, because in the calculations below we
+ * want to have room for it. */
+ len = strlen(title) + 1;
-#ifdef __sun
- size_t len;
- int i;
-
- len = 0;
- for (i = 0; i < setproctitle_argc; i++)
- len += strlen(setproctitle_argv[i]) + 1;
-
- if (len > (size_t)(p - setproctitle_argv[0])) {
- p += strlcpy(p, " (", LAST_SIZE);
- for (i = 0; i < setproctitle_argc; i++) {
- p += strlcpy(p, setproctitle_argv[i], LAST_SIZE);
- p += strlcpy(p, " ", LAST_SIZE);
- }
- }
-#endif
+ tmp_proctitle = realloc(proctitle, len);
+ if (!tmp_proctitle)
+ return -1;
- if (setproctitle_argv_last - p > 0)
- memset(p, SETPROCTITLE_PAD, LAST_SIZE);
+ 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
index 18249947..2fe685f1 100644
--- a/compat/setproctitle.h
+++ b/compat/setproctitle.h
@@ -1,28 +1,24 @@
/*
- * Copyright (C) 2002-2019 Igor Sysoev
- * Copyright (C) 2011-2019 Nginx, Inc.
- * All rights reserved.
+ * lxc: linux Container library
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * (C) Copyright IBM Corp. 2007, 2008
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * 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
@@ -36,7 +32,5 @@
#endif
#endif /* !__printflike */
-int setproctitle_init(int, char **);
-void setproctitle_free(void);
-__printflike(1, 2) void setproctitle(const char *, ...);
+__printflike(1, 2) int setproctitle(const char *, ...);
#endif