summaryrefslogtreecommitdiff
path: root/ext/sysvmsg
diff options
context:
space:
mode:
authorMáté Kocsis <kocsismate@woohoolabs.com>2020-05-08 17:18:39 +0200
committerMáté Kocsis <kocsismate@woohoolabs.com>2020-05-14 12:56:06 +0200
commit9198faa67fc2e0594bc1aff01b4eadb40835ac68 (patch)
treedd18c37f6c2e96d5a8ae79209b8a46ef81fbddc1 /ext/sysvmsg
parent75bac167885b611ce981abdcbb21da7bb98a14c6 (diff)
downloadphp-git-9198faa67fc2e0594bc1aff01b4eadb40835ac68.tar.gz
Convert resource to object in Sysvmsg
Closes GH-5546
Diffstat (limited to 'ext/sysvmsg')
-rw-r--r--ext/sysvmsg/sysvmsg.c106
-rw-r--r--ext/sysvmsg/sysvmsg.stub.php40
-rw-r--r--ext/sysvmsg/sysvmsg_arginfo.h17
-rw-r--r--ext/sysvmsg/tests/003.phpt3
-rw-r--r--ext/sysvmsg/tests/005.phpt8
5 files changed, 100 insertions, 74 deletions
diff --git a/ext/sysvmsg/sysvmsg.c b/ext/sysvmsg/sysvmsg.c
index 9721193945..e44bb58aea 100644
--- a/ext/sysvmsg/sysvmsg.c
+++ b/ext/sysvmsg/sysvmsg.c
@@ -25,6 +25,7 @@
#include "sysvmsg_arginfo.h"
#include "ext/standard/php_var.h"
#include "zend_smart_str.h"
+#include "Zend/zend_interfaces.h"
#include <sys/types.h>
#include <sys/ipc.h>
@@ -36,6 +37,7 @@ PHP_MINFO_FUNCTION(sysvmsg);
typedef struct {
key_t key;
zend_long id;
+ zend_object std;
} sysvmsg_queue_t;
struct php_msgbuf {
@@ -50,9 +52,6 @@ struct php_msgbuf {
#define PHP_MSG_NOERROR 2
#define PHP_MSG_EXCEPT 4
-/* True global resources - no need for thread safety here */
-static int le_sysvmsg;
-
/* {{{ sysvmsg_module_entry
*/
zend_module_entry sysvmsg_module_entry = {
@@ -73,17 +72,58 @@ zend_module_entry sysvmsg_module_entry = {
ZEND_GET_MODULE(sysvmsg)
#endif
-static void sysvmsg_release(zend_resource *rsrc)
+/* SysvMessageQueue class */
+
+zend_class_entry *sysvmsg_queue_ce;
+static zend_object_handlers sysvmsg_queue_object_handlers;
+
+static inline sysvmsg_queue_t *sysvmsg_queue_from_obj(zend_object *obj) {
+ return (sysvmsg_queue_t *)((char *)(obj) - XtOffsetOf(sysvmsg_queue_t, std));
+}
+
+#define Z_SYSVMSG_QUEUE_P(zv) sysvmsg_queue_from_obj(Z_OBJ_P(zv))
+
+static zend_object *sysvmsg_queue_create_object(zend_class_entry *class_type) {
+ sysvmsg_queue_t *intern = zend_object_alloc(sizeof(sysvmsg_queue_t), class_type);
+
+ zend_object_std_init(&intern->std, class_type);
+ object_properties_init(&intern->std, class_type);
+ intern->std.handlers = &sysvmsg_queue_object_handlers;
+
+ return &intern->std;
+}
+
+static zend_function *sysvmsg_queue_get_constructor(zend_object *object) {
+ zend_throw_error(NULL, "Cannot directly construct SysvMessageQueue, use msg_get_queue() instead");
+ return NULL;
+}
+
+static void sysvmsg_queue_free_obj(zend_object *object)
{
- sysvmsg_queue_t *mq = (sysvmsg_queue_t *) rsrc->ptr;
- efree(mq);
+ sysvmsg_queue_t *sysvmsg_queue = sysvmsg_queue_from_obj(object);
+
+ zend_object_std_dtor(&sysvmsg_queue->std);
}
+/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(sysvmsg)
{
- le_sysvmsg = zend_register_list_destructors_ex(sysvmsg_release, NULL, "sysvmsg queue", module_number);
+ zend_class_entry ce;
+ INIT_CLASS_ENTRY(ce, "SysvMessageQueue", class_SysvMessageQueue_methods);
+ sysvmsg_queue_ce = zend_register_internal_class(&ce);
+ sysvmsg_queue_ce->ce_flags |= ZEND_ACC_FINAL;
+ sysvmsg_queue_ce->create_object = sysvmsg_queue_create_object;
+ sysvmsg_queue_ce->serialize = zend_class_serialize_deny;
+ sysvmsg_queue_ce->unserialize = zend_class_unserialize_deny;
+
+ memcpy(&sysvmsg_queue_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
+ sysvmsg_queue_object_handlers.offset = XtOffsetOf(sysvmsg_queue_t, std);
+ sysvmsg_queue_object_handlers.free_obj = sysvmsg_queue_free_obj;
+ sysvmsg_queue_object_handlers.get_constructor = sysvmsg_queue_get_constructor;
+ sysvmsg_queue_object_handlers.clone_obj = NULL;
+
REGISTER_LONG_CONSTANT("MSG_IPC_NOWAIT", PHP_MSG_IPC_NOWAIT, CONST_PERSISTENT|CONST_CS);
REGISTER_LONG_CONSTANT("MSG_EAGAIN", EAGAIN, CONST_PERSISTENT|CONST_CS);
REGISTER_LONG_CONSTANT("MSG_ENOMSG", ENOMSG, CONST_PERSISTENT|CONST_CS);
@@ -103,7 +143,7 @@ PHP_MINFO_FUNCTION(sysvmsg)
}
/* }}} */
-/* {{{ proto bool msg_set_queue(resource queue, array data)
+/* {{{ proto bool msg_set_queue(SysvMessageQueue queue, array data)
Set information for a message queue */
PHP_FUNCTION(msg_set_queue)
{
@@ -113,13 +153,11 @@ PHP_FUNCTION(msg_set_queue)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &queue, &data) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa", &queue, sysvmsg_queue_ce, &data) == FAILURE) {
RETURN_THROWS();
}
- if ((mq = (sysvmsg_queue_t *)zend_fetch_resource(Z_RES_P(queue), "sysvmsg queue", le_sysvmsg)) == NULL) {
- RETURN_THROWS();
- }
+ mq = Z_SYSVMSG_QUEUE_P(queue);
if (msgctl(mq->id, IPC_STAT, &stat) == 0) {
zval *item;
@@ -144,7 +182,7 @@ PHP_FUNCTION(msg_set_queue)
}
/* }}} */
-/* {{{ proto array msg_stat_queue(resource queue)
+/* {{{ proto array msg_stat_queue(SysvMessageQueue queue)
Returns information about a message queue */
PHP_FUNCTION(msg_stat_queue)
{
@@ -154,13 +192,11 @@ PHP_FUNCTION(msg_stat_queue)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &queue) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &queue, sysvmsg_queue_ce) == FAILURE) {
RETURN_THROWS();
}
- if ((mq = (sysvmsg_queue_t *)zend_fetch_resource(Z_RES_P(queue), "sysvmsg queue", le_sysvmsg)) == NULL) {
- RETURN_THROWS();
- }
+ mq = Z_SYSVMSG_QUEUE_P(queue);
if (msgctl(mq->id, IPC_STAT, &stat) == 0) {
array_init(return_value);
@@ -197,7 +233,7 @@ PHP_FUNCTION(msg_queue_exists)
}
/* }}} */
-/* {{{ proto resource msg_get_queue(int key [, int perms])
+/* {{{ proto SysvMessageQueue msg_get_queue(int key [, int perms])
Attach to a message queue */
PHP_FUNCTION(msg_get_queue)
{
@@ -209,7 +245,8 @@ PHP_FUNCTION(msg_get_queue)
RETURN_THROWS();
}
- mq = (sysvmsg_queue_t *) emalloc(sizeof(sysvmsg_queue_t));
+ object_init_ex(return_value, sysvmsg_queue_ce);
+ mq = Z_SYSVMSG_QUEUE_P(return_value);
mq->key = key;
mq->id = msgget(key, 0);
@@ -218,28 +255,25 @@ PHP_FUNCTION(msg_get_queue)
mq->id = msgget(key, IPC_CREAT | IPC_EXCL | perms);
if (mq->id < 0) {
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", key, strerror(errno));
- efree(mq);
+ zval_ptr_dtor(return_value);
RETURN_FALSE;
}
}
- ZVAL_COPY_VALUE(return_value, zend_list_insert(mq, le_sysvmsg));
}
/* }}} */
-/* {{{ proto bool msg_remove_queue(resource queue)
+/* {{{ proto bool msg_remove_queue(SysvMessageQueue queue)
Destroy the queue */
PHP_FUNCTION(msg_remove_queue)
{
zval *queue;
sysvmsg_queue_t *mq = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &queue) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &queue, sysvmsg_queue_ce) == FAILURE) {
RETURN_THROWS();
}
- if ((mq = (sysvmsg_queue_t *)zend_fetch_resource(Z_RES_P(queue), "sysvmsg queue", le_sysvmsg)) == NULL) {
- RETURN_THROWS();
- }
+ mq = Z_SYSVMSG_QUEUE_P(queue);
if (msgctl(mq->id, IPC_RMID, NULL) == 0) {
RETVAL_TRUE;
@@ -249,7 +283,7 @@ PHP_FUNCTION(msg_remove_queue)
}
/* }}} */
-/* {{{ proto mixed msg_receive(resource queue, int desiredmsgtype, int &msgtype, int maxsize, mixed &message [, bool unserialize=true [, int flags=0 [, int &errorcode]]])
+/* {{{ proto mixed msg_receive(SysvMessageQueue queue, int desiredmsgtype, int &msgtype, int maxsize, mixed &message [, bool unserialize=true [, int flags=0 [, int &errorcode]]])
Send a message of type msgtype (must be > 0) to a message queue */
PHP_FUNCTION(msg_receive)
{
@@ -263,8 +297,8 @@ PHP_FUNCTION(msg_receive)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlzlz|blz",
- &queue, &desiredmsgtype, &out_msgtype, &maxsize,
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olzlz|blz",
+ &queue, sysvmsg_queue_ce, &desiredmsgtype, &out_msgtype, &maxsize,
&out_message, &do_unserialize, &flags, &zerrcode) == FAILURE) {
RETURN_THROWS();
}
@@ -291,9 +325,7 @@ PHP_FUNCTION(msg_receive)
}
}
- if ((mq = (sysvmsg_queue_t *)zend_fetch_resource(Z_RES_P(queue), "sysvmsg queue", le_sysvmsg)) == NULL) {
- RETURN_THROWS();
- }
+ mq = Z_SYSVMSG_QUEUE_P(queue);
messagebuffer = (struct php_msgbuf *) safe_emalloc(maxsize, 1, sizeof(struct php_msgbuf));
@@ -335,7 +367,7 @@ PHP_FUNCTION(msg_receive)
}
/* }}} */
-/* {{{ proto bool msg_send(resource queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])
+/* {{{ proto bool msg_send(SysvMessageQueue queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])
Send a message of type msgtype (must be > 0) to a message queue */
PHP_FUNCTION(msg_send)
{
@@ -349,14 +381,12 @@ PHP_FUNCTION(msg_send)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz|bbz",
- &queue, &msgtype, &message, &do_serialize, &blocking, &zerror) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz|bbz",
+ &queue, sysvmsg_queue_ce, &msgtype, &message, &do_serialize, &blocking, &zerror) == FAILURE) {
RETURN_THROWS();
}
- if ((mq = (sysvmsg_queue_t *)zend_fetch_resource(Z_RES_P(queue), "sysvmsg queue", le_sysvmsg)) == NULL) {
- RETURN_THROWS();
- }
+ mq = Z_SYSVMSG_QUEUE_P(queue);
if (do_serialize) {
smart_str msg_var = {0};
diff --git a/ext/sysvmsg/sysvmsg.stub.php b/ext/sysvmsg/sysvmsg.stub.php
index 5bbe100ca6..f6c4d07e43 100644
--- a/ext/sysvmsg/sysvmsg.stub.php
+++ b/ext/sysvmsg/sysvmsg.stub.php
@@ -2,30 +2,20 @@
/** @generate-function-entries */
-/** @return resource|false */
-function msg_get_queue(int $key, int $perms = 0666) {}
-
-/**
- * @param resource $queue
- */
-function msg_send($queue, int $msgtype, $message, bool $serialize = true, bool $blocking = true, &$errorcode = null): bool {}
-
-/**
- * @param resource $queue
- */
-function msg_receive($queue, int $desiredmsgtype, &$msgtype, int $maxsize, &$message, bool $unserialize = true, int $flags = 0, &$errorcode = null): bool {}
-
-/**
- * @param resource $queue
- */
-function msg_remove_queue($queue): bool {}
-
-/** @param resource $queue */
-function msg_stat_queue($queue): array|false {}
-
-/**
- * @param resource $queue
- */
-function msg_set_queue($queue, array $data): bool {}
+final class SysvMessageQueue
+{
+}
+
+function msg_get_queue(int $key, int $perms = 0666): SysvMessageQueue|false {}
+
+function msg_send(SysvMessageQueue $queue, int $msgtype, $message, bool $serialize = true, bool $blocking = true, &$errorcode = null): bool {}
+
+function msg_receive(SysvMessageQueue $queue, int $desiredmsgtype, &$msgtype, int $maxsize, &$message, bool $unserialize = true, int $flags = 0, &$errorcode = null): bool {}
+
+function msg_remove_queue(SysvMessageQueue $queue): bool {}
+
+function msg_stat_queue(SysvMessageQueue $queue): array|false {}
+
+function msg_set_queue(SysvMessageQueue $queue, array $data): bool {}
function msg_queue_exists(int $key): bool {}
diff --git a/ext/sysvmsg/sysvmsg_arginfo.h b/ext/sysvmsg/sysvmsg_arginfo.h
index 88ec5af6b8..30d08d968c 100644
--- a/ext/sysvmsg/sysvmsg_arginfo.h
+++ b/ext/sysvmsg/sysvmsg_arginfo.h
@@ -1,12 +1,12 @@
/* This is a generated file, edit the .stub.php file instead. */
-ZEND_BEGIN_ARG_INFO_EX(arginfo_msg_get_queue, 0, 0, 1)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_msg_get_queue, 0, 1, SysvMessageQueue, MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, perms, IS_LONG, 0, "0666")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_send, 0, 3, _IS_BOOL, 0)
- ZEND_ARG_INFO(0, queue)
+ ZEND_ARG_OBJ_INFO(0, queue, SysvMessageQueue, 0)
ZEND_ARG_TYPE_INFO(0, msgtype, IS_LONG, 0)
ZEND_ARG_INFO(0, message)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, serialize, _IS_BOOL, 0, "true")
@@ -15,7 +15,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_send, 0, 3, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_receive, 0, 5, _IS_BOOL, 0)
- ZEND_ARG_INFO(0, queue)
+ ZEND_ARG_OBJ_INFO(0, queue, SysvMessageQueue, 0)
ZEND_ARG_TYPE_INFO(0, desiredmsgtype, IS_LONG, 0)
ZEND_ARG_INFO(1, msgtype)
ZEND_ARG_TYPE_INFO(0, maxsize, IS_LONG, 0)
@@ -26,15 +26,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_receive, 0, 5, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_remove_queue, 0, 1, _IS_BOOL, 0)
- ZEND_ARG_INFO(0, queue)
+ ZEND_ARG_OBJ_INFO(0, queue, SysvMessageQueue, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_msg_stat_queue, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
- ZEND_ARG_INFO(0, queue)
+ ZEND_ARG_OBJ_INFO(0, queue, SysvMessageQueue, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_msg_set_queue, 0, 2, _IS_BOOL, 0)
- ZEND_ARG_INFO(0, queue)
+ ZEND_ARG_OBJ_INFO(0, queue, SysvMessageQueue, 0)
ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@@ -62,3 +62,8 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(msg_queue_exists, arginfo_msg_queue_exists)
ZEND_FE_END
};
+
+
+static const zend_function_entry class_SysvMessageQueue_methods[] = {
+ ZEND_FE_END
+};
diff --git a/ext/sysvmsg/tests/003.phpt b/ext/sysvmsg/tests/003.phpt
index 66ff046dd0..d447bf8f72 100644
--- a/ext/sysvmsg/tests/003.phpt
+++ b/ext/sysvmsg/tests/003.phpt
@@ -18,7 +18,8 @@ echo "Done\n";
?>
--EXPECTF--
bool(false)
-resource(%d) of type (sysvmsg queue)
+object(SysvMessageQueue)#1 (0) {
+}
bool(true)
bool(true)
bool(false)
diff --git a/ext/sysvmsg/tests/005.phpt b/ext/sysvmsg/tests/005.phpt
index 68323e9a30..727c42db66 100644
--- a/ext/sysvmsg/tests/005.phpt
+++ b/ext/sysvmsg/tests/005.phpt
@@ -7,7 +7,7 @@ sysvmsg functions on non-existing queue
$tests = array(null, 'foo');
-foreach ($tests as $q) {
+foreach ($tests as $i => $q) {
if ($q === null) {
do {
@@ -17,7 +17,7 @@ foreach ($tests as $q) {
$q = msg_get_queue($id) or die("Failed to create queue");
msg_remove_queue($q) or die("Failed to close queue");
- echo "Using '$q' as queue resource:\n";
+ echo "Iteration " . ($i + 1) . ":\n";
$errno = 0;
@@ -37,7 +37,7 @@ foreach ($tests as $q) {
echo "Done\n";
?>
--EXPECTF--
-Using 'Resource id #4' as queue resource:
+Iteration 1:
bool(false)
bool(false)
bool(false)
@@ -49,7 +49,7 @@ bool(false)
Warning: msg_send(): msgsnd failed: Invalid argument in %s on line %d
bool(false)
bool(true)
-Using 'Resource id #5' as queue resource:
+Iteration 2:
bool(false)
bool(false)
bool(false)