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.
This commit is contained in:
parent
14eb8b0391
commit
e89aced8d6
@ -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))
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
126
src/unix/proctitle.c
Normal file
126
src/unix/proctitle.c
Normal file
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user