1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 3e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 4e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 5e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 7e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 8e66f31c5Sopenharmony_ci * 9e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 10e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 11e66f31c5Sopenharmony_ci * 12e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 19e66f31c5Sopenharmony_ci */ 20e66f31c5Sopenharmony_ci 21e66f31c5Sopenharmony_ci#include "uv.h" 22e66f31c5Sopenharmony_ci#include "internal.h" 23e66f31c5Sopenharmony_ci 24e66f31c5Sopenharmony_ci#include <stdlib.h> 25e66f31c5Sopenharmony_ci#include <string.h> 26e66f31c5Sopenharmony_ci 27e66f31c5Sopenharmony_cistruct uv__process_title { 28e66f31c5Sopenharmony_ci char* str; 29e66f31c5Sopenharmony_ci size_t len; /* Length of the current process title. */ 30e66f31c5Sopenharmony_ci size_t cap; /* Maximum capacity. Computed once in uv_setup_args(). */ 31e66f31c5Sopenharmony_ci}; 32e66f31c5Sopenharmony_ci 33e66f31c5Sopenharmony_ciextern void uv__set_process_title(const char* title); 34e66f31c5Sopenharmony_ci 35e66f31c5Sopenharmony_cistatic uv_mutex_t process_title_mutex; 36e66f31c5Sopenharmony_cistatic uv_once_t process_title_mutex_once = UV_ONCE_INIT; 37e66f31c5Sopenharmony_cistatic struct uv__process_title process_title; 38e66f31c5Sopenharmony_cistatic void* args_mem; 39e66f31c5Sopenharmony_ci 40e66f31c5Sopenharmony_ci 41e66f31c5Sopenharmony_cistatic void init_process_title_mutex_once(void) { 42e66f31c5Sopenharmony_ci uv_mutex_init(&process_title_mutex); 43e66f31c5Sopenharmony_ci} 44e66f31c5Sopenharmony_ci 45e66f31c5Sopenharmony_ci 46e66f31c5Sopenharmony_cichar** uv_setup_args(int argc, char** argv) { 47e66f31c5Sopenharmony_ci struct uv__process_title pt; 48e66f31c5Sopenharmony_ci char** new_argv; 49e66f31c5Sopenharmony_ci size_t size; 50e66f31c5Sopenharmony_ci char* s; 51e66f31c5Sopenharmony_ci int i; 52e66f31c5Sopenharmony_ci 53e66f31c5Sopenharmony_ci if (argc <= 0) 54e66f31c5Sopenharmony_ci return argv; 55e66f31c5Sopenharmony_ci 56e66f31c5Sopenharmony_ci pt.str = argv[0]; 57e66f31c5Sopenharmony_ci pt.len = strlen(argv[0]); 58e66f31c5Sopenharmony_ci pt.cap = pt.len + 1; 59e66f31c5Sopenharmony_ci 60e66f31c5Sopenharmony_ci /* Calculate how much memory we need for the argv strings. */ 61e66f31c5Sopenharmony_ci size = pt.cap; 62e66f31c5Sopenharmony_ci for (i = 1; i < argc; i++) 63e66f31c5Sopenharmony_ci size += strlen(argv[i]) + 1; 64e66f31c5Sopenharmony_ci 65e66f31c5Sopenharmony_ci /* Add space for the argv pointers. */ 66e66f31c5Sopenharmony_ci size += (argc + 1) * sizeof(char*); 67e66f31c5Sopenharmony_ci 68e66f31c5Sopenharmony_ci new_argv = uv__malloc(size); 69e66f31c5Sopenharmony_ci if (new_argv == NULL) 70e66f31c5Sopenharmony_ci return argv; 71e66f31c5Sopenharmony_ci 72e66f31c5Sopenharmony_ci /* Copy over the strings and set up the pointer table. */ 73e66f31c5Sopenharmony_ci i = 0; 74e66f31c5Sopenharmony_ci s = (char*) &new_argv[argc + 1]; 75e66f31c5Sopenharmony_ci size = pt.cap; 76e66f31c5Sopenharmony_ci goto loop; 77e66f31c5Sopenharmony_ci 78e66f31c5Sopenharmony_ci for (/* empty */; i < argc; i++) { 79e66f31c5Sopenharmony_ci size = strlen(argv[i]) + 1; 80e66f31c5Sopenharmony_ci loop: 81e66f31c5Sopenharmony_ci memcpy(s, argv[i], size); 82e66f31c5Sopenharmony_ci new_argv[i] = s; 83e66f31c5Sopenharmony_ci s += size; 84e66f31c5Sopenharmony_ci } 85e66f31c5Sopenharmony_ci new_argv[i] = NULL; 86e66f31c5Sopenharmony_ci 87e66f31c5Sopenharmony_ci pt.cap = argv[i - 1] + size - argv[0]; 88e66f31c5Sopenharmony_ci 89e66f31c5Sopenharmony_ci args_mem = new_argv; 90e66f31c5Sopenharmony_ci process_title = pt; 91e66f31c5Sopenharmony_ci 92e66f31c5Sopenharmony_ci return new_argv; 93e66f31c5Sopenharmony_ci} 94e66f31c5Sopenharmony_ci 95e66f31c5Sopenharmony_ci 96e66f31c5Sopenharmony_ciint uv_set_process_title(const char* title) { 97e66f31c5Sopenharmony_ci struct uv__process_title* pt; 98e66f31c5Sopenharmony_ci size_t len; 99e66f31c5Sopenharmony_ci 100e66f31c5Sopenharmony_ci /* If uv_setup_args wasn't called or failed, we can't continue. */ 101e66f31c5Sopenharmony_ci if (args_mem == NULL) 102e66f31c5Sopenharmony_ci return UV_ENOBUFS; 103e66f31c5Sopenharmony_ci 104e66f31c5Sopenharmony_ci pt = &process_title; 105e66f31c5Sopenharmony_ci len = strlen(title); 106e66f31c5Sopenharmony_ci 107e66f31c5Sopenharmony_ci uv_once(&process_title_mutex_once, init_process_title_mutex_once); 108e66f31c5Sopenharmony_ci uv_mutex_lock(&process_title_mutex); 109e66f31c5Sopenharmony_ci 110e66f31c5Sopenharmony_ci if (len >= pt->cap) { 111e66f31c5Sopenharmony_ci len = 0; 112e66f31c5Sopenharmony_ci if (pt->cap > 0) 113e66f31c5Sopenharmony_ci len = pt->cap - 1; 114e66f31c5Sopenharmony_ci } 115e66f31c5Sopenharmony_ci 116e66f31c5Sopenharmony_ci memcpy(pt->str, title, len); 117e66f31c5Sopenharmony_ci memset(pt->str + len, '\0', pt->cap - len); 118e66f31c5Sopenharmony_ci pt->len = len; 119e66f31c5Sopenharmony_ci uv__set_process_title(pt->str); 120e66f31c5Sopenharmony_ci 121e66f31c5Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 122e66f31c5Sopenharmony_ci 123e66f31c5Sopenharmony_ci return 0; 124e66f31c5Sopenharmony_ci} 125e66f31c5Sopenharmony_ci 126e66f31c5Sopenharmony_ci 127e66f31c5Sopenharmony_ciint uv_get_process_title(char* buffer, size_t size) { 128e66f31c5Sopenharmony_ci if (buffer == NULL || size == 0) 129e66f31c5Sopenharmony_ci return UV_EINVAL; 130e66f31c5Sopenharmony_ci 131e66f31c5Sopenharmony_ci /* If uv_setup_args wasn't called or failed, we can't continue. */ 132e66f31c5Sopenharmony_ci if (args_mem == NULL) 133e66f31c5Sopenharmony_ci return UV_ENOBUFS; 134e66f31c5Sopenharmony_ci 135e66f31c5Sopenharmony_ci uv_once(&process_title_mutex_once, init_process_title_mutex_once); 136e66f31c5Sopenharmony_ci uv_mutex_lock(&process_title_mutex); 137e66f31c5Sopenharmony_ci 138e66f31c5Sopenharmony_ci if (size <= process_title.len) { 139e66f31c5Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 140e66f31c5Sopenharmony_ci return UV_ENOBUFS; 141e66f31c5Sopenharmony_ci } 142e66f31c5Sopenharmony_ci 143e66f31c5Sopenharmony_ci if (process_title.len != 0) 144e66f31c5Sopenharmony_ci memcpy(buffer, process_title.str, process_title.len + 1); 145e66f31c5Sopenharmony_ci 146e66f31c5Sopenharmony_ci buffer[process_title.len] = '\0'; 147e66f31c5Sopenharmony_ci 148e66f31c5Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 149e66f31c5Sopenharmony_ci 150e66f31c5Sopenharmony_ci return 0; 151e66f31c5Sopenharmony_ci} 152e66f31c5Sopenharmony_ci 153e66f31c5Sopenharmony_ci 154e66f31c5Sopenharmony_civoid uv__process_title_cleanup(void) { 155e66f31c5Sopenharmony_ci uv__free(args_mem); /* Keep valgrind happy. */ 156e66f31c5Sopenharmony_ci args_mem = NULL; 157e66f31c5Sopenharmony_ci} 158