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