Skip to content
This repository was archived by the owner on May 4, 2018. It is now read-only.

Commit e89aced

Browse files
committed
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.
1 parent 14eb8b0 commit e89aced

File tree

5 files changed

+139
-125
lines changed

5 files changed

+139
-125
lines changed

config-unix.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ SOEXT = dylib
7878
OBJS += src/unix/darwin.o
7979
OBJS += src/unix/kqueue.o
8080
OBJS += src/unix/fsevents.o
81+
OBJS += src/unix/proctitle.o
8182
OBJS += src/unix/darwin-proctitle.o
8283
endif
8384

@@ -87,7 +88,8 @@ LDFLAGS+=-ldl -lrt
8788
RUNNER_CFLAGS += -D_GNU_SOURCE
8889
OBJS += src/unix/linux-core.o \
8990
src/unix/linux-inotify.o \
90-
src/unix/linux-syscalls.o
91+
src/unix/linux-syscalls.o \
92+
src/unix/proctitle.o
9193
endif
9294

9395
ifeq (freebsd,$(OS))

src/unix/darwin.c

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
#include <sys/sysctl.h>
3838
#include <unistd.h> /* sysconf */
3939

40-
static char *process_title;
41-
4240
/* Forward declarations */
4341
void uv__cf_loop_runner(void* arg);
4442
void uv__cf_loop_cb(void* arg);
@@ -254,43 +252,6 @@ void uv_loadavg(double avg[3]) {
254252
}
255253

256254

257-
char** uv_setup_args(int argc, char** argv) {
258-
process_title = argc ? strdup(argv[0]) : NULL;
259-
return argv;
260-
}
261-
262-
263-
uv_err_t uv_set_process_title(const char* title) {
264-
int uv__set_process_title(const char*);
265-
266-
if (process_title != NULL)
267-
free(process_title);
268-
269-
process_title = strdup(title);
270-
271-
if (process_title == NULL)
272-
return uv__new_artificial_error(UV_ENOMEM);
273-
274-
if (uv__set_process_title(title))
275-
return uv__new_artificial_error(UV_ENOSYS);
276-
277-
return uv_ok_;
278-
}
279-
280-
281-
uv_err_t uv_get_process_title(char* buffer, size_t size) {
282-
if (process_title) {
283-
strncpy(buffer, process_title, size);
284-
} else {
285-
if (size > 0) {
286-
buffer[0] = '\0';
287-
}
288-
}
289-
290-
return uv_ok_;
291-
}
292-
293-
294255
uv_err_t uv_resident_set_memory(size_t* rss) {
295256
struct task_basic_info t_info;
296257
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;

src/unix/linux-core.c

Lines changed: 7 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,12 @@
5757
# define CLOCK_BOOTTIME 7
5858
#endif
5959

60-
static void* args_mem;
61-
62-
static struct {
63-
char *str;
64-
size_t len;
65-
} process_title;
66-
6760
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci);
6861
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
6962
static void read_times(unsigned int numcpus, uv_cpu_info_t* ci);
7063
static unsigned long read_cpufreq(unsigned int cpunum);
7164

7265

73-
__attribute__((destructor))
74-
static void free_args_mem(void) {
75-
free(args_mem); /* keep valgrind happy */
76-
}
77-
78-
7966
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
8067
int fd;
8168

@@ -296,78 +283,6 @@ uint64_t uv_get_total_memory(void) {
296283
}
297284

298285

299-
char** uv_setup_args(int argc, char** argv) {
300-
char **new_argv;
301-
char **new_env;
302-
size_t size;
303-
int envc;
304-
char *s;
305-
int i;
306-
307-
for (envc = 0; environ[envc]; envc++);
308-
309-
s = envc ? environ[envc - 1] : argv[argc - 1];
310-
311-
process_title.str = argv[0];
312-
process_title.len = s + strlen(s) + 1 - argv[0];
313-
314-
size = process_title.len;
315-
size += (argc + 1) * sizeof(char **);
316-
size += (envc + 1) * sizeof(char **);
317-
318-
if (NULL == (s = malloc(size))) {
319-
process_title.str = NULL;
320-
process_title.len = 0;
321-
return argv;
322-
}
323-
args_mem = s;
324-
325-
new_argv = (char **) s;
326-
new_env = new_argv + argc + 1;
327-
s = (char *) (new_env + envc + 1);
328-
memcpy(s, process_title.str, process_title.len);
329-
330-
for (i = 0; i < argc; i++)
331-
new_argv[i] = s + (argv[i] - argv[0]);
332-
new_argv[argc] = NULL;
333-
334-
s += environ[0] - argv[0];
335-
336-
for (i = 0; i < envc; i++)
337-
new_env[i] = s + (environ[i] - environ[0]);
338-
new_env[envc] = NULL;
339-
340-
environ = new_env;
341-
return new_argv;
342-
}
343-
344-
345-
uv_err_t uv_set_process_title(const char* title) {
346-
/* No need to terminate, last char is always '\0'. */
347-
if (process_title.len)
348-
strncpy(process_title.str, title, process_title.len - 1);
349-
350-
#if defined(PR_SET_NAME)
351-
prctl(PR_SET_NAME, title);
352-
#endif
353-
354-
return uv_ok_;
355-
}
356-
357-
358-
uv_err_t uv_get_process_title(char* buffer, size_t size) {
359-
if (process_title.str) {
360-
strncpy(buffer, process_title.str, size);
361-
} else {
362-
if (size > 0) {
363-
buffer[0] = '\0';
364-
}
365-
}
366-
367-
return uv_ok_;
368-
}
369-
370-
371286
uv_err_t uv_resident_set_memory(size_t* rss) {
372287
FILE* f;
373288
int itmp;
@@ -787,3 +702,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
787702

788703
free(addresses);
789704
}
705+
706+
707+
void uv__set_process_title(const char* title) {
708+
#if defined(PR_SET_NAME)
709+
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
710+
#endif
711+
}

src/unix/proctitle.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2+
* Permission is hereby granted, free of charge, to any person obtaining a copy
3+
* of this software and associated documentation files (the "Software"), to
4+
* deal in the Software without restriction, including without limitation the
5+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6+
* sell copies of the Software, and to permit persons to whom the Software is
7+
* furnished to do so, subject to the following conditions:
8+
*
9+
* The above copyright notice and this permission notice shall be included in
10+
* all copies or substantial portions of the Software.
11+
*
12+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18+
* IN THE SOFTWARE.
19+
*/
20+
21+
#include "uv.h"
22+
#include "internal.h"
23+
24+
#include <stdlib.h>
25+
#include <string.h>
26+
27+
extern void uv__set_process_title(const char* title);
28+
29+
static void* args_mem;
30+
31+
static struct {
32+
char* str;
33+
int len;
34+
} process_title;
35+
36+
37+
char** uv_setup_args(int argc, char** argv) {
38+
char** new_argv;
39+
char** new_env;
40+
size_t size;
41+
int envc;
42+
char* s;
43+
int i;
44+
45+
#if defined(__APPLE__)
46+
char*** _NSGetArgv(void);
47+
char*** _NSGetEnviron(void);
48+
char** environ = *_NSGetEnviron();
49+
#else
50+
extern char** environ;
51+
#endif
52+
53+
for (envc = 0; environ[envc]; envc++);
54+
55+
if (envc == 0)
56+
s = argv[argc - 1];
57+
else
58+
s = environ[envc - 1];
59+
60+
process_title.str = argv[0];
61+
process_title.len = s + strlen(s) + 1 - argv[0];
62+
63+
size = process_title.len;
64+
size += (argc + 1) * sizeof(char**);
65+
size += (envc + 1) * sizeof(char**);
66+
s = args_mem = malloc(size);
67+
68+
if (s == NULL) {
69+
process_title.str = NULL;
70+
process_title.len = 0;
71+
return argv;
72+
}
73+
74+
new_argv = (char**) s;
75+
new_env = new_argv + argc + 1;
76+
s = (char*) (new_env + envc + 1);
77+
memcpy(s, process_title.str, process_title.len);
78+
79+
for (i = 0; i < argc; i++)
80+
new_argv[i] = s + (argv[i] - argv[0]);
81+
new_argv[argc] = NULL;
82+
83+
s += environ[0] - argv[0];
84+
85+
for (i = 0; i < envc; i++)
86+
new_env[i] = s + (environ[i] - environ[0]);
87+
new_env[envc] = NULL;
88+
89+
#if defined(__APPLE__)
90+
*_NSGetArgv() = new_argv;
91+
*_NSGetEnviron() = new_env;
92+
#else
93+
environ = new_env;
94+
#endif
95+
96+
return new_argv;
97+
}
98+
99+
100+
uv_err_t uv_set_process_title(const char* title) {
101+
if (process_title.len == 0)
102+
return uv_ok_;
103+
104+
/* No need to terminate, last char is always '\0'. */
105+
strncpy(process_title.str, title, process_title.len - 1);
106+
uv__set_process_title(title);
107+
108+
return uv_ok_;
109+
}
110+
111+
112+
uv_err_t uv_get_process_title(char* buffer, size_t size) {
113+
if (process_title.len > 0)
114+
strncpy(buffer, process_title.str, size);
115+
else if (size > 0)
116+
buffer[0] = '\0';
117+
118+
return uv_ok_;
119+
}
120+
121+
122+
__attribute__((destructor))
123+
static void free_args_mem(void) {
124+
free(args_mem); /* Keep valgrind happy. */
125+
args_mem = NULL;
126+
}

uv.gyp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@
157157
}],
158158
],
159159
}],
160+
[ 'OS=="linux" or OS=="mac"', {
161+
'sources': [ 'src/unix/proctitle.c' ],
162+
}],
160163
[ 'OS=="mac"', {
161164
'sources': [
162165
'src/unix/darwin.c',

0 commit comments

Comments
 (0)