passenger 1.0.3 → 1.0.4
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.
- data/Rakefile +1 -1
- data/doc/Users guide.html +3 -1
- data/doc/Users guide.txt +4 -0
- data/doc/cxxapi/ApplicationPoolClientServer_8h-source.html +1 -1
- data/doc/cxxapi/ApplicationPool_8h-source.html +1 -1
- data/doc/cxxapi/Application_8h-source.html +1 -1
- data/doc/cxxapi/Configuration_8h-source.html +2 -2
- data/doc/cxxapi/DummySpawnManager_8h-source.html +1 -1
- data/doc/cxxapi/Exceptions_8h-source.html +1 -1
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/Logging_8h-source.html +1 -1
- data/doc/cxxapi/MessageChannel_8h-source.html +201 -210
- data/doc/cxxapi/SpawnManager_8h-source.html +1 -1
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +1 -1
- data/doc/cxxapi/Utils_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +1 -1
- data/doc/cxxapi/functions_func.html +1 -1
- data/doc/cxxapi/functions_type.html +1 -1
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +3 -3
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/hierarchy.html +1 -1
- data/doc/cxxapi/inherits.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -1
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +1 -1
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
- data/doc/rdoc/files/ext/passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/passenger/application_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/dependencies_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/request_handler_rb.html +1 -1
- data/doc/rdoc/files/lib/passenger/spawn_manager_rb.html +1 -1
- data/ext/apache2/Configuration.h +1 -1
- data/ext/apache2/Hooks.cpp +57 -71
- data/ext/apache2/MessageChannel.h +25 -34
- data/ext/passenger/native_support.c +25 -32
- data/test/stub/apache2/httpd.conf +3 -0
- metadata +2 -2
@@ -21,7 +21,7 @@
|
|
21
21
|
</ul>
|
22
22
|
</div>
|
23
23
|
<h1>Passenger::AnythingToString< T > Member List</h1>This is the complete list of members for <a class="el" href="structPassenger_1_1AnythingToString.html">Passenger::AnythingToString< T ></a>, including all inherited members.<p><table>
|
24
|
-
</table><hr size="1"><address style="text-align: right;"><small>Generated on
|
24
|
+
</table><hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by
|
25
25
|
<a href="http://www.doxygen.org/index.html">
|
26
26
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.3 </small></address>
|
27
27
|
</body>
|
@@ -37,7 +37,7 @@ Do not use directly. <table border="0" cellpadding="0" cellspacing="0">
|
|
37
37
|
</table>
|
38
38
|
<hr>The documentation for this struct was generated from the following file:<ul>
|
39
39
|
<li><a class="el" href="Utils_8h-source.html">Utils.h</a></ul>
|
40
|
-
<hr size="1"><address style="text-align: right;"><small>Generated on
|
40
|
+
<hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by
|
41
41
|
<a href="http://www.doxygen.org/index.html">
|
42
42
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.3 </small></address>
|
43
43
|
</body>
|
data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
</ul>
|
22
22
|
</div>
|
23
23
|
<h1>Passenger::AnythingToString< vector< string > > Member List</h1>This is the complete list of members for <a class="el" href="structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html">Passenger::AnythingToString< vector< string > ></a>, including all inherited members.<p><table>
|
24
|
-
</table><hr size="1"><address style="text-align: right;"><small>Generated on
|
24
|
+
</table><hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by
|
25
25
|
<a href="http://www.doxygen.org/index.html">
|
26
26
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.3 </small></address>
|
27
27
|
</body>
|
@@ -37,7 +37,7 @@ Do not use directly. <table border="0" cellpadding="0" cellspacing="0">
|
|
37
37
|
</table>
|
38
38
|
<hr>The documentation for this struct was generated from the following file:<ul>
|
39
39
|
<li><a class="el" href="Utils_8h-source.html">Utils.h</a></ul>
|
40
|
-
<hr size="1"><address style="text-align: right;"><small>Generated on
|
40
|
+
<hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by
|
41
41
|
<a href="http://www.doxygen.org/index.html">
|
42
42
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.3 </small></address>
|
43
43
|
</body>
|
data/doc/rdoc/created.rid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Thu, 01 May 2008 20:23:41 +0200
|
data/ext/apache2/Configuration.h
CHANGED
data/ext/apache2/Hooks.cpp
CHANGED
@@ -555,6 +555,8 @@ destroy_hooks(void *arg) {
|
|
555
555
|
static int
|
556
556
|
init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
|
557
557
|
/*
|
558
|
+
* HISTORICAL NOTE:
|
559
|
+
*
|
558
560
|
* The Apache initialization process has the following properties:
|
559
561
|
*
|
560
562
|
* 1. Apache on Unix calls the post_config hook twice, once before detach() and once
|
@@ -564,79 +566,63 @@ init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *
|
|
564
566
|
* 3. On Unix, if the -X commandline option is given (the 'DEBUG' config is set),
|
565
567
|
* detach() will not be called.
|
566
568
|
*
|
567
|
-
*
|
568
|
-
* to
|
569
|
-
*
|
570
|
-
*
|
571
|
-
* post_config is called. But unfortunately, that doesn't work if the Passenger
|
572
|
-
* module is loaded after a graceful restart. There also doesn't seem to be any
|
573
|
-
* good hooks that we can use to avoid double initialization.
|
574
|
-
*
|
575
|
-
* So as a hack, we check whether Apache has already been daemonized, by checking
|
576
|
-
* whether ppid() returns 1. This doesn't work with Apache 2.0.x though: ppid()
|
577
|
-
* doesn't return 1. So Apache 2.0.x users will just have to live with the double
|
578
|
-
* initialization overhead.
|
569
|
+
* Because of property #2, the post_config hook is called twice. We initially tried
|
570
|
+
* to avoid this with all kinds of hacks and workarounds, but none of them are
|
571
|
+
* universal, i.e. it works for some people but not for others. So we got rid of the
|
572
|
+
* hacks, and now we always initialize in the post_config hook.
|
579
573
|
*/
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
try {
|
589
|
-
hooks = new Hooks(pconf, plog, ptemp, s);
|
590
|
-
apr_pool_cleanup_register(pconf, NULL,
|
591
|
-
destroy_hooks,
|
592
|
-
apr_pool_cleanup_null);
|
593
|
-
return OK;
|
594
|
-
} catch (const thread_resource_error &e) {
|
595
|
-
struct rlimit lim;
|
596
|
-
string pthread_threads_max;
|
597
|
-
|
598
|
-
lim.rlim_cur = 0;
|
599
|
-
lim.rlim_max = 0;
|
600
|
-
getrlimit(RLIMIT_NPROC, &lim);
|
601
|
-
#ifdef PTHREAD_THREADS_MAX
|
602
|
-
pthread_threads_max = toString(PTHREAD_THREADS_MAX);
|
603
|
-
#else
|
604
|
-
pthread_threads_max = "unknown";
|
605
|
-
#endif
|
606
|
-
|
607
|
-
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
608
|
-
"*** Passenger could not be initialize because a "
|
609
|
-
"threading resource could not be allocated or initialized. "
|
610
|
-
"The error message is:");
|
611
|
-
fprintf(stderr,
|
612
|
-
" %s\n\n"
|
613
|
-
"System settings:\n"
|
614
|
-
" RLIMIT_NPROC: soft = %d, hard = %d\n"
|
615
|
-
" PTHREAD_THREADS_MAX: %s\n"
|
616
|
-
"\n",
|
617
|
-
e.what(),
|
618
|
-
(int) lim.rlim_cur, (int) lim.rlim_max,
|
619
|
-
pthread_threads_max.c_str());
|
620
|
-
|
621
|
-
fprintf(stderr, "Output of 'uname -a' follows:\n");
|
622
|
-
fflush(stderr);
|
623
|
-
system("uname -a >&2");
|
624
|
-
|
625
|
-
fprintf(stderr, "\nOutput of 'ulimit -a' follows:\n");
|
626
|
-
fflush(stderr);
|
627
|
-
system("ulimit -a >&2");
|
628
|
-
|
629
|
-
return DECLINED;
|
630
|
-
|
631
|
-
} catch (const exception &e) {
|
632
|
-
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
633
|
-
"*** Passenger could not be initialized because of this error: %s",
|
634
|
-
e.what());
|
635
|
-
hooks = NULL;
|
636
|
-
return DECLINED;
|
637
|
-
}
|
638
|
-
} else {
|
574
|
+
if (hooks != NULL) {
|
575
|
+
delete hooks;
|
576
|
+
}
|
577
|
+
try {
|
578
|
+
hooks = new Hooks(pconf, plog, ptemp, s);
|
579
|
+
apr_pool_cleanup_register(pconf, NULL,
|
580
|
+
destroy_hooks,
|
581
|
+
apr_pool_cleanup_null);
|
639
582
|
return OK;
|
583
|
+
} catch (const thread_resource_error &e) {
|
584
|
+
struct rlimit lim;
|
585
|
+
string pthread_threads_max;
|
586
|
+
|
587
|
+
lim.rlim_cur = 0;
|
588
|
+
lim.rlim_max = 0;
|
589
|
+
getrlimit(RLIMIT_NPROC, &lim);
|
590
|
+
#ifdef PTHREAD_THREADS_MAX
|
591
|
+
pthread_threads_max = toString(PTHREAD_THREADS_MAX);
|
592
|
+
#else
|
593
|
+
pthread_threads_max = "unknown";
|
594
|
+
#endif
|
595
|
+
|
596
|
+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
597
|
+
"*** Passenger could not be initialize because a "
|
598
|
+
"threading resource could not be allocated or initialized. "
|
599
|
+
"The error message is:");
|
600
|
+
fprintf(stderr,
|
601
|
+
" %s\n\n"
|
602
|
+
"System settings:\n"
|
603
|
+
" RLIMIT_NPROC: soft = %d, hard = %d\n"
|
604
|
+
" PTHREAD_THREADS_MAX: %s\n"
|
605
|
+
"\n",
|
606
|
+
e.what(),
|
607
|
+
(int) lim.rlim_cur, (int) lim.rlim_max,
|
608
|
+
pthread_threads_max.c_str());
|
609
|
+
|
610
|
+
fprintf(stderr, "Output of 'uname -a' follows:\n");
|
611
|
+
fflush(stderr);
|
612
|
+
system("uname -a >&2");
|
613
|
+
|
614
|
+
fprintf(stderr, "\nOutput of 'ulimit -a' follows:\n");
|
615
|
+
fflush(stderr);
|
616
|
+
system("ulimit -a >&2");
|
617
|
+
|
618
|
+
return DECLINED;
|
619
|
+
|
620
|
+
} catch (const exception &e) {
|
621
|
+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
622
|
+
"*** Passenger could not be initialized because of this error: %s",
|
623
|
+
e.what());
|
624
|
+
hooks = NULL;
|
625
|
+
return DECLINED;
|
640
626
|
}
|
641
627
|
}
|
642
628
|
|
@@ -256,33 +256,31 @@ public:
|
|
256
256
|
* @see readFileDescriptor()
|
257
257
|
*/
|
258
258
|
void writeFileDescriptor(int fileDescriptor) {
|
259
|
-
struct {
|
260
|
-
struct cmsghdr header;
|
261
|
-
int fd;
|
262
|
-
} control;
|
263
|
-
|
264
|
-
control.header.cmsg_len = sizeof(control);
|
265
|
-
control.header.cmsg_level = SOL_SOCKET;
|
266
|
-
control.header.cmsg_type = SCM_RIGHTS;
|
267
|
-
control.fd = fileDescriptor;
|
268
|
-
|
269
259
|
struct msghdr msg;
|
270
260
|
struct iovec vec;
|
271
261
|
char dummy[1];
|
272
|
-
|
262
|
+
char control_data[CMSG_SPACE(sizeof(int))];
|
263
|
+
struct cmsghdr *control_header;
|
264
|
+
|
273
265
|
msg.msg_name = NULL;
|
274
266
|
msg.msg_namelen = 0;
|
275
|
-
|
276
|
-
/* Linux and Solaris require msg_iov to be non-NULL
|
267
|
+
|
268
|
+
/* Linux and Solaris require msg_iov to be non-NULL. */
|
277
269
|
dummy[0] = '\0';
|
278
270
|
vec.iov_base = dummy;
|
279
271
|
vec.iov_len = sizeof(dummy);
|
280
272
|
msg.msg_iov = &vec;
|
281
273
|
msg.msg_iovlen = 1;
|
282
|
-
|
283
|
-
msg.msg_control = (caddr_t)
|
284
|
-
msg.msg_controllen = sizeof(
|
274
|
+
|
275
|
+
msg.msg_control = (caddr_t) control_data;
|
276
|
+
msg.msg_controllen = sizeof(control_data);
|
285
277
|
msg.msg_flags = 0;
|
278
|
+
|
279
|
+
control_header = CMSG_FIRSTHDR(&msg);
|
280
|
+
control_header->cmsg_len = CMSG_LEN(sizeof(int));
|
281
|
+
control_header->cmsg_level = SOL_SOCKET;
|
282
|
+
control_header->cmsg_type = SCM_RIGHTS;
|
283
|
+
memcpy(CMSG_DATA(control_header), &fileDescriptor, sizeof(int));
|
286
284
|
|
287
285
|
if (sendmsg(fd, &msg, 0) == -1) {
|
288
286
|
throw SystemException("Cannot send file descriptor with sendmsg()", errno);
|
@@ -422,19 +420,11 @@ public:
|
|
422
420
|
* file descriptor.
|
423
421
|
*/
|
424
422
|
int readFileDescriptor() {
|
425
|
-
struct {
|
426
|
-
struct cmsghdr header;
|
427
|
-
int fd;
|
428
|
-
} control;
|
429
|
-
|
430
|
-
control.header.cmsg_len = sizeof(control);
|
431
|
-
control.header.cmsg_level = SOL_SOCKET;
|
432
|
-
control.header.cmsg_type = SCM_RIGHTS;
|
433
|
-
control.fd = -1;
|
434
|
-
|
435
423
|
struct msghdr msg;
|
436
424
|
struct iovec vec;
|
437
425
|
char dummy[1];
|
426
|
+
char control_data[CMSG_SPACE(sizeof(int))];
|
427
|
+
struct cmsghdr *control_header;
|
438
428
|
|
439
429
|
msg.msg_name = NULL;
|
440
430
|
msg.msg_namelen = 0;
|
@@ -445,21 +435,22 @@ public:
|
|
445
435
|
msg.msg_iov = &vec;
|
446
436
|
msg.msg_iovlen = 1;
|
447
437
|
|
448
|
-
msg.msg_control = (caddr_t)
|
449
|
-
msg.msg_controllen = sizeof(
|
438
|
+
msg.msg_control = (caddr_t) control_data;
|
439
|
+
msg.msg_controllen = sizeof(control_data);
|
450
440
|
msg.msg_flags = 0;
|
451
|
-
|
441
|
+
|
452
442
|
if (recvmsg(fd, &msg, 0) == -1) {
|
453
443
|
throw SystemException("Cannot read file descriptor with recvmsg()", errno);
|
454
444
|
}
|
455
445
|
|
456
|
-
|
457
|
-
|
458
|
-
||
|
459
|
-
||
|
446
|
+
control_header = CMSG_FIRSTHDR(&msg);
|
447
|
+
if (msg.msg_controllen != sizeof(control_data)
|
448
|
+
|| control_header->cmsg_len != CMSG_LEN(sizeof(int))
|
449
|
+
|| control_header->cmsg_level != SOL_SOCKET
|
450
|
+
|| control_header->cmsg_type != SCM_RIGHTS) {
|
460
451
|
throw IOException("No valid file descriptor received.");
|
461
452
|
}
|
462
|
-
return
|
453
|
+
return *((int *) CMSG_DATA(control_header));
|
463
454
|
}
|
464
455
|
};
|
465
456
|
|
@@ -40,34 +40,34 @@ static VALUE mNativeSupport;
|
|
40
40
|
*/
|
41
41
|
static VALUE
|
42
42
|
send_fd(VALUE self, VALUE socket_fd, VALUE fd_to_send) {
|
43
|
-
int fd;
|
44
|
-
struct {
|
45
|
-
struct cmsghdr header;
|
46
|
-
int fd;
|
47
|
-
} control;
|
48
43
|
struct msghdr msg;
|
49
44
|
struct iovec vec;
|
50
45
|
char dummy[1];
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
control.fd = NUM2INT(fd_to_send);
|
56
|
-
|
46
|
+
char control_data[CMSG_SPACE(sizeof(int))];
|
47
|
+
struct cmsghdr *control_header;
|
48
|
+
int control_payload;
|
49
|
+
|
57
50
|
msg.msg_name = NULL;
|
58
51
|
msg.msg_namelen = 0;
|
59
52
|
|
60
|
-
/* Linux and Solaris require msg_iov to be non-NULL
|
53
|
+
/* Linux and Solaris require msg_iov to be non-NULL. */
|
61
54
|
dummy[0] = '\0';
|
62
55
|
vec.iov_base = dummy;
|
63
56
|
vec.iov_len = sizeof(dummy);
|
64
57
|
msg.msg_iov = &vec;
|
65
58
|
msg.msg_iovlen = 1;
|
66
59
|
|
67
|
-
msg.msg_control = (caddr_t)
|
68
|
-
msg.msg_controllen = sizeof(
|
60
|
+
msg.msg_control = (caddr_t) control_data;
|
61
|
+
msg.msg_controllen = sizeof(control_data);
|
69
62
|
msg.msg_flags = 0;
|
70
63
|
|
64
|
+
control_header = CMSG_FIRSTHDR(&msg);
|
65
|
+
control_header->cmsg_len = CMSG_LEN(sizeof(int));
|
66
|
+
control_header->cmsg_level = SOL_SOCKET;
|
67
|
+
control_header->cmsg_type = SCM_RIGHTS;
|
68
|
+
control_payload = NUM2INT(fd_to_send);
|
69
|
+
memcpy(CMSG_DATA(control_header), &control_payload, sizeof(int));
|
70
|
+
|
71
71
|
if (sendmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
|
72
72
|
rb_sys_fail("sendmsg(2)");
|
73
73
|
return Qnil;
|
@@ -88,19 +88,11 @@ send_fd(VALUE self, VALUE socket_fd, VALUE fd_to_send) {
|
|
88
88
|
*/
|
89
89
|
static VALUE
|
90
90
|
recv_fd(VALUE self, VALUE socket_fd) {
|
91
|
-
struct {
|
92
|
-
struct cmsghdr header;
|
93
|
-
int fd;
|
94
|
-
} control;
|
95
|
-
|
96
|
-
control.header.cmsg_len = sizeof(control);
|
97
|
-
control.header.cmsg_level = SOL_SOCKET;
|
98
|
-
control.header.cmsg_type = SCM_RIGHTS;
|
99
|
-
control.fd = -1;
|
100
|
-
|
101
91
|
struct msghdr msg;
|
102
92
|
struct iovec vec;
|
103
93
|
char dummy[1];
|
94
|
+
char control_data[CMSG_SPACE(sizeof(int))];
|
95
|
+
struct cmsghdr *control_header;
|
104
96
|
|
105
97
|
msg.msg_name = NULL;
|
106
98
|
msg.msg_namelen = 0;
|
@@ -111,23 +103,24 @@ recv_fd(VALUE self, VALUE socket_fd) {
|
|
111
103
|
msg.msg_iov = &vec;
|
112
104
|
msg.msg_iovlen = 1;
|
113
105
|
|
114
|
-
msg.msg_control = (caddr_t)
|
115
|
-
msg.msg_controllen = sizeof(
|
106
|
+
msg.msg_control = (caddr_t) control_data;
|
107
|
+
msg.msg_controllen = sizeof(control_data);
|
116
108
|
msg.msg_flags = 0;
|
117
|
-
|
109
|
+
|
118
110
|
if (recvmsg(NUM2INT(socket_fd), &msg, 0) == -1) {
|
119
111
|
rb_sys_fail("Cannot read file descriptor with recvmsg()");
|
120
112
|
return Qnil;
|
121
113
|
}
|
122
114
|
|
123
|
-
|
124
|
-
|
125
|
-
||
|
126
|
-
||
|
115
|
+
control_header = CMSG_FIRSTHDR(&msg);
|
116
|
+
if (msg.msg_controllen != sizeof(control_data)
|
117
|
+
|| control_header->cmsg_len != CMSG_LEN(sizeof(int))
|
118
|
+
|| control_header->cmsg_level != SOL_SOCKET
|
119
|
+
|| control_header->cmsg_type != SCM_RIGHTS) {
|
127
120
|
rb_sys_fail("No valid file descriptor received.");
|
128
121
|
return Qnil;
|
129
122
|
}
|
130
|
-
return INT2NUM(
|
123
|
+
return INT2NUM(*((int *) CMSG_DATA(control_header)));
|
131
124
|
}
|
132
125
|
|
133
126
|
/*
|