43
43
#include "fcgi_config.h"
44
44
#include "fcgiapp.h"
45
45
#include <stdio.h>
46
+ #if HAVE_STDLIB_H
46
47
#include <stdlib.h>
48
+ #endif
49
+ #if HAVE_UNISTD_H
47
50
#include <unistd.h>
51
+ #endif
48
52
#include <sys/wait.h>
49
53
#include <sys/stat.h>
50
54
55
+ #if HAVE_SYS_TYPES_H
56
+ #include <sys/types.h>
57
+ #endif
58
+ #if HAVE_SIGNAL_H
59
+ #include <signal.h>
60
+ #endif
51
61
52
62
#define TLS_D
53
63
#define TLS_DC
59
69
FCGX_Stream * in , * out , * err ;
60
70
FCGX_ParamArray envp ;
61
71
char * path_info = NULL ;
72
+ struct sigaction act , old_term , old_quit , old_int ;
62
73
63
74
/* Our original environment from when the FastCGI first started */
64
75
char * * orig_env ;
@@ -71,6 +82,21 @@ char **cgi_env;
71
82
*/
72
83
char * * merge_env ;
73
84
85
+ /**
86
+ * Number of child processes that will get created to service requests
87
+ */
88
+ static int children = 8 ;
89
+
90
+ /**
91
+ * Set to non-zero if we are the parent process
92
+ */
93
+ static int parent = 1 ;
94
+
95
+ /**
96
+ * Process group
97
+ */
98
+ static pid_t pgroup ;
99
+
74
100
75
101
static int sapi_fastcgi_ub_write (const char * str , uint str_length )
76
102
{
@@ -127,12 +153,12 @@ static void sapi_fastcgi_register_variables(zval *track_vars_array ELS_DC SLS_DC
127
153
char * ptr = strchr ( self , '?' );
128
154
129
155
/*
130
- * note that the environment will already have been set up
131
- * via fastcgi_module_main(), below.
132
- *
133
- * fastcgi_module_main() -> php_request_startup() ->
134
- * php_hash_environment() -> php_import_environment_variables()
135
- */
156
+ * note that the environment will already have been set up
157
+ * via fastcgi_module_main(), below.
158
+ *
159
+ * fastcgi_module_main() -> php_request_startup() ->
160
+ * php_hash_environment() -> php_import_environment_variables()
161
+ */
136
162
137
163
/* strip query string off this */
138
164
if ( ptr ) * ptr = 0 ;
@@ -271,6 +297,24 @@ void fastcgi_php_shutdown(void)
271
297
}
272
298
273
299
300
+ /**
301
+ * Clean up child processes upon exit
302
+ */
303
+ void fastcgi_cleanup (int signal )
304
+ {
305
+ int i ;
306
+
307
+ #ifdef DEBUG_FASTCGI
308
+ fprintf ( stderr , "FastCGI shutdown, pid %d\n" , getpid () );
309
+ #endif
310
+
311
+ sigaction ( SIGTERM , & old_term , 0 );
312
+
313
+ /* Kill all the processes in our process group */
314
+ kill ( - pgroup , SIGTERM );
315
+ }
316
+
317
+
274
318
int main (int argc , char * argv [])
275
319
{
276
320
int exit_status = SUCCESS ;
@@ -280,16 +324,21 @@ int main(int argc, char *argv[])
280
324
char * argv0 = NULL ;
281
325
char * script_file = NULL ;
282
326
zend_llist global_vars ;
283
- int children = 8 ;
284
327
int max_requests = 500 ;
285
328
int requests = 0 ;
286
329
int status ;
287
330
int env_size , cgi_env_size ;
288
331
289
- #ifdef FASTCGI_DEBUG
290
- fprintf ( stderr , "Initialising now!\n" );
332
+ #ifdef DEBUG_FASTCGI
333
+ fprintf ( stderr , "Initialising now, pid %d !\n" , getpid () );
291
334
#endif
292
335
336
+ if ( FCGX_IsCGI () ) {
337
+ fprintf ( stderr , "The FastCGI version of PHP cannot be "
338
+ "run as a CGI application\n" );
339
+ exit ( 1 );
340
+ }
341
+
293
342
/* Calculate environment size */
294
343
env_size = 0 ;
295
344
while ( environ [ env_size ] ) { env_size ++ ; }
@@ -342,21 +391,46 @@ int main(int argc, char *argv[])
342
391
}
343
392
344
393
if ( children ) {
345
- int parent = 1 ;
346
394
int running = 0 ;
395
+ int i ;
396
+ pid_t pid ;
397
+
398
+ /* Create a process group for ourself & children */
399
+ setsid ();
400
+ pgroup = getpgrp ();
401
+ #ifdef DEBUG_FASTCGI
402
+ fprintf ( stderr , "Process group %d\n" , pgroup );
403
+ #endif
404
+
405
+ /* Set up handler to kill children upon exit */
406
+ act .sa_flags = 0 ;
407
+ act .sa_handler = fastcgi_cleanup ;
408
+ if ( sigaction ( SIGTERM , & act , & old_term ) ||
409
+ sigaction ( SIGINT , & act , & old_int ) ||
410
+ sigaction ( SIGQUIT , & act , & old_quit )) {
411
+ perror ( "Can't set signals" );
412
+ exit ( 1 );
413
+ }
414
+
347
415
while ( parent ) {
348
416
do {
349
- #ifdef FASTCGI_DEBUG
417
+ #ifdef DEBUG_FASTCGI
350
418
fprintf ( stderr , "Forking, %d running\n" ,
351
419
running );
352
420
#endif
353
- switch ( fork () ) {
421
+ pid = fork ();
422
+ switch ( pid ) {
354
423
case 0 :
355
424
/* One of the children.
356
425
* Make sure we don't go round the
357
426
* fork loop any more
358
427
*/
359
428
parent = 0 ;
429
+
430
+ /* don't catch our signals */
431
+ sigaction ( SIGTERM , & old_term , 0 );
432
+ sigaction ( SIGQUIT , & old_quit , 0 );
433
+ sigaction ( SIGINT , & old_int , 0 );
360
434
break ;
361
435
case -1 :
362
436
perror ( "php (pre-forking)" );
@@ -370,34 +444,38 @@ int main(int argc, char *argv[])
370
444
} while ( parent && ( running < children ));
371
445
372
446
if ( parent ) {
447
+ #ifdef DEBUG_FASTCGI
448
+ fprintf ( stderr , "Wait for kids, pid %d\n" ,
449
+ getpid () );
450
+ #endif
373
451
wait ( & status );
374
452
running -- ;
375
453
}
376
454
}
377
455
}
378
456
379
457
/* Main FastCGI loop */
380
- #ifdef FASTCGI_DEBUG
458
+ #ifdef DEBUG_FASTCGI
381
459
fprintf ( stderr , "Going into accept loop\n" );
382
460
#endif
383
461
384
462
while ( FCGX_Accept ( & in , & out , & err , & cgi_env ) >= 0 ) {
385
463
386
- #ifdef FASTCGI_DEBUG
464
+ #ifdef DEBUG_FASTCGI
387
465
fprintf ( stderr , "Got accept\n" );
388
466
#endif
389
467
390
- cgi_env_size = 0 ;
391
- while ( cgi_env [ cgi_env_size ] ) { cgi_env_size ++ ; }
392
- merge_env = malloc ( (env_size + cgi_env_size )* sizeof (char * ) );
393
- if ( !merge_env ) {
394
- perror ( "Can't malloc environment" );
395
- exit ( 1 );
396
- }
397
- memcpy ( merge_env , orig_env , (env_size - 1 )* sizeof (char * ) );
398
- memcpy ( merge_env + env_size - 1 ,
399
- cgi_env , (cgi_env_size + 1 )* sizeof (char * ) );
400
- environ = merge_env ;
468
+ cgi_env_size = 0 ;
469
+ while ( cgi_env [ cgi_env_size ] ) { cgi_env_size ++ ; }
470
+ merge_env = malloc ( (env_size + cgi_env_size )* sizeof (char * ) );
471
+ if ( !merge_env ) {
472
+ perror ( "Can't malloc environment" );
473
+ exit ( 1 );
474
+ }
475
+ memcpy ( merge_env , orig_env , (env_size - 1 )* sizeof (char * ) );
476
+ memcpy ( merge_env + env_size - 1 ,
477
+ cgi_env , (cgi_env_size + 1 )* sizeof (char * ) );
478
+ environ = merge_env ;
401
479
402
480
init_request_info ( TLS_C SLS_CC );
403
481
SG (server_context ) = (void * ) 1 ; /* avoid server_context==NULL checks */
@@ -424,7 +502,7 @@ int main(int argc, char *argv[])
424
502
}
425
503
}
426
504
427
- #ifdef FASTCGI_DEBUG
505
+ #ifdef DEBUG_FASTCGI
428
506
fprintf ( stderr , "Exiting...\n" );
429
507
#endif
430
508
return 0 ;
0 commit comments