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.
- checksums.yaml +4 -4
- data/CHANGELOG +20 -0
- data/CONTRIBUTORS +1 -0
- data/build/cxx_dependency_map.rb +7338 -7104
- data/build/cxx_tests.rb +3 -3
- data/build/misc.rb +1 -0
- data/dev/index_cxx_dependencies.rb +3 -2
- data/resources/templates/standalone/config.erb +1 -1
- data/resources/templates/standalone/http.erb +1 -0
- data/resources/templates/standalone/server.erb +1 -0
- data/src/agent/Core/ApplicationPool/AbstractSession.h +83 -0
- data/src/agent/Core/ApplicationPool/Common.h +6 -4
- data/src/agent/Core/ApplicationPool/Options.h +4 -1
- data/src/agent/Core/ApplicationPool/Pool.h +2 -2
- data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +3 -6
- data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
- data/src/agent/Core/ApplicationPool/Session.h +15 -27
- data/src/agent/Core/ApplicationPool/TestSession.h +188 -0
- data/src/agent/Core/Controller.h +15 -6
- data/src/agent/Core/Controller/CheckoutSession.cpp +13 -5
- data/src/agent/Core/Controller/ForwardResponse.cpp +20 -2
- data/src/agent/Core/Controller/Hooks.cpp +15 -2
- data/src/agent/Core/Controller/InitRequest.cpp +5 -1
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +1 -0
- data/src/agent/Core/Controller/Request.h +11 -4
- data/src/agent/Core/Controller/SendRequest.cpp +34 -13
- data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +2 -2
- data/src/agent/Core/CoreMain.cpp +27 -1
- data/src/agent/Core/OptionParser.h +11 -1
- data/src/agent/Core/SpawningKit/DirectSpawner.h +1 -0
- data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -0
- data/src/agent/Core/SpawningKit/Spawner.h +21 -1
- data/src/agent/SpawnPreparer/SpawnPreparerMain.cpp +1 -1
- data/src/agent/UstRouter/OptionParser.h +7 -1
- data/src/agent/UstRouter/UstRouterMain.cpp +27 -1
- data/src/cxx_supportlib/Algorithms/MovingAverage.h +223 -0
- data/src/cxx_supportlib/Constants.h +2 -2
- data/src/cxx_supportlib/DataStructures/StringKeyTable.h +96 -40
- data/src/cxx_supportlib/ResourceLocator.h +33 -14
- data/src/cxx_supportlib/ServerKit/Channel.h +198 -69
- data/src/cxx_supportlib/ServerKit/Errors.h +6 -1
- data/src/cxx_supportlib/ServerKit/HttpRequest.h +20 -1
- data/src/cxx_supportlib/ServerKit/HttpServer.h +124 -32
- data/src/cxx_supportlib/ServerKit/Server.h +65 -1
- data/src/cxx_supportlib/Utils/IOUtils.cpp +12 -22
- data/src/cxx_supportlib/Utils/JsonUtils.h +87 -1
- data/src/cxx_supportlib/Utils/StrIntUtils.cpp +16 -1
- data/src/cxx_supportlib/Utils/StrIntUtils.h +31 -1
- data/src/cxx_supportlib/Utils/VariantMap.h +6 -1
- data/src/cxx_supportlib/WatchdogLauncher.h +17 -9
- data/src/cxx_supportlib/vendor-copy/libuv/AUTHORS +43 -0
- data/src/cxx_supportlib/vendor-copy/libuv/ChangeLog +350 -1
- data/src/cxx_supportlib/vendor-copy/libuv/Makefile.am +9 -1
- data/src/cxx_supportlib/vendor-copy/libuv/README.md +48 -0
- data/src/cxx_supportlib/vendor-copy/libuv/checksparse.sh +1 -0
- data/src/cxx_supportlib/vendor-copy/libuv/common.gypi +5 -5
- data/src/cxx_supportlib/vendor-copy/libuv/configure.ac +2 -1
- data/src/cxx_supportlib/vendor-copy/libuv/gyp_uv.py +0 -3
- data/src/cxx_supportlib/vendor-copy/libuv/include/uv-version.h +5 -1
- data/src/cxx_supportlib/vendor-copy/libuv/include/uv.h +30 -3
- data/src/cxx_supportlib/vendor-copy/libuv/src/fs-poll.c +3 -3
- data/src/cxx_supportlib/vendor-copy/libuv/src/inet.c +0 -4
- data/src/cxx_supportlib/vendor-copy/libuv/src/queue.h +17 -1
- data/src/cxx_supportlib/vendor-copy/libuv/src/threadpool.c +10 -10
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/aix.c +84 -166
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/android-ifaddrs.c +11 -11
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/async.c +7 -1
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/atomic-ops.h +17 -0
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/core.c +140 -21
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/darwin.c +15 -11
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/dl.c +4 -7
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/freebsd.c +52 -37
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fs.c +181 -60
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fsevents.c +39 -34
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/getaddrinfo.c +4 -4
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/internal.h +3 -1
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/kqueue.c +12 -4
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-core.c +38 -15
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-inotify.c +36 -8
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.c +4 -4
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.h +2 -2
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop-watcher.c +6 -1
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop.c +28 -8
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/netbsd.c +18 -16
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/openbsd.c +18 -16
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pipe.c +3 -3
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/process.c +18 -6
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/proctitle.c +2 -2
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pthread-fixes.c +1 -0
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/signal.c +2 -0
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/stream.c +47 -30
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/sunos.c +13 -11
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tcp.c +43 -8
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/thread.c +21 -15
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tty.c +16 -2
- data/src/cxx_supportlib/vendor-copy/libuv/src/unix/udp.c +54 -14
- data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.c +104 -21
- data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.h +14 -1
- data/src/cxx_supportlib/vendor-copy/libuv/src/version.c +1 -5
- data/src/cxx_supportlib/vendor-copy/libuv/uv.gyp +22 -1
- data/src/nginx_module/CacheLocationConfig.c +52 -0
- data/src/nginx_module/CacheLocationConfig.c.erb +13 -1
- data/src/nginx_module/Configuration.c +1 -0
- data/src/nginx_module/Configuration.h +1 -0
- data/src/nginx_module/ConfigurationCommands.c +20 -0
- data/src/nginx_module/ConfigurationFields.h +4 -0
- data/src/nginx_module/CreateLocationConfig.c +8 -0
- data/src/nginx_module/MergeLocationConfig.c +12 -0
- data/src/nginx_module/config +31 -13
- data/src/nginx_module/ngx_http_passenger_module.c +4 -0
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/constants.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +11 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +6 -1
- data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +32 -31
- data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +13 -2
- data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +6 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +6 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +29 -19
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +2 -3
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +2 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/spec_helper.rb +2 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/time_point.rb +3 -17
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +7 -10
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +11 -9
- metadata +5 -2
@@ -39,10 +39,8 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
|
|
39
39
|
|
40
40
|
|
41
41
|
void uv_dlclose(uv_lib_t* lib) {
|
42
|
-
|
43
|
-
|
44
|
-
lib->errmsg = NULL;
|
45
|
-
}
|
42
|
+
uv__free(lib->errmsg);
|
43
|
+
lib->errmsg = NULL;
|
46
44
|
|
47
45
|
if (lib->handle) {
|
48
46
|
/* Ignore errors. No good way to signal them without leaking memory. */
|
@@ -67,13 +65,12 @@ const char* uv_dlerror(const uv_lib_t* lib) {
|
|
67
65
|
static int uv__dlerror(uv_lib_t* lib) {
|
68
66
|
const char* errmsg;
|
69
67
|
|
70
|
-
|
71
|
-
free(lib->errmsg);
|
68
|
+
uv__free(lib->errmsg);
|
72
69
|
|
73
70
|
errmsg = dlerror();
|
74
71
|
|
75
72
|
if (errmsg) {
|
76
|
-
lib->errmsg =
|
73
|
+
lib->errmsg = uv__strdup(errmsg);
|
77
74
|
return -1;
|
78
75
|
}
|
79
76
|
else {
|
@@ -74,6 +74,30 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
|
|
74
74
|
}
|
75
75
|
|
76
76
|
|
77
|
+
#ifdef __DragonFly__
|
78
|
+
int uv_exepath(char* buffer, size_t* size) {
|
79
|
+
char abspath[PATH_MAX * 2 + 1];
|
80
|
+
ssize_t abspath_size;
|
81
|
+
|
82
|
+
if (buffer == NULL || size == NULL || *size == 0)
|
83
|
+
return -EINVAL;
|
84
|
+
|
85
|
+
abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath));
|
86
|
+
if (abspath_size < 0)
|
87
|
+
return -errno;
|
88
|
+
|
89
|
+
assert(abspath_size > 0);
|
90
|
+
*size -= 1;
|
91
|
+
|
92
|
+
if (*size > abspath_size)
|
93
|
+
*size = abspath_size;
|
94
|
+
|
95
|
+
memcpy(buffer, abspath, *size);
|
96
|
+
buffer[*size] = '\0';
|
97
|
+
|
98
|
+
return 0;
|
99
|
+
}
|
100
|
+
#else
|
77
101
|
int uv_exepath(char* buffer, size_t* size) {
|
78
102
|
char abspath[PATH_MAX * 2 + 1];
|
79
103
|
int mib[4];
|
@@ -82,19 +106,12 @@ int uv_exepath(char* buffer, size_t* size) {
|
|
82
106
|
if (buffer == NULL || size == NULL || *size == 0)
|
83
107
|
return -EINVAL;
|
84
108
|
|
85
|
-
#ifdef __DragonFly__
|
86
|
-
mib[0] = CTL_KERN;
|
87
|
-
mib[1] = KERN_PROC;
|
88
|
-
mib[2] = KERN_PROC_ARGS;
|
89
|
-
mib[3] = getpid();
|
90
|
-
#else
|
91
109
|
mib[0] = CTL_KERN;
|
92
110
|
mib[1] = KERN_PROC;
|
93
111
|
mib[2] = KERN_PROC_PATHNAME;
|
94
112
|
mib[3] = -1;
|
95
|
-
#endif
|
96
113
|
|
97
|
-
abspath_size = sizeof abspath
|
114
|
+
abspath_size = sizeof abspath;
|
98
115
|
if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
|
99
116
|
return -errno;
|
100
117
|
|
@@ -110,7 +127,7 @@ int uv_exepath(char* buffer, size_t* size) {
|
|
110
127
|
|
111
128
|
return 0;
|
112
129
|
}
|
113
|
-
|
130
|
+
#endif
|
114
131
|
|
115
132
|
uint64_t uv_get_free_memory(void) {
|
116
133
|
int freecount;
|
@@ -151,7 +168,7 @@ void uv_loadavg(double avg[3]) {
|
|
151
168
|
|
152
169
|
|
153
170
|
char** uv_setup_args(int argc, char** argv) {
|
154
|
-
process_title = argc ?
|
171
|
+
process_title = argc ? uv__strdup(argv[0]) : NULL;
|
155
172
|
return argv;
|
156
173
|
}
|
157
174
|
|
@@ -159,8 +176,8 @@ char** uv_setup_args(int argc, char** argv) {
|
|
159
176
|
int uv_set_process_title(const char* title) {
|
160
177
|
int oid[4];
|
161
178
|
|
162
|
-
|
163
|
-
process_title =
|
179
|
+
uv__free(process_title);
|
180
|
+
process_title = uv__strdup(title);
|
164
181
|
|
165
182
|
oid[0] = CTL_KERN;
|
166
183
|
oid[1] = KERN_PROC;
|
@@ -223,17 +240,13 @@ error:
|
|
223
240
|
|
224
241
|
|
225
242
|
int uv_uptime(double* uptime) {
|
226
|
-
|
227
|
-
struct
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
if (sysctl(which, 2, &info, &size, NULL, 0))
|
243
|
+
int r;
|
244
|
+
struct timespec sp;
|
245
|
+
r = clock_gettime(CLOCK_MONOTONIC, &sp);
|
246
|
+
if (r)
|
232
247
|
return -errno;
|
233
248
|
|
234
|
-
|
235
|
-
|
236
|
-
*uptime = (double)(now - info.tv_sec);
|
249
|
+
*uptime = sp.tv_sec;
|
237
250
|
return 0;
|
238
251
|
}
|
239
252
|
|
@@ -271,7 +284,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|
271
284
|
if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
|
272
285
|
return -errno;
|
273
286
|
|
274
|
-
*cpu_infos =
|
287
|
+
*cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
|
275
288
|
if (!(*cpu_infos))
|
276
289
|
return -ENOMEM;
|
277
290
|
|
@@ -279,7 +292,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|
279
292
|
|
280
293
|
size = sizeof(cpuspeed);
|
281
294
|
if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) {
|
282
|
-
SAVE_ERRNO(
|
295
|
+
SAVE_ERRNO(uv__free(*cpu_infos));
|
283
296
|
return -errno;
|
284
297
|
}
|
285
298
|
|
@@ -288,21 +301,21 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|
288
301
|
*/
|
289
302
|
size = sizeof(maxcpus);
|
290
303
|
if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
|
291
|
-
SAVE_ERRNO(
|
304
|
+
SAVE_ERRNO(uv__free(*cpu_infos));
|
292
305
|
return -errno;
|
293
306
|
}
|
294
307
|
|
295
308
|
size = maxcpus * CPUSTATES * sizeof(long);
|
296
309
|
|
297
|
-
cp_times =
|
310
|
+
cp_times = uv__malloc(size);
|
298
311
|
if (cp_times == NULL) {
|
299
|
-
|
312
|
+
uv__free(*cpu_infos);
|
300
313
|
return -ENOMEM;
|
301
314
|
}
|
302
315
|
|
303
316
|
if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
|
304
|
-
SAVE_ERRNO(
|
305
|
-
SAVE_ERRNO(
|
317
|
+
SAVE_ERRNO(uv__free(cp_times));
|
318
|
+
SAVE_ERRNO(uv__free(*cpu_infos));
|
306
319
|
return -errno;
|
307
320
|
}
|
308
321
|
|
@@ -315,13 +328,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|
315
328
|
cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
|
316
329
|
cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
|
317
330
|
|
318
|
-
cpu_info->model =
|
331
|
+
cpu_info->model = uv__strdup(model);
|
319
332
|
cpu_info->speed = cpuspeed;
|
320
333
|
|
321
334
|
cur+=CPUSTATES;
|
322
335
|
}
|
323
336
|
|
324
|
-
|
337
|
+
uv__free(cp_times);
|
325
338
|
return 0;
|
326
339
|
}
|
327
340
|
|
@@ -330,10 +343,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|
330
343
|
int i;
|
331
344
|
|
332
345
|
for (i = 0; i < count; i++) {
|
333
|
-
|
346
|
+
uv__free(cpu_infos[i].model);
|
334
347
|
}
|
335
348
|
|
336
|
-
|
349
|
+
uv__free(cpu_infos);
|
337
350
|
}
|
338
351
|
|
339
352
|
|
@@ -359,9 +372,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|
359
372
|
(*count)++;
|
360
373
|
}
|
361
374
|
|
362
|
-
*addresses =
|
363
|
-
if (!(*addresses))
|
375
|
+
*addresses = uv__malloc(*count * sizeof(**addresses));
|
376
|
+
if (!(*addresses)) {
|
377
|
+
freeifaddrs(addrs);
|
364
378
|
return -ENOMEM;
|
379
|
+
}
|
365
380
|
|
366
381
|
address = *addresses;
|
367
382
|
|
@@ -379,7 +394,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|
379
394
|
if (ent->ifa_addr->sa_family == AF_LINK)
|
380
395
|
continue;
|
381
396
|
|
382
|
-
address->name =
|
397
|
+
address->name = uv__strdup(ent->ifa_name);
|
383
398
|
|
384
399
|
if (ent->ifa_addr->sa_family == AF_INET6) {
|
385
400
|
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
@@ -428,8 +443,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
|
428
443
|
int i;
|
429
444
|
|
430
445
|
for (i = 0; i < count; i++) {
|
431
|
-
|
446
|
+
uv__free(addresses[i].name);
|
432
447
|
}
|
433
448
|
|
434
|
-
|
449
|
+
uv__free(addresses);
|
435
450
|
}
|
@@ -58,52 +58,67 @@
|
|
58
58
|
# include <sys/sendfile.h>
|
59
59
|
#endif
|
60
60
|
|
61
|
-
#define INIT(
|
61
|
+
#define INIT(subtype) \
|
62
62
|
do { \
|
63
|
-
|
64
|
-
(
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
req->type = UV_FS; \
|
64
|
+
if (cb != NULL) \
|
65
|
+
uv__req_init(loop, req, UV_FS); \
|
66
|
+
req->fs_type = UV_FS_ ## subtype; \
|
67
|
+
req->result = 0; \
|
68
|
+
req->ptr = NULL; \
|
69
|
+
req->loop = loop; \
|
70
|
+
req->path = NULL; \
|
71
|
+
req->new_path = NULL; \
|
72
|
+
req->cb = cb; \
|
71
73
|
} \
|
72
74
|
while (0)
|
73
75
|
|
74
76
|
#define PATH \
|
75
77
|
do { \
|
76
|
-
(
|
77
|
-
if (
|
78
|
-
|
78
|
+
assert(path != NULL); \
|
79
|
+
if (cb == NULL) { \
|
80
|
+
req->path = path; \
|
81
|
+
} else { \
|
82
|
+
req->path = uv__strdup(path); \
|
83
|
+
if (req->path == NULL) { \
|
84
|
+
uv__req_unregister(loop, req); \
|
85
|
+
return -ENOMEM; \
|
86
|
+
} \
|
87
|
+
} \
|
79
88
|
} \
|
80
89
|
while (0)
|
81
90
|
|
82
91
|
#define PATH2 \
|
83
92
|
do { \
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
if (cb == NULL) { \
|
94
|
+
req->path = path; \
|
95
|
+
req->new_path = new_path; \
|
96
|
+
} else { \
|
97
|
+
size_t path_len; \
|
98
|
+
size_t new_path_len; \
|
99
|
+
path_len = strlen(path) + 1; \
|
100
|
+
new_path_len = strlen(new_path) + 1; \
|
101
|
+
req->path = uv__malloc(path_len + new_path_len); \
|
102
|
+
if (req->path == NULL) { \
|
103
|
+
uv__req_unregister(loop, req); \
|
104
|
+
return -ENOMEM; \
|
105
|
+
} \
|
106
|
+
req->new_path = req->path + path_len; \
|
107
|
+
memcpy((void*) req->path, path, path_len); \
|
108
|
+
memcpy((void*) req->new_path, new_path, new_path_len); \
|
109
|
+
} \
|
94
110
|
} \
|
95
111
|
while (0)
|
96
112
|
|
97
113
|
#define POST \
|
98
114
|
do { \
|
99
|
-
if (
|
100
|
-
uv__work_submit(
|
115
|
+
if (cb != NULL) { \
|
116
|
+
uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
|
101
117
|
return 0; \
|
102
118
|
} \
|
103
119
|
else { \
|
104
|
-
uv__fs_work(&
|
105
|
-
|
106
|
-
return (req)->result; \
|
120
|
+
uv__fs_work(&req->work_req); \
|
121
|
+
return req->result; \
|
107
122
|
} \
|
108
123
|
} \
|
109
124
|
while (0)
|
@@ -309,8 +324,6 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
|
|
309
324
|
}
|
310
325
|
|
311
326
|
done:
|
312
|
-
if (req->bufs != req->bufsml)
|
313
|
-
free(req->bufs);
|
314
327
|
return result;
|
315
328
|
}
|
316
329
|
|
@@ -350,8 +363,8 @@ out:
|
|
350
363
|
int i;
|
351
364
|
|
352
365
|
for (i = 0; i < n; i++)
|
353
|
-
|
354
|
-
|
366
|
+
uv__free(dents[i]);
|
367
|
+
uv__free(dents);
|
355
368
|
}
|
356
369
|
errno = saved_errno;
|
357
370
|
|
@@ -361,21 +374,28 @@ out:
|
|
361
374
|
}
|
362
375
|
|
363
376
|
|
364
|
-
static ssize_t
|
365
|
-
ssize_t
|
366
|
-
char* buf;
|
377
|
+
static ssize_t uv__fs_pathmax_size(const char* path) {
|
378
|
+
ssize_t pathmax;
|
367
379
|
|
368
|
-
|
380
|
+
pathmax = pathconf(path, _PC_PATH_MAX);
|
369
381
|
|
370
|
-
if (
|
382
|
+
if (pathmax == -1) {
|
371
383
|
#if defined(PATH_MAX)
|
372
|
-
|
384
|
+
return PATH_MAX;
|
373
385
|
#else
|
374
|
-
|
386
|
+
return 4096;
|
375
387
|
#endif
|
376
388
|
}
|
377
389
|
|
378
|
-
|
390
|
+
return pathmax;
|
391
|
+
}
|
392
|
+
|
393
|
+
static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
394
|
+
ssize_t len;
|
395
|
+
char* buf;
|
396
|
+
|
397
|
+
len = uv__fs_pathmax_size(req->path);
|
398
|
+
buf = uv__malloc(len + 1);
|
379
399
|
|
380
400
|
if (buf == NULL) {
|
381
401
|
errno = ENOMEM;
|
@@ -385,7 +405,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|
385
405
|
len = readlink(req->path, buf, len);
|
386
406
|
|
387
407
|
if (len == -1) {
|
388
|
-
|
408
|
+
uv__free(buf);
|
389
409
|
return -1;
|
390
410
|
}
|
391
411
|
|
@@ -395,6 +415,27 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|
395
415
|
return 0;
|
396
416
|
}
|
397
417
|
|
418
|
+
static ssize_t uv__fs_realpath(uv_fs_t* req) {
|
419
|
+
ssize_t len;
|
420
|
+
char* buf;
|
421
|
+
|
422
|
+
len = uv__fs_pathmax_size(req->path);
|
423
|
+
buf = uv__malloc(len + 1);
|
424
|
+
|
425
|
+
if (buf == NULL) {
|
426
|
+
errno = ENOMEM;
|
427
|
+
return -1;
|
428
|
+
}
|
429
|
+
|
430
|
+
if (realpath(req->path, buf) == NULL) {
|
431
|
+
uv__free(buf);
|
432
|
+
return -1;
|
433
|
+
}
|
434
|
+
|
435
|
+
req->ptr = buf;
|
436
|
+
|
437
|
+
return 0;
|
438
|
+
}
|
398
439
|
|
399
440
|
static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
|
400
441
|
struct pollfd pfd;
|
@@ -545,7 +586,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
545
586
|
|
546
587
|
return -1;
|
547
588
|
}
|
548
|
-
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
589
|
+
#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
|
549
590
|
{
|
550
591
|
off_t len;
|
551
592
|
ssize_t r;
|
@@ -555,7 +596,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
555
596
|
* number of bytes have been sent, we don't consider it an error.
|
556
597
|
*/
|
557
598
|
|
558
|
-
#if defined(__FreeBSD__)
|
599
|
+
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
559
600
|
len = 0;
|
560
601
|
r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0);
|
561
602
|
#else
|
@@ -565,7 +606,14 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
565
606
|
r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
|
566
607
|
#endif
|
567
608
|
|
568
|
-
|
609
|
+
/*
|
610
|
+
* The man page for sendfile(2) on DragonFly states that `len` contains
|
611
|
+
* a meaningful value ONLY in case of EAGAIN and EINTR.
|
612
|
+
* Nothing is said about it's value in case of other errors, so better
|
613
|
+
* not depend on the potential wrong assumption that is was not modified
|
614
|
+
* by the syscall.
|
615
|
+
*/
|
616
|
+
if (r == 0 || ((errno == EAGAIN || errno == EINTR) && len != 0)) {
|
569
617
|
req->off += len;
|
570
618
|
return (ssize_t) len;
|
571
619
|
}
|
@@ -610,7 +658,9 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
|
|
610
658
|
*/
|
611
659
|
#if defined(__APPLE__)
|
612
660
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
613
|
-
|
661
|
+
|
662
|
+
if (pthread_mutex_lock(&lock))
|
663
|
+
abort();
|
614
664
|
#endif
|
615
665
|
|
616
666
|
if (req->off < 0) {
|
@@ -667,12 +717,10 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
|
|
667
717
|
|
668
718
|
done:
|
669
719
|
#if defined(__APPLE__)
|
670
|
-
pthread_mutex_unlock(&lock)
|
720
|
+
if (pthread_mutex_unlock(&lock))
|
721
|
+
abort();
|
671
722
|
#endif
|
672
723
|
|
673
|
-
if (req->bufs != req->bufsml)
|
674
|
-
free(req->bufs);
|
675
|
-
|
676
724
|
return r;
|
677
725
|
}
|
678
726
|
|
@@ -777,6 +825,47 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
|
|
777
825
|
}
|
778
826
|
|
779
827
|
|
828
|
+
typedef ssize_t (*uv__fs_buf_iter_processor)(uv_fs_t* req);
|
829
|
+
static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process) {
|
830
|
+
unsigned int iovmax;
|
831
|
+
unsigned int nbufs;
|
832
|
+
uv_buf_t* bufs;
|
833
|
+
ssize_t total;
|
834
|
+
ssize_t result;
|
835
|
+
|
836
|
+
iovmax = uv__getiovmax();
|
837
|
+
nbufs = req->nbufs;
|
838
|
+
bufs = req->bufs;
|
839
|
+
total = 0;
|
840
|
+
|
841
|
+
while (nbufs > 0) {
|
842
|
+
req->nbufs = nbufs;
|
843
|
+
if (req->nbufs > iovmax)
|
844
|
+
req->nbufs = iovmax;
|
845
|
+
|
846
|
+
result = process(req);
|
847
|
+
if (result <= 0) {
|
848
|
+
if (total == 0)
|
849
|
+
total = result;
|
850
|
+
break;
|
851
|
+
}
|
852
|
+
|
853
|
+
if (req->off >= 0)
|
854
|
+
req->off += result;
|
855
|
+
|
856
|
+
req->bufs += req->nbufs;
|
857
|
+
nbufs -= req->nbufs;
|
858
|
+
total += result;
|
859
|
+
}
|
860
|
+
|
861
|
+
if (bufs != req->bufsml)
|
862
|
+
uv__free(bufs);
|
863
|
+
req->bufs = NULL;
|
864
|
+
|
865
|
+
return total;
|
866
|
+
}
|
867
|
+
|
868
|
+
|
780
869
|
static void uv__fs_work(struct uv__work* w) {
|
781
870
|
int retry_on_eintr;
|
782
871
|
uv_fs_t* req;
|
@@ -810,9 +899,10 @@ static void uv__fs_work(struct uv__work* w) {
|
|
810
899
|
X(MKDIR, mkdir(req->path, req->mode));
|
811
900
|
X(MKDTEMP, uv__fs_mkdtemp(req));
|
812
901
|
X(OPEN, uv__fs_open(req));
|
813
|
-
X(READ,
|
902
|
+
X(READ, uv__fs_buf_iter(req, uv__fs_read));
|
814
903
|
X(SCANDIR, uv__fs_scandir(req));
|
815
904
|
X(READLINK, uv__fs_readlink(req));
|
905
|
+
X(REALPATH, uv__fs_realpath(req));
|
816
906
|
X(RENAME, rename(req->path, req->new_path));
|
817
907
|
X(RMDIR, rmdir(req->path));
|
818
908
|
X(SENDFILE, uv__fs_sendfile(req));
|
@@ -820,7 +910,7 @@ static void uv__fs_work(struct uv__work* w) {
|
|
820
910
|
X(SYMLINK, symlink(req->path, req->new_path));
|
821
911
|
X(UNLINK, unlink(req->path));
|
822
912
|
X(UTIME, uv__fs_utime(req));
|
823
|
-
X(WRITE,
|
913
|
+
X(WRITE, uv__fs_buf_iter(req, uv__fs_write));
|
824
914
|
default: abort();
|
825
915
|
}
|
826
916
|
#undef X
|
@@ -850,8 +940,7 @@ static void uv__fs_done(struct uv__work* w, int status) {
|
|
850
940
|
req->result = -ECANCELED;
|
851
941
|
}
|
852
942
|
|
853
|
-
|
854
|
-
req->cb(req);
|
943
|
+
req->cb(req);
|
855
944
|
}
|
856
945
|
|
857
946
|
|
@@ -1008,9 +1097,12 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
|
|
1008
1097
|
const char* tpl,
|
1009
1098
|
uv_fs_cb cb) {
|
1010
1099
|
INIT(MKDTEMP);
|
1011
|
-
req->path =
|
1012
|
-
if (req->path == NULL)
|
1100
|
+
req->path = uv__strdup(tpl);
|
1101
|
+
if (req->path == NULL) {
|
1102
|
+
if (cb != NULL)
|
1103
|
+
uv__req_unregister(loop, req);
|
1013
1104
|
return -ENOMEM;
|
1105
|
+
}
|
1014
1106
|
POST;
|
1015
1107
|
}
|
1016
1108
|
|
@@ -1035,16 +1127,22 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
|
|
1035
1127
|
unsigned int nbufs,
|
1036
1128
|
int64_t off,
|
1037
1129
|
uv_fs_cb cb) {
|
1130
|
+
if (bufs == NULL || nbufs == 0)
|
1131
|
+
return -EINVAL;
|
1132
|
+
|
1038
1133
|
INIT(READ);
|
1039
1134
|
req->file = file;
|
1040
1135
|
|
1041
1136
|
req->nbufs = nbufs;
|
1042
1137
|
req->bufs = req->bufsml;
|
1043
1138
|
if (nbufs > ARRAY_SIZE(req->bufsml))
|
1044
|
-
req->bufs =
|
1139
|
+
req->bufs = uv__malloc(nbufs * sizeof(*bufs));
|
1045
1140
|
|
1046
|
-
if (req->bufs == NULL)
|
1141
|
+
if (req->bufs == NULL) {
|
1142
|
+
if (cb != NULL)
|
1143
|
+
uv__req_unregister(loop, req);
|
1047
1144
|
return -ENOMEM;
|
1145
|
+
}
|
1048
1146
|
|
1049
1147
|
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
1050
1148
|
|
@@ -1075,6 +1173,16 @@ int uv_fs_readlink(uv_loop_t* loop,
|
|
1075
1173
|
}
|
1076
1174
|
|
1077
1175
|
|
1176
|
+
int uv_fs_realpath(uv_loop_t* loop,
|
1177
|
+
uv_fs_t* req,
|
1178
|
+
const char * path,
|
1179
|
+
uv_fs_cb cb) {
|
1180
|
+
INIT(REALPATH);
|
1181
|
+
PATH;
|
1182
|
+
POST;
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
|
1078
1186
|
int uv_fs_rename(uv_loop_t* loop,
|
1079
1187
|
uv_fs_t* req,
|
1080
1188
|
const char* path,
|
@@ -1157,16 +1265,22 @@ int uv_fs_write(uv_loop_t* loop,
|
|
1157
1265
|
unsigned int nbufs,
|
1158
1266
|
int64_t off,
|
1159
1267
|
uv_fs_cb cb) {
|
1268
|
+
if (bufs == NULL || nbufs == 0)
|
1269
|
+
return -EINVAL;
|
1270
|
+
|
1160
1271
|
INIT(WRITE);
|
1161
1272
|
req->file = file;
|
1162
1273
|
|
1163
1274
|
req->nbufs = nbufs;
|
1164
1275
|
req->bufs = req->bufsml;
|
1165
1276
|
if (nbufs > ARRAY_SIZE(req->bufsml))
|
1166
|
-
req->bufs =
|
1277
|
+
req->bufs = uv__malloc(nbufs * sizeof(*bufs));
|
1167
1278
|
|
1168
|
-
if (req->bufs == NULL)
|
1279
|
+
if (req->bufs == NULL) {
|
1280
|
+
if (cb != NULL)
|
1281
|
+
uv__req_unregister(loop, req);
|
1169
1282
|
return -ENOMEM;
|
1283
|
+
}
|
1170
1284
|
|
1171
1285
|
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
1172
1286
|
|
@@ -1176,7 +1290,14 @@ int uv_fs_write(uv_loop_t* loop,
|
|
1176
1290
|
|
1177
1291
|
|
1178
1292
|
void uv_fs_req_cleanup(uv_fs_t* req) {
|
1179
|
-
|
1293
|
+
/* Only necessary for asychronous requests, i.e., requests with a callback.
|
1294
|
+
* Synchronous ones don't copy their arguments and have req->path and
|
1295
|
+
* req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
|
1296
|
+
* exception to the rule, it always allocates memory.
|
1297
|
+
*/
|
1298
|
+
if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
|
1299
|
+
uv__free((void*) req->path); /* Memory is shared with req->new_path. */
|
1300
|
+
|
1180
1301
|
req->path = NULL;
|
1181
1302
|
req->new_path = NULL;
|
1182
1303
|
|
@@ -1184,6 +1305,6 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
|
1184
1305
|
uv__fs_scandir_cleanup(req);
|
1185
1306
|
|
1186
1307
|
if (req->ptr != &req->statbuf)
|
1187
|
-
|
1308
|
+
uv__free(req->ptr);
|
1188
1309
|
req->ptr = NULL;
|
1189
1310
|
}
|