@@ -360,6 +360,183 @@ PHP_FUNCTION(frankenphp_request_headers) {
360360}
361361/* }}} */
362362
363+ /* Process title implementation borrowed from sapi/cli/ps_title.c */
364+ #ifdef PHP_WIN32
365+ #include "win32/codepage.h"
366+ #include <process.h>
367+ #include <windows.h>
368+ #endif
369+
370+ #ifdef HAVE_SETPROCTITLE
371+ #define PS_USE_SETPROCTITLE
372+ #elif defined(__linux__ ) || defined(_AIX ) || defined(__sgi ) || \
373+ (defined(sun ) && !defined(BSD )) || defined(ultrix ) || defined(__osf__ ) || \
374+ defined(__APPLE__ )
375+ #define PS_USE_CLOBBER_ARGV
376+ #elif defined(PHP_WIN32 )
377+ #define PS_USE_WIN32
378+ #else
379+ #define PS_USE_NONE
380+ #endif
381+
382+ typedef enum {
383+ PS_TITLE_SUCCESS = 0 ,
384+ PS_TITLE_NOT_AVAILABLE = 1 ,
385+ PS_TITLE_NOT_INITIALIZED = 2 ,
386+ PS_TITLE_BUFFER_NOT_AVAILABLE = 3 ,
387+ PS_TITLE_WINDOWS_ERROR = 4 ,
388+ PS_TITLE_TOO_LONG = 5 ,
389+ } ps_title_status ;
390+
391+ static char * ps_buffer = NULL ;
392+ static size_t ps_buffer_size = 0 ;
393+ static size_t ps_buffer_cur_len = 0 ;
394+
395+ static ps_title_status is_ps_title_available (void ) {
396+ #ifdef PS_USE_NONE
397+ return PS_TITLE_NOT_AVAILABLE ;
398+ #else
399+ if (!ps_buffer ) {
400+ return PS_TITLE_NOT_INITIALIZED ;
401+ }
402+ return PS_TITLE_SUCCESS ;
403+ #endif
404+ }
405+
406+ static const char * ps_title_errno (ps_title_status rc ) {
407+ switch (rc ) {
408+ case PS_TITLE_SUCCESS :
409+ return "Success" ;
410+ case PS_TITLE_NOT_AVAILABLE :
411+ return "Not available on this platform" ;
412+ case PS_TITLE_NOT_INITIALIZED :
413+ return "Not initialized" ;
414+ case PS_TITLE_BUFFER_NOT_AVAILABLE :
415+ return "Buffer not available" ;
416+ case PS_TITLE_WINDOWS_ERROR :
417+ return "Windows error" ;
418+ case PS_TITLE_TOO_LONG :
419+ return "Title too long" ;
420+ default :
421+ return "Unknown error" ;
422+ }
423+ }
424+
425+ static ps_title_status set_ps_title (const char * title , size_t title_len ) {
426+ #ifdef PS_USE_NONE
427+ return PS_TITLE_NOT_AVAILABLE ;
428+ #else
429+ if (title_len >= ps_buffer_size ) {
430+ return PS_TITLE_TOO_LONG ;
431+ }
432+ ps_title_status rc = is_ps_title_available ();
433+ if (rc != PS_TITLE_SUCCESS )
434+ return rc ;
435+
436+ memcpy (ps_buffer , title , title_len );
437+ ps_buffer [title_len ] = '\0' ;
438+ ps_buffer_cur_len = title_len ;
439+
440+ #ifdef PS_USE_SETPROCTITLE
441+ setproctitle ("%s" , ps_buffer );
442+ #endif
443+ #ifdef PS_USE_WIN32
444+ {
445+ wchar_t * ps_buffer_w = php_win32_cp_any_to_w (ps_buffer );
446+ if (!ps_buffer_w || !SetConsoleTitleW (ps_buffer_w )) {
447+ if (ps_buffer_w )
448+ free (ps_buffer_w );
449+ return PS_TITLE_WINDOWS_ERROR ;
450+ }
451+ free (ps_buffer_w );
452+ }
453+ #endif
454+ return PS_TITLE_SUCCESS ;
455+ #endif
456+ }
457+
458+ static ps_title_status get_ps_title (size_t * displen , const char * * string ) {
459+ ps_title_status rc = is_ps_title_available ();
460+ if (rc != PS_TITLE_SUCCESS )
461+ return rc ;
462+
463+ #ifdef PS_USE_WIN32
464+ {
465+ wchar_t ps_buffer_w [MAX_PATH ];
466+ char * tmp ;
467+
468+ if (!(ps_buffer_cur_len =
469+ GetConsoleTitleW (ps_buffer_w , (DWORD )sizeof (ps_buffer_w )))) {
470+ return PS_TITLE_WINDOWS_ERROR ;
471+ }
472+
473+ tmp = php_win32_cp_conv_w_to_any (ps_buffer_w , PHP_WIN32_CP_IGNORE_LEN ,
474+ & ps_buffer_cur_len );
475+ if (!tmp ) {
476+ return PS_TITLE_WINDOWS_ERROR ;
477+ }
478+
479+ ps_buffer_cur_len = ps_buffer_cur_len > ps_buffer_size - 1
480+ ? ps_buffer_size - 1
481+ : ps_buffer_cur_len ;
482+ memmove (ps_buffer , tmp , ps_buffer_cur_len );
483+ free (tmp );
484+ }
485+ #endif
486+ * displen = ps_buffer_cur_len ;
487+ * string = ps_buffer ;
488+ return PS_TITLE_SUCCESS ;
489+ }
490+
491+ /* {{{ cli_set_process_title */
492+ PHP_FUNCTION (cli_set_process_title ) {
493+ char * title ;
494+ size_t title_len ;
495+ ps_title_status rc ;
496+
497+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
498+ Z_PARAM_STRING (title , title_len )
499+ ZEND_PARSE_PARAMETERS_END ();
500+
501+ if (!ps_buffer ) {
502+ ps_buffer_size = 256 ; /* Reasonable default */
503+ ps_buffer = malloc (ps_buffer_size );
504+ if (ps_buffer ) {
505+ ps_buffer [0 ] = '\0' ;
506+ ps_buffer_cur_len = 0 ;
507+ }
508+ }
509+
510+ rc = set_ps_title (title , title_len );
511+ if (rc != PS_TITLE_SUCCESS ) {
512+ php_error_docref (NULL , E_WARNING , "cli_set_process_title had an error: %s" ,
513+ ps_title_errno (rc ));
514+ RETURN_FALSE ;
515+ }
516+
517+ RETURN_TRUE ;
518+ }
519+ /* }}} */
520+
521+ /* {{{ cli_get_process_title */
522+ PHP_FUNCTION (cli_get_process_title ) {
523+ const char * title = NULL ;
524+ size_t length = 0 ;
525+ ps_title_status rc ;
526+
527+ ZEND_PARSE_PARAMETERS_NONE ();
528+
529+ rc = get_ps_title (& length , & title );
530+ if (rc != PS_TITLE_SUCCESS ) {
531+ php_error_docref (NULL , E_WARNING , "cli_get_process_title had an error: %s" ,
532+ ps_title_errno (rc ));
533+ RETURN_NULL ();
534+ }
535+
536+ RETURN_STRINGL (title , length );
537+ }
538+ /* }}} */
539+
363540/* add_response_header and apache_response_headers are copied from
364541 * https://github.com/php/php-src/blob/master/sapi/cli/php_cli_server.c
365542 * Copyright (c) The PHP Group
@@ -1119,6 +1296,13 @@ static void *execute_script_cli(void *arg) {
11191296 php_embed_init (cli_argc , cli_argv );
11201297
11211298 cli_register_file_handles (false);
1299+
1300+ #if PHP_VERSION_ID < 80400
1301+ zend_register_module (& frankenphp_module );
1302+ #else
1303+ zend_register_module_ex (& frankenphp_module , MODULE_PERSISTENT );
1304+ #endif
1305+
11221306 zend_first_try {
11231307 if (eval ) {
11241308 /* evaluate the cli_script as literal PHP code (php-cli -r "...") */
0 commit comments