diff options
author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-02-17 00:25:32 +0000 |
---|---|---|
committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-02-17 00:25:32 +0000 |
commit | 9bbc114b593ddc66785021a954fde9078afd08fb (patch) | |
tree | a5e7648886d068e6e8eb931d116e9cbeffbca435 /main | |
parent | eb0dd2b8ab91910e7dd3ae29109de2bfd9e0cc7d (diff) | |
download | php-git-9bbc114b593ddc66785021a954fde9078afd08fb.tar.gz |
- Classes that implement stream wrappers can define a method called
stream_truncate that will respond to truncation, e.g. through ftruncate.
Closes feature request #53888.
Diffstat (limited to 'main')
-rw-r--r-- | main/streams/userspace.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 49c3c662ae..7380c535e1 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -26,6 +26,7 @@ #ifdef HAVE_SYS_FILE_H #include <sys/file.h> #endif +#include <stddef.h> static int le_protocols; @@ -129,6 +130,7 @@ typedef struct _php_userstream_data php_userstream_data_t; #define USERSTREAM_LOCK "stream_lock" #define USERSTREAM_CAST "stream_cast" #define USERSTREAM_SET_OPTION "stream_set_option" +#define USERSTREAM_TRUNCATE "stream_truncate" /* {{{ class should have methods like these: @@ -254,6 +256,11 @@ typedef struct _php_userstream_data php_userstream_data_t; { return true / false; } + + function stream_truncate($new_size) + { + return true / false; + } }}} **/ @@ -992,6 +999,51 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value } break; + + case PHP_STREAM_OPTION_TRUNCATE_API: + ZVAL_STRINGL(&func_name, USERSTREAM_TRUNCATE, sizeof(USERSTREAM_TRUNCATE)-1, 0); + + switch (value) { + case PHP_STREAM_TRUNCATE_SUPPORTED: + if (zend_is_callable_ex(&func_name, us->object, IS_CALLABLE_CHECK_SILENT, + NULL, NULL, NULL, NULL TSRMLS_CC)) + ret = PHP_STREAM_OPTION_RETURN_OK; + else + ret = PHP_STREAM_OPTION_RETURN_ERR; + break; + + case PHP_STREAM_TRUNCATE_SET_SIZE: { + ptrdiff_t new_size = *(ptrdiff_t*) ptrparam; + if (new_size >= 0 && new_size <= (ptrdiff_t)LONG_MAX) { + MAKE_STD_ZVAL(zvalue); + ZVAL_LONG(zvalue, (long)new_size); + args[0] = &zvalue; + call_result = call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 1, args, 0, NULL TSRMLS_CC); + if (call_result == SUCCESS && retval != NULL) { + if (Z_TYPE_P(retval) == IS_BOOL) { + ret = Z_LVAL_P(retval) ? PHP_STREAM_OPTION_RETURN_OK : + PHP_STREAM_OPTION_RETURN_ERR; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "%s::" USERSTREAM_TRUNCATE " did not return a boolean!", + us->wrapper->classname); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "%s::" USERSTREAM_TRUNCATE " is not implemented!", + us->wrapper->classname); + } + } else { /* bad new size */ + ret = PHP_STREAM_OPTION_RETURN_ERR; + } + break; + } + } + break; case PHP_STREAM_OPTION_READ_BUFFER: case PHP_STREAM_OPTION_WRITE_BUFFER: |