diff --git a/config-unix.mk b/config-unix.mk index 34a17f59..8d018982 100644 --- a/config-unix.mk +++ b/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)) diff --git a/src/unix/darwin.c b/src/unix/darwin.c index 59b223f8..82a640a8 100644 --- a/src/unix/darwin.c +++ b/src/unix/darwin.c @@ -37,8 +37,6 @@ #include #include /* 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; diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c index e1a75150..0b0f58d1 100644 --- a/src/unix/linux-core.c +++ b/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 +} diff --git a/src/unix/proctitle.c b/src/unix/proctitle.c new file mode 100644 index 00000000..c4043af3 --- /dev/null +++ b/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 +#include + +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; +} diff --git a/uv.gyp b/uv.gyp index e49e348d..075724dc 100644 --- a/uv.gyp +++ b/uv.gyp @@ -157,6 +157,9 @@ }], ], }], + [ 'OS=="linux" or OS=="mac"', { + 'sources': [ 'src/unix/proctitle.c' ], + }], [ 'OS=="mac"', { 'sources': [ 'src/unix/darwin.c',