aix: enable uv_get/set_process_title
This patch enables querying and setting the process title on AIX. libuv takes ownership of the memory for argv and returns a deep copy of the array and its contents. It also enables the process_title test case. The process title can be changed on AIX but is handled differently to Linux/Mac. Commands like ps read the original argv array passed to the process instead of the memory at argv[0]. To change the process title we need to update argv[0] to point at a new string and set argv[1] to NULL (if it exists). This means the process title can be set to a string of any length. PR-URL: https://github.com/libuv/libuv/pull/1187 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
parent
c5bb773bdd
commit
d6427e4beb
@ -192,7 +192,11 @@ API
|
||||
|
||||
.. c:function:: int uv_set_process_title(const char* title)
|
||||
|
||||
Sets the current process title.
|
||||
Sets the current process title. On platforms with a fixed size buffer for the
|
||||
process title the contents of `title` will be copied to the buffer and
|
||||
truncated if larger than the available space. Other platforms will return
|
||||
`UV_ENOMEM` if they cannot allocate enough space to duplicate the contents of
|
||||
`title`.
|
||||
|
||||
.. c:function:: int uv_resident_set_memory(size_t* rss)
|
||||
|
||||
|
||||
@ -64,6 +64,11 @@
|
||||
#define RDWR_BUF_SIZE 4096
|
||||
#define EQ(a,b) (strcmp(a,b) == 0)
|
||||
|
||||
static void* args_mem = NULL;
|
||||
static char** process_argv = NULL;
|
||||
static int process_argc = 0;
|
||||
static char* process_title_ptr = NULL;
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
loop->fs_fd = -1;
|
||||
|
||||
@ -881,24 +886,94 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
return argv;
|
||||
char** new_argv;
|
||||
size_t size;
|
||||
char* s;
|
||||
int i;
|
||||
|
||||
if (argc <= 0)
|
||||
return argv;
|
||||
|
||||
/* Save the original pointer to argv.
|
||||
* AIX uses argv to read the process name.
|
||||
* (Not the memory pointed to by argv[0..n] as on Linux.)
|
||||
*/
|
||||
process_argv = argv;
|
||||
process_argc = argc;
|
||||
|
||||
/* Calculate how much memory we need for the argv strings. */
|
||||
size = 0;
|
||||
for (i = 0; i < argc; i++)
|
||||
size += strlen(argv[i]) + 1;
|
||||
|
||||
/* Add space for the argv pointers. */
|
||||
size += (argc + 1) * sizeof(char*);
|
||||
|
||||
new_argv = uv__malloc(size);
|
||||
if (new_argv == NULL)
|
||||
return argv;
|
||||
args_mem = new_argv;
|
||||
|
||||
/* Copy over the strings and set up the pointer table. */
|
||||
s = (char*) &new_argv[argc + 1];
|
||||
for (i = 0; i < argc; i++) {
|
||||
size = strlen(argv[i]) + 1;
|
||||
memcpy(s, argv[i], size);
|
||||
new_argv[i] = s;
|
||||
s += size;
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
return new_argv;
|
||||
}
|
||||
|
||||
|
||||
int uv_set_process_title(const char* title) {
|
||||
char* new_title;
|
||||
|
||||
/* We cannot free this pointer when libuv shuts down,
|
||||
* the process may still be using it.
|
||||
*/
|
||||
new_title = uv__strdup(title);
|
||||
if (new_title == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* If this is the first time this is set,
|
||||
* don't free and set argv[1] to NULL.
|
||||
*/
|
||||
if (process_title_ptr != NULL)
|
||||
uv__free(process_title_ptr);
|
||||
|
||||
process_title_ptr = new_title;
|
||||
|
||||
process_argv[0] = process_title_ptr;
|
||||
if (process_argc > 1)
|
||||
process_argv[1] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
size_t len;
|
||||
len = strlen(process_argv[0]);
|
||||
if (buffer == NULL || size == 0)
|
||||
return -EINVAL;
|
||||
else if (size <= len)
|
||||
return -ENOBUFS;
|
||||
|
||||
memcpy(buffer, process_argv[0], len + 1);
|
||||
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
UV_DESTRUCTOR(static void free_args_mem(void)) {
|
||||
uv__free(args_mem); /* Keep valgrind happy. */
|
||||
args_mem = NULL;
|
||||
}
|
||||
|
||||
|
||||
int uv_resident_set_memory(size_t* rss) {
|
||||
char pp[64];
|
||||
psinfo_t psinfo;
|
||||
|
||||
@ -60,7 +60,7 @@ static void uv_get_process_title_edge_cases() {
|
||||
|
||||
|
||||
TEST_IMPL(process_title) {
|
||||
#if defined(__sun) || defined(_AIX) || defined(__MVS__)
|
||||
#if defined(__sun) || defined(__MVS__)
|
||||
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
|
||||
#else
|
||||
/* Check for format string vulnerabilities. */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user