@@ -4572,206 +4572,227 @@ static void preload_send_header(sapi_header_struct *sapi_header, void *server_co
4572
4572
{
4573
4573
}
4574
4574
4575
- static int accel_finish_startup (void )
4575
+ #ifndef ZEND_WIN32
4576
+ static int accel_finish_startup_preload (bool in_child )
4576
4577
{
4577
- if (!ZCG (enabled ) || !accel_startup_ok ) {
4578
- return SUCCESS ;
4579
- }
4578
+ int ret = SUCCESS ;
4579
+ int rc ;
4580
+ int orig_error_reporting ;
4581
+
4582
+ int (* orig_activate )(void ) = sapi_module .activate ;
4583
+ int (* orig_deactivate )(void ) = sapi_module .deactivate ;
4584
+ void (* orig_register_server_variables )(zval * track_vars_array ) = sapi_module .register_server_variables ;
4585
+ int (* orig_header_handler )(sapi_header_struct * sapi_header , sapi_header_op_enum op , sapi_headers_struct * sapi_headers ) = sapi_module .header_handler ;
4586
+ int (* orig_send_headers )(sapi_headers_struct * sapi_headers ) = sapi_module .send_headers ;
4587
+ void (* orig_send_header )(sapi_header_struct * sapi_header , void * server_context )= sapi_module .send_header ;
4588
+ char * (* orig_getenv )(const char * name , size_t name_len ) = sapi_module .getenv ;
4589
+ size_t (* orig_ub_write )(const char * str , size_t str_length ) = sapi_module .ub_write ;
4590
+ void (* orig_flush )(void * server_context ) = sapi_module .flush ;
4591
+ #ifdef ZEND_SIGNALS
4592
+ bool old_reset_signals = SIGG (reset );
4593
+ #endif
4594
+
4595
+ sapi_module .activate = NULL ;
4596
+ sapi_module .deactivate = NULL ;
4597
+ sapi_module .register_server_variables = NULL ;
4598
+ sapi_module .header_handler = preload_header_handler ;
4599
+ sapi_module .send_headers = preload_send_headers ;
4600
+ sapi_module .send_header = preload_send_header ;
4601
+ sapi_module .getenv = NULL ;
4602
+ sapi_module .ub_write = preload_ub_write ;
4603
+ sapi_module .flush = preload_flush ;
4604
+
4605
+ zend_interned_strings_switch_storage (1 );
4580
4606
4581
- if (ZCG (accel_directives ).preload && * ZCG (accel_directives ).preload ) {
4582
- #ifdef ZEND_WIN32
4583
- zend_accel_error_noreturn (ACCEL_LOG_ERROR , "Preloading is not supported on Windows" );
4584
- return FAILURE ;
4585
- #else
4586
- bool in_child = false;
4587
- int ret = SUCCESS ;
4588
- int rc ;
4589
- int orig_error_reporting ;
4590
-
4591
- int (* orig_activate )(void ) = sapi_module .activate ;
4592
- int (* orig_deactivate )(void ) = sapi_module .deactivate ;
4593
- void (* orig_register_server_variables )(zval * track_vars_array ) = sapi_module .register_server_variables ;
4594
- int (* orig_header_handler )(sapi_header_struct * sapi_header , sapi_header_op_enum op , sapi_headers_struct * sapi_headers ) = sapi_module .header_handler ;
4595
- int (* orig_send_headers )(sapi_headers_struct * sapi_headers ) = sapi_module .send_headers ;
4596
- void (* orig_send_header )(sapi_header_struct * sapi_header , void * server_context )= sapi_module .send_header ;
4597
- char * (* orig_getenv )(const char * name , size_t name_len ) = sapi_module .getenv ;
4598
- size_t (* orig_ub_write )(const char * str , size_t str_length ) = sapi_module .ub_write ;
4599
- void (* orig_flush )(void * server_context ) = sapi_module .flush ;
4600
4607
#ifdef ZEND_SIGNALS
4601
- bool old_reset_signals = SIGG (reset );
4608
+ SIGG (reset ) = false ;
4602
4609
#endif
4603
4610
4604
- if (UNEXPECTED (file_cache_only )) {
4605
- zend_accel_error (ACCEL_LOG_WARNING , "Preloading doesn't work in \"file_cache_only\" mode" );
4606
- return SUCCESS ;
4611
+ orig_error_reporting = EG (error_reporting );
4612
+ EG (error_reporting ) = 0 ;
4613
+
4614
+ rc = php_request_startup ();
4615
+
4616
+ EG (error_reporting ) = orig_error_reporting ;
4617
+
4618
+ if (rc == SUCCESS ) {
4619
+ bool orig_report_memleaks ;
4620
+
4621
+ /* don't send headers */
4622
+ SG (headers_sent ) = true;
4623
+ SG (request_info ).no_headers = true;
4624
+ php_output_set_status (0 );
4625
+
4626
+ ZCG (auto_globals_mask ) = 0 ;
4627
+ ZCG (request_time ) = (time_t )sapi_get_request_time ();
4628
+ ZCG (cache_opline ) = NULL ;
4629
+ ZCG (cache_persistent_script ) = NULL ;
4630
+ ZCG (include_path_key_len ) = 0 ;
4631
+ ZCG (include_path_check ) = true;
4632
+
4633
+ ZCG (cwd ) = NULL ;
4634
+ ZCG (cwd_key_len ) = 0 ;
4635
+ ZCG (cwd_check ) = true;
4636
+
4637
+ if (accel_preload (ZCG (accel_directives ).preload , in_child ) != SUCCESS ) {
4638
+ ret = FAILURE ;
4607
4639
}
4640
+ preload_flush (NULL );
4608
4641
4609
- /* exclusive lock */
4610
- zend_shared_alloc_lock ();
4642
+ orig_report_memleaks = PG (report_memleaks );
4643
+ PG (report_memleaks ) = false;
4644
+ #ifdef ZEND_SIGNALS
4645
+ /* We may not have registered signal handlers due to SIGG(reset)=0, so
4646
+ * also disable the check that they are registered. */
4647
+ SIGG (check ) = false;
4648
+ #endif
4649
+ php_request_shutdown (NULL ); /* calls zend_shared_alloc_unlock(); */
4650
+ PG (report_memleaks ) = orig_report_memleaks ;
4651
+ } else {
4652
+ zend_shared_alloc_unlock ();
4653
+ ret = FAILURE ;
4654
+ }
4655
+ #ifdef ZEND_SIGNALS
4656
+ SIGG (reset ) = old_reset_signals ;
4657
+ #endif
4611
4658
4612
- if (ZCSG (preload_script )) {
4613
- /* Preloading was done in another process */
4614
- preload_load ();
4615
- zend_shared_alloc_unlock ();
4616
- return SUCCESS ;
4659
+ sapi_module .activate = orig_activate ;
4660
+ sapi_module .deactivate = orig_deactivate ;
4661
+ sapi_module .register_server_variables = orig_register_server_variables ;
4662
+ sapi_module .header_handler = orig_header_handler ;
4663
+ sapi_module .send_headers = orig_send_headers ;
4664
+ sapi_module .send_header = orig_send_header ;
4665
+ sapi_module .getenv = orig_getenv ;
4666
+ sapi_module .ub_write = orig_ub_write ;
4667
+ sapi_module .flush = orig_flush ;
4668
+
4669
+ sapi_activate ();
4670
+
4671
+ return ret ;
4672
+ }
4673
+
4674
+ static int accel_finish_startup_preload_subprocess (pid_t * pid )
4675
+ {
4676
+ uid_t euid = geteuid ();
4677
+ if (euid != 0 ) {
4678
+ if (ZCG (accel_directives ).preload_user
4679
+ && * ZCG (accel_directives ).preload_user ) {
4680
+ zend_accel_error (ACCEL_LOG_WARNING , "\"opcache.preload_user\" is ignored" );
4617
4681
}
4618
4682
4619
- uid_t euid = geteuid ();
4620
- if (euid == 0 ) {
4621
- pid_t pid ;
4622
- struct passwd * pw ;
4683
+ * pid = -1 ;
4684
+ return SUCCESS ;
4685
+ }
4623
4686
4624
- if (!ZCG (accel_directives ).preload_user
4625
- || !* ZCG (accel_directives ).preload_user ) {
4626
- zend_shared_alloc_unlock ();
4627
- zend_accel_error_noreturn (ACCEL_LOG_FATAL , "\"opcache.preload\" requires \"opcache.preload_user\" when running under uid 0" );
4628
- return FAILURE ;
4629
- }
4687
+ if (!ZCG (accel_directives ).preload_user
4688
+ || !* ZCG (accel_directives ).preload_user ) {
4630
4689
4631
- pw = getpwnam (ZCG (accel_directives ).preload_user );
4632
- if (pw == NULL ) {
4633
- zend_shared_alloc_unlock ();
4634
- zend_accel_error_noreturn (ACCEL_LOG_FATAL , "Preloading failed to getpwnam(\"%s\")" , ZCG (accel_directives ).preload_user );
4635
- return FAILURE ;
4636
- }
4637
4690
4638
- if (pw -> pw_uid != euid ) {
4639
- pid = fork ();
4640
- if (pid == -1 ) {
4641
- zend_shared_alloc_unlock ();
4642
- zend_accel_error_noreturn (ACCEL_LOG_FATAL , "Preloading failed to fork()" );
4643
- return FAILURE ;
4644
- } else if (pid == 0 ) { /* children */
4645
- if (setgid (pw -> pw_gid ) < 0 ) {
4646
- zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setgid(%d)" , pw -> pw_gid );
4647
- exit (1 );
4648
- }
4649
- if (initgroups (pw -> pw_name , pw -> pw_gid ) < 0 ) {
4650
- zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to initgroups(\"%s\", %d)" , pw -> pw_name , pw -> pw_uid );
4651
- exit (1 );
4652
- }
4653
- if (setuid (pw -> pw_uid ) < 0 ) {
4654
- zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setuid(%d)" , pw -> pw_uid );
4655
- exit (1 );
4656
- }
4657
- in_child = true;
4658
- } else { /* parent */
4659
- int status ;
4691
+ zend_shared_alloc_unlock ();
4692
+ zend_accel_error_noreturn (ACCEL_LOG_FATAL , "\"opcache.preload\" requires \"opcache.preload_user\" when running under uid 0" );
4693
+ return FAILURE ;
4694
+ }
4660
4695
4661
- if (waitpid (pid , & status , 0 ) < 0 ) {
4662
- zend_shared_alloc_unlock ();
4663
- zend_accel_error_noreturn (ACCEL_LOG_FATAL , "Preloading failed to waitpid(%d)" , pid );
4664
- return FAILURE ;
4665
- }
4696
+ struct passwd * pw = getpwnam (ZCG (accel_directives ).preload_user );
4697
+ if (pw == NULL ) {
4698
+ zend_shared_alloc_unlock ();
4699
+ zend_accel_error_noreturn (ACCEL_LOG_FATAL , "Preloading failed to getpwnam(\"%s\")" , ZCG (accel_directives ).preload_user );
4700
+ return FAILURE ;
4701
+ }
4666
4702
4667
- if (ZCSG (preload_script )) {
4668
- preload_load ();
4669
- }
4703
+ if (pw -> pw_uid == euid ) {
4704
+ * pid = -1 ;
4705
+ return SUCCESS ;
4706
+ }
4670
4707
4671
- zend_shared_alloc_unlock ();
4672
- if (WIFEXITED (status ) && WEXITSTATUS (status ) == 0 ) {
4673
- return SUCCESS ;
4674
- } else {
4675
- return FAILURE ;
4676
- }
4677
- }
4678
- }
4679
- } else {
4680
- if (ZCG (accel_directives ).preload_user
4681
- && * ZCG (accel_directives ).preload_user ) {
4682
- zend_accel_error (ACCEL_LOG_WARNING , "\"opcache.preload_user\" is ignored" );
4683
- }
4708
+ * pid = fork ();
4709
+ if (* pid == -1 ) {
4710
+ zend_shared_alloc_unlock ();
4711
+ zend_accel_error_noreturn (ACCEL_LOG_FATAL , "Preloading failed to fork()" );
4712
+ return FAILURE ;
4713
+ }
4714
+
4715
+ if (* pid == 0 ) { /* children */
4716
+ if (setgid (pw -> pw_gid ) < 0 ) {
4717
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setgid(%d)" , pw -> pw_gid );
4718
+ exit (1 );
4719
+ }
4720
+ if (initgroups (pw -> pw_name , pw -> pw_gid ) < 0 ) {
4721
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to initgroups(\"%s\", %d)" , pw -> pw_name , pw -> pw_uid );
4722
+ exit (1 );
4723
+ }
4724
+ if (setuid (pw -> pw_uid ) < 0 ) {
4725
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading failed to setuid(%d)" , pw -> pw_uid );
4726
+ exit (1 );
4684
4727
}
4728
+ }
4685
4729
4686
- sapi_module .activate = NULL ;
4687
- sapi_module .deactivate = NULL ;
4688
- sapi_module .register_server_variables = NULL ;
4689
- sapi_module .header_handler = preload_header_handler ;
4690
- sapi_module .send_headers = preload_send_headers ;
4691
- sapi_module .send_header = preload_send_header ;
4692
- sapi_module .getenv = NULL ;
4693
- sapi_module .ub_write = preload_ub_write ;
4694
- sapi_module .flush = preload_flush ;
4730
+ return SUCCESS ;
4731
+ }
4732
+ #endif /* ZEND_WIN32 */
4695
4733
4696
- zend_interned_strings_switch_storage (1 );
4734
+ static int accel_finish_startup (void )
4735
+ {
4736
+ if (!ZCG (enabled ) || !accel_startup_ok ) {
4737
+ return SUCCESS ;
4738
+ }
4697
4739
4698
- #ifdef ZEND_SIGNALS
4699
- SIGG ( reset ) = false ;
4700
- #endif
4740
+ if (!( ZCG ( accel_directives ). preload && * ZCG ( accel_directives ). preload )) {
4741
+ return SUCCESS ;
4742
+ }
4701
4743
4702
- orig_error_reporting = EG (error_reporting );
4703
- EG (error_reporting ) = 0 ;
4744
+ #ifdef ZEND_WIN32
4745
+ zend_accel_error_noreturn (ACCEL_LOG_ERROR , "Preloading is not supported on Windows" );
4746
+ return FAILURE ;
4747
+ #else /* ZEND_WIN32 */
4704
4748
4705
- rc = php_request_startup ();
4749
+ if (UNEXPECTED (file_cache_only )) {
4750
+ zend_accel_error (ACCEL_LOG_WARNING , "Preloading doesn't work in \"file_cache_only\" mode" );
4751
+ return SUCCESS ;
4752
+ }
4706
4753
4707
- EG (error_reporting ) = orig_error_reporting ;
4754
+ /* exclusive lock */
4755
+ zend_shared_alloc_lock ();
4708
4756
4709
- if (rc == SUCCESS ) {
4710
- bool orig_report_memleaks ;
4757
+ if (ZCSG (preload_script )) {
4758
+ /* Preloading was done in another process */
4759
+ preload_load ();
4760
+ zend_shared_alloc_unlock ();
4761
+ return SUCCESS ;
4762
+ }
4711
4763
4712
- /* don't send headers */
4713
- SG (headers_sent ) = true;
4714
- SG (request_info ).no_headers = true;
4715
- php_output_set_status (0 );
4716
4764
4717
- ZCG (auto_globals_mask ) = 0 ;
4718
- ZCG (request_time ) = (time_t )sapi_get_request_time ();
4719
- ZCG (cache_opline ) = NULL ;
4720
- ZCG (cache_persistent_script ) = NULL ;
4721
- ZCG (include_path_key_len ) = 0 ;
4722
- ZCG (include_path_check ) = true;
4765
+ pid_t pid ;
4766
+ if (accel_finish_startup_preload_subprocess (& pid ) == FAILURE ) {
4767
+ zend_shared_alloc_unlock ();
4768
+ return FAILURE ;
4769
+ }
4723
4770
4724
- ZCG (cwd ) = NULL ;
4725
- ZCG (cwd_key_len ) = 0 ;
4726
- ZCG (cwd_check ) = true;
4771
+ if (pid == -1 ) { /* no subprocess was needed */
4772
+ return accel_finish_startup_preload (false);
4773
+ } else if (pid == 0 ) { /* subprocess */
4774
+ int ret = accel_finish_startup_preload (true);
4727
4775
4728
- if (accel_preload (ZCG (accel_directives ).preload , in_child ) != SUCCESS ) {
4729
- ret = FAILURE ;
4730
- }
4731
- preload_flush (NULL );
4776
+ exit (ret == SUCCESS ? 0 : 1 );
4777
+ } else { /* parent */
4778
+ int status ;
4732
4779
4733
- orig_report_memleaks = PG (report_memleaks );
4734
- PG (report_memleaks ) = false;
4735
- #ifdef ZEND_SIGNALS
4736
- /* We may not have registered signal handlers due to SIGG(reset)=0, so
4737
- * also disable the check that they are registered. */
4738
- SIGG (check ) = false;
4739
- #endif
4740
- php_request_shutdown (NULL ); /* calls zend_shared_alloc_unlock(); */
4741
- PG (report_memleaks ) = orig_report_memleaks ;
4742
- } else {
4780
+ if (waitpid (pid , & status , 0 ) < 0 ) {
4743
4781
zend_shared_alloc_unlock ();
4744
- ret = FAILURE ;
4782
+ zend_accel_error_noreturn ( ACCEL_LOG_FATAL , "Preloading failed to waitpid(%d)" , pid ) ;
4745
4783
}
4746
- #ifdef ZEND_SIGNALS
4747
- SIGG (reset ) = old_reset_signals ;
4748
- #endif
4749
4784
4750
- sapi_module .activate = orig_activate ;
4751
- sapi_module .deactivate = orig_deactivate ;
4752
- sapi_module .register_server_variables = orig_register_server_variables ;
4753
- sapi_module .header_handler = orig_header_handler ;
4754
- sapi_module .send_headers = orig_send_headers ;
4755
- sapi_module .send_header = orig_send_header ;
4756
- sapi_module .getenv = orig_getenv ;
4757
- sapi_module .ub_write = orig_ub_write ;
4758
- sapi_module .flush = orig_flush ;
4759
-
4760
- sapi_activate ();
4761
-
4762
- if (in_child ) {
4763
- if (ret == SUCCESS ) {
4764
- exit (0 );
4765
- } else {
4766
- exit (2 );
4767
- }
4785
+ if (ZCSG (preload_script )) {
4786
+ preload_load ();
4768
4787
}
4769
4788
4770
- return ret ;
4771
- #endif
4789
+ if (WIFEXITED (status ) && WEXITSTATUS (status ) == 0 ) {
4790
+ return SUCCESS ;
4791
+ } else {
4792
+ return FAILURE ;
4793
+ }
4772
4794
}
4773
-
4774
- return SUCCESS ;
4795
+ #endif /* ZEND_WIN32 */
4775
4796
}
4776
4797
4777
4798
ZEND_EXT_API zend_extension zend_extension_entry = {
0 commit comments