Skip to content

Convert resource to object in Sysvmsg #5546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,11 @@ PHP 8.0 UPGRADE NOTES
explicit setlocale() call is now always required if you wish to change any
locale component from the default.

- Sysvmsg:
. msg_get_queue() will now return an SysvMessageQueue object rather than a resource.
Return value checks using is_resource() should be replaced with checks
for `false`.

- Sysvsem:
. sem_get() will now return an SysvSemaphore object rather than a resource.
Return value checks using is_resource() should be replaced with checks
Expand Down
106 changes: 68 additions & 38 deletions ext/sysvmsg/sysvmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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 {
Expand All @@ -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 = {
Expand All @@ -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);
Expand All @@ -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)
{
Expand All @@ -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;
Expand All @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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)
{
Expand All @@ -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();
}
Expand All @@ -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));

Expand Down Expand Up @@ -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)
{
Expand All @@ -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};
Expand Down
40 changes: 15 additions & 25 deletions ext/sysvmsg/sysvmsg.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
17 changes: 11 additions & 6 deletions ext/sysvmsg/sysvmsg_arginfo.h
Original file line number Diff line number Diff line change
@@ -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")
Expand All @@ -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)
Expand All @@ -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()

Expand Down Expand Up @@ -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
};
3 changes: 2 additions & 1 deletion ext/sysvmsg/tests/003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading