Skip to content

Commit 2cc4c52

Browse files
committed
Use SetConsoleTitle on Windows, instead of an Event. Also update test to run on Windows using some PowerShell commands.
1 parent b54f25c commit 2cc4c52

File tree

3 files changed

+47
-27
lines changed

3 files changed

+47
-27
lines changed

sapi/cli/ps_title.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,17 @@ extern char** environ;
105105
#define PS_PADDING ' '
106106
#endif
107107

108-
#ifndef PS_USE_CLOBBER_ARGV
108+
#ifdef PS_USE_WIN32
109+
static char windows_error_details[64];
110+
static char ps_buffer[MAX_PATH];
111+
static const size_t ps_buffer_size = MAX_PATH;
112+
#elif PS_USE_CLOBBER_ARGV
113+
static char *ps_buffer; /* will point to argv area */
114+
static size_t ps_buffer_size; /* space determined at run time */
115+
#else
109116
#define PS_BUFFER_SIZE 256
110117
static char ps_buffer[PS_BUFFER_SIZE];
111118
static const size_t ps_buffer_size = PS_BUFFER_SIZE;
112-
#else
113-
static char *ps_buffer; /* will point to argv area */
114-
static size_t ps_buffer_size; /* space determined at run time */
115119
#endif
116120

117121
static size_t ps_buffer_cur_len; /* actual string length in ps_buffer */
@@ -297,6 +301,12 @@ const char* ps_title_errno(int rc)
297301

298302
case PS_TITLE_BUFFER_NOT_AVAILABLE:
299303
return "Buffer not contiguous";
304+
305+
#ifdef PS_USE_WIN32
306+
case PS_TITLE_WINDOWS_ERROR:
307+
sprintf(windows_error_details, "Windows error code: %d", GetLastError());
308+
return windows_error_details;
309+
#endif
300310
}
301311

302312
return "Unknown error code";
@@ -348,20 +358,8 @@ int set_ps_title(const char* title)
348358

349359
#ifdef PS_USE_WIN32
350360
{
351-
/*
352-
* Win32 does not support showing any changed arguments. To make it at
353-
* all possible to track which backend is doing what, we create a
354-
* named object that can be viewed with for example Process Explorer.
355-
*/
356-
static HANDLE ident_handle = INVALID_HANDLE_VALUE;
357-
char name[PS_BUFFER_SIZE + 32];
358-
359-
if (ident_handle != INVALID_HANDLE_VALUE)
360-
CloseHandle(ident_handle);
361-
362-
sprintf(name, "php-process(%d): %s", _getpid(), ps_buffer);
363-
364-
ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
361+
if (!SetConsoleTitle(ps_buffer))
362+
return PS_TITLE_WINDOWS_ERROR;
365363
}
366364
#endif /* PS_USE_WIN32 */
367365

@@ -374,12 +372,16 @@ int set_ps_title(const char* title)
374372
* length into *displen.
375373
* The return code indicates the error.
376374
*/
377-
int get_ps_title(int *displen, const char** string)
375+
int get_ps_title(size_t *displen, const char** string)
378376
{
379377
int rc = is_ps_title_available();
380378
if (rc != PS_TITLE_SUCCESS)
381379
return rc;
382380

381+
#ifdef PS_USE_WIN32
382+
if (!(ps_buffer_cur_len = GetConsoleTitle(ps_buffer, ps_buffer_size)))
383+
return PS_TITLE_WINDOWS_ERROR;
384+
#endif
383385
*displen = ps_buffer_cur_len;
384386
*string = ps_buffer;
385387
return PS_TITLE_SUCCESS;

sapi/cli/ps_title.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@
2525
#define PS_TITLE_NOT_AVAILABLE 1
2626
#define PS_TITLE_NOT_INITIALIZED 2
2727
#define PS_TITLE_BUFFER_NOT_AVAILABLE 3
28+
#define PS_TITLE_WINDOWS_ERROR 4
2829

2930
extern char** save_ps_args(int argc, char** argv);
3031

3132
extern int set_ps_title(const char* new_str);
3233

33-
extern int get_ps_title(int* displen, const char** string);
34+
extern int get_ps_title(size_t* displen, const char** string);
3435

3536
extern const char* ps_title_errno(int rc);
3637

sapi/cli/tests/cli_process_title.phpt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
--TEST--
22
Check cli_process_title support
3-
--SKIPIF--
4-
<?php
5-
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') print "skip";
6-
?>
73
--FILE--
84
<?php
95
echo "*** Testing setting the process title ***\n";
106

11-
$set_title = $original_title = "test title for php cli";
7+
$set_title = $original_title = uniqid("title", true);
128
$pid = getmypid();
139

1410
if (cli_set_process_title($original_title) === true)
1511
echo "Successfully set title\n";
1612

17-
$ps_output = shell_exec("ps -p $pid -o command | tail -n 1");
18-
if ($ps_output === null) {
13+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
14+
$ps_output = shell_exec("PowerShell \"get-process cmd*,powershell* | Select-Object mainWindowTitle | ft -hide\"");
15+
else
16+
$ps_output = shell_exec("ps -p $pid -o command | tail -n 1");
17+
18+
if ($ps_output === null)
19+
{
1920
echo "ps failed\n";
2021
die();
2122
}
@@ -26,6 +27,22 @@ if (strpos(strtoupper(substr(PHP_OS, 0, 13)), "BSD") !== false)
2627
// Fix title for BSD
2728
$set_title = "php: $original_title (php)";
2829
}
30+
else if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
31+
{
32+
// Kind of convoluted. So when the test is run, the console where the run-tests.php
33+
// is executed forks a php.exe, which forks a cmd.exe, which then forks a final php.exe
34+
// to run the actual test. But the console title is set for the original console.
35+
// I couldn't figure out a good way to navigate this, so we're "grep'ing" all possible
36+
// console windows for our very unique title. It should occur exactly once in the grep
37+
// output.
38+
$pos = strpos($ps_output, $set_title, 0);
39+
if ($pos !== false)
40+
{
41+
$pos = strpos($ps_output, $set_title, $pos + strlen($set_title));
42+
if ($pos === false)
43+
$load_title = $set_title;
44+
}
45+
}
2946

3047
if ($load_title == $set_title)
3148
echo "Successfully verified title using ps\n";

0 commit comments

Comments
 (0)