passenger 5.0.25 → 5.0.26

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +20 -0
  3. data/CONTRIBUTORS +1 -0
  4. data/build/cxx_dependency_map.rb +7338 -7104
  5. data/build/cxx_tests.rb +3 -3
  6. data/build/misc.rb +1 -0
  7. data/dev/index_cxx_dependencies.rb +3 -2
  8. data/resources/templates/standalone/config.erb +1 -1
  9. data/resources/templates/standalone/http.erb +1 -0
  10. data/resources/templates/standalone/server.erb +1 -0
  11. data/src/agent/Core/ApplicationPool/AbstractSession.h +83 -0
  12. data/src/agent/Core/ApplicationPool/Common.h +6 -4
  13. data/src/agent/Core/ApplicationPool/Options.h +4 -1
  14. data/src/agent/Core/ApplicationPool/Pool.h +2 -2
  15. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +3 -6
  16. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
  17. data/src/agent/Core/ApplicationPool/Session.h +15 -27
  18. data/src/agent/Core/ApplicationPool/TestSession.h +188 -0
  19. data/src/agent/Core/Controller.h +15 -6
  20. data/src/agent/Core/Controller/CheckoutSession.cpp +13 -5
  21. data/src/agent/Core/Controller/ForwardResponse.cpp +20 -2
  22. data/src/agent/Core/Controller/Hooks.cpp +15 -2
  23. data/src/agent/Core/Controller/InitRequest.cpp +5 -1
  24. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +1 -0
  25. data/src/agent/Core/Controller/Request.h +11 -4
  26. data/src/agent/Core/Controller/SendRequest.cpp +34 -13
  27. data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +2 -2
  28. data/src/agent/Core/CoreMain.cpp +27 -1
  29. data/src/agent/Core/OptionParser.h +11 -1
  30. data/src/agent/Core/SpawningKit/DirectSpawner.h +1 -0
  31. data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -0
  32. data/src/agent/Core/SpawningKit/Spawner.h +21 -1
  33. data/src/agent/SpawnPreparer/SpawnPreparerMain.cpp +1 -1
  34. data/src/agent/UstRouter/OptionParser.h +7 -1
  35. data/src/agent/UstRouter/UstRouterMain.cpp +27 -1
  36. data/src/cxx_supportlib/Algorithms/MovingAverage.h +223 -0
  37. data/src/cxx_supportlib/Constants.h +2 -2
  38. data/src/cxx_supportlib/DataStructures/StringKeyTable.h +96 -40
  39. data/src/cxx_supportlib/ResourceLocator.h +33 -14
  40. data/src/cxx_supportlib/ServerKit/Channel.h +198 -69
  41. data/src/cxx_supportlib/ServerKit/Errors.h +6 -1
  42. data/src/cxx_supportlib/ServerKit/HttpRequest.h +20 -1
  43. data/src/cxx_supportlib/ServerKit/HttpServer.h +124 -32
  44. data/src/cxx_supportlib/ServerKit/Server.h +65 -1
  45. data/src/cxx_supportlib/Utils/IOUtils.cpp +12 -22
  46. data/src/cxx_supportlib/Utils/JsonUtils.h +87 -1
  47. data/src/cxx_supportlib/Utils/StrIntUtils.cpp +16 -1
  48. data/src/cxx_supportlib/Utils/StrIntUtils.h +31 -1
  49. data/src/cxx_supportlib/Utils/VariantMap.h +6 -1
  50. data/src/cxx_supportlib/WatchdogLauncher.h +17 -9
  51. data/src/cxx_supportlib/vendor-copy/libuv/AUTHORS +43 -0
  52. data/src/cxx_supportlib/vendor-copy/libuv/ChangeLog +350 -1
  53. data/src/cxx_supportlib/vendor-copy/libuv/Makefile.am +9 -1
  54. data/src/cxx_supportlib/vendor-copy/libuv/README.md +48 -0
  55. data/src/cxx_supportlib/vendor-copy/libuv/checksparse.sh +1 -0
  56. data/src/cxx_supportlib/vendor-copy/libuv/common.gypi +5 -5
  57. data/src/cxx_supportlib/vendor-copy/libuv/configure.ac +2 -1
  58. data/src/cxx_supportlib/vendor-copy/libuv/gyp_uv.py +0 -3
  59. data/src/cxx_supportlib/vendor-copy/libuv/include/uv-version.h +5 -1
  60. data/src/cxx_supportlib/vendor-copy/libuv/include/uv.h +30 -3
  61. data/src/cxx_supportlib/vendor-copy/libuv/src/fs-poll.c +3 -3
  62. data/src/cxx_supportlib/vendor-copy/libuv/src/inet.c +0 -4
  63. data/src/cxx_supportlib/vendor-copy/libuv/src/queue.h +17 -1
  64. data/src/cxx_supportlib/vendor-copy/libuv/src/threadpool.c +10 -10
  65. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/aix.c +84 -166
  66. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/android-ifaddrs.c +11 -11
  67. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/async.c +7 -1
  68. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/atomic-ops.h +17 -0
  69. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/core.c +140 -21
  70. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/darwin.c +15 -11
  71. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/dl.c +4 -7
  72. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/freebsd.c +52 -37
  73. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fs.c +181 -60
  74. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fsevents.c +39 -34
  75. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/getaddrinfo.c +4 -4
  76. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/internal.h +3 -1
  77. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/kqueue.c +12 -4
  78. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-core.c +38 -15
  79. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-inotify.c +36 -8
  80. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.c +4 -4
  81. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.h +2 -2
  82. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop-watcher.c +6 -1
  83. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop.c +28 -8
  84. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/netbsd.c +18 -16
  85. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/openbsd.c +18 -16
  86. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pipe.c +3 -3
  87. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/process.c +18 -6
  88. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/proctitle.c +2 -2
  89. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pthread-fixes.c +1 -0
  90. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/signal.c +2 -0
  91. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/stream.c +47 -30
  92. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/sunos.c +13 -11
  93. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tcp.c +43 -8
  94. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/thread.c +21 -15
  95. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tty.c +16 -2
  96. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/udp.c +54 -14
  97. data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.c +104 -21
  98. data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.h +14 -1
  99. data/src/cxx_supportlib/vendor-copy/libuv/src/version.c +1 -5
  100. data/src/cxx_supportlib/vendor-copy/libuv/uv.gyp +22 -1
  101. data/src/nginx_module/CacheLocationConfig.c +52 -0
  102. data/src/nginx_module/CacheLocationConfig.c.erb +13 -1
  103. data/src/nginx_module/Configuration.c +1 -0
  104. data/src/nginx_module/Configuration.h +1 -0
  105. data/src/nginx_module/ConfigurationCommands.c +20 -0
  106. data/src/nginx_module/ConfigurationFields.h +4 -0
  107. data/src/nginx_module/CreateLocationConfig.c +8 -0
  108. data/src/nginx_module/MergeLocationConfig.c +12 -0
  109. data/src/nginx_module/config +31 -13
  110. data/src/nginx_module/ngx_http_passenger_module.c +4 -0
  111. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  112. data/src/ruby_supportlib/phusion_passenger/constants.rb +1 -1
  113. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +11 -1
  114. data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +6 -1
  115. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +32 -31
  116. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +13 -2
  117. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +1 -0
  118. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +6 -1
  119. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +6 -0
  120. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +29 -19
  121. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +2 -2
  122. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +2 -3
  123. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +2 -1
  124. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/spec_helper.rb +2 -0
  125. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/time_point.rb +3 -17
  126. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +7 -10
  127. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +11 -9
  128. metadata +5 -2
@@ -35,6 +35,7 @@
35
35
  struct watcher_list {
36
36
  RB_ENTRY(watcher_list) entry;
37
37
  QUEUE watchers;
38
+ int iterating;
38
39
  char* path;
39
40
  int wd;
40
41
  };
@@ -113,6 +114,15 @@ static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
113
114
  return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w);
114
115
  }
115
116
 
117
+ static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) {
118
+ /* if the watcher_list->watchers is being iterated over, we can't free it. */
119
+ if ((!w->iterating) && QUEUE_EMPTY(&w->watchers)) {
120
+ /* No watchers left for this path. Clean up. */
121
+ RB_REMOVE(watcher_root, CAST(&loop->inotify_watchers), w);
122
+ uv__inotify_rm_watch(loop->inotify_fd, w->wd);
123
+ uv__free(w);
124
+ }
125
+ }
116
126
 
117
127
  static void uv__inotify_read(uv_loop_t* loop,
118
128
  uv__io_t* dummy,
@@ -120,6 +130,7 @@ static void uv__inotify_read(uv_loop_t* loop,
120
130
  const struct uv__inotify_event* e;
121
131
  struct watcher_list* w;
122
132
  uv_fs_event_t* h;
133
+ QUEUE queue;
123
134
  QUEUE* q;
124
135
  const char* path;
125
136
  ssize_t size;
@@ -159,10 +170,31 @@ static void uv__inotify_read(uv_loop_t* loop,
159
170
  */
160
171
  path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path);
161
172
 
162
- QUEUE_FOREACH(q, &w->watchers) {
173
+ /* We're about to iterate over the queue and call user's callbacks.
174
+ * What can go wrong?
175
+ * A callback could call uv_fs_event_stop()
176
+ * and the queue can change under our feet.
177
+ * So, we use QUEUE_MOVE() trick to safely iterate over the queue.
178
+ * And we don't free the watcher_list until we're done iterating.
179
+ *
180
+ * First,
181
+ * tell uv_fs_event_stop() (that could be called from a user's callback)
182
+ * not to free watcher_list.
183
+ */
184
+ w->iterating = 1;
185
+ QUEUE_MOVE(&w->watchers, &queue);
186
+ while (!QUEUE_EMPTY(&queue)) {
187
+ q = QUEUE_HEAD(&queue);
163
188
  h = QUEUE_DATA(q, uv_fs_event_t, watchers);
189
+
190
+ QUEUE_REMOVE(q);
191
+ QUEUE_INSERT_TAIL(&w->watchers, q);
192
+
164
193
  h->cb(h, path, events, 0);
165
194
  }
195
+ /* done iterating, time to (maybe) free empty watcher_list */
196
+ w->iterating = 0;
197
+ maybe_free_watcher_list(w, loop);
166
198
  }
167
199
  }
168
200
  }
@@ -207,13 +239,14 @@ int uv_fs_event_start(uv_fs_event_t* handle,
207
239
  if (w)
208
240
  goto no_insert;
209
241
 
210
- w = malloc(sizeof(*w) + strlen(path) + 1);
242
+ w = uv__malloc(sizeof(*w) + strlen(path) + 1);
211
243
  if (w == NULL)
212
244
  return -ENOMEM;
213
245
 
214
246
  w->wd = wd;
215
247
  w->path = strcpy((char*)(w + 1), path);
216
248
  QUEUE_INIT(&w->watchers);
249
+ w->iterating = 0;
217
250
  RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w);
218
251
 
219
252
  no_insert:
@@ -241,12 +274,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
241
274
  uv__handle_stop(handle);
242
275
  QUEUE_REMOVE(&handle->watchers);
243
276
 
244
- if (QUEUE_EMPTY(&w->watchers)) {
245
- /* No watchers left for this path. Clean up. */
246
- RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
247
- uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
248
- free(w);
249
- }
277
+ maybe_free_watcher_list(w, handle->loop);
250
278
 
251
279
  return 0;
252
280
  }
@@ -444,18 +444,18 @@ int uv__utimesat(int dirfd,
444
444
  }
445
445
 
446
446
 
447
- ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
447
+ ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
448
448
  #if defined(__NR_preadv)
449
- return syscall(__NR_preadv, fd, iov, iovcnt, offset);
449
+ return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
450
450
  #else
451
451
  return errno = ENOSYS, -1;
452
452
  #endif
453
453
  }
454
454
 
455
455
 
456
- ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
456
+ ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
457
457
  #if defined(__NR_pwritev)
458
- return syscall(__NR_pwritev, fd, iov, iovcnt, offset);
458
+ return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
459
459
  #else
460
460
  return errno = ENOSYS, -1;
461
461
  #endif
@@ -151,8 +151,8 @@ int uv__utimesat(int dirfd,
151
151
  const char* path,
152
152
  const struct timespec times[2],
153
153
  int flags);
154
- ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
155
- ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
154
+ ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
155
+ ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
156
156
  int uv__dup3(int oldfd, int newfd, int flags);
157
157
 
158
158
  #endif /* UV_LINUX_SYSCALL_H_ */
@@ -47,9 +47,14 @@
47
47
  \
48
48
  void uv__run_##name(uv_loop_t* loop) { \
49
49
  uv_##name##_t* h; \
50
+ QUEUE queue; \
50
51
  QUEUE* q; \
51
- QUEUE_FOREACH(q, &loop->name##_handles) { \
52
+ QUEUE_MOVE(&loop->name##_handles, &queue); \
53
+ while (!QUEUE_EMPTY(&queue)) { \
54
+ q = QUEUE_HEAD(&queue); \
52
55
  h = QUEUE_DATA(q, uv_##name##_t, queue); \
56
+ QUEUE_REMOVE(q); \
57
+ QUEUE_INSERT_TAIL(&loop->name##_handles, q); \
53
58
  h->name##_cb(h); \
54
59
  } \
55
60
  } \
@@ -63,24 +63,44 @@ int uv_loop_init(uv_loop_t* loop) {
63
63
  if (err)
64
64
  return err;
65
65
 
66
- uv_signal_init(loop, &loop->child_watcher);
66
+ err = uv_signal_init(loop, &loop->child_watcher);
67
+ if (err)
68
+ goto fail_signal_init;
69
+
67
70
  uv__handle_unref(&loop->child_watcher);
68
71
  loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
69
72
  QUEUE_INIT(&loop->process_handles);
70
73
 
71
- if (uv_rwlock_init(&loop->cloexec_lock))
72
- abort();
74
+ err = uv_rwlock_init(&loop->cloexec_lock);
75
+ if (err)
76
+ goto fail_rwlock_init;
73
77
 
74
- if (uv_mutex_init(&loop->wq_mutex))
75
- abort();
78
+ err = uv_mutex_init(&loop->wq_mutex);
79
+ if (err)
80
+ goto fail_mutex_init;
76
81
 
77
- if (uv_async_init(loop, &loop->wq_async, uv__work_done))
78
- abort();
82
+ err = uv_async_init(loop, &loop->wq_async, uv__work_done);
83
+ if (err)
84
+ goto fail_async_init;
79
85
 
80
86
  uv__handle_unref(&loop->wq_async);
81
87
  loop->wq_async.flags |= UV__HANDLE_INTERNAL;
82
88
 
83
89
  return 0;
90
+
91
+ fail_async_init:
92
+ uv_mutex_destroy(&loop->wq_mutex);
93
+
94
+ fail_mutex_init:
95
+ uv_rwlock_destroy(&loop->cloexec_lock);
96
+
97
+ fail_rwlock_init:
98
+ uv__signal_loop_cleanup(loop);
99
+
100
+ fail_signal_init:
101
+ uv__platform_loop_delete(loop);
102
+
103
+ return err;
84
104
  }
85
105
 
86
106
 
@@ -117,7 +137,7 @@ void uv__loop_close(uv_loop_t* loop) {
117
137
  assert(loop->nfds == 0);
118
138
  #endif
119
139
 
120
- free(loop->watchers);
140
+ uv__free(loop->watchers);
121
141
  loop->watchers = NULL;
122
142
  loop->nwatchers = 0;
123
143
  }
@@ -131,15 +131,15 @@ uint64_t uv_get_total_memory(void) {
131
131
 
132
132
 
133
133
  char** uv_setup_args(int argc, char** argv) {
134
- process_title = argc ? strdup(argv[0]) : NULL;
134
+ process_title = argc ? uv__strdup(argv[0]) : NULL;
135
135
  return argv;
136
136
  }
137
137
 
138
138
 
139
139
  int uv_set_process_title(const char* title) {
140
- if (process_title) free(process_title);
140
+ if (process_title) uv__free(process_title);
141
141
 
142
- process_title = strdup(title);
142
+ process_title = uv__strdup(title);
143
143
  setproctitle("%s", title);
144
144
 
145
145
  return 0;
@@ -234,17 +234,17 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
234
234
  cpuspeed = 0;
235
235
 
236
236
  size = numcpus * CPUSTATES * sizeof(*cp_times);
237
- cp_times = malloc(size);
237
+ cp_times = uv__malloc(size);
238
238
  if (cp_times == NULL)
239
239
  return -ENOMEM;
240
240
 
241
241
  if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
242
242
  return -errno;
243
243
 
244
- *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
244
+ *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
245
245
  if (!(*cpu_infos)) {
246
- free(cp_times);
247
- free(*cpu_infos);
246
+ uv__free(cp_times);
247
+ uv__free(*cpu_infos);
248
248
  return -ENOMEM;
249
249
  }
250
250
 
@@ -255,11 +255,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
255
255
  cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
256
256
  cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
257
257
  cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
258
- cpu_info->model = strdup(model);
258
+ cpu_info->model = uv__strdup(model);
259
259
  cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
260
260
  cur += CPUSTATES;
261
261
  }
262
- free(cp_times);
262
+ uv__free(cp_times);
263
263
  return 0;
264
264
  }
265
265
 
@@ -268,10 +268,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
268
268
  int i;
269
269
 
270
270
  for (i = 0; i < count; i++) {
271
- free(cpu_infos[i].model);
271
+ uv__free(cpu_infos[i].model);
272
272
  }
273
273
 
274
- free(cpu_infos);
274
+ uv__free(cpu_infos);
275
275
  }
276
276
 
277
277
 
@@ -296,10 +296,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
296
296
  (*count)++;
297
297
  }
298
298
 
299
- *addresses = malloc(*count * sizeof(**addresses));
299
+ *addresses = uv__malloc(*count * sizeof(**addresses));
300
300
 
301
- if (!(*addresses))
301
+ if (!(*addresses)) {
302
+ freeifaddrs(addrs);
302
303
  return -ENOMEM;
304
+ }
303
305
 
304
306
  address = *addresses;
305
307
 
@@ -313,7 +315,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
313
315
  if (ent->ifa_addr->sa_family != PF_INET)
314
316
  continue;
315
317
 
316
- address->name = strdup(ent->ifa_name);
318
+ address->name = uv__strdup(ent->ifa_name);
317
319
 
318
320
  if (ent->ifa_addr->sa_family == AF_INET6) {
319
321
  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -361,8 +363,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
361
363
  int i;
362
364
 
363
365
  for (i = 0; i < count; i++) {
364
- free(addresses[i].name);
366
+ uv__free(addresses[i].name);
365
367
  }
366
368
 
367
- free(addresses);
369
+ uv__free(addresses);
368
370
  }
@@ -91,7 +91,7 @@ int uv_exepath(char* buffer, size_t* size) {
91
91
  mypid = getpid();
92
92
  for (;;) {
93
93
  err = -ENOMEM;
94
- argsbuf_tmp = realloc(argsbuf, argsbuf_size);
94
+ argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size);
95
95
  if (argsbuf_tmp == NULL)
96
96
  goto out;
97
97
  argsbuf = argsbuf_tmp;
@@ -124,7 +124,7 @@ int uv_exepath(char* buffer, size_t* size) {
124
124
  err = 0;
125
125
 
126
126
  out:
127
- free(argsbuf);
127
+ uv__free(argsbuf);
128
128
 
129
129
  return err;
130
130
  }
@@ -155,14 +155,14 @@ uint64_t uv_get_total_memory(void) {
155
155
 
156
156
 
157
157
  char** uv_setup_args(int argc, char** argv) {
158
- process_title = argc ? strdup(argv[0]) : NULL;
158
+ process_title = argc ? uv__strdup(argv[0]) : NULL;
159
159
  return argv;
160
160
  }
161
161
 
162
162
 
163
163
  int uv_set_process_title(const char* title) {
164
- if (process_title) free(process_title);
165
- process_title = strdup(title);
164
+ uv__free(process_title);
165
+ process_title = uv__strdup(title);
166
166
  setproctitle(title);
167
167
  return 0;
168
168
  }
@@ -238,7 +238,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
238
238
  if (sysctl(which, 2, &numcpus, &size, NULL, 0))
239
239
  return -errno;
240
240
 
241
- *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
241
+ *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
242
242
  if (!(*cpu_infos))
243
243
  return -ENOMEM;
244
244
 
@@ -247,7 +247,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
247
247
  which[1] = HW_CPUSPEED;
248
248
  size = sizeof(cpuspeed);
249
249
  if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
250
- SAVE_ERRNO(free(*cpu_infos));
250
+ SAVE_ERRNO(uv__free(*cpu_infos));
251
251
  return -errno;
252
252
  }
253
253
 
@@ -258,7 +258,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
258
258
  which[2] = i;
259
259
  size = sizeof(info);
260
260
  if (sysctl(which, 3, &info, &size, NULL, 0)) {
261
- SAVE_ERRNO(free(*cpu_infos));
261
+ SAVE_ERRNO(uv__free(*cpu_infos));
262
262
  return -errno;
263
263
  }
264
264
 
@@ -270,7 +270,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
270
270
  cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier;
271
271
  cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier;
272
272
 
273
- cpu_info->model = strdup(model);
273
+ cpu_info->model = uv__strdup(model);
274
274
  cpu_info->speed = cpuspeed;
275
275
  }
276
276
 
@@ -282,10 +282,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
282
282
  int i;
283
283
 
284
284
  for (i = 0; i < count; i++) {
285
- free(cpu_infos[i].model);
285
+ uv__free(cpu_infos[i].model);
286
286
  }
287
287
 
288
- free(cpu_infos);
288
+ uv__free(cpu_infos);
289
289
  }
290
290
 
291
291
 
@@ -311,10 +311,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
311
311
  (*count)++;
312
312
  }
313
313
 
314
- *addresses = malloc(*count * sizeof(**addresses));
314
+ *addresses = uv__malloc(*count * sizeof(**addresses));
315
315
 
316
- if (!(*addresses))
316
+ if (!(*addresses)) {
317
+ freeifaddrs(addrs);
317
318
  return -ENOMEM;
319
+ }
318
320
 
319
321
  address = *addresses;
320
322
 
@@ -328,7 +330,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
328
330
  if (ent->ifa_addr->sa_family != PF_INET)
329
331
  continue;
330
332
 
331
- address->name = strdup(ent->ifa_name);
333
+ address->name = uv__strdup(ent->ifa_name);
332
334
 
333
335
  if (ent->ifa_addr->sa_family == AF_INET6) {
334
336
  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -377,8 +379,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
377
379
  int i;
378
380
 
379
381
  for (i = 0; i < count; i++) {
380
- free(addresses[i].name);
382
+ uv__free(addresses[i].name);
381
383
  }
382
384
 
383
- free(addresses);
385
+ uv__free(addresses);
384
386
  }
@@ -54,7 +54,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
54
54
  return -EINVAL;
55
55
 
56
56
  /* Make a copy of the file name, it outlives this function's scope. */
57
- pipe_fname = strdup(name);
57
+ pipe_fname = uv__strdup(name);
58
58
  if (pipe_fname == NULL)
59
59
  return -ENOMEM;
60
60
 
@@ -88,7 +88,7 @@ err_bind:
88
88
  uv__close(sockfd);
89
89
 
90
90
  err_socket:
91
- free((void*)pipe_fname);
91
+ uv__free((void*)pipe_fname);
92
92
  return err;
93
93
  }
94
94
 
@@ -116,7 +116,7 @@ void uv__pipe_close(uv_pipe_t* handle) {
116
116
  * another thread or process.
117
117
  */
118
118
  unlink(handle->pipe_fname);
119
- free((void*)handle->pipe_fname);
119
+ uv__free((void*)handle->pipe_fname);
120
120
  handle->pipe_fname = NULL;
121
121
  }
122
122
 
@@ -226,13 +226,14 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
226
226
  int pipefds[2],
227
227
  int writable) {
228
228
  int flags;
229
+ int err;
229
230
 
230
231
  if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
231
232
  return 0;
232
233
 
233
- if (uv__close(pipefds[1]))
234
- if (errno != EINTR && errno != EINPROGRESS)
235
- abort();
234
+ err = uv__close(pipefds[1]);
235
+ if (err != 0 && err != -EINPROGRESS)
236
+ abort();
236
237
 
237
238
  pipefds[1] = -1;
238
239
  uv__nonblock(pipefds[0], 1);
@@ -269,6 +270,11 @@ static void uv__write_int(int fd, int val) {
269
270
  }
270
271
 
271
272
 
273
+ #if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
274
+ /* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
275
+ * avoided. Since this isn't called on those targets, the function
276
+ * doesn't even need to be defined for them.
277
+ */
272
278
  static void uv__process_child_init(const uv_process_options_t* options,
273
279
  int stdio_count,
274
280
  int (*pipes)[2],
@@ -374,11 +380,16 @@ static void uv__process_child_init(const uv_process_options_t* options,
374
380
  uv__write_int(error_fd, -errno);
375
381
  _exit(127);
376
382
  }
383
+ #endif
377
384
 
378
385
 
379
386
  int uv_spawn(uv_loop_t* loop,
380
387
  uv_process_t* process,
381
388
  const uv_process_options_t* options) {
389
+ #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
390
+ /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
391
+ return -ENOSYS;
392
+ #else
382
393
  int signal_pipe[2] = { -1, -1 };
383
394
  int (*pipes)[2];
384
395
  int stdio_count;
@@ -404,7 +415,7 @@ int uv_spawn(uv_loop_t* loop,
404
415
  stdio_count = 3;
405
416
 
406
417
  err = -ENOMEM;
407
- pipes = malloc(stdio_count * sizeof(*pipes));
418
+ pipes = uv__malloc(stdio_count * sizeof(*pipes));
408
419
  if (pipes == NULL)
409
420
  goto error;
410
421
 
@@ -509,7 +520,7 @@ int uv_spawn(uv_loop_t* loop,
509
520
  process->pid = pid;
510
521
  process->exit_cb = options->exit_cb;
511
522
 
512
- free(pipes);
523
+ uv__free(pipes);
513
524
  return exec_errorno;
514
525
 
515
526
  error:
@@ -523,10 +534,11 @@ error:
523
534
  if (pipes[i][1] != -1)
524
535
  close(pipes[i][1]);
525
536
  }
526
- free(pipes);
537
+ uv__free(pipes);
527
538
  }
528
539
 
529
540
  return err;
541
+ #endif
530
542
  }
531
543
 
532
544