proctitle.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. #include "uv.h"
  21. #include "internal.h"
  22. #include <stdlib.h>
  23. #include <string.h>
  24. struct uv__process_title {
  25. char* str;
  26. size_t len; /* Length of the current process title. */
  27. size_t cap; /* Maximum capacity. Computed once in uv_setup_args(). */
  28. };
  29. extern void uv__set_process_title(const char* title);
  30. static uv_mutex_t process_title_mutex;
  31. static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
  32. static struct uv__process_title process_title;
  33. static void* args_mem;
  34. static void init_process_title_mutex_once(void) {
  35. uv_mutex_init(&process_title_mutex);
  36. }
  37. char** uv_setup_args(int argc, char** argv) {
  38. struct uv__process_title pt;
  39. char** new_argv;
  40. size_t size;
  41. char* s;
  42. int i;
  43. if (argc <= 0)
  44. return argv;
  45. pt.str = argv[0];
  46. pt.len = strlen(argv[0]);
  47. pt.cap = pt.len + 1;
  48. /* Calculate how much memory we need for the argv strings. */
  49. size = pt.cap;
  50. for (i = 1; i < argc; i++)
  51. size += strlen(argv[i]) + 1;
  52. /* Add space for the argv pointers. */
  53. size += (argc + 1) * sizeof(char*);
  54. new_argv = uv__malloc(size);
  55. if (new_argv == NULL)
  56. return argv;
  57. /* Copy over the strings and set up the pointer table. */
  58. i = 0;
  59. s = (char*) &new_argv[argc + 1];
  60. size = pt.cap;
  61. goto loop;
  62. for (/* empty */; i < argc; i++) {
  63. size = strlen(argv[i]) + 1;
  64. loop:
  65. memcpy(s, argv[i], size);
  66. new_argv[i] = s;
  67. s += size;
  68. }
  69. new_argv[i] = NULL;
  70. pt.cap = argv[i - 1] + size - argv[0];
  71. args_mem = new_argv;
  72. process_title = pt;
  73. return new_argv;
  74. }
  75. int uv_set_process_title(const char* title) {
  76. struct uv__process_title* pt;
  77. size_t len;
  78. /* If uv_setup_args wasn't called or failed, we can't continue. */
  79. if (args_mem == NULL)
  80. return UV_ENOBUFS;
  81. pt = &process_title;
  82. len = strlen(title);
  83. uv_once(&process_title_mutex_once, init_process_title_mutex_once);
  84. uv_mutex_lock(&process_title_mutex);
  85. if (len >= pt->cap) {
  86. len = 0;
  87. if (pt->cap > 0)
  88. len = pt->cap - 1;
  89. }
  90. memcpy(pt->str, title, len);
  91. memset(pt->str + len, '\0', pt->cap - len);
  92. pt->len = len;
  93. uv__set_process_title(pt->str);
  94. uv_mutex_unlock(&process_title_mutex);
  95. return 0;
  96. }
  97. int uv_get_process_title(char* buffer, size_t size) {
  98. if (buffer == NULL || size == 0)
  99. return UV_EINVAL;
  100. /* If uv_setup_args wasn't called or failed, we can't continue. */
  101. if (args_mem == NULL)
  102. return UV_ENOBUFS;
  103. uv_once(&process_title_mutex_once, init_process_title_mutex_once);
  104. uv_mutex_lock(&process_title_mutex);
  105. if (size <= process_title.len) {
  106. uv_mutex_unlock(&process_title_mutex);
  107. return UV_ENOBUFS;
  108. }
  109. if (process_title.len != 0)
  110. memcpy(buffer, process_title.str, process_title.len + 1);
  111. buffer[process_title.len] = '\0';
  112. uv_mutex_unlock(&process_title_mutex);
  113. return 0;
  114. }
  115. void uv__process_title_cleanup(void) {
  116. uv__free(args_mem); /* Keep valgrind happy. */
  117. args_mem = NULL;
  118. }