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