From c2589424f93f5b1fd5808238071bf23a20da3564 Mon Sep 17 00:00:00 2001 From: "Shuowang (Wayne) Zhang" Date: Wed, 2 Dec 2020 12:07:31 -0500 Subject: [PATCH] zos: use custom proctitle implementation ZOSLIB uses `argv[0]` to determine the exepath. So it is necessary to use an implementation of proctitle that does not modify `argv[0]`. Since there is currently no support for process titles on z/OS, the custom proctitle implementation simply stores the desired title in memory. This resolves failure in tests `get_currentexe` and `process_title` on z/OS. PR-URL: https://github.com/libuv/libuv/pull/3060 Reviewed-By: Richard Lau --- CMakeLists.txt | 5 +- src/unix/os390-proctitle.c | 136 +++++++++++++++++++++++++++++++++++++ src/unix/os390.c | 3 - src/unix/proctitle.c | 3 - 4 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 src/unix/os390-proctitle.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a4b9164c..72428bd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android") src/unix/random-sysctl-linux.c) endif() -if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390") +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux") list(APPEND uv_sources src/unix/proctitle.c) endif() @@ -286,7 +286,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390") list(APPEND uv_sources src/unix/pthread-fixes.c src/unix/os390.c - src/unix/os390-syscalls.c) + src/unix/os390-syscalls.c + src/unix/os390-proctitle.c) list(APPEND uv_cflags -q64 -qascii diff --git a/src/unix/os390-proctitle.c b/src/unix/os390-proctitle.c new file mode 100644 index 00000000..ccda97c9 --- /dev/null +++ b/src/unix/os390-proctitle.c @@ -0,0 +1,136 @@ +/* Copyright libuv project 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 + +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static char* process_title = NULL; +static void* args_mem = NULL; + + +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + +char** uv_setup_args(int argc, char** argv) { + char** new_argv; + size_t size; + char* s; + int i; + + if (argc <= 0) + return argv; + + /* 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; + + /* 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; + + args_mem = new_argv; + process_title = uv__strdup(argv[0]); + + return new_argv; +} + + +int uv_set_process_title(const char* title) { + char* new_title; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL) + return UV_ENOBUFS; + + /* 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 UV_ENOMEM; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title != NULL) + uv__free(process_title); + + process_title = new_title; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + + if (buffer == NULL || size == 0) + return UV_EINVAL; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL || process_title == NULL) + return UV_ENOBUFS; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + len = strlen(process_title); + + if (size <= len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + strcpy(buffer, process_title); + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +void uv__process_title_cleanup(void) { + uv__free(args_mem); /* Keep valgrind happy. */ + args_mem = NULL; +} diff --git a/src/unix/os390.c b/src/unix/os390.c index 30439c33..2912579a 100644 --- a/src/unix/os390.c +++ b/src/unix/os390.c @@ -869,9 +869,6 @@ update_timeout: } } -void uv__set_process_title(const char* title) { - /* do nothing */ -} int uv__io_fork(uv_loop_t* loop) { /* diff --git a/src/unix/proctitle.c b/src/unix/proctitle.c index 9e39545e..9d1f00dd 100644 --- a/src/unix/proctitle.c +++ b/src/unix/proctitle.c @@ -84,10 +84,7 @@ char** uv_setup_args(int argc, char** argv) { } new_argv[i] = NULL; - /* argv is not adjacent on z/os, we use just argv[0] on that platform. */ -#ifndef __MVS__ pt.cap = argv[i - 1] + size - argv[0]; -#endif args_mem = new_argv; process_title = pt;