Skip to content

Commit 1157444

Browse files
committed
stream: add stream_get_errors function
1 parent 7b89400 commit 1157444

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

ext/standard/basic_functions.stub.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3535,6 +3535,12 @@ function stream_resolve_include_path(string $filename): string|false {}
35353535
*/
35363536
function stream_get_wrappers(): array {}
35373537

3538+
/**
3539+
* @param resource|string|null $subject
3540+
* @return array<int, array>
3541+
*/
3542+
function stream_get_errors($subject = null): array {}
3543+
35383544
/**
35393545
* @return array<int, string>
35403546
* @refcount 1

ext/standard/basic_functions_arginfo.h

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/streamsfuncs.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,104 @@ PHP_FUNCTION(stream_get_wrappers)
594594
}
595595
/* }}} */
596596

597+
/* Helper function to convert error list to array */
598+
static void php_stream_errors_list_to_array(zend_llist *list, zval *return_value)
599+
{
600+
php_stream_error_entry **err_entry_p;
601+
zend_llist_position pos;
602+
603+
for (err_entry_p = zend_llist_get_first_ex(list, &pos);
604+
err_entry_p;
605+
err_entry_p = zend_llist_get_next_ex(list, &pos)) {
606+
php_stream_error_entry *entry = *err_entry_p;
607+
zval error_array;
608+
array_init(&error_array);
609+
610+
add_assoc_str(&error_array, "message", zend_string_copy(entry->message));
611+
add_assoc_long(&error_array, "code", entry->code);
612+
add_assoc_long(&error_array, "severity", entry->severity);
613+
add_assoc_bool(&error_array, "terminal", entry->terminal);
614+
615+
if (entry->wrapper_name) {
616+
add_assoc_string(&error_array, "wrapper", entry->wrapper_name);
617+
}
618+
if (entry->param) {
619+
add_assoc_string(&error_array, "param", entry->param);
620+
}
621+
if (entry->docref) {
622+
add_assoc_string(&error_array, "docref", entry->docref);
623+
}
624+
625+
add_next_index_zval(return_value, &error_array);
626+
}
627+
}
628+
629+
/* Retrieves list of stored stream errors */
630+
PHP_FUNCTION(stream_get_errors)
631+
{
632+
zval *subject = NULL;
633+
php_stream *stream = NULL;
634+
char *wrapper_name = NULL;
635+
size_t wrapper_name_len = 0;
636+
bool get_all_wrappers = false;
637+
638+
ZEND_PARSE_PARAMETERS_START(0, 1)
639+
Z_PARAM_OPTIONAL
640+
Z_PARAM_ZVAL(subject)
641+
ZEND_PARSE_PARAMETERS_END();
642+
643+
/* Determine what we're querying for */
644+
if (subject == NULL) {
645+
/* No parameter - get all wrapper errors */
646+
get_all_wrappers = true;
647+
} else if (Z_TYPE_P(subject) == IS_RESOURCE) {
648+
/* Stream resource - get errors for this stream */
649+
php_stream_from_zval_no_verify(stream, subject);
650+
if (stream == NULL) {
651+
zend_argument_type_error(1, "must be a valid stream resource");
652+
RETURN_THROWS();
653+
}
654+
} else if (Z_TYPE_P(subject) == IS_STRING) {
655+
/* Wrapper name - get errors for this wrapper */
656+
wrapper_name = Z_STRVAL_P(subject);
657+
wrapper_name_len = Z_STRLEN_P(subject);
658+
} else {
659+
zend_argument_type_error(1, "must be a stream resource, string, or null");
660+
RETURN_THROWS();
661+
}
662+
663+
array_init(return_value);
664+
665+
/* Handle stream errors */
666+
if (stream) {
667+
if (stream->error_list) {
668+
php_stream_errors_list_to_array(stream->error_list, return_value);
669+
}
670+
} else if (get_all_wrappers) {
671+
/* Get errors from all wrappers */
672+
if (FG(wrapper_stored_errors)) {
673+
zend_string *key;
674+
zval *val;
675+
ZEND_HASH_FOREACH_STR_KEY_VAL(FG(wrapper_stored_errors), key, val) {
676+
if (key) {
677+
zend_llist *list = (zend_llist *) Z_PTR_P(val);
678+
php_stream_errors_list_to_array(list, return_value);
679+
}
680+
} ZEND_HASH_FOREACH_END();
681+
}
682+
} else if (wrapper_name) {
683+
/* Get errors for specific wrapper */
684+
if (FG(wrapper_stored_errors)) {
685+
zend_llist *list = zend_hash_str_find_ptr(
686+
FG(wrapper_stored_errors), wrapper_name, wrapper_name_len);
687+
688+
if (list) {
689+
php_stream_errors_list_to_array(list, return_value);
690+
}
691+
}
692+
}
693+
}
694+
597695
/* {{{ stream_select related functions */
598696
static int stream_array_to_fd_set(const HashTable *stream_array, fd_set *fds, php_socket_t *max_fd)
599697
{

0 commit comments

Comments
 (0)