11cb0ef41Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 21cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 31cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 41cb0ef41Sopenharmony_ci * deal in the Software without restriction, including without limitation the 51cb0ef41Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 61cb0ef41Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 71cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions: 81cb0ef41Sopenharmony_ci * 91cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 101cb0ef41Sopenharmony_ci * all copies or substantial portions of the Software. 111cb0ef41Sopenharmony_ci * 121cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 131cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 151cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 161cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 171cb0ef41Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 181cb0ef41Sopenharmony_ci * IN THE SOFTWARE. 191cb0ef41Sopenharmony_ci */ 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#include "uv.h" 221cb0ef41Sopenharmony_ci#include "internal.h" 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci#include <stdlib.h> 251cb0ef41Sopenharmony_ci#include <string.h> 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cistruct uv__process_title { 281cb0ef41Sopenharmony_ci char* str; 291cb0ef41Sopenharmony_ci size_t len; /* Length of the current process title. */ 301cb0ef41Sopenharmony_ci size_t cap; /* Maximum capacity. Computed once in uv_setup_args(). */ 311cb0ef41Sopenharmony_ci}; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciextern void uv__set_process_title(const char* title); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cistatic uv_mutex_t process_title_mutex; 361cb0ef41Sopenharmony_cistatic uv_once_t process_title_mutex_once = UV_ONCE_INIT; 371cb0ef41Sopenharmony_cistatic struct uv__process_title process_title; 381cb0ef41Sopenharmony_cistatic void* args_mem; 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_cistatic void init_process_title_mutex_once(void) { 421cb0ef41Sopenharmony_ci uv_mutex_init(&process_title_mutex); 431cb0ef41Sopenharmony_ci} 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_cichar** uv_setup_args(int argc, char** argv) { 471cb0ef41Sopenharmony_ci struct uv__process_title pt; 481cb0ef41Sopenharmony_ci char** new_argv; 491cb0ef41Sopenharmony_ci size_t size; 501cb0ef41Sopenharmony_ci char* s; 511cb0ef41Sopenharmony_ci int i; 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci if (argc <= 0) 541cb0ef41Sopenharmony_ci return argv; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci pt.str = argv[0]; 571cb0ef41Sopenharmony_ci pt.len = strlen(argv[0]); 581cb0ef41Sopenharmony_ci pt.cap = pt.len + 1; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci /* Calculate how much memory we need for the argv strings. */ 611cb0ef41Sopenharmony_ci size = pt.cap; 621cb0ef41Sopenharmony_ci for (i = 1; i < argc; i++) 631cb0ef41Sopenharmony_ci size += strlen(argv[i]) + 1; 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci /* Add space for the argv pointers. */ 661cb0ef41Sopenharmony_ci size += (argc + 1) * sizeof(char*); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci new_argv = uv__malloc(size); 691cb0ef41Sopenharmony_ci if (new_argv == NULL) 701cb0ef41Sopenharmony_ci return argv; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci /* Copy over the strings and set up the pointer table. */ 731cb0ef41Sopenharmony_ci i = 0; 741cb0ef41Sopenharmony_ci s = (char*) &new_argv[argc + 1]; 751cb0ef41Sopenharmony_ci size = pt.cap; 761cb0ef41Sopenharmony_ci goto loop; 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci for (/* empty */; i < argc; i++) { 791cb0ef41Sopenharmony_ci size = strlen(argv[i]) + 1; 801cb0ef41Sopenharmony_ci loop: 811cb0ef41Sopenharmony_ci memcpy(s, argv[i], size); 821cb0ef41Sopenharmony_ci new_argv[i] = s; 831cb0ef41Sopenharmony_ci s += size; 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci new_argv[i] = NULL; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci pt.cap = argv[i - 1] + size - argv[0]; 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci args_mem = new_argv; 901cb0ef41Sopenharmony_ci process_title = pt; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci return new_argv; 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ciint uv_set_process_title(const char* title) { 971cb0ef41Sopenharmony_ci struct uv__process_title* pt; 981cb0ef41Sopenharmony_ci size_t len; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci /* If uv_setup_args wasn't called or failed, we can't continue. */ 1011cb0ef41Sopenharmony_ci if (args_mem == NULL) 1021cb0ef41Sopenharmony_ci return UV_ENOBUFS; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci pt = &process_title; 1051cb0ef41Sopenharmony_ci len = strlen(title); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci uv_once(&process_title_mutex_once, init_process_title_mutex_once); 1081cb0ef41Sopenharmony_ci uv_mutex_lock(&process_title_mutex); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci if (len >= pt->cap) { 1111cb0ef41Sopenharmony_ci len = 0; 1121cb0ef41Sopenharmony_ci if (pt->cap > 0) 1131cb0ef41Sopenharmony_ci len = pt->cap - 1; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci memcpy(pt->str, title, len); 1171cb0ef41Sopenharmony_ci memset(pt->str + len, '\0', pt->cap - len); 1181cb0ef41Sopenharmony_ci pt->len = len; 1191cb0ef41Sopenharmony_ci uv__set_process_title(pt->str); 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci return 0; 1241cb0ef41Sopenharmony_ci} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciint uv_get_process_title(char* buffer, size_t size) { 1281cb0ef41Sopenharmony_ci if (buffer == NULL || size == 0) 1291cb0ef41Sopenharmony_ci return UV_EINVAL; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci /* If uv_setup_args wasn't called or failed, we can't continue. */ 1321cb0ef41Sopenharmony_ci if (args_mem == NULL) 1331cb0ef41Sopenharmony_ci return UV_ENOBUFS; 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci uv_once(&process_title_mutex_once, init_process_title_mutex_once); 1361cb0ef41Sopenharmony_ci uv_mutex_lock(&process_title_mutex); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci if (size <= process_title.len) { 1391cb0ef41Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 1401cb0ef41Sopenharmony_ci return UV_ENOBUFS; 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci if (process_title.len != 0) 1441cb0ef41Sopenharmony_ci memcpy(buffer, process_title.str, process_title.len + 1); 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci buffer[process_title.len] = '\0'; 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci uv_mutex_unlock(&process_title_mutex); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci return 0; 1511cb0ef41Sopenharmony_ci} 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_civoid uv__process_title_cleanup(void) { 1551cb0ef41Sopenharmony_ci uv__free(args_mem); /* Keep valgrind happy. */ 1561cb0ef41Sopenharmony_ci args_mem = NULL; 1571cb0ef41Sopenharmony_ci} 158