|
22 | 22 | #include "php_ini.h"
|
23 | 23 | #include "ext/standard/info.h"
|
24 | 24 | #include "ext/standard/file.h"
|
| 25 | +#include "ext/standard/flock_compat.h" |
25 | 26 | #include "ext/standard/scanf.h"
|
26 | 27 | #include "ext/standard/php_string.h"
|
27 | 28 | #include "zend_compile.h"
|
@@ -2547,18 +2548,47 @@ PHP_METHOD(SplFileObject, getCsvControl)
|
2547 | 2548 | }
|
2548 | 2549 | /* }}} */
|
2549 | 2550 |
|
2550 |
| -/* {{{ Portable file locking */ |
| 2551 | +/* {{{ Portable file locking, copy pasted from ext/standard/file.c flock() function. |
| 2552 | + * This is done to prevent this to fail if flock is disabled via disable_functions */ |
| 2553 | +static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; |
| 2554 | + |
2551 | 2555 | PHP_METHOD(SplFileObject, flock)
|
2552 | 2556 | {
|
2553 | 2557 | spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS);
|
2554 |
| - zend_function *func_ptr; |
| 2558 | + zval *wouldblock = NULL; |
| 2559 | + int act; |
| 2560 | + zend_long operation = 0; |
2555 | 2561 |
|
2556 |
| - func_ptr = (zend_function *)zend_hash_str_find_ptr(EG(function_table), "flock", sizeof("flock") - 1); |
2557 |
| - if (func_ptr == NULL) { |
2558 |
| - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Internal error, function flock() not found. Please report"); |
| 2562 | + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z", &operation, &wouldblock) == FAILURE) { |
2559 | 2563 | RETURN_THROWS();
|
2560 | 2564 | }
|
2561 |
| - spl_filesystem_file_call(intern, func_ptr, ZEND_NUM_ARGS(), return_value); |
| 2565 | + |
| 2566 | + if(!intern->u.file.stream) { |
| 2567 | + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); |
| 2568 | + RETURN_THROWS(); |
| 2569 | + } |
| 2570 | + |
| 2571 | + act = operation & PHP_LOCK_UN; |
| 2572 | + // TODO doesn't this fail if operation is a bitmask with LOCK_NB? |
| 2573 | + //if (act != PHP_LOCK_SH && act != PHP_LOCK_EX && act != PHP_LOCK_UN) { |
| 2574 | + if (act < 1 || act > 3) { |
| 2575 | + zend_argument_value_error(1, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); |
| 2576 | + RETURN_THROWS(); |
| 2577 | + } |
| 2578 | + |
| 2579 | + if (wouldblock) { |
| 2580 | + ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 0); |
| 2581 | + } |
| 2582 | + |
| 2583 | + /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */ |
| 2584 | + act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); |
| 2585 | + if (php_stream_lock(intern->u.file.stream, act)) { |
| 2586 | + if (operation && errno == EWOULDBLOCK && wouldblock) { |
| 2587 | + ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 1); |
| 2588 | + } |
| 2589 | + RETURN_FALSE; |
| 2590 | + } |
| 2591 | + RETURN_TRUE; |
2562 | 2592 | }
|
2563 | 2593 | /* }}} */
|
2564 | 2594 |
|
|
0 commit comments