Skip to content
Browse files

darwin: implement uv_set_process_title, part 2

Make changes to the process title visible to tools like `ps`.

The argv clobber technique is reasonably portable across Unices;
the common code has been moved into src/unix/proctitle.c and is used
on Linux and OS X. Other platforms will probably follow in the future.
  • Loading branch information...
1 parent 14eb8b0 commit e89aced8d6ca9e5fcb3d5e6159db0322beef4234 @bnoordhuis bnoordhuis committed
Showing with 139 additions and 125 deletions.
  1. +3 −1 config-unix.mk
  2. +0 −39 src/unix/darwin.c
  3. +7 −85 src/unix/linux-core.c
  4. +126 −0 src/unix/proctitle.c
  5. +3 −0 uv.gyp
View
4 config-unix.mk
@@ -78,6 +78,7 @@ SOEXT = dylib
OBJS += src/unix/darwin.o
OBJS += src/unix/kqueue.o
OBJS += src/unix/fsevents.o
+OBJS += src/unix/proctitle.o
OBJS += src/unix/darwin-proctitle.o
endif
@@ -87,7 +88,8 @@ LDFLAGS+=-ldl -lrt
RUNNER_CFLAGS += -D_GNU_SOURCE
OBJS += src/unix/linux-core.o \
src/unix/linux-inotify.o \
- src/unix/linux-syscalls.o
+ src/unix/linux-syscalls.o \
+ src/unix/proctitle.o
endif
ifeq (freebsd,$(OS))
View
39 src/unix/darwin.c
@@ -37,8 +37,6 @@
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */
-static char *process_title;
-
/* Forward declarations */
void uv__cf_loop_runner(void* arg);
void uv__cf_loop_cb(void* arg);
@@ -254,43 +252,6 @@ void uv_loadavg(double avg[3]) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-uv_err_t uv_set_process_title(const char* title) {
- int uv__set_process_title(const char*);
-
- if (process_title != NULL)
- free(process_title);
-
- process_title = strdup(title);
-
- if (process_title == NULL)
- return uv__new_artificial_error(UV_ENOMEM);
-
- if (uv__set_process_title(title))
- return uv__new_artificial_error(UV_ENOSYS);
-
- return uv_ok_;
-}
-
-
-uv_err_t uv_get_process_title(char* buffer, size_t size) {
- if (process_title) {
- strncpy(buffer, process_title, size);
- } else {
- if (size > 0) {
- buffer[0] = '\0';
- }
- }
-
- return uv_ok_;
-}
-
-
uv_err_t uv_resident_set_memory(size_t* rss) {
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
View
92 src/unix/linux-core.c
@@ -57,25 +57,12 @@
# define CLOCK_BOOTTIME 7
#endif
-static void* args_mem;
-
-static struct {
- char *str;
- size_t len;
-} process_title;
-
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci);
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static void read_times(unsigned int numcpus, uv_cpu_info_t* ci);
static unsigned long read_cpufreq(unsigned int cpunum);
-__attribute__((destructor))
-static void free_args_mem(void) {
- free(args_mem); /* keep valgrind happy */
-}
-
-
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
int fd;
@@ -296,78 +283,6 @@ uint64_t uv_get_total_memory(void) {
}
-char** uv_setup_args(int argc, char** argv) {
- char **new_argv;
- char **new_env;
- size_t size;
- int envc;
- char *s;
- int i;
-
- for (envc = 0; environ[envc]; envc++);
-
- s = envc ? environ[envc - 1] : argv[argc - 1];
-
- process_title.str = argv[0];
- process_title.len = s + strlen(s) + 1 - argv[0];
-
- size = process_title.len;
- size += (argc + 1) * sizeof(char **);
- size += (envc + 1) * sizeof(char **);
-
- if (NULL == (s = malloc(size))) {
- process_title.str = NULL;
- process_title.len = 0;
- return argv;
- }
- args_mem = s;
-
- new_argv = (char **) s;
- new_env = new_argv + argc + 1;
- s = (char *) (new_env + envc + 1);
- memcpy(s, process_title.str, process_title.len);
-
- for (i = 0; i < argc; i++)
- new_argv[i] = s + (argv[i] - argv[0]);
- new_argv[argc] = NULL;
-
- s += environ[0] - argv[0];
-
- for (i = 0; i < envc; i++)
- new_env[i] = s + (environ[i] - environ[0]);
- new_env[envc] = NULL;
-
- environ = new_env;
- return new_argv;
-}
-
-
-uv_err_t uv_set_process_title(const char* title) {
- /* No need to terminate, last char is always '\0'. */
- if (process_title.len)
- strncpy(process_title.str, title, process_title.len - 1);
-
-#if defined(PR_SET_NAME)
- prctl(PR_SET_NAME, title);
-#endif
-
- return uv_ok_;
-}
-
-
-uv_err_t uv_get_process_title(char* buffer, size_t size) {
- if (process_title.str) {
- strncpy(buffer, process_title.str, size);
- } else {
- if (size > 0) {
- buffer[0] = '\0';
- }
- }
-
- return uv_ok_;
-}
-
-
uv_err_t uv_resident_set_memory(size_t* rss) {
FILE* f;
int itmp;
@@ -787,3 +702,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
free(addresses);
}
+
+
+void uv__set_process_title(const char* title) {
+#if defined(PR_SET_NAME)
+ prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
+#endif
+}
View
126 src/unix/proctitle.c
@@ -0,0 +1,126 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+extern void uv__set_process_title(const char* title);
+
+static void* args_mem;
+
+static struct {
+ char* str;
+ int len;
+} process_title;
+
+
+char** uv_setup_args(int argc, char** argv) {
+ char** new_argv;
+ char** new_env;
+ size_t size;
+ int envc;
+ char* s;
+ int i;
+
+#if defined(__APPLE__)
+ char*** _NSGetArgv(void);
+ char*** _NSGetEnviron(void);
+ char** environ = *_NSGetEnviron();
+#else
+ extern char** environ;
+#endif
+
+ for (envc = 0; environ[envc]; envc++);
+
+ if (envc == 0)
+ s = argv[argc - 1];
+ else
+ s = environ[envc - 1];
+
+ process_title.str = argv[0];
+ process_title.len = s + strlen(s) + 1 - argv[0];
+
+ size = process_title.len;
+ size += (argc + 1) * sizeof(char**);
+ size += (envc + 1) * sizeof(char**);
+ s = args_mem = malloc(size);
+
+ if (s == NULL) {
+ process_title.str = NULL;
+ process_title.len = 0;
+ return argv;
+ }
+
+ new_argv = (char**) s;
+ new_env = new_argv + argc + 1;
+ s = (char*) (new_env + envc + 1);
+ memcpy(s, process_title.str, process_title.len);
+
+ for (i = 0; i < argc; i++)
+ new_argv[i] = s + (argv[i] - argv[0]);
+ new_argv[argc] = NULL;
+
+ s += environ[0] - argv[0];
+
+ for (i = 0; i < envc; i++)
+ new_env[i] = s + (environ[i] - environ[0]);
+ new_env[envc] = NULL;
+
+#if defined(__APPLE__)
+ *_NSGetArgv() = new_argv;
+ *_NSGetEnviron() = new_env;
+#else
+ environ = new_env;
+#endif
+
+ return new_argv;
+}
+
+
+uv_err_t uv_set_process_title(const char* title) {
+ if (process_title.len == 0)
+ return uv_ok_;
+
+ /* No need to terminate, last char is always '\0'. */
+ strncpy(process_title.str, title, process_title.len - 1);
+ uv__set_process_title(title);
+
+ return uv_ok_;
+}
+
+
+uv_err_t uv_get_process_title(char* buffer, size_t size) {
+ if (process_title.len > 0)
+ strncpy(buffer, process_title.str, size);
+ else if (size > 0)
+ buffer[0] = '\0';
+
+ return uv_ok_;
+}
+
+
+__attribute__((destructor))
+static void free_args_mem(void) {
+ free(args_mem); /* Keep valgrind happy. */
+ args_mem = NULL;
+}
View
3 uv.gyp
@@ -157,6 +157,9 @@
}],
],
}],
+ [ 'OS=="linux" or OS=="mac"', {
+ 'sources': [ 'src/unix/proctitle.c' ],
+ }],
[ 'OS=="mac"', {
'sources': [
'src/unix/darwin.c',

2 comments on commit e89aced

@TooTallNate

This is awesome :)

@ry

nice

Please sign in to comment.
Something went wrong with that request. Please try again.