mirror of
https://github.com/php/php-src.git
synced 2024-12-04 15:23:44 +08:00
11accb5cdf
* Include from build dir first This fixes out of tree builds by ensuring that configure artifacts are included from the build dir. Before, out of tree builds would preferably include files from the src dir, as the include path was defined as follows (ignoring includes from ext/ and sapi/) : -I$(top_builddir)/main -I$(top_srcdir) -I$(top_builddir)/TSRM -I$(top_builddir)/Zend -I$(top_srcdir)/main -I$(top_srcdir)/Zend -I$(top_srcdir)/TSRM -I$(top_builddir)/ As a result, an out of tree build would include configure artifacts such as `main/php_config.h` from the src dir. After this change, the include path is defined as follows: -I$(top_builddir)/main -I$(top_builddir) -I$(top_srcdir)/main -I$(top_srcdir) -I$(top_builddir)/TSRM -I$(top_builddir)/Zend -I$(top_srcdir)/Zend -I$(top_srcdir)/TSRM * Fix extension include path for out of tree builds * Include config.h with the brackets form `#include "config.h"` searches in the directory containing the including-file before any other include path. This can include the wrong config.h when building out of tree and a config.h exists in the source tree. Using `#include <config.h>` uses exclusively the include path, and gives priority to the build dir.
1339 lines
28 KiB
C
1339 lines
28 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 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: |
|
|
| https://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: Kristian Koehntopp <kris@koehntopp.de> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include "php.h"
|
|
#include <unistd.h>
|
|
#include "ext/standard/info.h"
|
|
#include "php_posix.h"
|
|
|
|
#ifdef HAVE_POSIX
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include <sys/resource.h>
|
|
#include <sys/utsname.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <signal.h>
|
|
#include <sys/times.h>
|
|
#include <errno.h>
|
|
#include <grp.h>
|
|
#include <pwd.h>
|
|
#ifdef MAJOR_IN_MKDEV
|
|
# include <sys/mkdev.h>
|
|
#elif defined(MAJOR_IN_SYSMACROS)
|
|
# include <sys/sysmacros.h>
|
|
#endif
|
|
|
|
#include "posix_arginfo.h"
|
|
|
|
ZEND_DECLARE_MODULE_GLOBALS(posix)
|
|
static PHP_MINFO_FUNCTION(posix);
|
|
|
|
/* {{{ PHP_MINFO_FUNCTION */
|
|
static PHP_MINFO_FUNCTION(posix)
|
|
{
|
|
php_info_print_table_start();
|
|
php_info_print_table_row(2, "POSIX support", "enabled");
|
|
php_info_print_table_end();
|
|
}
|
|
/* }}} */
|
|
|
|
static PHP_GINIT_FUNCTION(posix) /* {{{ */
|
|
{
|
|
#if defined(COMPILE_DL_POSIX) && defined(ZTS)
|
|
ZEND_TSRMLS_CACHE_UPDATE();
|
|
#endif
|
|
posix_globals->last_error = 0;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ PHP_MINIT_FUNCTION(posix) */
|
|
static PHP_MINIT_FUNCTION(posix)
|
|
{
|
|
register_posix_symbols(module_number);
|
|
|
|
return SUCCESS;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ posix_module_entry */
|
|
zend_module_entry posix_module_entry = {
|
|
STANDARD_MODULE_HEADER,
|
|
"posix",
|
|
ext_functions,
|
|
PHP_MINIT(posix),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
PHP_MINFO(posix),
|
|
PHP_POSIX_VERSION,
|
|
PHP_MODULE_GLOBALS(posix),
|
|
PHP_GINIT(posix),
|
|
NULL,
|
|
NULL,
|
|
STANDARD_MODULE_PROPERTIES_EX
|
|
};
|
|
/* }}} */
|
|
|
|
#ifdef COMPILE_DL_POSIX
|
|
#ifdef ZTS
|
|
ZEND_TSRMLS_CACHE_DEFINE()
|
|
#endif
|
|
ZEND_GET_MODULE(posix)
|
|
#endif
|
|
|
|
#define PHP_POSIX_RETURN_LONG_FUNC(func_name) \
|
|
ZEND_PARSE_PARAMETERS_NONE(); \
|
|
RETURN_LONG(func_name());
|
|
|
|
#define PHP_POSIX_SINGLE_ARG_FUNC(func_name) \
|
|
zend_long val; \
|
|
ZEND_PARSE_PARAMETERS_START(1, 1) \
|
|
Z_PARAM_LONG(val) \
|
|
ZEND_PARSE_PARAMETERS_END(); \
|
|
if (func_name(val) < 0) { \
|
|
POSIX_G(last_error) = errno; \
|
|
RETURN_FALSE; \
|
|
} \
|
|
RETURN_TRUE;
|
|
|
|
/* {{{ Send a signal to a process (POSIX.1, 3.3.2) */
|
|
|
|
PHP_FUNCTION(posix_kill)
|
|
{
|
|
zend_long pid, sig;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_LONG(pid)
|
|
Z_PARAM_LONG(sig)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (kill(pid, sig) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the current process id (POSIX.1, 4.1.1) */
|
|
PHP_FUNCTION(posix_getpid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getpid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the parent process id (POSIX.1, 4.1.1) */
|
|
PHP_FUNCTION(posix_getppid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getppid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the current user id (POSIX.1, 4.2.1) */
|
|
PHP_FUNCTION(posix_getuid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getuid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the current group id (POSIX.1, 4.2.1) */
|
|
PHP_FUNCTION(posix_getgid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getgid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the current effective user id (POSIX.1, 4.2.1) */
|
|
PHP_FUNCTION(posix_geteuid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(geteuid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the current effective group id (POSIX.1, 4.2.1) */
|
|
PHP_FUNCTION(posix_getegid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getegid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Set user id (POSIX.1, 4.2.2) */
|
|
PHP_FUNCTION(posix_setuid)
|
|
{
|
|
PHP_POSIX_SINGLE_ARG_FUNC(setuid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Set group id (POSIX.1, 4.2.2) */
|
|
PHP_FUNCTION(posix_setgid)
|
|
{
|
|
PHP_POSIX_SINGLE_ARG_FUNC(setgid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Set effective user id */
|
|
#ifdef HAVE_SETEUID
|
|
PHP_FUNCTION(posix_seteuid)
|
|
{
|
|
PHP_POSIX_SINGLE_ARG_FUNC(seteuid);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Set effective group id */
|
|
#ifdef HAVE_SETEGID
|
|
PHP_FUNCTION(posix_setegid)
|
|
{
|
|
PHP_POSIX_SINGLE_ARG_FUNC(setegid);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Get supplementary group id's (POSIX.1, 4.2.3) */
|
|
#ifdef HAVE_GETGROUPS
|
|
PHP_FUNCTION(posix_getgroups)
|
|
{
|
|
gid_t *gidlist;
|
|
int result;
|
|
int i;
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
/* MacOS may return more than NGROUPS_MAX groups.
|
|
* Fetch the actual number of groups and create an appropriate allocation. */
|
|
if ((result = getgroups(0, NULL)) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
gidlist = emalloc(sizeof(gid_t) * result);
|
|
if ((result = getgroups(result, gidlist)) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
efree(gidlist);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
array_init(return_value);
|
|
|
|
for (i=0; i<result; i++) {
|
|
add_next_index_long(return_value, gidlist[i]);
|
|
}
|
|
efree(gidlist);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Get user name (POSIX.1, 4.2.4) */
|
|
#ifdef HAVE_GETLOGIN
|
|
PHP_FUNCTION(posix_getlogin)
|
|
{
|
|
char *p;
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
if (NULL == (p = getlogin())) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_STRING(p);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Get current process group id (POSIX.1, 4.3.1) */
|
|
PHP_FUNCTION(posix_getpgrp)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(getpgrp);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Create session and set process group id (POSIX.1, 4.3.2) */
|
|
#ifdef HAVE_SETSID
|
|
PHP_FUNCTION(posix_setsid)
|
|
{
|
|
PHP_POSIX_RETURN_LONG_FUNC(setsid);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Set process group id for job control (POSIX.1, 4.3.3) */
|
|
PHP_FUNCTION(posix_setpgid)
|
|
{
|
|
zend_long pid, pgid;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_LONG(pid)
|
|
Z_PARAM_LONG(pgid)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (setpgid(pid, pgid) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally) */
|
|
#ifdef HAVE_GETPGID
|
|
PHP_FUNCTION(posix_getpgid)
|
|
{
|
|
zend_long val;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(val)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if ((val = getpgid(val)) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(val);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally) */
|
|
#ifdef HAVE_GETSID
|
|
PHP_FUNCTION(posix_getsid)
|
|
{
|
|
zend_long val;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(val)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if ((val = getsid(val)) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(val);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Get system name (POSIX.1, 4.4.1) */
|
|
PHP_FUNCTION(posix_uname)
|
|
{
|
|
struct utsname u;
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
if (uname(&u) < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
array_init(return_value);
|
|
|
|
add_assoc_string(return_value, "sysname", u.sysname);
|
|
add_assoc_string(return_value, "nodename", u.nodename);
|
|
add_assoc_string(return_value, "release", u.release);
|
|
add_assoc_string(return_value, "version", u.version);
|
|
add_assoc_string(return_value, "machine", u.machine);
|
|
|
|
#if defined(_GNU_SOURCE) && defined(HAVE_STRUCT_UTSNAME_DOMAINNAME)
|
|
add_assoc_string(return_value, "domainname", u.domainname);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
/* POSIX.1, 4.5.1 time() - Get System Time
|
|
already covered by PHP
|
|
*/
|
|
|
|
/* {{{ Get process times (POSIX.1, 4.5.2) */
|
|
PHP_FUNCTION(posix_times)
|
|
{
|
|
struct tms t;
|
|
clock_t ticks;
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
if ((ticks = times(&t)) == -1) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
array_init(return_value);
|
|
|
|
add_assoc_long(return_value, "ticks", ticks); /* clock ticks */
|
|
add_assoc_long(return_value, "utime", t.tms_utime); /* user time */
|
|
add_assoc_long(return_value, "stime", t.tms_stime); /* system time */
|
|
add_assoc_long(return_value, "cutime", t.tms_cutime); /* user time of children */
|
|
add_assoc_long(return_value, "cstime", t.tms_cstime); /* system time of children */
|
|
}
|
|
/* }}} */
|
|
|
|
/* POSIX.1, 4.6.1 getenv() - Environment Access
|
|
already covered by PHP
|
|
*/
|
|
|
|
/* {{{ Generate terminal path name (POSIX.1, 4.7.1) */
|
|
#ifdef HAVE_CTERMID
|
|
PHP_FUNCTION(posix_ctermid)
|
|
{
|
|
char buffer[L_ctermid];
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
if (NULL == ctermid(buffer)) {
|
|
/* Found no documentation how the defined behaviour is when this
|
|
* function fails
|
|
*/
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_STRING(buffer);
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* Checks if the provides resource is a stream and if it provides a file descriptor */
|
|
static zend_result php_posix_stream_get_fd(zval *zfp, zend_long *fd) /* {{{ */
|
|
{
|
|
php_stream *stream;
|
|
|
|
php_stream_from_zval_no_verify(stream, zfp);
|
|
|
|
if (stream == NULL) {
|
|
return FAILURE;
|
|
}
|
|
|
|
/* get the fd.
|
|
* NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting.
|
|
* It is only used here so that the buffered data warning is not displayed.
|
|
*/
|
|
if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL) == SUCCESS) {
|
|
php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)fd, 0);
|
|
} else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL) == SUCCESS) {
|
|
php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)fd, 0);
|
|
} else {
|
|
php_error_docref(NULL, E_WARNING, "Could not use stream of type '%s'",
|
|
stream->ops->label);
|
|
return FAILURE;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Determine terminal device name (POSIX.1, 4.7.2) */
|
|
PHP_FUNCTION(posix_ttyname)
|
|
{
|
|
zval *z_fd;
|
|
char *p;
|
|
zend_long fd = 0;
|
|
#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
|
|
zend_long buflen;
|
|
int err;
|
|
#endif
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_ZVAL(z_fd)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
|
|
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
} else {
|
|
if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
|
|
php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be of type int|resource, %s given",
|
|
zend_zval_value_name(z_fd));
|
|
fd = zval_get_long(z_fd);
|
|
}
|
|
/* fd must fit in an int and be positive */
|
|
if (fd < 0 || fd > INT_MAX) {
|
|
php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be between 0 and %d", INT_MAX);
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
|
|
buflen = sysconf(_SC_TTY_NAME_MAX);
|
|
if (buflen < 1) {
|
|
buflen = 32;
|
|
}
|
|
#if ZEND_DEBUG
|
|
/* Test retry logic */
|
|
buflen = 1;
|
|
#endif
|
|
p = emalloc(buflen);
|
|
|
|
try_again:
|
|
err = ttyname_r(fd, p, buflen);
|
|
if (err) {
|
|
if (err == ERANGE) {
|
|
buflen *= 2;
|
|
p = erealloc(p, buflen);
|
|
goto try_again;
|
|
}
|
|
POSIX_G(last_error) = err;
|
|
efree(p);
|
|
RETURN_FALSE;
|
|
}
|
|
RETVAL_STRING(p);
|
|
efree(p);
|
|
#else
|
|
if (NULL == (p = ttyname(fd))) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_STRING(p);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Determine if filedesc is a tty (POSIX.1, 4.7.1) */
|
|
PHP_FUNCTION(posix_isatty)
|
|
{
|
|
zval *z_fd;
|
|
zend_long fd = 0;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_ZVAL(z_fd)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
|
|
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
} else {
|
|
if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
|
|
php_error_docref(NULL, E_WARNING, "Argument #1 ($file_descriptor) must be of type int|resource, %s given",
|
|
zend_zval_value_name(z_fd));
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
|
|
/* A valid file descriptor must fit in an int and be positive */
|
|
if (fd < 0 || fd > INT_MAX) {
|
|
POSIX_G(last_error) = EBADF;
|
|
RETURN_FALSE;
|
|
}
|
|
if (isatty(fd)) {
|
|
RETURN_TRUE;
|
|
} else {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
/* }}} */
|
|
|
|
/*
|
|
POSIX.1, 4.8.1 sysconf()
|
|
POSIX.1, 5.7.1 pathconf(), fpathconf()
|
|
|
|
POSIX.1, 5.1.2 opendir(), readdir(), rewinddir(), closedir()
|
|
POSIX.1, 5.2.1 chdir()
|
|
already supported by PHP
|
|
*/
|
|
|
|
/* {{{ Get working directory pathname (POSIX.1, 5.2.2) */
|
|
PHP_FUNCTION(posix_getcwd)
|
|
{
|
|
char buffer[MAXPATHLEN];
|
|
char *p;
|
|
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
p = VCWD_GETCWD(buffer, MAXPATHLEN);
|
|
if (!p) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_STRING(buffer);
|
|
}
|
|
/* }}} */
|
|
|
|
/*
|
|
POSIX.1, 5.3.x open(), creat(), umask()
|
|
POSIX.1, 5.4.1 link()
|
|
already supported by PHP.
|
|
*/
|
|
|
|
/* {{{ Make a FIFO special file (POSIX.1, 5.4.2) */
|
|
#ifdef HAVE_MKFIFO
|
|
PHP_FUNCTION(posix_mkfifo)
|
|
{
|
|
zend_string *path;
|
|
zend_long mode;
|
|
int result;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_PATH_STR(path)
|
|
Z_PARAM_LONG(mode)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (php_check_open_basedir_ex(ZSTR_VAL(path), 0)) {
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
result = mkfifo(ZSTR_VAL(path), mode);
|
|
if (result < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* {{{ Make a special or ordinary file (POSIX.1) */
|
|
#ifdef HAVE_MKNOD
|
|
PHP_FUNCTION(posix_mknod)
|
|
{
|
|
zend_string *path;
|
|
zend_long mode;
|
|
zend_long major = 0, minor = 0;
|
|
int result;
|
|
dev_t php_dev = 0;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 4)
|
|
Z_PARAM_PATH_STR(path)
|
|
Z_PARAM_LONG(mode)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_LONG(major)
|
|
Z_PARAM_LONG(minor)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (php_check_open_basedir_ex(ZSTR_VAL(path), 0)) {
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if ((mode & S_IFCHR) || (mode & S_IFBLK)) {
|
|
if (major == 0) {
|
|
zend_argument_value_error(3, "cannot be 0 for the POSIX_S_IFCHR and POSIX_S_IFBLK modes");
|
|
RETURN_THROWS();
|
|
} else {
|
|
#ifdef HAVE_MAKEDEV
|
|
php_dev = makedev(major, minor);
|
|
#else
|
|
php_error_docref(NULL, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
result = mknod(ZSTR_VAL(path), mode, php_dev);
|
|
if (result < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
#endif
|
|
/* }}} */
|
|
|
|
/* Takes a pointer to posix group and a pointer to an already initialized ZVAL
|
|
* array container and fills the array with the posix group member data. */
|
|
int php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ */
|
|
{
|
|
zval array_members;
|
|
int count;
|
|
|
|
if (NULL == g)
|
|
return 0;
|
|
|
|
if (array_group == NULL || Z_TYPE_P(array_group) != IS_ARRAY)
|
|
return 0;
|
|
|
|
array_init(&array_members);
|
|
|
|
add_assoc_string(array_group, "name", g->gr_name);
|
|
if (g->gr_passwd) {
|
|
add_assoc_string(array_group, "passwd", g->gr_passwd);
|
|
} else {
|
|
add_assoc_null(array_group, "passwd");
|
|
}
|
|
for (count = 0;; count++) {
|
|
/* gr_mem entries may be misaligned on macos. */
|
|
char *gr_mem;
|
|
memcpy(&gr_mem, &g->gr_mem[count], sizeof(char *));
|
|
if (!gr_mem) {
|
|
break;
|
|
}
|
|
|
|
add_next_index_string(&array_members, gr_mem);
|
|
}
|
|
zend_hash_str_update(Z_ARRVAL_P(array_group), "members", sizeof("members")-1, &array_members);
|
|
add_assoc_long(array_group, "gid", g->gr_gid);
|
|
return 1;
|
|
}
|
|
/* }}} */
|
|
|
|
/*
|
|
POSIX.1, 5.5.1 unlink()
|
|
POSIX.1, 5.5.2 rmdir()
|
|
POSIX.1, 5.5.3 rename()
|
|
POSIX.1, 5.6.x stat(), chmod(), utime() already supported by PHP.
|
|
*/
|
|
|
|
/* {{{ Determine accessibility of a file (POSIX.1 5.6.3) */
|
|
PHP_FUNCTION(posix_access)
|
|
{
|
|
zend_long mode = 0;
|
|
size_t filename_len, ret;
|
|
char *filename, *path;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
|
Z_PARAM_PATH(filename, filename_len)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_LONG(mode)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
path = expand_filepath(filename, NULL);
|
|
if (!path) {
|
|
POSIX_G(last_error) = EIO;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (php_check_open_basedir_ex(path, 0)) {
|
|
efree(path);
|
|
POSIX_G(last_error) = EPERM;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ret = access(path, mode);
|
|
efree(path);
|
|
|
|
if (ret) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
|
|
#ifdef HAVE_EACCESS
|
|
PHP_FUNCTION(posix_eaccess)
|
|
{
|
|
zend_long mode = 0;
|
|
size_t filename_len, ret;
|
|
char *filename, *path;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
|
Z_PARAM_PATH(filename, filename_len)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_LONG(mode)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
path = expand_filepath(filename, NULL);
|
|
if (!path) {
|
|
zend_argument_value_error(1, "cannot be empty");
|
|
RETURN_THROWS();
|
|
}
|
|
|
|
if (php_check_open_basedir_ex(path, 0)) {
|
|
efree(path);
|
|
POSIX_G(last_error) = EPERM;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ret = eaccess(path, mode);
|
|
efree(path);
|
|
|
|
if (ret) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
#endif
|
|
|
|
/* }}} */
|
|
|
|
/*
|
|
POSIX.1, 6.x most I/O functions already supported by PHP.
|
|
POSIX.1, 7.x tty functions, TODO
|
|
POSIX.1, 8.x interactions with other C language functions
|
|
POSIX.1, 9.x system database access
|
|
*/
|
|
|
|
/* {{{ Group database access (POSIX.1, 9.2.1) */
|
|
PHP_FUNCTION(posix_getgrnam)
|
|
{
|
|
char *name;
|
|
struct group *g;
|
|
size_t name_len;
|
|
#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
struct group gbuf;
|
|
long buflen;
|
|
char *buf;
|
|
int err;
|
|
#endif
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_STRING(name, name_len)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
if (buflen < 1) {
|
|
buflen = 1024;
|
|
}
|
|
#if ZEND_DEBUG
|
|
/* Test retry logic */
|
|
buflen = 1;
|
|
#endif
|
|
buf = emalloc(buflen);
|
|
try_again:
|
|
g = &gbuf;
|
|
|
|
err = getgrnam_r(name, g, buf, buflen, &g);
|
|
if (err || g == NULL) {
|
|
if (err == ERANGE) {
|
|
buflen *= 2;
|
|
buf = erealloc(buf, buflen);
|
|
goto try_again;
|
|
}
|
|
POSIX_G(last_error) = err;
|
|
efree(buf);
|
|
RETURN_FALSE;
|
|
}
|
|
#else
|
|
if (NULL == (g = getgrnam(name))) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
#endif
|
|
array_init(return_value);
|
|
|
|
if (!php_posix_group_to_array(g, return_value)) {
|
|
zend_array_destroy(Z_ARR_P(return_value));
|
|
php_error_docref(NULL, E_WARNING, "Unable to convert posix group to array");
|
|
RETVAL_FALSE;
|
|
}
|
|
#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
efree(buf);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Group database access (POSIX.1, 9.2.1) */
|
|
PHP_FUNCTION(posix_getgrgid)
|
|
{
|
|
zend_long gid;
|
|
#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
int err;
|
|
struct group _g;
|
|
struct group *retgrptr = NULL;
|
|
long grbuflen;
|
|
char *grbuf;
|
|
#endif
|
|
struct group *g;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(gid)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
|
|
grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
|
|
if (grbuflen < 1) {
|
|
grbuflen = 1024;
|
|
}
|
|
#if ZEND_DEBUG
|
|
/* Test retry logic */
|
|
grbuflen = 1;
|
|
#endif
|
|
|
|
grbuf = emalloc(grbuflen);
|
|
|
|
try_again:
|
|
err = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
|
|
if (err || retgrptr == NULL) {
|
|
if (err == ERANGE) {
|
|
grbuflen *= 2;
|
|
grbuf = erealloc(grbuf, grbuflen);
|
|
goto try_again;
|
|
}
|
|
POSIX_G(last_error) = err;
|
|
efree(grbuf);
|
|
RETURN_FALSE;
|
|
}
|
|
g = &_g;
|
|
#else
|
|
if (NULL == (g = getgrgid(gid))) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
#endif
|
|
array_init(return_value);
|
|
|
|
if (!php_posix_group_to_array(g, return_value)) {
|
|
zend_array_destroy(Z_ARR_P(return_value));
|
|
php_error_docref(NULL, E_WARNING, "Unable to convert posix group struct to array");
|
|
RETVAL_FALSE;
|
|
}
|
|
#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
|
|
efree(grbuf);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
int php_posix_passwd_to_array(struct passwd *pw, zval *return_value) /* {{{ */
|
|
{
|
|
if (NULL == pw)
|
|
return 0;
|
|
if (NULL == return_value || Z_TYPE_P(return_value) != IS_ARRAY)
|
|
return 0;
|
|
|
|
add_assoc_string(return_value, "name", pw->pw_name);
|
|
add_assoc_string(return_value, "passwd", pw->pw_passwd);
|
|
add_assoc_long (return_value, "uid", pw->pw_uid);
|
|
add_assoc_long (return_value, "gid", pw->pw_gid);
|
|
add_assoc_string(return_value, "gecos", pw->pw_gecos);
|
|
add_assoc_string(return_value, "dir", pw->pw_dir);
|
|
add_assoc_string(return_value, "shell", pw->pw_shell);
|
|
return 1;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ User database access (POSIX.1, 9.2.2) */
|
|
PHP_FUNCTION(posix_getpwnam)
|
|
{
|
|
struct passwd *pw;
|
|
char *name;
|
|
size_t name_len;
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
|
|
struct passwd pwbuf;
|
|
long buflen;
|
|
char *buf;
|
|
int err;
|
|
#endif
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_STRING(name, name_len)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
|
|
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
if (buflen < 1) {
|
|
buflen = 1024;
|
|
}
|
|
#if ZEND_DEBUG
|
|
/* Test retry logic */
|
|
buflen = 1;
|
|
#endif
|
|
buf = emalloc(buflen);
|
|
|
|
try_again:
|
|
pw = &pwbuf;
|
|
err = getpwnam_r(name, pw, buf, buflen, &pw);
|
|
if (err || pw == NULL) {
|
|
if (err == ERANGE) {
|
|
buflen *= 2;
|
|
buf = erealloc(buf, buflen);
|
|
goto try_again;
|
|
}
|
|
efree(buf);
|
|
POSIX_G(last_error) = err;
|
|
RETURN_FALSE;
|
|
}
|
|
#else
|
|
if (NULL == (pw = getpwnam(name))) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
#endif
|
|
array_init(return_value);
|
|
|
|
if (!php_posix_passwd_to_array(pw, return_value)) {
|
|
zend_array_destroy(Z_ARR_P(return_value));
|
|
php_error_docref(NULL, E_WARNING, "Unable to convert posix passwd struct to array");
|
|
RETVAL_FALSE;
|
|
}
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
|
|
efree(buf);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ User database access (POSIX.1, 9.2.2) */
|
|
PHP_FUNCTION(posix_getpwuid)
|
|
{
|
|
zend_long uid;
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
|
|
struct passwd _pw;
|
|
struct passwd *retpwptr = NULL;
|
|
long pwbuflen;
|
|
char *pwbuf;
|
|
int err;
|
|
#endif
|
|
struct passwd *pw;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(uid)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
|
|
pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
if (pwbuflen < 1) {
|
|
pwbuflen = 1024;
|
|
}
|
|
#if ZEND_DEBUG
|
|
/* Test retry logic */
|
|
pwbuflen = 1;
|
|
#endif
|
|
pwbuf = emalloc(pwbuflen);
|
|
|
|
try_again:
|
|
err = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
|
|
if (err || retpwptr == NULL) {
|
|
if (err == ERANGE) {
|
|
pwbuflen *= 2;
|
|
pwbuf = erealloc(pwbuf, pwbuflen);
|
|
goto try_again;
|
|
}
|
|
POSIX_G(last_error) = err;
|
|
efree(pwbuf);
|
|
RETURN_FALSE;
|
|
}
|
|
pw = &_pw;
|
|
#else
|
|
if (NULL == (pw = getpwuid(uid))) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
#endif
|
|
array_init(return_value);
|
|
|
|
if (!php_posix_passwd_to_array(pw, return_value)) {
|
|
zend_array_destroy(Z_ARR_P(return_value));
|
|
php_error_docref(NULL, E_WARNING, "Unable to convert posix passwd struct to array");
|
|
RETVAL_FALSE;
|
|
}
|
|
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
|
|
efree(pwbuf);
|
|
#endif
|
|
}
|
|
/* }}} */
|
|
|
|
|
|
#ifdef HAVE_GETRLIMIT
|
|
|
|
#define UNLIMITED_STRING "unlimited"
|
|
|
|
/* {{{ posix_addlimit */
|
|
static zend_result posix_addlimit(int limit, const char *name, zval *return_value) {
|
|
int result;
|
|
struct rlimit rl;
|
|
char hard[80];
|
|
char soft[80];
|
|
|
|
snprintf(hard, 80, "hard %s", name);
|
|
snprintf(soft, 80, "soft %s", name);
|
|
|
|
result = getrlimit(limit, &rl);
|
|
if (result < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
return FAILURE;
|
|
}
|
|
|
|
if (rl.rlim_cur == RLIM_INFINITY) {
|
|
add_assoc_stringl(return_value, soft, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
|
|
} else {
|
|
add_assoc_long(return_value, soft, rl.rlim_cur);
|
|
}
|
|
|
|
if (rl.rlim_max == RLIM_INFINITY) {
|
|
add_assoc_stringl(return_value, hard, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
|
|
} else {
|
|
add_assoc_long(return_value, hard, rl.rlim_max);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ limits[] */
|
|
static const struct limitlist {
|
|
int limit;
|
|
const char *name;
|
|
} limits[] = {
|
|
#ifdef RLIMIT_CORE
|
|
{ RLIMIT_CORE, "core" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_DATA
|
|
{ RLIMIT_DATA, "data" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_STACK
|
|
{ RLIMIT_STACK, "stack" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_VMEM
|
|
{ RLIMIT_VMEM, "virtualmem" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_AS
|
|
{ RLIMIT_AS, "totalmem" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_RSS
|
|
{ RLIMIT_RSS, "rss" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_NPROC
|
|
{ RLIMIT_NPROC, "maxproc" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_MEMLOCK
|
|
{ RLIMIT_MEMLOCK, "memlock" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_CPU
|
|
{ RLIMIT_CPU, "cpu" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_FSIZE
|
|
{ RLIMIT_FSIZE, "filesize" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_NOFILE
|
|
{ RLIMIT_NOFILE, "openfiles" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_OFILE
|
|
{ RLIMIT_OFILE, "openfiles" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_KQUEUES
|
|
{ RLIMIT_KQUEUES, "kqueues" },
|
|
#endif
|
|
|
|
#ifdef RLIMIT_NPTS
|
|
{ RLIMIT_NPTS, "npts" },
|
|
#endif
|
|
|
|
{ 0, NULL }
|
|
};
|
|
/* }}} */
|
|
|
|
|
|
/* {{{ Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally) */
|
|
PHP_FUNCTION(posix_getrlimit)
|
|
{
|
|
const struct limitlist *l = NULL;
|
|
zend_long res;
|
|
bool res_is_null = true;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(0, 1)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_LONG_OR_NULL(res, res_is_null)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (res_is_null) {
|
|
array_init(return_value);
|
|
|
|
for (l=limits; l->name; l++) {
|
|
if (posix_addlimit(l->limit, l->name, return_value) == FAILURE) {
|
|
zend_array_destroy(Z_ARR_P(return_value));
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
} else {
|
|
struct rlimit rl;
|
|
int result = getrlimit(res, &rl);
|
|
if (result < 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
array_init(return_value);
|
|
if (rl.rlim_cur == RLIM_INFINITY) {
|
|
add_next_index_stringl(return_value, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
|
|
} else {
|
|
add_next_index_long(return_value, rl.rlim_cur);
|
|
}
|
|
|
|
if (rl.rlim_max == RLIM_INFINITY) {
|
|
add_next_index_stringl(return_value, UNLIMITED_STRING, sizeof(UNLIMITED_STRING)-1);
|
|
} else {
|
|
add_next_index_long(return_value, rl.rlim_max);
|
|
}
|
|
}
|
|
}
|
|
/* }}} */
|
|
|
|
#endif /* HAVE_GETRLIMIT */
|
|
|
|
#ifdef HAVE_SETRLIMIT
|
|
/* {{{ Set system resource consumption limits (POSIX.1-2001) */
|
|
PHP_FUNCTION(posix_setrlimit)
|
|
{
|
|
struct rlimit rl;
|
|
zend_long res, cur, max;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(3, 3)
|
|
Z_PARAM_LONG(res)
|
|
Z_PARAM_LONG(cur)
|
|
Z_PARAM_LONG(max)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
rl.rlim_cur = cur;
|
|
rl.rlim_max = max;
|
|
|
|
if (setrlimit(res, &rl) == -1) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
#endif /* HAVE_SETRLIMIT */
|
|
|
|
|
|
/* {{{ Retrieve the error number set by the last posix function which failed. */
|
|
PHP_FUNCTION(posix_get_last_error)
|
|
{
|
|
ZEND_PARSE_PARAMETERS_NONE();
|
|
|
|
RETURN_LONG(POSIX_G(last_error));
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ Retrieve the system error message associated with the given errno. */
|
|
PHP_FUNCTION(posix_strerror)
|
|
{
|
|
zend_long error;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(error)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
RETURN_STRING(strerror(error));
|
|
}
|
|
/* }}} */
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_INITGROUPS
|
|
/* {{{ Calculate the group access list for the user specified in name. */
|
|
PHP_FUNCTION(posix_initgroups)
|
|
{
|
|
zend_long basegid;
|
|
char *name;
|
|
size_t name_len;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_STRING(name, name_len)
|
|
Z_PARAM_LONG(basegid)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (name_len == 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_BOOL(!initgroups((const char *)name, basegid));
|
|
}
|
|
/* }}} */
|
|
#endif
|
|
|
|
PHP_FUNCTION(posix_sysconf)
|
|
{
|
|
zend_long conf_id;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(conf_id)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
RETURN_LONG(sysconf(conf_id));
|
|
}
|
|
|
|
#ifdef HAVE_PATHCONF
|
|
PHP_FUNCTION(posix_pathconf)
|
|
{
|
|
zend_long name, ret;
|
|
char *path;
|
|
size_t path_len;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_PATH(path, path_len)
|
|
Z_PARAM_LONG(name);
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (path_len == 0) {
|
|
zend_argument_value_error(1, "cannot be empty");
|
|
RETURN_THROWS();
|
|
} else if (php_check_open_basedir(path)) {
|
|
php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ret = pathconf(path, name);
|
|
|
|
if (ret < 0 && errno != 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_LONG(ret);
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_FPATHCONF
|
|
PHP_FUNCTION(posix_fpathconf)
|
|
{
|
|
zend_long name, ret, fd = 0;
|
|
zval *z_fd;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_ZVAL(z_fd)
|
|
Z_PARAM_LONG(name);
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
|
|
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
} else {
|
|
if (!zend_parse_arg_long(z_fd, &fd, /* is_null */ NULL, /* check_null */ false, /* arg_num */ 1)) {
|
|
zend_argument_type_error(1, "must be of type int|resource, %s given",
|
|
zend_zval_value_name(z_fd));
|
|
RETURN_THROWS();
|
|
}
|
|
}
|
|
|
|
ret = fpathconf(fd, name);
|
|
|
|
if (ret < 0 && errno != 0) {
|
|
POSIX_G(last_error) = errno;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_LONG(ret);
|
|
}
|
|
#endif
|