183 lines
4.3 KiB
C
183 lines
4.3 KiB
C
//
|
|
// ext-ioctl/ioctl.c
|
|
//
|
|
// @Author CismonX
|
|
//
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <php.h>
|
|
#include <ext/standard/info.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "php_ioctl.h"
|
|
|
|
#define ERRNO_SET(zval, err) \
|
|
if (zval) { \
|
|
ZVAL_DEREF(zval); \
|
|
ZVAL_LONG(zval, err); \
|
|
}
|
|
|
|
PHP_FUNCTION(ioctl)
|
|
{
|
|
zval *fd;
|
|
zend_long request;
|
|
zend_string *argp = NULL;
|
|
zval *err = NULL;
|
|
ZEND_PARSE_PARAMETERS_START(2, 4)
|
|
Z_PARAM_ZVAL(fd)
|
|
Z_PARAM_LONG(request)
|
|
Z_PARAM_OPTIONAL
|
|
Z_PARAM_STR(argp)
|
|
Z_PARAM_ZVAL(err)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
php_stream *stream;
|
|
int fd_num;
|
|
if (Z_TYPE_P(fd) == IS_LONG) {
|
|
fd_num = Z_LVAL_P(fd);
|
|
} else if (UNEXPECTED(Z_TYPE_P(fd) != IS_RESOURCE)) {
|
|
ERRNO_SET(err, -1);
|
|
php_error_docref(NULL, E_WARNING, "Invalid fd. Resource or integer expected.");
|
|
RETURN_FALSE;
|
|
} else {
|
|
php_stream_from_zval(stream, fd);
|
|
struct {
|
|
FILE *file;
|
|
int fd;
|
|
} *stream_data = stream->abstract;
|
|
if (stream_data == NULL) {
|
|
ERRNO_SET(err, -2);
|
|
php_error_docref(NULL, E_WARNING, "Unexpected error. Failed to fetch stream data.");
|
|
RETURN_FALSE;
|
|
}
|
|
fd_num = stream_data->fd;
|
|
}
|
|
int result = ioctl(fd_num, (int)request, argp ? ZSTR_VAL(argp) : NULL);
|
|
if (result == -1) {
|
|
ERRNO_SET(err, errno);
|
|
RETURN_FALSE;
|
|
}
|
|
RETVAL_LONG(result);
|
|
}
|
|
|
|
ZEND_BEGIN_ARG_INFO(ioctl_arginfo, 0)
|
|
ZEND_ARG_INFO(0, fd)
|
|
ZEND_ARG_TYPE_INFO(0, request, IS_LONG, 0)
|
|
ZEND_ARG_TYPE_INFO(0, argp, IS_STRING, 0)
|
|
ZEND_ARG_INFO(1, errno)
|
|
ZEND_END_ARG_INFO()
|
|
|
|
#ifdef IOCTL_ENABLE_HELPER_FUNCTIONS
|
|
|
|
PHP_FUNCTION(str_alloc)
|
|
{
|
|
zend_long len;
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_LONG(len);
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
if (len < 0) {
|
|
php_error_docref(NULL, E_WARNING, "Buffer length should be positive.");
|
|
RETURN_EMPTY_STRING();
|
|
}
|
|
zend_string *buf = zend_string_alloc(len, 0);
|
|
#ifdef PHP_DEBUG
|
|
// Make the string nul-terminated to prevent warnings on debug builds of PHP.
|
|
ZSTR_VAL(buf)[len] = '\0';
|
|
#endif
|
|
RETVAL_STR(buf);
|
|
}
|
|
|
|
ZEND_BEGIN_ARG_INFO(str_alloc_arginfo, 0)
|
|
ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0)
|
|
ZEND_END_ARG_INFO()
|
|
|
|
PHP_FUNCTION(str2ptr)
|
|
{
|
|
zend_string *str;
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_STR(str);
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
RETVAL_LONG((zend_long)ZSTR_VAL(str));
|
|
}
|
|
|
|
ZEND_BEGIN_ARG_INFO(str2ptr_arginfo, 0)
|
|
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
|
|
ZEND_END_ARG_INFO()
|
|
|
|
PHP_FUNCTION(ptr2str)
|
|
{
|
|
zend_long ptr;
|
|
zend_long length;
|
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
|
Z_PARAM_LONG(ptr)
|
|
Z_PARAM_LONG(length)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
RETVAL_STR(zend_string_init((char*)ptr, length, 0));
|
|
}
|
|
|
|
ZEND_BEGIN_ARG_INFO(ptr2str_arginfo, 0)
|
|
ZEND_ARG_TYPE_INFO(0, ptr, IS_LONG, 0)
|
|
ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0)
|
|
ZEND_END_ARG_INFO()
|
|
|
|
PHP_FUNCTION(res2fd)
|
|
{
|
|
zval *res;
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
Z_PARAM_ZVAL(res)
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
php_stream* stream;
|
|
php_stream_from_zval(stream, res);
|
|
struct {
|
|
FILE *file;
|
|
int fd;
|
|
} *stream_data = stream->abstract;
|
|
if (stream_data) {
|
|
RETURN_LONG(stream_data->fd);
|
|
}
|
|
RETVAL_LONG(-1);
|
|
}
|
|
|
|
ZEND_BEGIN_ARG_INFO(res2fd_arginfo, 0)
|
|
ZEND_ARG_TYPE_INFO(0, res, IS_RESOURCE, 0)
|
|
ZEND_END_ARG_INFO()
|
|
|
|
#endif // IOCTL_ENABLE_HELPER_FUNCTIONS
|
|
|
|
zend_function_entry ioctl_functions[] = {
|
|
PHP_FE(ioctl, ioctl_arginfo)
|
|
#ifdef IOCTL_ENABLE_HELPER_FUNCTIONS
|
|
PHP_FE(str_alloc, str_alloc_arginfo)
|
|
PHP_FE(str2ptr, str2ptr_arginfo)
|
|
PHP_FE(ptr2str, ptr2str_arginfo)
|
|
PHP_FE(res2fd, res2fd_arginfo)
|
|
#endif // IOCTL_ENABLE_HELPER_FUNCTIONS
|
|
PHP_FE_END
|
|
};
|
|
|
|
PHP_MINFO_FUNCTION(ioctl)
|
|
{
|
|
php_info_print_table_start();
|
|
php_info_print_table_header(2, "ioctl support", "enabled");
|
|
php_info_print_table_end();
|
|
}
|
|
|
|
zend_module_entry ioctl_module_entry = {
|
|
STANDARD_MODULE_HEADER,
|
|
"ioctl",
|
|
ioctl_functions,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
PHP_MINFO(ioctl),
|
|
PHP_IOCTL_VERSION,
|
|
STANDARD_MODULE_PROPERTIES
|
|
};
|
|
|
|
#ifdef COMPILE_DL_IOCTL
|
|
ZEND_GET_MODULE(ioctl)
|
|
#endif
|