Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4
index cdfa1f7..9a1b98d 100644
--- a/sapi/cli/config.m4
+++ b/sapi/cli/config.m4
@@ -6,6 +6,23 @@ PHP_ARG_ENABLE(cli,,
[ --disable-cli Disable building CLI version of PHP
(this forces --without-pear)], yes, no)
+AC_CHECK_FUNCS(setproctitle)
+
+AC_CHECK_HEADERS([sys/pstat.h])
+
+AC_CACHE_CHECK([for PS_STRINGS], [cli_cv_var_PS_STRINGS],
+[AC_TRY_LINK(
+[#include <machine/vmparam.h>
+#include <sys/exec.h>
+],
+[PS_STRINGS->ps_nargvstr = 1;
+PS_STRINGS->ps_argvstr = "foo";],
+[cli_cv_var_PS_STRINGS=yes],
+[cli_cv_var_PS_STRINGS=no])])
+if test "$cli_cv_var_PS_STRINGS" = yes ; then
+ AC_DEFINE([HAVE_PS_STRINGS], [], [Define to 1 if the PS_STRINGS thing exists.])
+fi
+
AC_MSG_CHECKING(for CLI build)
if test "$PHP_CLI" != "no"; then
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cli/Makefile.frag)
@@ -14,7 +31,7 @@ if test "$PHP_CLI" != "no"; then
SAPI_CLI_PATH=sapi/cli/php
dnl Select SAPI
- PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c,, '$(SAPI_CLI_PATH)')
+ PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c,, '$(SAPI_CLI_PATH)')
case $host_alias in
*aix*)
diff --git a/sapi/cli/config.w32 b/sapi/cli/config.w32
index 4d0dad5..adcbb2b 100644
--- a/sapi/cli/config.w32
+++ b/sapi/cli/config.w32
@@ -6,7 +6,7 @@ ARG_ENABLE('crt-debug', 'Enable CRT memory dumps for debugging sent to STDERR',
ARG_ENABLE('cli-win32', 'Build console-less CLI version of PHP', 'no');
if (PHP_CLI == "yes") {
- SAPI('cli', 'php_cli.c php_http_parser.c php_cli_server.c', 'php.exe');
+ SAPI('cli', 'php_cli.c php_http_parser.c php_cli_server.c php_cli_process_title.c ps_title.c', 'php.exe');
ADD_FLAG("LIBS_CLI", "ws2_32.lib");
if (PHP_CRT_DEBUG == "yes") {
ADD_FLAG("CFLAGS_CLI", "/D PHP_WIN32_DEBUG_HEAP");
@@ -15,7 +15,7 @@ if (PHP_CLI == "yes") {
}
if (PHP_CLI_WIN32 == "yes") {
- SAPI('cli_win32', 'cli_win32.c', 'php-win.exe');
+ SAPI('cli_win32', 'cli_win32.c php_cli_process_title.c ps_title.c', 'php-win.exe');
ADD_FLAG("LDFLAGS_CLI_WIN32", "/stack:8388608");
}
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index c01f370..ffb6a69 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -86,6 +86,9 @@
#include "php_cli_server.h"
#endif
+#include "ps_title.h"
+#include "php_cli_process_title.h"
+
#ifndef PHP_WIN32
# define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
@@ -478,6 +481,8 @@ ZEND_END_ARG_INFO()
static const zend_function_entry additional_functions[] = {
ZEND_FE(dl, arginfo_dl)
+ PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
+ PHP_FE(cli_get_process_title, NULL)
{NULL, NULL, NULL}
};
@@ -1200,6 +1205,7 @@ int main(int argc, char *argv[])
int argc = __argc;
char **argv = __argv;
#endif
+
int c;
int exit_status = SUCCESS;
int module_started = 0, sapi_started = 0;
@@ -1211,6 +1217,12 @@ int main(int argc, char *argv[])
int ini_ignore = 0;
sapi_module_struct *sapi_module = &cli_sapi_module;
+ /*
+ * Do not move this initialization. It needs to happen before argv is used
+ * in any way.
+ */
+ argv = save_ps_args(argc, argv);
+
cli_sapi_module.additional_functions = additional_functions;
#if defined(PHP_WIN32) && defined(_DEBUG) && defined(PHP_WIN32_DEBUG_HEAP)
@@ -1299,6 +1311,7 @@ int main(int argc, char *argv[])
#ifndef PHP_CLI_WIN32_NO_CONSOLE
case 'S':
sapi_module = &cli_server_sapi_module;
+ cli_server_sapi_module.additional_functions = server_additional_functions;
break;
#endif
case 'h': /* help & quit */
diff --git a/sapi/cli/php_cli_process_title.c b/sapi/cli/php_cli_process_title.c
new file mode 100644
index 0000000..8631f82
--- /dev/null
+++ b/sapi/cli/php_cli_process_title.c
@@ -0,0 +1,76 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Keyur Govande (kgovande@gmail.com) |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_cli_process_title.h"
+#include "ps_title.h"
+
+/* {{{ proto boolean cli_set_process_title(string arg)
+ Return a boolean to confirm if the process title was successfully changed or not */
+PHP_FUNCTION(cli_set_process_title)
+{
+ char *title = NULL;
+ int title_len;
+ int rc;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &title, &title_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ rc = set_ps_title(title);
+ if (rc == PS_TITLE_SUCCESS) {
+ RETURN_TRUE;
+ }
+
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "cli_set_process_title had an error: %s", ps_title_errno(rc));
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string cli_get_process_title(string arg)
+ Return a string with the current process title. NULL if error. */
+PHP_FUNCTION(cli_get_process_title)
+{
+ int length = 0;
+ const char* title = NULL;
+ int rc;
+
+ rc = get_ps_title(&length, &title);
+ if (rc != PS_TITLE_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "cli_get_process_title had an error: %s", ps_title_errno(rc));
+ RETURN_NULL();
+ }
+
+ RETURN_STRINGL(title, length, 1);
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/sapi/cli/php_cli_process_title.h b/sapi/cli/php_cli_process_title.h
new file mode 100644
index 0000000..62ef567
--- /dev/null
+++ b/sapi/cli/php_cli_process_title.h
@@ -0,0 +1,40 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Keyur Govande (kgovande@gmail.com) |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_PS_TITLE_HEADER
+#define PHP_PS_TITLE_HEADER
+
+ZEND_BEGIN_ARG_INFO(arginfo_cli_set_process_title, 0)
+ ZEND_ARG_INFO(0, title)
+ZEND_END_ARG_INFO()
+
+PHP_FUNCTION(cli_set_process_title);
+PHP_FUNCTION(cli_get_process_title);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index 28aba19..dfacdbd 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -103,6 +103,8 @@
#include "php_http_parser.h"
#include "php_cli_server.h"
+#include "php_cli_process_title.h"
+
#define OUTPUT_NOT_CHECKED -1
#define OUTPUT_IS_TTY 1
#define OUTPUT_NOT_TTY 0
@@ -423,6 +425,12 @@ zend_module_entry cli_server_module_entry = {
};
/* }}} */
+const zend_function_entry server_additional_functions[] = {
+ PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
+ PHP_FE(cli_get_process_title, NULL)
+ {NULL, NULL, NULL}
+};
+
static int sapi_cli_server_startup(sapi_module_struct *sapi_module) /* {{{ */
{
if (php_module_startup(sapi_module, &cli_server_module_entry, 1) == FAILURE) {
diff --git a/sapi/cli/php_cli_server.h b/sapi/cli/php_cli_server.h
index ed716f9..9a29626 100644
--- a/sapi/cli/php_cli_server.h
+++ b/sapi/cli/php_cli_server.h
@@ -23,6 +23,7 @@
#include "SAPI.h"
+extern const zend_function_entry server_additional_functions[];
extern sapi_module_struct cli_server_sapi_module;
extern int do_cli_server(int argc, char **argv TSRMLS_DC);
diff --git a/sapi/cli/ps_title.c b/sapi/cli/ps_title.c
new file mode 100644
index 0000000..610def7
--- /dev/null
+++ b/sapi/cli/ps_title.c
@@ -0,0 +1,384 @@
+/*
+ * PostgreSQL is released under the PostgreSQL License, a liberal Open Source
+ * license, similar to the BSD or MIT licenses.
+ * PostgreSQL Database Management System (formerly known as Postgres, then as
+ * Postgres95)
+ *
+ * Portions Copyright (c) 1996-2013, The PostgreSQL Global Development Group
+ *
+ * Portions Copyright (c) 1994, The Regents of the University of California
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without a written
+ * agreement is hereby granted, provided that the above copyright notice
+ * and this paragraph and the following two paragraphs appear in all copies.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
+ * EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
+ * "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * The following code is adopted from the PostgreSQL's ps_status(.h/.c).
+ */
+
+#include "ps_title.h"
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef PHP_WIN32
+#include "config.w32.h"
+#include <windows.h>
+#include <process.h>
+#else
+#include "php_config.h"
+extern char** environ;
+#endif
+
+#ifdef HAVE_SYS_PSTAT_H
+#include <sys/pstat.h> // for HP-UX
+#endif
+#ifdef HAVE_PS_STRINGS
+#include <machine/vmparam.h> // for old BSD
+#include <sys/exec.h>
+#endif
+#if defined(DARWIN)
+#include <crt_externs.h>
+#endif
+
+/*
+ * Ways of updating ps display:
+ *
+ * PS_USE_SETPROCTITLE
+ * use the function setproctitle(const char *, ...)
+ * (newer BSD systems)
+ * PS_USE_PSTAT
+ * use the pstat(PSTAT_SETCMD, )
+ * (HPUX)
+ * PS_USE_PS_STRINGS
+ * assign PS_STRINGS->ps_argvstr = "string"
+ * (some BSD systems)
+ * PS_USE_CHANGE_ARGV
+ * assign argv[0] = "string"
+ * (some other BSD systems)
+ * PS_USE_CLOBBER_ARGV
+ * write over the argv and environment area
+ * (Linux and most SysV-like systems)
+ * PS_USE_WIN32
+ * push the string out as the name of a Windows event
+ * PS_USE_NONE
+ * don't update ps display
+ * (This is the default, as it is safest.)
+ */
+#if defined(HAVE_SETPROCTITLE)
+#define PS_USE_SETPROCTITLE
+#elif defined(HAVE_SYS_PSTAT_H) && defined(PSTAT_SETCMD)
+#define PS_USE_PSTAT
+#elif defined(HAVE_PS_STRINGS)
+#define PS_USE_PS_STRINGS
+#elif defined(BSD) && !defined(DARWIN)
+#define PS_USE_CHANGE_ARGV
+#elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__osf__) || defined(DARWIN)
+#define PS_USE_CLOBBER_ARGV
+#elif defined(PHP_WIN32)
+#define PS_USE_WIN32
+#else
+#define PS_USE_NONE
+#endif
+
+/* Different systems want the buffer padded differently */
+#if defined(_AIX) || defined(__linux__) || defined(DARWIN)
+#define PS_PADDING '\0'
+#else
+#define PS_PADDING ' '
+#endif
+
+#ifndef PS_USE_CLOBBER_ARGV
+#define PS_BUFFER_SIZE 256
+static char ps_buffer[PS_BUFFER_SIZE];
+static const size_t ps_buffer_size = PS_BUFFER_SIZE;
+#else
+static char *ps_buffer; /* will point to argv area */
+static size_t ps_buffer_size; /* space determined at run time */
+#endif
+
+static size_t ps_buffer_cur_len; /* actual string length in ps_buffer */
+
+/* save the original argv[] location here */
+static int save_argc;
+static char** save_argv;
+
+
+/*
+ * Call this early in startup to save the original argc/argv values.
+ * If needed, we make a copy of the original argv[] array to preserve it
+ * from being clobbered by subsequent ps_display actions.
+ *
+ * (The original argv[] will not be overwritten by this routine.
+ * Also, the physical location of the environment strings may be moved,
+ * so this should be called before any code that might try to hang onto a
+ * getenv() result.)
+ */
+char** save_ps_args(int argc, char** argv)
+{
+ save_argc = argc;
+ save_argv = argv;
+
+#if defined(PS_USE_CLOBBER_ARGV)
+ /*
+ * If we're going to overwrite the argv area, count the available space.
+ * Also move the environment to make additional room.
+ */
+ {
+ char* end_of_area = NULL;
+ int non_contiguous_area = 0;
+ char** new_environ;
+ int i;
+
+ /*
+ * check for contiguous argv strings
+ */
+ for (i = 0; (non_contiguous_area == 0) && (i < argc); i++)
+ {
+ if (i != 0 && end_of_area + 1 != argv[i])
+ non_contiguous_area = 1;
+ end_of_area = argv[i] + strlen(argv[i]);
+ }
+
+ /*
+ * check for contiguous environ strings following argv
+ */
+ for (i = 0; (non_contiguous_area == 0) && (environ[i] != NULL); i++)
+ {
+ if (end_of_area + 1 != environ[i])
+ non_contiguous_area = 1;
+ end_of_area = environ[i] + strlen(environ[i]);
+ }
+
+ if (non_contiguous_area != 0)
+ goto clobber_error;
+
+ ps_buffer = argv[0];
+ ps_buffer_size = end_of_area - argv[0];
+
+ /*
+ * move the environment out of the way
+ */
+ new_environ = (char **) malloc((i + 1) * sizeof(char *));
+ for (i = 0; environ[i] != NULL; i++)
+ {
+ new_environ[i] = strdup(environ[i]);
+ if (!new_environ[i])
+ goto clobber_error;
+ }
+ new_environ[i] = NULL;
+ environ = new_environ;
+
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+ /*
+ * If we're going to change the original argv[] then make a copy for
+ * argument parsing purposes.
+ *
+ * (NB: do NOT think to remove the copying of argv[]!
+ * On some platforms, getopt() keeps pointers into the argv array, and
+ * will get horribly confused when it is re-called to analyze a subprocess'
+ * argument string if the argv storage has been clobbered meanwhile.
+ * Other platforms have other dependencies on argv[].)
+ */
+ {
+ char** new_argv;
+ int i;
+
+ new_argv = (char **) malloc((argc + 1) * sizeof(char *));
+ for (i = 0; i < argc; i++)
+ {
+ new_argv[i] = strdup(argv[i]);
+ if (!new_argv[i])
+ goto clobber_error;
+ }
+ new_argv[argc] = NULL;
+
+#if defined(DARWIN)
+ /*
+ * Darwin (and perhaps other NeXT-derived platforms?) has a static
+ * copy of the argv pointer, which we may fix like so:
+ */
+ *_NSGetArgv() = new_argv;
+#endif
+
+ argv = new_argv;
+
+ }
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CLOBBER_ARGV)
+ {
+ /* make extra argv slots point at end_of_area (a NUL) */
+ int i;
+ for (i = 1; i < save_argc; i++)
+ save_argv[i] = ps_buffer + ps_buffer_size;
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#ifdef PS_USE_CHANGE_ARGV
+ save_argv[0] = ps_buffer; // ps_buffer here is a static const array of size PS_BUFFER_SIZE
+ save_argv[1] = NULL;
+#endif /* PS_USE_CHANGE_ARGV */
+
+ return argv;
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+clobber_error:
+ /* probably can't happen?!
+ * if we ever get here, argv still points to originally passed
+ * in argument
+ */
+ ps_buffer = NULL;
+ ps_buffer_size = 0;
+ return argv;
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+}
+
+/*
+ * Returns PS_TITLE_SUCCESS if the OS supports this functionality
+ * and the init function was called.
+ * Otherwise returns NOT_AVAILABLE or NOT_INITIALIZED
+ */
+int is_ps_title_available()
+{
+#ifdef PS_USE_NONE
+ return PS_TITLE_NOT_AVAILABLE; // disabled functionality
+#endif
+
+ if (!save_argv)
+ return PS_TITLE_NOT_INITIALIZED;
+
+#ifdef PS_USE_CLOBBER_ARGV
+ if (!ps_buffer)
+ return PS_TITLE_BUFFER_NOT_AVAILABLE;
+#endif /* PS_USE_CLOBBER_ARGV */
+
+ return PS_TITLE_SUCCESS;
+}
+
+/*
+ * Convert error codes into error strings
+ */
+const char* ps_title_errno(int rc)
+{
+ switch(rc)
+ {
+ case PS_TITLE_SUCCESS:
+ return "Success";
+
+ case PS_TITLE_NOT_AVAILABLE:
+ return "Not available on this OS";
+
+ case PS_TITLE_NOT_INITIALIZED:
+ return "Not initialized correctly";
+
+ case PS_TITLE_BUFFER_NOT_AVAILABLE:
+ return "Buffer not contiguous";
+ }
+
+ return "Unknown error code";
+}
+
+/*
+ * Set a new process title.
+ * Returns the appropriate error code if if there's an error
+ * (like the functionality is compile time disabled, or the
+ * save_ps_args() was not called.
+ * Else returns 0 on success.
+ */
+int set_ps_title(const char* title)
+{
+ int rc = is_ps_title_available();
+ if (rc != PS_TITLE_SUCCESS)
+ return rc;
+
+ strncpy(ps_buffer, title, ps_buffer_size);
+ ps_buffer[ps_buffer_size - 1] = '\0';
+ ps_buffer_cur_len = strlen(ps_buffer);
+
+#ifdef PS_USE_SETPROCTITLE
+ setproctitle("%s", ps_buffer);
+#endif
+
+#ifdef PS_USE_PSTAT
+ {
+ union pstun pst;
+
+ pst.pst_command = ps_buffer;
+ pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
+ }
+#endif /* PS_USE_PSTAT */
+
+#ifdef PS_USE_PS_STRINGS
+ PS_STRINGS->ps_nargvstr = 1;
+ PS_STRINGS->ps_argvstr = ps_buffer;
+#endif /* PS_USE_PS_STRINGS */
+
+#ifdef PS_USE_CLOBBER_ARGV
+ /* pad unused memory */
+ if (ps_buffer_cur_len < ps_buffer_size)
+ {
+ memset(ps_buffer + ps_buffer_cur_len, PS_PADDING,
+ ps_buffer_size - ps_buffer_cur_len);
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#ifdef PS_USE_WIN32
+ {
+ /*
+ * Win32 does not support showing any changed arguments. To make it at
+ * all possible to track which backend is doing what, we create a
+ * named object that can be viewed with for example Process Explorer.
+ */
+ static HANDLE ident_handle = INVALID_HANDLE_VALUE;
+ char name[PS_BUFFER_SIZE + 32];
+
+ if (ident_handle != INVALID_HANDLE_VALUE)
+ CloseHandle(ident_handle);
+
+ sprintf(name, "php-process(%d): %s", _getpid(), ps_buffer);
+
+ ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
+ }
+#endif /* PS_USE_WIN32 */
+
+ return PS_TITLE_SUCCESS;
+}
+
+/*
+ * Returns the current ps_buffer value into string. On some platforms
+ * the string will not be null-terminated, so return the effective
+ * length into *displen.
+ * The return code indicates the error.
+ */
+int get_ps_title(int *displen, const char** string)
+{
+ int rc = is_ps_title_available();
+ if (rc != PS_TITLE_SUCCESS)
+ return rc;
+
+ *displen = ps_buffer_cur_len;
+ *string = ps_buffer;
+ return PS_TITLE_SUCCESS;
+}
+
diff --git a/sapi/cli/ps_title.h b/sapi/cli/ps_title.h
new file mode 100644
index 0000000..00eddfd
--- /dev/null
+++ b/sapi/cli/ps_title.h
@@ -0,0 +1,39 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Keyur Govande <kgovande@gmail.com> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef PS_TITLE_HEADER
+#define PS_TITLE_HEADER
+
+#define PS_TITLE_SUCCESS 0
+#define PS_TITLE_NOT_AVAILABLE 1
+#define PS_TITLE_NOT_INITIALIZED 2
+#define PS_TITLE_BUFFER_NOT_AVAILABLE 3
+
+extern char** save_ps_args(int argc, char** argv);
+
+extern int set_ps_title(const char* new_str);
+
+extern int get_ps_title(int* displen, const char** string);
+
+extern const char* ps_title_errno(int rc);
+
+extern int is_ps_title_available();
+
+#endif // PS_TITLE_HEADER
diff --git a/sapi/cli/tests/cli_process_title.phpt b/sapi/cli/tests/cli_process_title.phpt
new file mode 100644
index 0000000..8ee2894
--- /dev/null
+++ b/sapi/cli/tests/cli_process_title.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Check cli_process_title support
+--SKIPIF--
+<?php
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') print "skip";
+?>
+--FILE--
+<?php
+echo "*** Testing setting the process title ***\n";
+
+$set_title = $original_title = "test title for php cli";
+$pid = getmypid();
+
+if (cli_set_process_title($original_title) === true)
+ echo "Successfully set title\n";
+
+$ps_output = shell_exec("ps -p $pid -o command | tail -n 1");
+if ($ps_output === null) {
+ echo "ps failed\n";
+ die();
+}
+
+$load_title = trim($ps_output);
+if (strpos(strtoupper(substr(PHP_OS, 0, 13)), "BSD") !== false)
+{
+ // Fix title for BSD
+ $set_title = "php: $original_title (php)";
+}
+
+if ($load_title == $set_title)
+ echo "Successfully verified title using ps\n";
+else
+ echo "Actually loaded from ps: $load_title\n";
+
+$read_title = cli_get_process_title();
+if ($read_title == $original_title)
+ echo "Successfully verified title using get\n";
+else
+ echo "Actually loaded from get: $read_title\n";
+
+?>
+--EXPECTF--
+*** Testing setting the process title ***
+Successfully set title
+Successfully verified title using ps
+Successfully verified title using get
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.