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.

Files changed (76) hide show
  1. data/Rakefile +1 -1
  2. data/doc/Users guide.html +3 -1
  3. data/doc/Users guide.txt +4 -0
  4. data/doc/cxxapi/ApplicationPoolClientServer_8h-source.html +1 -1
  5. data/doc/cxxapi/ApplicationPool_8h-source.html +1 -1
  6. data/doc/cxxapi/Application_8h-source.html +1 -1
  7. data/doc/cxxapi/Configuration_8h-source.html +2 -2
  8. data/doc/cxxapi/DummySpawnManager_8h-source.html +1 -1
  9. data/doc/cxxapi/Exceptions_8h-source.html +1 -1
  10. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  11. data/doc/cxxapi/Logging_8h-source.html +1 -1
  12. data/doc/cxxapi/MessageChannel_8h-source.html +201 -210
  13. data/doc/cxxapi/SpawnManager_8h-source.html +1 -1
  14. data/doc/cxxapi/StandardApplicationPool_8h-source.html +1 -1
  15. data/doc/cxxapi/Utils_8h-source.html +1 -1
  16. data/doc/cxxapi/annotated.html +1 -1
  17. data/doc/cxxapi/classPassenger_1_1Application-members.html +1 -1
  18. data/doc/cxxapi/classPassenger_1_1Application.html +1 -1
  19. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +1 -1
  20. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +1 -1
  21. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -1
  22. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +1 -1
  23. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +1 -1
  24. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +1 -1
  25. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -1
  26. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +1 -1
  27. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -1
  28. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +1 -1
  29. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -1
  30. data/doc/cxxapi/classPassenger_1_1IOException.html +1 -1
  31. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +1 -1
  32. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +1 -1
  33. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -1
  34. data/doc/cxxapi/classPassenger_1_1SpawnException.html +1 -1
  35. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +1 -1
  36. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +1 -1
  37. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +1 -1
  38. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +1 -1
  39. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +1 -1
  40. data/doc/cxxapi/classPassenger_1_1SystemException.html +1 -1
  41. data/doc/cxxapi/definitions_8h-source.html +1 -1
  42. data/doc/cxxapi/files.html +1 -1
  43. data/doc/cxxapi/functions.html +1 -1
  44. data/doc/cxxapi/functions_func.html +1 -1
  45. data/doc/cxxapi/functions_type.html +1 -1
  46. data/doc/cxxapi/graph_legend.html +1 -1
  47. data/doc/cxxapi/graph_legend.png +0 -0
  48. data/doc/cxxapi/group__Configuration.html +3 -3
  49. data/doc/cxxapi/group__Configuration.png +0 -0
  50. data/doc/cxxapi/group__Core.html +1 -1
  51. data/doc/cxxapi/group__Core.png +0 -0
  52. data/doc/cxxapi/group__Exceptions.html +1 -1
  53. data/doc/cxxapi/group__Hooks.html +1 -1
  54. data/doc/cxxapi/group__Hooks.png +0 -0
  55. data/doc/cxxapi/group__Support.html +1 -1
  56. data/doc/cxxapi/hierarchy.html +1 -1
  57. data/doc/cxxapi/inherits.html +1 -1
  58. data/doc/cxxapi/main.html +1 -1
  59. data/doc/cxxapi/modules.html +1 -1
  60. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -1
  61. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +1 -1
  62. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -1
  63. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +1 -1
  64. data/doc/rdoc/created.rid +1 -1
  65. data/doc/rdoc/files/DEVELOPERS_TXT.html +1 -1
  66. data/doc/rdoc/files/ext/passenger/native_support_c.html +1 -1
  67. data/doc/rdoc/files/lib/passenger/application_spawner_rb.html +1 -1
  68. data/doc/rdoc/files/lib/passenger/dependencies_rb.html +1 -1
  69. data/doc/rdoc/files/lib/passenger/request_handler_rb.html +1 -1
  70. data/doc/rdoc/files/lib/passenger/spawn_manager_rb.html +1 -1
  71. data/ext/apache2/Configuration.h +1 -1
  72. data/ext/apache2/Hooks.cpp +57 -71
  73. data/ext/apache2/MessageChannel.h +25 -34
  74. data/ext/passenger/native_support.c +25 -32
  75. data/test/stub/apache2/httpd.conf +3 -0
  76. metadata +2 -2
@@ -21,7 +21,7 @@
21
21
  </ul>
22
22
  </div>
23
23
  <h1>Passenger::AnythingToString&lt; T &gt; Member List</h1>This is the complete list of members for <a class="el" href="structPassenger_1_1AnythingToString.html">Passenger::AnythingToString&lt; T &gt;</a>, including all inherited members.<p><table>
24
- </table><hr size="1"><address style="text-align: right;"><small>Generated on Wed Apr 30 00:07:02 2008 for Passenger by&nbsp;
24
+ </table><hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by&nbsp;
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 Wed Apr 30 00:07:02 2008 for Passenger by&nbsp;
40
+ <hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by&nbsp;
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>
@@ -21,7 +21,7 @@
21
21
  </ul>
22
22
  </div>
23
23
  <h1>Passenger::AnythingToString&lt; vector&lt; string &gt; &gt; 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&lt; vector&lt; string &gt; &gt;</a>, including all inherited members.<p><table>
24
- </table><hr size="1"><address style="text-align: right;"><small>Generated on Wed Apr 30 00:07:02 2008 for Passenger by&nbsp;
24
+ </table><hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by&nbsp;
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 Wed Apr 30 00:07:02 2008 for Passenger by&nbsp;
40
+ <hr size="1"><address style="text-align: right;"><small>Generated on Thu May 1 20:23:47 2008 for Passenger by&nbsp;
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>
@@ -1 +1 @@
1
- Wed, 30 Apr 2008 00:06:55 +0200
1
+ Thu, 01 May 2008 20:23:41 +0200
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Mon Apr 28 11:44:32 +0200 2008</td>
66
+ <td>Thu May 01 20:10:04 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Mon Apr 28 23:34:04 +0200 2008</td>
66
+ <td>Thu May 01 10:46:21 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Wed Apr 30 00:05:27 +0200 2008</td>
66
+ <td>Thu May 01 10:46:21 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Mon Apr 28 23:34:04 +0200 2008</td>
66
+ <td>Thu May 01 20:10:04 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Tue Apr 29 22:50:15 +0200 2008</td>
66
+ <td>Thu May 01 10:46:21 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -63,7 +63,7 @@
63
63
  </tr>
64
64
  <tr>
65
65
  <td>Modified:</td>
66
- <td>Mon Apr 28 23:34:04 +0200 2008</td>
66
+ <td>Thu May 01 10:46:21 +0200 2008</td>
67
67
  </tr>
68
68
  </table>
69
69
  </td></tr>
@@ -29,7 +29,7 @@
29
29
  */
30
30
 
31
31
  /** Module version number. */
32
- #define PASSENGER_VERSION "1.0.3"
32
+ #define PASSENGER_VERSION "1.0.4"
33
33
 
34
34
  #ifdef __cplusplus
35
35
  #include <set>
@@ -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
- * The Passenger initialization process is pretty expensive because a spawn server has
568
- * to be started, so we'll want to avoid initializing twice because of property #2.
569
- *
570
- * The most straightforward solution is to initialize Passenger the second time
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
- bool passengerShouldBeInitialized;
581
-
582
- #if (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER >= 2) || AP_SERVER_MAJORVERSION_NUMBER > 2
583
- passengerShouldBeInitialized = getppid() == 1 || ap_exists_config_define("DEBUG");
584
- #else
585
- passengerShouldBeInitialized = true;
586
- #endif
587
- if (passengerShouldBeInitialized) {
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) &control;
284
- msg.msg_controllen = sizeof(control);
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) &control;
449
- msg.msg_controllen = sizeof(control);
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
- if (msg.msg_controllen != sizeof(control)
457
- || control.header.cmsg_len != sizeof(control)
458
- || control.header.cmsg_level != SOL_SOCKET
459
- || control.header.cmsg_type != SCM_RIGHTS) {
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 control.fd;
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
- control.header.cmsg_len = sizeof(control);
53
- control.header.cmsg_level = SOL_SOCKET;
54
- control.header.cmsg_type = SCM_RIGHTS;
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) &control;
68
- msg.msg_controllen = sizeof(control);
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) &control;
115
- msg.msg_controllen = sizeof(control);
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
- if (msg.msg_controllen != sizeof(control)
124
- || control.header.cmsg_len != sizeof(control)
125
- || control.header.cmsg_level != SOL_SOCKET
126
- || control.header.cmsg_type != SCM_RIGHTS) {
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(control.fd);
123
+ return INT2NUM(*((int *) CMSG_DATA(control_header)));
131
124
  }
132
125
 
133
126
  /*