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
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  Copyright (c) 2013, Kenneth MacKay
3
- Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement 289016)
3
+ Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement #289016)
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without modification,
@@ -137,8 +137,8 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
137
137
  {
138
138
  int l_read;
139
139
 
140
- free(l_buffer);
141
- l_buffer = malloc(l_size);
140
+ uv__free(l_buffer);
141
+ l_buffer = uv__malloc(l_size);
142
142
  if (l_buffer == NULL)
143
143
  {
144
144
  return NULL;
@@ -148,7 +148,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
148
148
  *p_size = l_read;
149
149
  if(l_read == -2)
150
150
  {
151
- free(l_buffer);
151
+ uv__free(l_buffer);
152
152
  return NULL;
153
153
  }
154
154
  if(l_read >= 0)
@@ -170,7 +170,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
170
170
 
171
171
  if(l_hdr->nlmsg_type == NLMSG_ERROR)
172
172
  {
173
- free(l_buffer);
173
+ uv__free(l_buffer);
174
174
  return NULL;
175
175
  }
176
176
  }
@@ -183,7 +183,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
183
183
 
184
184
  static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
185
185
  {
186
- NetlinkList *l_item = malloc(sizeof(NetlinkList));
186
+ NetlinkList *l_item = uv__malloc(sizeof(NetlinkList));
187
187
  if (l_item == NULL)
188
188
  {
189
189
  return NULL;
@@ -202,8 +202,8 @@ static void freeResultList(NetlinkList *p_list)
202
202
  {
203
203
  l_cur = p_list;
204
204
  p_list = p_list->m_next;
205
- free(l_cur->m_data);
206
- free(l_cur);
205
+ uv__free(l_cur->m_data);
206
+ uv__free(l_cur);
207
207
  }
208
208
  }
209
209
 
@@ -349,7 +349,7 @@ static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
349
349
  }
350
350
  }
351
351
 
352
- l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
352
+ l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
353
353
  if (l_entry == NULL)
354
354
  {
355
355
  return -1;
@@ -478,7 +478,7 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
478
478
  }
479
479
  }
480
480
 
481
- l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
481
+ l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
482
482
  if (l_entry == NULL)
483
483
  {
484
484
  return -1;
@@ -698,6 +698,6 @@ void freeifaddrs(struct ifaddrs *ifa)
698
698
  {
699
699
  l_cur = ifa;
700
700
  ifa = ifa->ifa_next;
701
- free(l_cur);
701
+ uv__free(l_cur);
702
702
  }
703
703
  }
@@ -78,12 +78,18 @@ void uv__async_close(uv_async_t* handle) {
78
78
  static void uv__async_event(uv_loop_t* loop,
79
79
  struct uv__async* w,
80
80
  unsigned int nevents) {
81
+ QUEUE queue;
81
82
  QUEUE* q;
82
83
  uv_async_t* h;
83
84
 
84
- QUEUE_FOREACH(q, &loop->async_handles) {
85
+ QUEUE_MOVE(&loop->async_handles, &queue);
86
+ while (!QUEUE_EMPTY(&queue)) {
87
+ q = QUEUE_HEAD(&queue);
85
88
  h = QUEUE_DATA(q, uv_async_t, queue);
86
89
 
90
+ QUEUE_REMOVE(q);
91
+ QUEUE_INSERT_TAIL(&loop->async_handles, q);
92
+
87
93
  if (cmpxchgi(&h->pending, 1, 0) == 0)
88
94
  continue;
89
95
 
@@ -18,6 +18,11 @@
18
18
 
19
19
  #include "internal.h" /* UV_UNUSED */
20
20
 
21
+ #if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
22
+ #include <atomic.h>
23
+ #define __sync_val_compare_and_swap(p, o, n) atomic_cas_ptr(p, o, n)
24
+ #endif
25
+
21
26
  UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
22
27
  UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
23
28
  UV_UNUSED(static void cpu_relax(void));
@@ -33,6 +38,10 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
33
38
  : "r" (newval), "0" (oldval)
34
39
  : "memory");
35
40
  return out;
41
+ #elif defined(_AIX) && defined(__xlC__)
42
+ const int out = (*(volatile int*) ptr);
43
+ __compare_and_swap(ptr, &oldval, newval);
44
+ return out;
36
45
  #else
37
46
  return __sync_val_compare_and_swap(ptr, oldval, newval);
38
47
  #endif
@@ -46,6 +55,14 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
46
55
  : "r" (newval), "0" (oldval)
47
56
  : "memory");
48
57
  return out;
58
+ #elif defined(_AIX) && defined(__xlC__)
59
+ const long out = (*(volatile int*) ptr);
60
+ # if defined(__64BIT__)
61
+ __compare_and_swaplp(ptr, &oldval, newval);
62
+ # else
63
+ __compare_and_swap(ptr, &oldval, newval);
64
+ # endif /* if defined(__64BIT__) */
65
+ return out;
49
66
  #else
50
67
  return __sync_val_compare_and_swap(ptr, oldval, newval);
51
68
  #endif
@@ -35,9 +35,10 @@
35
35
  #include <sys/un.h>
36
36
  #include <netinet/in.h>
37
37
  #include <arpa/inet.h>
38
- #include <limits.h> /* INT_MAX, PATH_MAX */
38
+ #include <limits.h> /* INT_MAX, PATH_MAX, IOV_MAX */
39
39
  #include <sys/uio.h> /* writev */
40
40
  #include <sys/resource.h> /* getrusage */
41
+ #include <pwd.h>
41
42
 
42
43
  #ifdef __linux__
43
44
  # include <sys/ioctl.h>
@@ -54,13 +55,13 @@
54
55
  # include <sys/ioctl.h>
55
56
  #endif
56
57
 
57
- #ifdef __FreeBSD__
58
+ #if defined(__FreeBSD__) || defined(__DragonFly__)
58
59
  # include <sys/sysctl.h>
59
60
  # include <sys/filio.h>
60
61
  # include <sys/ioctl.h>
61
62
  # include <sys/wait.h>
62
63
  # define UV__O_CLOEXEC O_CLOEXEC
63
- # if __FreeBSD__ >= 10
64
+ # if defined(__FreeBSD__) && __FreeBSD__ >= 10
64
65
  # define uv__accept4 accept4
65
66
  # define UV__SOCK_NONBLOCK SOCK_NONBLOCK
66
67
  # define UV__SOCK_CLOEXEC SOCK_CLOEXEC
@@ -74,6 +75,10 @@
74
75
  #include <sys/ioctl.h>
75
76
  #endif
76
77
 
78
+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
79
+ # include <dlfcn.h> /* for dlsym */
80
+ #endif
81
+
77
82
  static int uv__run_pending(uv_loop_t* loop);
78
83
 
79
84
  /* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@@ -198,6 +203,25 @@ void uv__make_close_pending(uv_handle_t* handle) {
198
203
  handle->loop->closing_handles = handle;
199
204
  }
200
205
 
206
+ int uv__getiovmax(void) {
207
+ #if defined(IOV_MAX)
208
+ return IOV_MAX;
209
+ #elif defined(_SC_IOV_MAX)
210
+ static int iovmax = -1;
211
+ if (iovmax == -1) {
212
+ iovmax = sysconf(_SC_IOV_MAX);
213
+ /* On some embedded devices (arm-linux-uclibc based ip camera),
214
+ * sysconf(_SC_IOV_MAX) can not get the correct value. The return
215
+ * value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
216
+ */
217
+ if (iovmax == -1) iovmax = 1;
218
+ }
219
+ return iovmax;
220
+ #else
221
+ return 1024;
222
+ #endif
223
+ }
224
+
201
225
 
202
226
  static void uv__finish_close(uv_handle_t* handle) {
203
227
  /* Note: while the handle is in the UV_CLOSING state now, it's still possible
@@ -282,6 +306,9 @@ int uv_backend_timeout(const uv_loop_t* loop) {
282
306
  if (!QUEUE_EMPTY(&loop->idle_handles))
283
307
  return 0;
284
308
 
309
+ if (!QUEUE_EMPTY(&loop->pending_queue))
310
+ return 0;
311
+
285
312
  if (loop->closing_handles)
286
313
  return 0;
287
314
 
@@ -473,7 +500,7 @@ int uv__close(int fd) {
473
500
 
474
501
 
475
502
  #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
476
- defined(_AIX)
503
+ defined(_AIX) || defined(__DragonFly__)
477
504
 
478
505
  int uv__nonblock(int fd, int set) {
479
506
  int r;
@@ -502,7 +529,8 @@ int uv__cloexec(int fd, int set) {
502
529
  return 0;
503
530
  }
504
531
 
505
- #else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) */
532
+ #else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
533
+ defined(_AIX) || defined(__DragonFly__)) */
506
534
 
507
535
  int uv__nonblock(int fd, int set) {
508
536
  int flags;
@@ -565,7 +593,8 @@ int uv__cloexec(int fd, int set) {
565
593
  return 0;
566
594
  }
567
595
 
568
- #endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
596
+ #endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
597
+ defined(_AIX) || defined(__DragonFly__) */
569
598
 
570
599
 
571
600
  /* This function is not execve-safe, there is a race window
@@ -696,16 +725,18 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
696
725
 
697
726
  static int uv__run_pending(uv_loop_t* loop) {
698
727
  QUEUE* q;
728
+ QUEUE pq;
699
729
  uv__io_t* w;
700
730
 
701
731
  if (QUEUE_EMPTY(&loop->pending_queue))
702
732
  return 0;
703
733
 
704
- while (!QUEUE_EMPTY(&loop->pending_queue)) {
705
- q = QUEUE_HEAD(&loop->pending_queue);
734
+ QUEUE_MOVE(&loop->pending_queue, &pq);
735
+
736
+ while (!QUEUE_EMPTY(&pq)) {
737
+ q = QUEUE_HEAD(&pq);
706
738
  QUEUE_REMOVE(q);
707
739
  QUEUE_INIT(q);
708
-
709
740
  w = QUEUE_DATA(q, uv__io_t, pending_queue);
710
741
  w->cb(loop, w, UV__POLLOUT);
711
742
  }
@@ -745,8 +776,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
745
776
  }
746
777
 
747
778
  nwatchers = next_power_of_two(len + 2) - 2;
748
- watchers = realloc(loop->watchers,
749
- (nwatchers + 2) * sizeof(loop->watchers[0]));
779
+ watchers = uv__realloc(loop->watchers,
780
+ (nwatchers + 2) * sizeof(loop->watchers[0]));
750
781
 
751
782
  if (watchers == NULL)
752
783
  abort();
@@ -899,7 +930,8 @@ int uv__open_cloexec(const char* path, int flags) {
899
930
  int err;
900
931
  int fd;
901
932
 
902
- #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9)
933
+ #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9) || \
934
+ defined(__DragonFly__)
903
935
  static int no_cloexec;
904
936
 
905
937
  if (!no_cloexec) {
@@ -932,16 +964,12 @@ int uv__open_cloexec(const char* path, int flags) {
932
964
  int uv__dup2_cloexec(int oldfd, int newfd) {
933
965
  int r;
934
966
  #if defined(__FreeBSD__) && __FreeBSD__ >= 10
935
- do
936
- r = dup3(oldfd, newfd, O_CLOEXEC);
937
- while (r == -1 && errno == EINTR);
967
+ r = dup3(oldfd, newfd, O_CLOEXEC);
938
968
  if (r == -1)
939
969
  return -errno;
940
970
  return r;
941
971
  #elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
942
- do
943
- r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
944
- while (r == -1 && errno == EINTR);
972
+ r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
945
973
  if (r != -1)
946
974
  return r;
947
975
  if (errno != EINVAL)
@@ -952,7 +980,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
952
980
  if (!no_dup3) {
953
981
  do
954
982
  r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC);
955
- while (r == -1 && (errno == EINTR || errno == EBUSY));
983
+ while (r == -1 && errno == EBUSY);
956
984
  if (r != -1)
957
985
  return r;
958
986
  if (errno != ENOSYS)
@@ -966,9 +994,9 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
966
994
  do
967
995
  r = dup2(oldfd, newfd);
968
996
  #if defined(__linux__)
969
- while (r == -1 && (errno == EINTR || errno == EBUSY));
997
+ while (r == -1 && errno == EBUSY);
970
998
  #else
971
- while (r == -1 && errno == EINTR);
999
+ while (0); /* Never retry. */
972
1000
  #endif
973
1001
 
974
1002
  if (r == -1)
@@ -983,3 +1011,94 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
983
1011
  return r;
984
1012
  }
985
1013
  }
1014
+
1015
+
1016
+ int uv_os_homedir(char* buffer, size_t* size) {
1017
+ struct passwd pw;
1018
+ struct passwd* result;
1019
+ char* buf;
1020
+ uid_t uid;
1021
+ size_t bufsize;
1022
+ size_t len;
1023
+ long initsize;
1024
+ int r;
1025
+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
1026
+ int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);
1027
+ #endif
1028
+
1029
+ if (buffer == NULL || size == NULL || *size == 0)
1030
+ return -EINVAL;
1031
+
1032
+ /* Check if the HOME environment variable is set first */
1033
+ buf = getenv("HOME");
1034
+
1035
+ if (buf != NULL) {
1036
+ len = strlen(buf);
1037
+
1038
+ if (len >= *size) {
1039
+ *size = len;
1040
+ return -ENOBUFS;
1041
+ }
1042
+
1043
+ memcpy(buffer, buf, len + 1);
1044
+ *size = len;
1045
+
1046
+ return 0;
1047
+ }
1048
+
1049
+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
1050
+ getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
1051
+ if (getpwuid_r == NULL)
1052
+ return -ENOSYS;
1053
+ #endif
1054
+
1055
+ /* HOME is not set, so call getpwuid() */
1056
+ initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
1057
+
1058
+ if (initsize <= 0)
1059
+ bufsize = 4096;
1060
+ else
1061
+ bufsize = (size_t) initsize;
1062
+
1063
+ uid = getuid();
1064
+ buf = NULL;
1065
+
1066
+ for (;;) {
1067
+ uv__free(buf);
1068
+ buf = uv__malloc(bufsize);
1069
+
1070
+ if (buf == NULL)
1071
+ return -ENOMEM;
1072
+
1073
+ r = getpwuid_r(uid, &pw, buf, bufsize, &result);
1074
+
1075
+ if (r != ERANGE)
1076
+ break;
1077
+
1078
+ bufsize *= 2;
1079
+ }
1080
+
1081
+ if (r != 0) {
1082
+ uv__free(buf);
1083
+ return -r;
1084
+ }
1085
+
1086
+ if (result == NULL) {
1087
+ uv__free(buf);
1088
+ return -ENOENT;
1089
+ }
1090
+
1091
+ len = strlen(pw.pw_dir);
1092
+
1093
+ if (len >= *size) {
1094
+ *size = len;
1095
+ uv__free(buf);
1096
+ return -ENOBUFS;
1097
+ }
1098
+
1099
+ memcpy(buffer, pw.pw_dir, len + 1);
1100
+ *size = len;
1101
+ uv__free(buf);
1102
+
1103
+ return 0;
1104
+ }
@@ -198,9 +198,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
198
198
  return -EINVAL; /* FIXME(bnoordhuis) Translate error. */
199
199
  }
200
200
 
201
- *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
202
- if (!(*cpu_infos))
203
- return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */
201
+ *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
202
+ if (!(*cpu_infos)) {
203
+ vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
204
+ return -ENOMEM;
205
+ }
204
206
 
205
207
  *count = numcpus;
206
208
 
@@ -213,7 +215,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
213
215
  cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier;
214
216
  cpu_info->cpu_times.irq = 0;
215
217
 
216
- cpu_info->model = strdup(model);
218
+ cpu_info->model = uv__strdup(model);
217
219
  cpu_info->speed = cpuspeed/1000000;
218
220
  }
219
221
  vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
@@ -226,10 +228,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
226
228
  int i;
227
229
 
228
230
  for (i = 0; i < count; i++) {
229
- free(cpu_infos[i].model);
231
+ uv__free(cpu_infos[i].model);
230
232
  }
231
233
 
232
- free(cpu_infos);
234
+ uv__free(cpu_infos);
233
235
  }
234
236
 
235
237
 
@@ -255,9 +257,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
255
257
  (*count)++;
256
258
  }
257
259
 
258
- *addresses = malloc(*count * sizeof(**addresses));
259
- if (!(*addresses))
260
+ *addresses = uv__malloc(*count * sizeof(**addresses));
261
+ if (!(*addresses)) {
262
+ freeifaddrs(addrs);
260
263
  return -ENOMEM;
264
+ }
261
265
 
262
266
  address = *addresses;
263
267
 
@@ -275,7 +279,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
275
279
  if (ent->ifa_addr->sa_family == AF_LINK)
276
280
  continue;
277
281
 
278
- address->name = strdup(ent->ifa_name);
282
+ address->name = uv__strdup(ent->ifa_name);
279
283
 
280
284
  if (ent->ifa_addr->sa_family == AF_INET6) {
281
285
  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -324,8 +328,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
324
328
  int i;
325
329
 
326
330
  for (i = 0; i < count; i++) {
327
- free(addresses[i].name);
331
+ uv__free(addresses[i].name);
328
332
  }
329
333
 
330
- free(addresses);
334
+ uv__free(addresses);
331
335
  }