1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2012 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Shuhei Tanuma <chobieeee@php.net> |
16 | Bob Weinand <bobwei9@hotmail.com> |
17 +----------------------------------------------------------------------+
18 */
19
20 #pragma GCC diagnostic ignored "-Wmissing-braces"
21
22 #include "php_uv.h"
23 #include "php_main.h"
24 #include "ext/standard/info.h"
25 #include "zend_smart_str.h"
26
27 #ifndef PHP_UV_DEBUG
28 #define PHP_UV_DEBUG 0
29 #endif
30
31 #if defined(ZTS) && PHP_VERSION_ID < 80000
32 #undef TSRMLS_C
33 #undef TSRMLS_CC
34 #undef TSRMLS_D
35 #undef TSRMLS_DC
36 #define TSRMLS_C tsrm_ls
37 #define TSRMLS_CC , TSRMLS_C
38 #define TSRMLS_D void *tsrm_ls
39 #define TSRMLS_DC , TSRMLS_D
40
41 #ifdef COMPILE_DL_UV
42 ZEND_TSRMLS_CACHE_DEFINE()
43 #endif
44 #endif
45
46 ZEND_DECLARE_MODULE_GLOBALS(uv);
47
48 #ifndef GC_ADDREF
49 #define GC_ADDREF(ref) ++GC_REFCOUNT(ref)
50 #endif
51
52 #if PHP_VERSION_ID < 70100
53 #define uv_zend_wrong_parameter_class_error(throw, ...) zend_wrong_paramer_class_error(__VA_ARGS__)
54 #elif PHP_VERSION_ID < 70200 || PHP_VERSION_ID >= 70300
55 #define uv_zend_wrong_parameter_class_error(throw, ...) zend_wrong_parameter_class_error(__VA_ARGS__)
56 #else
57 #define uv_zend_wrong_parameter_class_error(...) zend_wrong_parameter_class_error(__VA_ARGS__)
58 #endif
59
60 #if PHP_VERSION_ID < 70200
61 #define UV_PARAM_PROLOGUE Z_PARAM_PROLOGUE(0)
62 #else
63 #define UV_PARAM_PROLOGUE Z_PARAM_PROLOGUE(0, 0)
64 #endif
65
66 #if PHP_VERSION_ID < 70400
67 #define _error_code error_code
68 #endif
69
70 #if PHP_VERSION_ID >= 80000
71 #define zend_internal_type_error(strict_types, ...) zend_type_error(__VA_ARGS__)
72 #endif
73
74 #define UV_PARAM_OBJ_EX(dest, type, check_null, ce, ...) \
75 { \
76 zval *zv; \
77 UV_PARAM_PROLOGUE \
78 if (UNEXPECTED(!uv_parse_arg_object(_arg, &zv, check_null, ce, ##__VA_ARGS__, NULL))) { \
79 if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
80 zend_string *names = php_uv_concat_ce_names(ce, ##__VA_ARGS__, NULL); \
81 uv_zend_wrong_parameter_class_error(_flags & ZEND_PARSE_PARAMS_THROW, _i, ZSTR_VAL(names), _arg); \
82 zend_string_release(names); \
83 } \
84 _error_code = ZPP_ERROR_FAILURE; \
85 break; \
86 } \
87 if (GC_FLAGS(Z_OBJ_P(zv)) & IS_OBJ_DESTRUCTOR_CALLED) { \
88 if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \
89 php_error_docref(NULL, E_WARNING, "passed %s handle is already closed", ZSTR_VAL(Z_OBJCE_P(_arg)->name)); \
90 } \
91 _error_code = ZPP_ERROR_FAILURE; \
92 break; \
93 } \
94 dest = zv == NULL ? NULL : (type *) Z_OBJ_P(zv); \
95 }
96
97 #define UV_PARAM_OBJ(dest, type, ...) UV_PARAM_OBJ_EX(dest, type, 0, ##__VA_ARGS__, NULL)
98 #define UV_PARAM_OBJ_NULL(dest, type, ...) UV_PARAM_OBJ_EX(dest, type, 1, ##__VA_ARGS__, NULL)
99
php_uv_concat_ce_names(zend_class_entry * ce,zend_class_entry * next,...)100 static ZEND_COLD zend_string *php_uv_concat_ce_names(zend_class_entry *ce, zend_class_entry *next, ...) {
101 va_list va;
102 smart_str buf = {0};
103
104 va_start(va, next);
105
106 if (!next) {
107 return zend_string_copy(ce->name);
108 }
109
110 goto start;
111 do {
112 if (next) {
113 smart_str_appends(&buf, ", ");
114 } else {
115 smart_str_appends(&buf, " or ");
116 }
117 start:
118 smart_str_append(&buf, ce->name);
119 ce = next;
120 next = (zend_class_entry *) va_arg(va, zend_class_entry *);
121 } while (next);
122
123 va_end(va);
124
125 smart_str_0(&buf);
126 return buf.s;
127 }
128
129 /* gcc complains: sorry, unimplemented: function ‘uv_parse_arg_object’ can never be inlined because it uses variable argument lists */
130 #ifdef __clang__
uv_parse_arg_object(zval * arg,zval ** dest,int check_null,zend_class_entry * ce,...)131 static zend_always_inline int uv_parse_arg_object(zval *arg, zval **dest, int check_null, zend_class_entry *ce, ...) {
132 #else
133 static int uv_parse_arg_object(zval *arg, zval **dest, int check_null, zend_class_entry *ce, ...) {
134 #endif
135 if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
136 va_list va;
137 zend_class_entry *argce = Z_OBJCE_P(arg);
138 va_start(va, ce);
139 do {
140 if (instanceof_function(argce, ce)) {
141 *dest = arg;
142 return 1;
143 }
144 ce = (zend_class_entry *) va_arg(va, zend_class_entry *);
145 } while (ce);
146 } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
147 *dest = NULL;
148 return 1;
149 }
150 return 0;
151 }
152
153 #define PHP_UV_DEINIT_UV(uv) \
154 clean_uv_handle(uv); \
155 OBJ_RELEASE(&uv->std);
156
157 #define PHP_UV_INIT_GENERIC(dest, type, ce) \
158 do { \
159 zval zv; \
160 object_init_ex(&zv, ce); \
161 dest = (type *) Z_OBJ(zv); \
162 } while (0)
163
164 #define PHP_UV_INIT_UV(uv, ce) PHP_UV_INIT_GENERIC(uv, php_uv_t, ce)
165
166 #define PHP_UV_INIT_UV_EX(_uv, ce, cb, ...) \
167 do { \
168 int r; \
169 PHP_UV_INIT_UV(_uv, ce); \
170 r = cb(&loop->loop, (void *) &_uv->uv.handle, ##__VA_ARGS__); \
171 if (r) { \
172 PHP_UV_DEINIT_UV(_uv); \
173 php_error_docref(NULL, E_WARNING, #cb " failed"); \
174 RETURN_FALSE; \
175 } \
176 } while (0)
177
178 #define PHP_UV_INIT_CONNECT(req, uv) \
179 req = (uv_connect_t *) emalloc(sizeof(uv_connect_t)); \
180 req->data = uv;
181
182 #define PHP_UV_INIT_WRITE_REQ(w, uv, str, strlen, cb) \
183 w = (write_req_t *) emalloc(sizeof(write_req_t)); \
184 w->req.data = uv; \
185 w->buf = uv_buf_init(estrndup(str, strlen), strlen); \
186 w->cb = cb; \
187
188 #define PHP_UV_INIT_SEND_REQ(w, uv, str, strlen) \
189 w = (send_req_t *) emalloc(sizeof(send_req_t)); \
190 w->req.data = uv; \
191 w->buf = uv_buf_init(estrndup(str, strlen), strlen); \
192
193 #define PHP_UV_FETCH_UV_DEFAULT_LOOP(loop) \
194 if (loop == NULL) { \
195 loop = php_uv_default_loop(); \
196 } \
197
198 #define PHP_UV_INIT_LOCK(lock, lock_type) \
199 PHP_UV_INIT_GENERIC(lock, php_uv_lock_t, uv_lock_ce); \
200 lock->type = lock_type;
201
202 #define PHP_UV_CHECK_VALID_FD(fd, zstream) \
203 if (fd < 0) { \
204 php_error_docref(NULL, E_WARNING, "invalid variable passed. can't convert to fd."); \
205 PHP_UV_DEINIT_UV(uv); \
206 RETURN_FALSE; \
207 } \
208 if (Z_ISUNDEF(uv->fs_fd)) { \
209 ZVAL_COPY(&uv->fs_fd, zstream); \
210 }
211
212 #define PHP_UV_ZVAL_TO_VALID_POLL_FD(fd, zstream) \
213 { \
214 fd = php_uv_zval_to_valid_poll_fd(zstream); \
215 PHP_UV_CHECK_VALID_FD(fd, zstream) \
216 }
217
218 #define PHP_UV_ZVAL_TO_FD(fd, zstream) \
219 { \
220 fd = php_uv_zval_to_fd(zstream); \
221 PHP_UV_CHECK_VALID_FD(fd, zstream) \
222 }
223
224 #define PHP_UV_FS_ASYNC(loop, func, ...) \
225 error = uv_fs_##func(&loop->loop, (uv_fs_t*)&uv->uv.fs, __VA_ARGS__, php_uv_fs_cb); \
226 if (error) { \
227 PHP_UV_DEINIT_UV(uv); \
228 php_error_docref(NULL, E_WARNING, "uv_" #func " failed"); \
229 return; \
230 }
231
232 #define PHP_UV_INIT_ZVALS(uv) \
233 { \
234 int ix = 0;\
235 for (ix = 0; ix < PHP_UV_CB_MAX; ix++) {\
236 uv->callback[ix] = NULL;\
237 } \
238 ZVAL_UNDEF(&uv->fs_fd); \
239 ZVAL_UNDEF(&uv->fs_fd_alt); \
240 }
241
242 #if PHP_VERSION_ID < 70300
243 #define PHP_UV_SKIP_DTOR(uv) do { GC_FLAGS(&uv->std) |= IS_OBJ_DESTRUCTOR_CALLED; } while (0)
244 #else
245 #define PHP_UV_SKIP_DTOR(uv) do { GC_ADD_FLAGS(&uv->std, IS_OBJ_DESTRUCTOR_CALLED); } while (0)
246 #endif
247 #define PHP_UV_IS_DTORED(uv) (GC_FLAGS(&uv->std) & IS_OBJ_DESTRUCTOR_CALLED)
248
249 #define PHP_UV_SOCKADDR_IPV4_INIT(sockaddr) PHP_UV_INIT_GENERIC(sockaddr, php_uv_sockaddr_t, uv_sockaddr_ipv4_ce);
250 #define PHP_UV_SOCKADDR_IPV6_INIT(sockaddr) PHP_UV_INIT_GENERIC(sockaddr, php_uv_sockaddr_t, uv_sockaddr_ipv6_ce);
251
252 #define PHP_UV_SOCKADDR_IS_IPV4(sockaddr) (sockaddr->std.ce == uv_sockaddr_ipv4_ce)
253 #define PHP_UV_SOCKADDR_IS_IPV6(sockaddr) (sockaddr->std.ce == uv_sockaddr_ipv6_ce)
254
255 #define PHP_UV_SOCKADDR_IPV4(sockaddr) sockaddr->addr.ipv4
256 #define PHP_UV_SOCKADDR_IPV4_P(sockaddr) &sockaddr->addr.ipv4
257
258 #define PHP_UV_SOCKADDR_IPV6(sockaddr) sockaddr->addr.ipv6
259 #define PHP_UV_SOCKADDR_IPV6_P(sockaddr) &sockaddr->addr.ipv6
260
261 #define PHP_UV_LOCK_RWLOCK_P(_lock) &_lock->lock.rwlock
262 #define PHP_UV_LOCK_MUTEX_P(_lock) &_lock->lock.mutex
263 #define PHP_UV_LOCK_SEM_P(_lock) &_lock->lock.semaphore
264
265 #define PHP_UV_FD_TO_ZVAL(zv, fd) { php_stream *_stream = php_stream_fopen_from_fd(fd, "w+", NULL); zval *_z = (zv); php_stream_to_zval(_stream, _z); }
266
267 #if PHP_UV_DEBUG>=1
268 #define PHP_UV_DEBUG_PRINT(format, ...) fprintf(stderr, format, ## __VA_ARGS__)
269 #else
270 #define PHP_UV_DEBUG_PRINT(format, ...)
271 #endif
272
273 #if PHP_UV_DEBUG>=1
274 #define PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(handler, uv) \
275 { \
276 PHP_UV_DEBUG_PRINT("# %s add(%p - %s): %u->%u\n", #handler, uv, ZSTR_VAL(uv->std.ce->name), GC_REFCOUNT(&(uv)->std) - 1, GC_REFCOUNT(&(uv)->std)); \
277 }
278 #define PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(handler, uv) \
279 { \
280 PHP_UV_DEBUG_PRINT("# %s del(%p - %s): %u->%u\n", #handler, uv, ZSTR_VAL(uv->std.ce->name), GC_REFCOUNT(&(uv)->std), GC_REFCOUNT(&(uv)->std) - 1); \
281 }
282 #else
283 #define PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(hander, uv)
284 #define PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(hander, uv)
285 #endif
286
287 #if defined(ZTS) && PHP_VERSION_ID < 80000
288 #define UV_FETCH_ALL(ls, id, type) ((type) (*((void ***) ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])
289 #define UV_FETCH_CTX(ls, id, type, element) (((type) (*((void ***) ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
290 #define UV_CG(ls, v) UV_FETCH_CTX(ls, compiler_globals_id, zend_compiler_globals*, v)
291 #define UV_CG_ALL(ls) UV_FETCH_ALL(ls, compiler_globals_id, zend_compiler_globals*)
292 #define UV_EG(ls, v) UV_FETCH_CTX(ls, executor_globals_id, zend_executor_globals*, v)
293 #define UV_SG(ls, v) UV_FETCH_CTX(ls, sapi_globals_id, sapi_globals_struct*, v)
294 #define UV_EG_ALL(ls) UV_FETCH_ALL(ls, executor_globals_id, zend_executor_globals*)
295 #endif
296
297 #if !defined(PHP_WIN32) && !(defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS))
298 # if PHP_VERSION_ID >= 80000
299 __attribute__((weak)) zend_class_entry *socket_ce = NULL;
300 # else
301 int (*php_sockets_le_socket_ptr)(void) = NULL;
302 int php_sockets_le_socket(void) __attribute__((weak));
303 # endif
304 #endif
305
306 /* objects */
307 extern void php_uv_init(zend_class_entry *uv_ce);
308
309 static zend_object_handlers uv_default_handlers;
310
311 static zend_class_entry *uv_ce;
312 static zend_object_handlers uv_handlers;
313
314 static zend_class_entry *uv_stream_ce;
315
316 static zend_class_entry *uv_tcp_ce;
317 static zend_class_entry *uv_udp_ce;
318 static zend_class_entry *uv_pipe_ce;
319 static zend_class_entry *uv_idle_ce;
320 static zend_class_entry *uv_timer_ce;
321 static zend_class_entry *uv_async_ce;
322 static zend_class_entry *uv_addrinfo_ce;
323 static zend_class_entry *uv_process_ce;
324 static zend_class_entry *uv_prepare_ce;
325 static zend_class_entry *uv_check_ce;
326 static zend_class_entry *uv_work_ce;
327 static zend_class_entry *uv_fs_ce;
328 static zend_class_entry *uv_fs_event_ce;
329 static zend_class_entry *uv_tty_ce;
330 static zend_class_entry *uv_fs_poll_ce;
331 static zend_class_entry *uv_poll_ce;
332 static zend_class_entry *uv_signal_ce;
333
334 static zend_class_entry *uv_loop_ce;
335 static zend_object_handlers uv_loop_handlers;
336
337 static zend_class_entry *uv_sockaddr_ce;
338
339 static zend_class_entry *uv_sockaddr_ipv4_ce;
340 static zend_class_entry *uv_sockaddr_ipv6_ce;
341
342 static zend_class_entry *uv_lock_ce;
343 static zend_object_handlers uv_lock_handlers;
344
345 static zend_class_entry *uv_stdio_ce;
346 static zend_object_handlers uv_stdio_handlers;
347
348
349 typedef struct {
350 uv_write_t req;
351 uv_buf_t buf;
352 php_uv_cb_t *cb;
353 } write_req_t;
354
355 typedef struct {
356 uv_udp_send_t req;
357 uv_buf_t buf;
358 } send_req_t;
359
360 enum php_uv_socket_type {
361 PHP_UV_TCP_IPV4 = 1,
362 PHP_UV_TCP_IPV6 = 2,
363 PHP_UV_TCP = 3,
364 PHP_UV_UDP_IPV4 = 16,
365 PHP_UV_UDP_IPV6 = 32,
366 PHP_UV_UDP = 48,
367 };
368
369 /* declarations */
370
371 static void php_uv_fs_cb(uv_fs_t* req);
372 /**
373 * execute callback
374 *
375 * @param zval* retval_ptr non-initialized pointer. this will be allocate from zend_call_function
376 * @param php_uv_cb_t* callback callable object
377 * @param zval* params parameters.
378 * @param int param_count
379 * @return int (maybe..)
380 */
381 static int php_uv_do_callback(zval *retval_ptr, php_uv_cb_t *callback, zval *params, int param_count TSRMLS_DC);
382
383 void static destruct_uv(zend_object *obj);
384 void static clean_uv_handle(php_uv_t *uv);
385
386 static void php_uv_tcp_connect_cb(uv_connect_t *conn_req, int status);
387
388 static void php_uv_write_cb(uv_write_t* req, int status);
389
390 static void php_uv_listen_cb(uv_stream_t* server, int status);
391
392 static void php_uv_shutdown_cb(uv_shutdown_t* req, int status);
393
394 static void php_uv_read_cb(uv_stream_t* handle, ssize_t nread,const uv_buf_t* buf);
395
396 /* unused: static void php_uv_read2_cb(uv_pipe_t* handle, ssize_t nread, uv_buf_t buf, uv_handle_type pending); */
397
398 static void php_uv_read_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
399
400 static void php_uv_close(php_uv_t *uv);
401
402 static void php_uv_timer_cb(uv_timer_t *handle);
403
404 static void php_uv_idle_cb(uv_timer_t *handle);
405
406 static void php_uv_signal_cb(uv_signal_t *handle, int sig_num);
407
408
409 static php_uv_loop_t *php_uv_default_loop()
410 {
411 if (UV_G(default_loop) == NULL) {
412 zval zv;
413 object_init_ex(&zv, uv_loop_ce);
414 UV_G(default_loop) = (php_uv_loop_t *) Z_OBJ(zv);
415 }
416
417 return UV_G(default_loop);
418 }
419
420 static php_socket_t php_uv_zval_to_valid_poll_fd(zval *ptr)
421 {
422 php_socket_t fd = -1;
423 php_stream *stream;
424
425 /* Validate Checks */
426
427 #if !defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS))
428 php_socket *socket;
429 #endif
430 /* TODO: is this correct on windows platform? */
431 if (Z_TYPE_P(ptr) == IS_RESOURCE) {
432 if ((stream = (php_stream *) zend_fetch_resource_ex(ptr, NULL, php_file_le_stream()))) {
433 /* make sure only valid resource streams are passed - plainfiles and most php streams are invalid */
434 if (stream->wrapper && !strcmp((char *)stream->wrapper->wops->label, "PHP") && (!stream->orig_path || (strncmp(stream->orig_path, "php://std", sizeof("php://std") - 1) && strncmp(stream->orig_path, "php://fd", sizeof("php://fd") - 1)))) {
435 php_error_docref(NULL, E_WARNING, "invalid resource passed, this resource is not supported");
436 return -1;
437 }
438
439 /* Some streams (specifically STDIO and encrypted streams) can be cast to FDs */
440 if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) == SUCCESS && fd >= 0) {
441 if (stream->wrapper && !strcmp((char *)stream->wrapper->wops->label, "plainfile")) {
442 #ifndef PHP_WIN32
443 struct stat stat;
444 fstat(fd, &stat);
445 if (!S_ISFIFO(stat.st_mode))
446 #endif
447 {
448 php_error_docref(NULL, E_WARNING, "invalid resource passed, this plain files are not supported");
449 return -1;
450 }
451 }
452 return fd;
453 }
454
455 fd = -1;
456 #if PHP_VERSION_ID < 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS)))
457 } else if (php_sockets_le_socket_ptr && (socket = (php_socket *) zend_fetch_resource_ex(ptr, NULL, php_sockets_le_socket_ptr()))) {
458 fd = socket->bsd_socket;
459 #endif
460 } else {
461 php_error_docref(NULL, E_WARNING, "unhandled resource type detected.");
462 fd = -1;
463 }
464 #if PHP_VERSION_ID >= 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS)))
465 } else if (socket_ce && Z_TYPE_P(ptr) == IS_OBJECT && Z_OBJCE_P(ptr) == socket_ce && (socket = (php_socket *) ((char *)(Z_OBJ_P(ptr)) - XtOffsetOf(php_socket, std)))) {
466 fd = socket->bsd_socket;
467 #endif
468 }
469
470 return fd;
471 }
472
473 static php_socket_t php_uv_zval_to_fd(zval *ptr)
474 {
475 php_socket_t fd = -1;
476 php_stream *stream;
477 #if !defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS))
478 php_socket *socket;
479 #endif
480 /* TODO: is this correct on windows platform? */
481 if (Z_TYPE_P(ptr) == IS_RESOURCE) {
482 if ((stream = (php_stream *) zend_fetch_resource_ex(ptr, NULL, php_file_le_stream()))) {
483 if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void *) &fd, 1) != SUCCESS || fd < 0) {
484 fd = -1;
485 }
486 #if PHP_VERSION_ID < 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS)))
487 } else if (php_sockets_le_socket_ptr && (socket = (php_socket *) zend_fetch_resource_ex(ptr, NULL, php_sockets_le_socket_ptr()))) {
488 fd = socket->bsd_socket;
489 #endif
490 } else {
491 php_error_docref(NULL, E_WARNING, "unhandled resource type detected.");
492 fd = -1;
493 }
494 } else if (Z_TYPE_P(ptr) == IS_LONG) {
495 fd = Z_LVAL_P(ptr);
496 if (fd < 0) {
497 fd = -1;
498 }
499
500 {
501 /* make sure that a valid resource handle was passed - issue #36 */
502 int err = uv_guess_handle((uv_file) fd);
503 if (err == UV_UNKNOWN_HANDLE) {
504 php_error_docref(NULL, E_WARNING, "invalid resource type detected");
505 fd = -1;
506 }
507 }
508 #if PHP_VERSION_ID >= 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS)))
509 } else if (socket_ce && Z_TYPE_P(ptr) == IS_OBJECT && Z_OBJCE_P(ptr) == socket_ce && (socket = (php_socket *) ((char *)(Z_OBJ_P(ptr)) - XtOffsetOf(php_socket, std)))) {
510 fd = socket->bsd_socket;
511 #endif
512 }
513
514 return fd;
515 }
516
517 static const char* php_uv_strerror(long error_code)
518 {
519 /* Note: uv_strerror doesn't use assert. we don't need check value here */
520 return uv_strerror(error_code);
521 }
522
523 static php_uv_cb_t* php_uv_cb_init_dynamic(php_uv_t *uv, zend_fcall_info *fci, zend_fcall_info_cache *fcc) {
524 php_uv_cb_t *cb = emalloc(sizeof(php_uv_cb_t));
525
526 memcpy(&cb->fci, fci, sizeof(zend_fcall_info));
527 memcpy(&cb->fcc, fcc, sizeof(zend_fcall_info_cache));
528
529 if (ZEND_FCI_INITIALIZED(*fci)) {
530 Z_TRY_ADDREF(cb->fci.function_name);
531 if (fci->object) {
532 GC_ADDREF(cb->fci.object);
533 }
534 }
535
536 return cb;
537 }
538
539 static void php_uv_cb_init(php_uv_cb_t **result, php_uv_t *uv, zend_fcall_info *fci, zend_fcall_info_cache *fcc, enum php_uv_callback_type type)
540 {
541 php_uv_cb_t *cb;
542
543 if (uv->callback[type] == NULL) {
544 cb = emalloc(sizeof(php_uv_cb_t));
545 } else {
546 cb = uv->callback[type];
547
548 if (Z_TYPE(cb->fci.function_name) != IS_UNDEF) {
549 zval_dtor(&cb->fci.function_name);
550 }
551 if (fci->object) {
552 OBJ_RELEASE(fci->object);
553 }
554 }
555
556 memcpy(&cb->fci, fci, sizeof(zend_fcall_info));
557 memcpy(&cb->fcc, fcc, sizeof(zend_fcall_info_cache));
558
559 if (ZEND_FCI_INITIALIZED(*fci)) {
560 Z_TRY_ADDREF(cb->fci.function_name);
561 if (fci->object) {
562 GC_ADDREF(cb->fci.object);
563 }
564 }
565
566 uv->callback[type] = cb;
567 }
568
569 static void php_uv_lock_init(enum php_uv_lock_type lock_type, INTERNAL_FUNCTION_PARAMETERS)
570 {
571 php_uv_lock_t *lock = NULL;
572 int error = 0;
573
574 switch (lock_type) {
575 case IS_UV_RWLOCK:
576 case IS_UV_RWLOCK_WR:
577 case IS_UV_RWLOCK_RD:
578 {
579 PHP_UV_INIT_LOCK(lock, IS_UV_RWLOCK);
580 error = uv_rwlock_init(PHP_UV_LOCK_RWLOCK_P(lock));
581 }
582 break;
583 case IS_UV_MUTEX:
584 {
585 PHP_UV_INIT_LOCK(lock, IS_UV_MUTEX);
586 error = uv_mutex_init(PHP_UV_LOCK_MUTEX_P(lock));
587 }
588 break;
589 case IS_UV_SEMAPHORE:
590 {
591 zend_long val = 0;
592
593 if (zend_parse_parameters(ZEND_NUM_ARGS(),
594 "l", &val) == FAILURE) {
595 return;
596 }
597
598 PHP_UV_INIT_LOCK(lock, IS_UV_SEMAPHORE);
599 error = uv_sem_init(PHP_UV_LOCK_SEM_P(lock), (int) val);
600 }
601 break;
602 default:
603 php_error_docref(NULL, E_ERROR, "unexpected type");
604 break;
605 }
606
607 if (error == 0) {
608 RETURN_OBJ(&lock->std);
609 } else {
610 OBJ_RELEASE(&lock->std);
611 RETURN_FALSE;
612 }
613 }
614
615 static void php_uv_lock_lock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTION_PARAMETERS)
616 {
617 php_uv_lock_t *lock;
618
619 ZEND_PARSE_PARAMETERS_START(1, 1)
620 UV_PARAM_OBJ(lock, php_uv_lock_t, uv_lock_ce)
621 ZEND_PARSE_PARAMETERS_END();
622
623 switch (lock_type) {
624 case IS_UV_RWLOCK:
625 case IS_UV_RWLOCK_RD:
626 {
627 if (lock->locked == 0x01) {
628 zend_error(E_WARNING, "Cannot acquire a read lock while holding a write lock");
629 RETURN_FALSE;
630 }
631
632 uv_rwlock_rdlock(PHP_UV_LOCK_RWLOCK_P(lock));
633 if (!lock->locked++) {
634 lock->locked = 0x02;
635 }
636 }
637 break;
638 case IS_UV_RWLOCK_WR:
639 {
640 if (lock->locked) {
641 zend_error(E_WARNING, "Cannot acquire a write lock when already holding a lock");
642 RETURN_FALSE;
643 }
644
645 uv_rwlock_wrlock(PHP_UV_LOCK_RWLOCK_P(lock));
646 lock->locked = 0x01;
647 }
648 break;
649 case IS_UV_MUTEX:
650 {
651 uv_mutex_lock(PHP_UV_LOCK_MUTEX_P(lock));
652 lock->locked = 0x01;
653 }
654 break;
655 case IS_UV_SEMAPHORE:
656 {
657 uv_sem_post(PHP_UV_LOCK_SEM_P(lock));
658 }
659 break;
660 default:
661 php_error_docref(NULL, E_ERROR, "unexpected type");
662 break;
663 }
664 }
665
666 static void php_uv_lock_unlock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTION_PARAMETERS)
667 {
668 php_uv_lock_t *lock;
669
670 ZEND_PARSE_PARAMETERS_START(1, 1)
671 UV_PARAM_OBJ(lock, php_uv_lock_t, uv_lock_ce)
672 ZEND_PARSE_PARAMETERS_END();
673
674 switch (lock_type) {
675 case IS_UV_RWLOCK:
676 case IS_UV_RWLOCK_RD:
677 {
678 if (lock->locked > 0x01) {
679 uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
680 if (--lock->locked == 0x01) {
681 lock->locked = 0x00;
682 }
683 }
684 }
685 break;
686 case IS_UV_RWLOCK_WR:
687 {
688 if (lock->locked == 0x01) {
689 uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
690 lock->locked = 0x00;
691 }
692 }
693 break;
694 case IS_UV_MUTEX:
695 {
696 if (lock->locked == 0x01) {
697 uv_mutex_unlock(PHP_UV_LOCK_MUTEX_P(lock));
698 lock->locked = 0x00;
699 }
700 }
701 break;
702 case IS_UV_SEMAPHORE:
703 {
704 uv_sem_wait(PHP_UV_LOCK_SEM_P(lock));
705 }
706 break;
707 default:
708 php_error_docref(NULL, E_ERROR, "unexpected type");
709 break;
710 }
711 }
712
713 static void php_uv_lock_trylock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTION_PARAMETERS)
714 {
715 php_uv_lock_t *lock;
716 int error = 0;
717
718 ZEND_PARSE_PARAMETERS_START(1, 1)
719 UV_PARAM_OBJ(lock, php_uv_lock_t, uv_lock_ce)
720 ZEND_PARSE_PARAMETERS_END();
721
722 switch(lock_type) {
723 case IS_UV_RWLOCK:
724 case IS_UV_RWLOCK_RD:
725 {
726 if (lock->locked == 0x01) {
727 zend_error(E_WARNING, "Cannot acquire a read lock while holding a write lock");
728 RETURN_FALSE;
729 }
730
731 error = uv_rwlock_tryrdlock(PHP_UV_LOCK_RWLOCK_P(lock));
732 if (error == 0) {
733 if (!lock->locked++) {
734 lock->locked = 0x02;
735 }
736 RETURN_TRUE;
737 } else {
738 RETURN_FALSE;
739 }
740 }
741 break;
742 case IS_UV_RWLOCK_WR:
743 {
744 if (lock->locked) {
745 zend_error(E_WARNING, "Cannot acquire a write lock when already holding a lock");
746 RETURN_FALSE;
747 }
748
749 error = uv_rwlock_trywrlock(PHP_UV_LOCK_RWLOCK_P(lock));
750 if (error == 0) {
751 lock->locked = 0x01;
752 RETURN_TRUE;
753 } else {
754 RETURN_FALSE;
755 }
756 }
757 break;
758 case IS_UV_MUTEX:
759 {
760 error = uv_mutex_trylock(PHP_UV_LOCK_MUTEX_P(lock));
761
762 if (error == 0) {
763 lock->locked = 0x01;
764 RETURN_TRUE;
765 } else {
766 RETURN_FALSE;
767 }
768 }
769 break;
770 case IS_UV_SEMAPHORE:
771 {
772 error = uv_sem_trywait(PHP_UV_LOCK_SEM_P(lock));
773 RETURN_LONG(error);
774 }
775 default:
776 php_error_docref(NULL, E_ERROR, "unexpected type");
777 break;
778 }
779 }
780
781
782 static void php_uv_fs_common(uv_fs_type fs_type, INTERNAL_FUNCTION_PARAMETERS)
783 {
784 int error = 0;
785 php_uv_loop_t *loop;
786 php_uv_t *uv;
787 zend_fcall_info fci = empty_fcall_info;
788 zend_fcall_info_cache fcc = empty_fcall_info_cache;
789 php_uv_cb_t *cb;
790
791 #define PHP_UV_FS_PARSE_PARAMETERS_EX(num, params, required_cb) \
792 ZEND_PARSE_PARAMETERS_START(1 + num + required_cb, 2 + num) \
793 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce) \
794 params \
795 if (!required_cb) { \
796 Z_PARAM_OPTIONAL \
797 } \
798 Z_PARAM_FUNC_EX(fci, fcc, 1, 0) \
799 ZEND_PARSE_PARAMETERS_END()
800
801 #define PHP_UV_FS_PARSE_PARAMETERS(num, params) PHP_UV_FS_PARSE_PARAMETERS_EX(num, params, 0)
802
803 #define PHP_UV_FS_SETUP() \
804 PHP_UV_INIT_UV(uv, uv_fs_ce); \
805 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop); \
806 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_FS_CB);
807
808 #define PHP_UV_FS_SETUP_AND_EXECUTE(command, ...) \
809 PHP_UV_FS_SETUP(); \
810 PHP_UV_FS_ASYNC(loop, command, __VA_ARGS__);
811
812 switch (fs_type) {
813 case UV_FS_SYMLINK:
814 {
815 zend_string *from, *to;
816 zend_long flags;
817
818 PHP_UV_FS_PARSE_PARAMETERS(3, Z_PARAM_STR(from) Z_PARAM_STR(to) Z_PARAM_LONG(flags));
819 PHP_UV_FS_SETUP_AND_EXECUTE(symlink, from->val, to->val, flags);
820 break;
821 }
822 case UV_FS_LINK:
823 {
824 zend_string *from, *to;
825
826 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_STR(from) Z_PARAM_STR(to));
827 PHP_UV_FS_SETUP_AND_EXECUTE(link, from->val, to->val);
828 break;
829 }
830 case UV_FS_CHMOD:
831 {
832 zend_long mode;
833 zend_string *path;
834
835 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_STR(path) Z_PARAM_LONG(mode));
836 PHP_UV_FS_SETUP_AND_EXECUTE(chmod, path->val, mode);
837 break;
838 }
839 case UV_FS_FCHMOD:
840 {
841 zval *zstream;
842 zend_long mode;
843 unsigned long fd;
844
845 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_RESOURCE(zstream) Z_PARAM_LONG(mode));
846 PHP_UV_FS_SETUP();
847 PHP_UV_ZVAL_TO_FD(fd, zstream);
848 uv->fs_fd = *zstream;
849 Z_ADDREF(uv->fs_fd);
850 PHP_UV_FS_ASYNC(loop, fchmod, fd, mode);
851 break;
852 }
853 case UV_FS_RENAME:
854 {
855 zend_string *from, *to;
856
857 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_STR(from) Z_PARAM_STR(to));
858 PHP_UV_FS_SETUP_AND_EXECUTE(rename, from->val, to->val);
859 break;
860 }
861 case UV_FS_UNLINK:
862 {
863 zend_string *path;
864
865 PHP_UV_FS_PARSE_PARAMETERS(1, Z_PARAM_STR(path));
866 PHP_UV_FS_SETUP_AND_EXECUTE(unlink, path->val);
867 break;
868 }
869 case UV_FS_RMDIR:
870 {
871 zend_string *path;
872
873 PHP_UV_FS_PARSE_PARAMETERS(1, Z_PARAM_STR(path));
874 PHP_UV_FS_SETUP_AND_EXECUTE(rmdir, path->val);
875 break;
876 }
877 case UV_FS_MKDIR:
878 {
879 zend_string *path;
880 zend_long mode;
881
882 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_STR(path) Z_PARAM_LONG(mode));
883 PHP_UV_FS_SETUP_AND_EXECUTE(mkdir, path->val, mode);
884 break;
885 }
886 case UV_FS_FTRUNCATE:
887 {
888 zval *zstream = NULL;
889 zend_long offset = 0;
890 unsigned long fd;
891
892 PHP_UV_FS_PARSE_PARAMETERS(2, Z_PARAM_RESOURCE(zstream) Z_PARAM_LONG(offset));
893 PHP_UV_FS_SETUP()
894 PHP_UV_ZVAL_TO_FD(fd, zstream);
895 uv->fs_fd = *zstream;
896 Z_ADDREF(uv->fs_fd);
897 PHP_UV_FS_ASYNC(loop, ftruncate, fd, offset);
898 break;
899 }
900 case UV_FS_FDATASYNC:
901 {
902 zval *zstream = NULL;
903 unsigned long fd;
904
905 PHP_UV_FS_PARSE_PARAMETERS(1, Z_PARAM_RESOURCE(zstream));
906 PHP_UV_FS_SETUP()
907 PHP_UV_ZVAL_TO_FD(fd, zstream);
908 uv->fs_fd = *zstream;
909 Z_ADDREF(uv->fs_fd);
910 PHP_UV_FS_ASYNC(loop, fdatasync, fd);
911 break;
912 }
913 case UV_FS_FSYNC:
914 {
915 zval *zstream = NULL;
916 unsigned long fd;
917
918 PHP_UV_FS_PARSE_PARAMETERS(1, Z_PARAM_RESOURCE(zstream));
919 PHP_UV_FS_SETUP()
920 PHP_UV_ZVAL_TO_FD(fd, zstream);
921 uv->fs_fd = *zstream;
922 Z_ADDREF(uv->fs_fd);
923 PHP_UV_FS_ASYNC(loop, fsync, fd);
924 break;
925 }
926 case UV_FS_CLOSE:
927 {
928 zval *zstream = NULL;
929 unsigned long fd;
930
931 PHP_UV_FS_PARSE_PARAMETERS(1, Z_PARAM_RESOURCE(zstream));
932 PHP_UV_FS_SETUP()
933 PHP_UV_ZVAL_TO_FD(fd, zstream);
934 uv->fs_fd = *zstream;
935 Z_ADDREF(uv->fs_fd);
936 PHP_UV_FS_ASYNC(loop, close, fd);
937 break;
938 }
939 case UV_FS_CHOWN:
940 {
941 zend_long uid, gid;
942 zend_string *path;
943
944 PHP_UV_FS_PARSE_PARAMETERS(3, Z_PARAM_STR(path) Z_PARAM_LONG(uid) Z_PARAM_LONG(gid));
945 PHP_UV_FS_SETUP_AND_EXECUTE(chown, path->val, uid, gid);
946 break;
947 }
948 case UV_FS_FCHOWN:
949 {
950 zval *zstream = NULL;
951 zend_long uid, gid;
952 unsigned long fd;
953
954 PHP_UV_FS_PARSE_PARAMETERS(3, Z_PARAM_RESOURCE(zstream) Z_PARAM_LONG(uid) Z_PARAM_LONG(gid));
955 PHP_UV_FS_SETUP()
956 PHP_UV_ZVAL_TO_FD(fd, zstream);
957 uv->fs_fd = *zstream;
958 Z_ADDREF(uv->fs_fd);
959 PHP_UV_FS_ASYNC(loop, fchown, fd, uid, gid);
960 break;
961 }
962 case UV_FS_OPEN:
963 {
964 zend_string *path;
965 zend_long flag, mode;
966
967 PHP_UV_FS_PARSE_PARAMETERS_EX(3, Z_PARAM_STR(path) Z_PARAM_LONG(flag) Z_PARAM_LONG(mode), 1);
968 PHP_UV_FS_SETUP_AND_EXECUTE(open, path->val, flag, mode);
969 break;
970 }
971 case UV_FS_SCANDIR:
972 {
973 zend_string *path;
974 zend_long flags = 0;
975
976 ZEND_PARSE_PARAMETERS_START(3, 4)
977 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
978 Z_PARAM_STR(path)
979 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
980 Z_PARAM_OPTIONAL
981 Z_PARAM_LONG(flags)
982 ZEND_PARSE_PARAMETERS_END();
983 PHP_UV_FS_SETUP_AND_EXECUTE(scandir, path->val, flags);
984 break;
985 }
986 case UV_FS_LSTAT:
987 {
988 zend_string *path;
989
990 PHP_UV_FS_PARSE_PARAMETERS_EX(1, Z_PARAM_STR(path), 1);
991 PHP_UV_FS_SETUP_AND_EXECUTE(lstat, path->val);
992 break;
993 }
994 case UV_FS_FSTAT:
995 {
996 zval *zstream = NULL;
997 unsigned long fd;
998
999 PHP_UV_FS_PARSE_PARAMETERS_EX(1, Z_PARAM_RESOURCE(zstream), 1);
1000 PHP_UV_FS_SETUP()
1001 PHP_UV_ZVAL_TO_FD(fd, zstream);
1002 uv->fs_fd = *zstream;
1003 Z_ADDREF(uv->fs_fd);
1004 PHP_UV_FS_ASYNC(loop, fstat, fd);
1005 break;
1006 }
1007 case UV_FS_STAT:
1008 {
1009 zend_string *path;
1010
1011 PHP_UV_FS_PARSE_PARAMETERS_EX(1, Z_PARAM_STR(path), 1);
1012 PHP_UV_FS_SETUP_AND_EXECUTE(stat, path->val);
1013 break;
1014 }
1015 case UV_FS_UTIME:
1016 {
1017 zend_long utime, atime;
1018 zend_string *path;
1019
1020 PHP_UV_FS_PARSE_PARAMETERS(3, Z_PARAM_STR(path) Z_PARAM_LONG(utime) Z_PARAM_LONG(atime));
1021 PHP_UV_FS_SETUP_AND_EXECUTE(utime, path->val, utime, atime);
1022 break;
1023 }
1024 case UV_FS_FUTIME:
1025 {
1026 zval *zstream = NULL;
1027 zend_long utime, atime;
1028 unsigned long fd;
1029
1030 PHP_UV_FS_PARSE_PARAMETERS(3, Z_PARAM_RESOURCE(zstream) Z_PARAM_LONG(utime) Z_PARAM_LONG(atime));
1031 PHP_UV_FS_SETUP()
1032 PHP_UV_ZVAL_TO_FD(fd, zstream);
1033 uv->fs_fd = *zstream;
1034 Z_ADDREF(uv->fs_fd);
1035 PHP_UV_FS_ASYNC(loop, futime, fd, utime, atime);
1036 break;
1037 }
1038 case UV_FS_READLINK:
1039 {
1040 zend_string *path;
1041
1042 PHP_UV_FS_PARSE_PARAMETERS_EX(1, Z_PARAM_STR(path), 1);
1043 PHP_UV_FS_SETUP_AND_EXECUTE(readlink, path->val);
1044 break;
1045 }
1046 case UV_FS_READ:
1047 {
1048 zval *zstream = NULL;
1049 unsigned long fd;
1050 zend_long length;
1051 zend_long offset;
1052 uv_buf_t buf;
1053
1054 PHP_UV_FS_PARSE_PARAMETERS_EX(3, Z_PARAM_RESOURCE(zstream) Z_PARAM_LONG(offset) Z_PARAM_LONG(length), 1);
1055 if (length <= 0) {
1056 length = 0;
1057 }
1058 if (offset < 0) {
1059 offset = 0;
1060 }
1061 PHP_UV_FS_SETUP()
1062 PHP_UV_ZVAL_TO_FD(fd, zstream);
1063 uv->fs_fd = *zstream;
1064 Z_ADDREF(uv->fs_fd);
1065
1066 uv->buffer = (char*) emalloc(length);
1067 buf = uv_buf_init(uv->buffer, length);
1068
1069 PHP_UV_FS_ASYNC(loop, read, fd, &buf, 1, offset);
1070 break;
1071 }
1072 case UV_FS_SENDFILE:
1073 {
1074 zval *z_instream, *z_outstream = NULL;
1075 unsigned long in_fd, out_fd;
1076 zend_long offset, length = 0;
1077
1078 PHP_UV_FS_PARSE_PARAMETERS(4, Z_PARAM_RESOURCE(z_instream) Z_PARAM_RESOURCE(z_outstream) Z_PARAM_LONG(offset) Z_PARAM_LONG(length));
1079 PHP_UV_FS_SETUP()
1080 /* TODO */
1081 PHP_UV_ZVAL_TO_FD(in_fd, z_instream);
1082 PHP_UV_ZVAL_TO_FD(out_fd, z_outstream);
1083 uv->fs_fd = *z_outstream;
1084 Z_ADDREF(uv->fs_fd);
1085 uv->fs_fd_alt = *z_instream;
1086 Z_ADDREF(uv->fs_fd_alt);
1087 PHP_UV_FS_ASYNC(loop, sendfile, in_fd, out_fd, offset, length);
1088 break;
1089 }
1090 case UV_FS_WRITE:
1091 {
1092 zval *zstream = NULL;
1093 zend_string *buffer;
1094 zend_long fd, offset = -1;
1095 uv_buf_t uv_fs_write_buf_t;
1096
1097 ZEND_PARSE_PARAMETERS_START(3, 5)
1098 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
1099 Z_PARAM_RESOURCE(zstream)
1100 Z_PARAM_STR(buffer)
1101 Z_PARAM_OPTIONAL
1102 Z_PARAM_LONG(offset)
1103 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
1104 ZEND_PARSE_PARAMETERS_END();
1105 PHP_UV_FS_SETUP();
1106 PHP_UV_ZVAL_TO_FD(fd, zstream);
1107 uv->fs_fd = *zstream;
1108 Z_ADDREF(uv->fs_fd);
1109 uv->buffer = estrndup(buffer->val, buffer->len);
1110
1111 /* TODO: is this right?! */
1112 uv_fs_write_buf_t = uv_buf_init(uv->buffer, buffer->len);
1113 PHP_UV_FS_ASYNC(loop, write, fd, &uv_fs_write_buf_t, 1, offset);
1114 break;
1115 }
1116 case UV_FS_UNKNOWN:
1117 case UV_FS_CUSTOM:
1118 default: {
1119 php_error_docref(NULL, E_ERROR, "type; %d does not support yet.", fs_type);
1120 break;
1121 }
1122 }
1123
1124 #undef PHP_UV_FS_PARSE_PARAMETERS
1125 #undef PHP_UV_FS_SETUP
1126 #undef PHP_UV_FS_SETUP_AND_EXECUTE
1127
1128 }
1129 /* util */
1130
1131 static zval php_uv_address_to_zval(const struct sockaddr *addr)
1132 {
1133 zval tmp = {0};
1134 char ip[INET6_ADDRSTRLEN];
1135 const struct sockaddr_in *a4;
1136 const struct sockaddr_in6 *a6;
1137 int port;
1138
1139 array_init(&tmp);
1140
1141 switch (addr->sa_family) {
1142 case AF_INET6:
1143 {
1144 a6 = (const struct sockaddr_in6 *)addr;
1145 uv_inet_ntop(AF_INET, &a6->sin6_addr, ip, sizeof ip);
1146 port = ntohs(a6->sin6_port);
1147
1148 add_assoc_string_ex(&tmp, ZEND_STRL("address"), ip);
1149 add_assoc_long_ex(&tmp, ZEND_STRL("port"), port);
1150 add_assoc_string_ex(&tmp, ZEND_STRL("family"), "IPv6");
1151 break;
1152 }
1153 case AF_INET:
1154 {
1155 a4 = (const struct sockaddr_in *)addr;
1156 uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip);
1157 port = ntohs(a4->sin_port);
1158
1159 add_assoc_string_ex(&tmp, ZEND_STRL("address"), ip);
1160 add_assoc_long_ex(&tmp, ZEND_STRL("port"), port);
1161 add_assoc_string_ex(&tmp, ZEND_STRL("family"), "IPv4");
1162 break;
1163 }
1164 default:
1165 break;
1166 }
1167
1168 return tmp;
1169 }
1170
1171 static zval php_uv_make_stat(const uv_stat_t *s)
1172 {
1173 zval tmp = {0};
1174 array_init(&tmp);
1175
1176 add_assoc_long_ex(&tmp, ZEND_STRL("dev"), s->st_dev);
1177 add_assoc_long_ex(&tmp, ZEND_STRL("ino"), s->st_ino);
1178 add_assoc_long_ex(&tmp, ZEND_STRL("mode"), s->st_mode);
1179 add_assoc_long_ex(&tmp, ZEND_STRL("nlink"), s->st_nlink);
1180 add_assoc_long_ex(&tmp, ZEND_STRL("uid"), s->st_uid);
1181 add_assoc_long_ex(&tmp, ZEND_STRL("gid"), s->st_gid);
1182 add_assoc_long_ex(&tmp, ZEND_STRL("rdev"), s->st_rdev);
1183 add_assoc_long_ex(&tmp, ZEND_STRL("size"), s->st_size);
1184
1185 #ifndef PHP_WIN32
1186 add_assoc_long_ex(&tmp, ZEND_STRL("blksize"), s->st_blksize);
1187 add_assoc_long_ex(&tmp, ZEND_STRL("blocks"), s->st_blocks);
1188 #endif
1189
1190 add_assoc_long_ex(&tmp, ZEND_STRL("atime"), s->st_atim.tv_sec);
1191 add_assoc_long_ex(&tmp, ZEND_STRL("mtime"), s->st_mtim.tv_sec);
1192 add_assoc_long_ex(&tmp, ZEND_STRL("ctime"), s->st_ctim.tv_sec);
1193
1194 return tmp;
1195 }
1196
1197 static inline zend_bool php_uv_closeable_type(php_uv_t *uv) {
1198 zend_class_entry *ce = uv->std.ce;
1199 return ce == uv_pipe_ce || ce == uv_tty_ce || ce == uv_tcp_ce || ce == uv_udp_ce || ce == uv_prepare_ce || ce == uv_check_ce || ce == uv_idle_ce || ce == uv_async_ce || ce == uv_timer_ce || ce == uv_process_ce || ce == uv_fs_event_ce || ce == uv_poll_ce || ce == uv_fs_poll_ce || ce == uv_signal_ce;
1200 }
1201
1202 /* destructor */
1203
1204 void static destruct_uv_lock(zend_object *obj)
1205 {
1206 php_uv_lock_t *lock = (php_uv_lock_t *) obj;
1207
1208 if (lock->type == IS_UV_RWLOCK) {
1209 if (lock->locked == 0x01) {
1210 php_error_docref(NULL, E_NOTICE, "uv_rwlock: still locked resource detected; forcing wrunlock");
1211 uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
1212 } else if (lock->locked) {
1213 php_error_docref(NULL, E_NOTICE, "uv_rwlock: still locked resource detected; forcing rdunlock");
1214 while (--lock->locked > 0) {
1215 uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
1216 }
1217 }
1218 uv_rwlock_destroy(PHP_UV_LOCK_RWLOCK_P(lock));
1219 } else if (lock->type == IS_UV_MUTEX) {
1220 if (lock->locked == 0x01) {
1221 php_error_docref(NULL, E_NOTICE, "uv_mutex: still locked resource detected; forcing unlock");
1222 uv_mutex_unlock(PHP_UV_LOCK_MUTEX_P(lock));
1223 }
1224 uv_mutex_destroy(PHP_UV_LOCK_MUTEX_P(lock));
1225 } else if (lock->type == IS_UV_SEMAPHORE) {
1226 if (lock->locked == 0x01) {
1227 php_error_docref(NULL, E_NOTICE, "uv_sem: still locked resource detected; forcing unlock");
1228 uv_sem_post(PHP_UV_LOCK_SEM_P(lock));
1229 }
1230 uv_sem_destroy(PHP_UV_LOCK_SEM_P(lock));
1231 }
1232 }
1233
1234 static void destruct_uv_loop_walk_cb(uv_handle_t* handle, void* arg)
1235 {
1236 php_uv_t *uv = (php_uv_t *) handle->data;
1237 if (!PHP_UV_IS_DTORED(uv)) { // otherwise we're already closing
1238 php_uv_close(uv);
1239 }
1240 }
1241
1242 void static destruct_uv_loop(zend_object *obj)
1243 {
1244 php_uv_loop_t *loop_obj = (php_uv_loop_t *) obj;
1245 uv_loop_t *loop = &loop_obj->loop;
1246 if (loop_obj != UV_G(default_loop)) {
1247 uv_stop(loop); /* in case we haven't stopped the loop yet otherwise ... */
1248 uv_run(loop, UV_RUN_DEFAULT); /* invalidate the stop ;-) */
1249
1250 /* for proper destruction: close all handles, let libuv call close callback and then close and free the loop */
1251 uv_walk(loop, destruct_uv_loop_walk_cb, NULL);
1252 uv_run(loop, UV_RUN_DEFAULT);
1253 }
1254 }
1255
1256 void static free_uv_loop(zend_object *obj)
1257 {
1258 php_uv_loop_t *loop_obj = (php_uv_loop_t *) obj;
1259 if (loop_obj != UV_G(default_loop)) {
1260 uv_loop_close(&loop_obj->loop);
1261 }
1262 if (loop_obj->gc_buffer) {
1263 efree(loop_obj->gc_buffer);
1264 }
1265 }
1266
1267 void static clean_uv_handle(php_uv_t *uv) {
1268 int i;
1269
1270 /* for now */
1271 for (i = 0; i < PHP_UV_CB_MAX; i++) {
1272 php_uv_cb_t *cb = uv->callback[i];
1273 if (cb != NULL) {
1274 if (ZEND_FCI_INITIALIZED(cb->fci)) {
1275 zval_dtor(&cb->fci.function_name);
1276
1277 if (cb->fci.object != NULL) {
1278 OBJ_RELEASE(cb->fci.object);
1279 }
1280 }
1281
1282 efree(cb);
1283 cb = NULL;
1284 }
1285 }
1286
1287 PHP_UV_SKIP_DTOR(uv);
1288
1289 if (!Z_ISUNDEF(uv->fs_fd)) {
1290 zval_ptr_dtor(&uv->fs_fd);
1291 ZVAL_UNDEF(&uv->fs_fd);
1292 if (!Z_ISUNDEF(uv->fs_fd_alt)) {
1293 zval_ptr_dtor(&uv->fs_fd_alt);
1294 ZVAL_UNDEF(&uv->fs_fd_alt);
1295 }
1296 }
1297 }
1298
1299 void static destruct_uv(zend_object *obj)
1300 {
1301 php_uv_t *uv = (php_uv_t *) obj;
1302
1303 PHP_UV_DEBUG_PRINT("# will be free: (obj: %p)\n", obj);
1304
1305 if (!php_uv_closeable_type(uv)) {
1306 if (uv_cancel(&uv->uv.req) == UV_EBUSY) {
1307 GC_ADDREF(obj);
1308 }
1309 clean_uv_handle(uv);
1310 } else {
1311 php_uv_close(uv);
1312 /* cleaning happens in close_cb */
1313 }
1314 }
1315
1316 void static php_uv_free_write_req(write_req_t *wr) {
1317 if (wr->cb) {
1318 if (ZEND_FCI_INITIALIZED(wr->cb->fci)) {
1319 zval_ptr_dtor(&wr->cb->fci.function_name);
1320 if (wr->cb->fci.object != NULL) {
1321 OBJ_RELEASE(wr->cb->fci.object);
1322 }
1323 }
1324
1325 efree(wr->cb);
1326 }
1327 if (wr->buf.base) {
1328 efree(wr->buf.base);
1329 }
1330 efree(wr);
1331 }
1332
1333 /* callback */
1334 static int php_uv_do_callback(zval *retval_ptr, php_uv_cb_t *callback, zval *params, int param_count TSRMLS_DC)
1335 {
1336 int error;
1337
1338 #if defined(ZTS) && PHP_VERSION_ID < 80000
1339 void *old = tsrm_set_interpreter_context(tsrm_ls);
1340 #endif
1341
1342 if (ZEND_FCI_INITIALIZED(callback->fci)) {
1343 callback->fci.params = params;
1344 callback->fci.retval = retval_ptr;
1345 callback->fci.param_count = param_count;
1346 #if PHP_VERSION_ID < 80000
1347 callback->fci.no_separation = 1;
1348 #endif
1349
1350 error = zend_call_function(&callback->fci, &callback->fcc);
1351 } else {
1352 error = -1;
1353 }
1354
1355 #if defined(ZTS) && PHP_VERSION_ID < 80000
1356 tsrm_set_interpreter_context(old);
1357 #endif
1358
1359 return error;
1360 }
1361
1362 static int php_uv_do_callback2(zval *retval_ptr, php_uv_t *uv, zval *params, int param_count, enum php_uv_callback_type type TSRMLS_DC)
1363 {
1364 int error = 0;
1365
1366 #if defined(ZTS) && PHP_VERSION_ID < 80000
1367 void *old = tsrm_set_interpreter_context(tsrm_ls);
1368 #endif
1369 if (ZEND_FCI_INITIALIZED(uv->callback[type]->fci)) {
1370 uv->callback[type]->fci.params = params;
1371 uv->callback[type]->fci.retval = retval_ptr;
1372 uv->callback[type]->fci.param_count = param_count;
1373 #if PHP_VERSION_ID < 80000
1374 uv->callback[type]->fci.no_separation = 1;
1375 #endif
1376
1377 if (zend_call_function(&uv->callback[type]->fci, &uv->callback[type]->fcc) != SUCCESS) {
1378 error = -1;
1379 }
1380 } else {
1381 error = -2;
1382 }
1383
1384 #if defined(ZTS) && PHP_VERSION_ID < 80000
1385 tsrm_set_interpreter_context(old);
1386 #endif
1387 //zend_fcall_info_args_clear(&uv->callback[type]->fci, 0);
1388
1389 if (EG(exception)) {
1390 switch (type) {
1391 case PHP_UV_FS_CB:
1392 uv_stop(uv->uv.fs.loop);
1393 break;
1394 case PHP_UV_GETADDR_CB:
1395 uv_stop(uv->uv.addrinfo.loop);
1396 break;
1397 case PHP_UV_AFTER_WORK_CB:
1398 uv_stop(uv->uv.work.loop);
1399 break;
1400 case PHP_UV_SHUTDOWN_CB:
1401 uv_stop(uv->uv.shutdown.handle->loop);
1402 break;
1403 case PHP_UV_SEND_CB:
1404 uv_stop(uv->uv.udp_send.handle->loop);
1405 break;
1406 case PHP_UV_CONNECT_CB:
1407 case PHP_UV_PIPE_CONNECT_CB:
1408 uv_stop(uv->uv.connect.handle->loop);
1409 break;
1410 default:
1411 uv_stop(uv->uv.handle.loop);
1412 }
1413 }
1414
1415 return error;
1416 }
1417
1418 #if defined(ZTS) && PHP_VERSION_ID < 80000
1419
1420 static int php_uv_do_callback3(zval *retval_ptr, php_uv_t *uv, zval *params, int param_count, enum php_uv_callback_type type)
1421 {
1422 int error = 0;
1423 void *tsrm_ls, *old;
1424 zend_op_array *ops;
1425 zend_function fn, *old_fn;
1426
1427 if (ZEND_FCI_INITIALIZED(uv->callback[type]->fci)) {
1428 tsrm_ls = tsrm_new_interpreter_context();
1429 old = tsrm_set_interpreter_context(tsrm_ls);
1430
1431 PG(expose_php) = 0;
1432 PG(auto_globals_jit) = 0;
1433
1434 php_request_startup();
1435 EG(current_execute_data) = NULL;
1436 EG(current_module) = phpext_uv_ptr;
1437
1438 uv->callback[type]->fci.params = params;
1439 uv->callback[type]->fci.retval = retval_ptr;
1440 uv->callback[type]->fci.param_count = param_count;
1441 #if PHP_VERSION_ID < 80000
1442 uv->callback[type]->fci.no_separation = 1;
1443 #endif
1444 uv->callback[type]->fci.object = NULL;
1445 #if PHP_VERSION_ID >= 70300
1446 uv->callback[type]->fci.size = sizeof(zend_fcall_info);
1447 #else
1448 uv->callback[type]->fcc.initialized = 1;
1449 #endif
1450
1451 uv->callback[type]->fcc.calling_scope = NULL;
1452 uv->callback[type]->fcc.called_scope = NULL;
1453 uv->callback[type]->fcc.object = NULL;
1454
1455 if (!ZEND_USER_CODE(uv->callback[type]->fcc.function_handler->type)) {
1456 return error = -2;
1457 }
1458
1459 fn = *(old_fn = uv->callback[type]->fcc.function_handler);
1460 uv->callback[type]->fcc.function_handler = &fn;
1461
1462 ops = &fn.op_array;
1463 #if PHP_VERSION_ID < 70400
1464 ops->run_time_cache = NULL;
1465 #else
1466 ZEND_MAP_PTR_SET(ops->run_time_cache, NULL);
1467 #endif
1468 if (ops->fn_flags) {
1469 ops->fn_flags &= ~ZEND_ACC_CLOSURE;
1470 ops->prototype = NULL;
1471 }
1472
1473 zend_try {
1474 if (zend_call_function(&uv->callback[type]->fci, &uv->callback[type]->fcc) != SUCCESS) {
1475 error = -1;
1476 }
1477 } zend_catch {
1478 error = -1;
1479 } zend_end_try();
1480
1481 // after PHP 7.4 this is arena allocated and automatically freed
1482 #if PHP_VERSION_ID < 70400
1483 if (ops->run_time_cache && !ops->function_name) {
1484 efree(ops->run_time_cache);
1485 }
1486 #endif
1487
1488 uv->callback[type]->fcc.function_handler = old_fn;
1489
1490 php_request_shutdown(NULL);
1491 tsrm_set_interpreter_context(old);
1492 tsrm_free_interpreter_context(tsrm_ls);
1493 } else {
1494 error = -2;
1495 }
1496
1497 //zend_fcall_info_args_clear(&uv->callback[type]->fci, 0);
1498
1499 return error;
1500 }
1501 #endif
1502
1503 static void php_uv_tcp_connect_cb(uv_connect_t *req, int status)
1504 {
1505 zval retval = {0};
1506 zval params[2] = {0};
1507 php_uv_t *uv = (php_uv_t *) req->data;
1508 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1509
1510 ZVAL_OBJ(¶ms[0], &uv->std);
1511 ZVAL_LONG(¶ms[1], status);
1512
1513 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_CONNECT_CB TSRMLS_CC);
1514
1515 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_udp_tcp_cb, uv);
1516 zval_ptr_dtor(¶ms[0]);
1517 zval_ptr_dtor(¶ms[1]);
1518
1519 zval_ptr_dtor(&retval);
1520 efree(req);
1521 }
1522
1523 static void php_uv_process_close_cb(uv_process_t* process, int64_t exit_status, int term_signal)
1524 {
1525 zval retval = {0};
1526 zval params[3] = {0};
1527 php_uv_t *uv = (php_uv_t *) process->data;
1528 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1529
1530 ZVAL_OBJ(¶ms[0], &uv->std);
1531 ZVAL_LONG(¶ms[1], exit_status);
1532 ZVAL_LONG(¶ms[2], term_signal);
1533
1534 php_uv_do_callback2(&retval, uv, params, 3, PHP_UV_PROC_CLOSE_CB TSRMLS_CC);
1535
1536 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_process_close_cb, uv);
1537 zval_ptr_dtor(¶ms[0]);
1538 zval_ptr_dtor(¶ms[1]);
1539 zval_ptr_dtor(¶ms[2]);
1540
1541 zval_ptr_dtor(&retval);
1542 }
1543
1544
1545 static void php_uv_pipe_connect_cb(uv_connect_t *req, int status)
1546 {
1547 zval retval = {0};
1548 zval params[2] = {0};
1549 php_uv_t *uv = (php_uv_t*)req->data;
1550 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1551
1552 ZVAL_OBJ(¶ms[0], &uv->std);
1553 ZVAL_LONG(¶ms[1], status);
1554
1555 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_PIPE_CONNECT_CB TSRMLS_CC);
1556
1557 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_pipe_connect_cb, uv);
1558 zval_ptr_dtor(¶ms[0]);
1559 zval_ptr_dtor(¶ms[1]);
1560
1561 zval_ptr_dtor(&retval);
1562 efree(req);
1563 }
1564
1565
1566 static void php_uv_walk_cb(uv_handle_t* handle, void* arg)
1567 {
1568 /*
1569 zval retval = {0};
1570 zval params[2] = {0};
1571 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1572
1573 ZVAL_LONG(¶ms[0], status);
1574 ZVAL_OBJ(¶ms[1], &uv->std);
1575
1576 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_PIPE_CONNECT_CB TSRMLS_CC);
1577
1578 zval_ptr_dtor(¶ms[0]);
1579 zval_ptr_dtor(¶ms[1]);
1580 zval_ptr_dtor(&retval);
1581 efree(req);
1582 */
1583 }
1584
1585 static void php_uv_write_cb(uv_write_t* req, int status)
1586 {
1587 write_req_t* wr = (write_req_t*) req;
1588 zval retval = {0};
1589 zval params[2] = {0};
1590 php_uv_t *uv = (php_uv_t *) req->handle->data;
1591 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1592
1593 PHP_UV_DEBUG_PRINT("uv_write_cb: status: %d\n", status);
1594
1595 ZVAL_OBJ(¶ms[0], &uv->std);
1596 ZVAL_LONG(¶ms[1], status);
1597
1598 php_uv_do_callback(&retval, wr->cb, params, 2 TSRMLS_CC);
1599
1600 if (EG(exception)) {
1601 uv_stop(uv->uv.handle.loop);
1602 }
1603
1604 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_write_cb, uv);
1605 zval_ptr_dtor(¶ms[0]);
1606 zval_ptr_dtor(¶ms[1]);
1607
1608 zval_ptr_dtor(&retval);
1609
1610 php_uv_free_write_req(wr);
1611 }
1612
1613 static void php_uv_udp_send_cb(uv_udp_send_t* req, int status)
1614 {
1615 send_req_t* wr = (send_req_t*) req;
1616 zval retval = {0};
1617 zval params[2] = {0};
1618 php_uv_t *uv = (php_uv_t *) req->data;
1619 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1620
1621 ZVAL_OBJ(¶ms[0], &uv->std);
1622 ZVAL_LONG(¶ms[1], status);
1623
1624 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_SEND_CB TSRMLS_CC);
1625
1626 if (!uv_is_closing(&uv->uv.handle)) { /* send_cb is invoked *before* the handle is marked as inactive - uv_close() will thus *not* increment the refcount and we must then not delete the refcount here */
1627 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_udp_send_cb, uv);
1628 zval_ptr_dtor(¶ms[0]);
1629 }
1630 zval_ptr_dtor(¶ms[1]);
1631
1632 zval_ptr_dtor(&retval);
1633
1634 if (wr->buf.base) {
1635 efree(wr->buf.base);
1636 }
1637 efree(wr);
1638 }
1639
1640 static void php_uv_listen_cb(uv_stream_t* server, int status)
1641 {
1642 zval retval = {0};
1643 zval params[2] = {0};
1644 php_uv_t *uv = (php_uv_t *) server->data;
1645
1646 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1647
1648 ZVAL_OBJ(¶ms[0], &uv->std);
1649 GC_ADDREF(&uv->std);
1650 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_listen_cb, uv);
1651 ZVAL_LONG(¶ms[1], status);
1652
1653 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_LISTEN_CB TSRMLS_CC);
1654
1655 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_listen_cb, uv);
1656 zval_ptr_dtor(¶ms[0]);
1657 zval_ptr_dtor(¶ms[1]);
1658
1659 zval_ptr_dtor(&retval);
1660 }
1661
1662 static void php_uv_shutdown_cb(uv_shutdown_t* handle, int status)
1663 {
1664 zval retval = {0};
1665 zval params[2] = {0};
1666 php_uv_t *uv = (php_uv_t *) handle->data;
1667 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1668
1669 ZVAL_OBJ(¶ms[0], &uv->std);
1670 ZVAL_LONG(¶ms[1], status);
1671
1672 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_SHUTDOWN_CB TSRMLS_CC);
1673
1674 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_shutdown_cb, uv);
1675 zval_ptr_dtor(¶ms[0]);
1676 zval_ptr_dtor(¶ms[1]);
1677
1678 zval_ptr_dtor(&retval);
1679 }
1680
1681 static void php_uv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf)
1682 {
1683 zval retval = {0};
1684 zval params[2] = {0};
1685 php_uv_t *uv = (php_uv_t *) handle->data;
1686 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1687
1688 PHP_UV_DEBUG_PRINT("uv_read_cb\n");
1689
1690 ZVAL_OBJ(¶ms[0], &uv->std);
1691 if (nread > 0) { // uv disables itself when it reaches EOF/error
1692 GC_ADDREF(&uv->std);
1693 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_read_cb, uv);
1694 }
1695
1696 if (nread > 0) {
1697 ZVAL_STRINGL(¶ms[1], buf->base, nread);
1698 } else {
1699 ZVAL_LONG(¶ms[1], nread);
1700 }
1701
1702 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_READ_CB TSRMLS_CC);
1703
1704 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_read_cb, uv);
1705 zval_ptr_dtor(¶ms[0]);
1706 zval_ptr_dtor(¶ms[1]);
1707
1708 zval_ptr_dtor(&retval);
1709
1710 if (buf->base) {
1711 efree(buf->base);
1712 }
1713 }
1714
1715 /* unused
1716 static void php_uv_read2_cb(uv_pipe_t* handle, ssize_t nread, uv_buf_t buf, uv_handle_type pending)
1717 {
1718 zval retval = {0};
1719 zval params[3] = {0};
1720 php_uv_t *uv = (php_uv_t*)handle->data;
1721 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1722
1723 PHP_UV_DEBUG_PRINT("uv_read2_cb\n");
1724
1725 ZVAL_OBJ(¶ms[0], &uv->std);
1726 if (nread > 0) { // uv disables itself when it reaches EOF/error
1727 GC_ADDREF(&uv->std);
1728 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_read2_cb, uv);
1729 }
1730 if (nread > 0) {
1731 ZVAL_STRINGL(¶ms[1], buf.base,nread);
1732 } else {
1733 ZVAL_LONG(¶ms[1], nread);
1734 }
1735 ZVAL_LONG(¶ms[2], pending);
1736
1737 php_uv_do_callback2(&retval, uv, params, 3, PHP_UV_READ2_CB TSRMLS_CC);
1738
1739 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_read2_cb, uv);
1740 zval_ptr_dtor(¶ms[0]);
1741 zval_ptr_dtor(¶ms[1]);
1742 zval_ptr_dtor(¶ms[2]);
1743
1744 zval_ptr_dtor(&retval);
1745
1746 if (buf.base) {
1747 efree(buf.base);
1748 }
1749 }
1750 */
1751
1752 static void php_uv_prepare_cb(uv_prepare_t* handle)
1753 {
1754 zval retval = {0};
1755 zval params[1];
1756 php_uv_t *uv = (php_uv_t*)handle->data;
1757 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1758
1759 PHP_UV_DEBUG_PRINT("prepare_cb\n");
1760
1761 ZVAL_OBJ(¶ms[0], &uv->std);
1762 GC_ADDREF(&uv->std);
1763 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_prepare_cb, uv);
1764
1765 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_PREPARE_CB TSRMLS_CC);
1766
1767 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_prepare_cb, uv);
1768 zval_ptr_dtor(¶ms[0]);
1769
1770 zval_ptr_dtor(&retval);
1771 }
1772
1773 static void php_uv_check_cb(uv_check_t* handle)
1774 {
1775 zval retval = {0};
1776 zval params[1];
1777 php_uv_t *uv = (php_uv_t*)handle->data;
1778 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1779
1780 PHP_UV_DEBUG_PRINT("check_cb\n");
1781
1782 ZVAL_OBJ(¶ms[0], &uv->std);
1783 GC_ADDREF(&uv->std);
1784 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_check_cb, uv);
1785
1786 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_CHECK_CB TSRMLS_CC);
1787
1788 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_check_cb, uv);
1789 zval_ptr_dtor(¶ms[0]);
1790
1791 zval_ptr_dtor(&retval);
1792 }
1793
1794
1795 static void php_uv_async_cb(uv_async_t* handle)
1796 {
1797 zval retval = {0};
1798 zval params[1];
1799 php_uv_t *uv = (php_uv_t*)handle->data;
1800 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1801
1802 PHP_UV_DEBUG_PRINT("async_cb\n");
1803
1804 ZVAL_OBJ(¶ms[0], &uv->std);
1805 GC_ADDREF(&uv->std);
1806 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_async_cb, uv);
1807
1808 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_ASYNC_CB TSRMLS_CC);
1809
1810 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_async_cb, uv);
1811 zval_ptr_dtor(¶ms[0]);
1812
1813 zval_ptr_dtor(&retval);
1814 }
1815
1816 #if defined(ZTS) && PHP_VERSION_ID < 80000
1817 static void php_uv_work_cb(uv_work_t* req)
1818 {
1819 zval retval = {0};
1820 php_uv_t *uv = (php_uv_t*)req->data;
1821
1822 uv = (php_uv_t*)req->data;
1823
1824 PHP_UV_DEBUG_PRINT("work_cb\n");
1825
1826 php_uv_do_callback3(&retval, uv, NULL, 0, PHP_UV_WORK_CB);
1827 }
1828
1829 static void php_uv_after_work_cb(uv_work_t* req, int status)
1830 {
1831 zval retval = {0};
1832 php_uv_t *uv = (php_uv_t*)req->data;
1833 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1834
1835 uv = (php_uv_t*)req->data;
1836
1837 PHP_UV_DEBUG_PRINT("after_work_cb\n");
1838
1839 php_uv_do_callback2(&retval, uv, NULL, 0, PHP_UV_AFTER_WORK_CB TSRMLS_CC);
1840
1841 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_after_work_cb, uv);
1842
1843 /* as uv_cancel inside destruct_uv will return EBUSY here as were still in the work callback, but freeing is safe here */
1844 clean_uv_handle(uv); /* this avoids a cancel */
1845 OBJ_RELEASE(&uv->std);
1846 }
1847 #endif
1848
1849 static void php_uv_fs_cb(uv_fs_t* req)
1850 {
1851 zval params[3] = {0};
1852 zval retval = {0};
1853 php_uv_t *uv = (php_uv_t*)req->data;
1854 int argc, i = 0;
1855 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
1856
1857 PHP_UV_DEBUG_PRINT("# php_uv_fs_cb %p\n", uv);
1858
1859 if (PHP_UV_IS_DTORED(uv)) {
1860 uv_fs_req_cleanup(req);
1861
1862 OBJ_RELEASE(&uv->std);
1863 return;
1864 }
1865
1866 if (!Z_ISUNDEF(uv->fs_fd)) {
1867 ZVAL_COPY_VALUE(¶ms[0], &uv->fs_fd);
1868 ZVAL_UNDEF(&uv->fs_fd);
1869 }
1870
1871 switch (uv->uv.fs.fs_type) {
1872 case UV_FS_SYMLINK:
1873 case UV_FS_LINK:
1874 case UV_FS_CHMOD:
1875 case UV_FS_RENAME:
1876 case UV_FS_UNLINK:
1877 case UV_FS_RMDIR:
1878 case UV_FS_MKDIR:
1879 case UV_FS_CLOSE:
1880 case UV_FS_CHOWN:
1881 case UV_FS_UTIME:
1882 case UV_FS_FUTIME:
1883 argc = 1;
1884 ZVAL_LONG(¶ms[0], uv->uv.fs.result);
1885 break;
1886
1887 case UV_FS_FCHMOD:
1888 case UV_FS_FCHOWN:
1889 case UV_FS_FTRUNCATE:
1890 case UV_FS_FDATASYNC:
1891 case UV_FS_FSYNC:
1892 argc = 2;
1893 ZVAL_LONG(¶ms[1], uv->uv.fs.result);
1894 break;
1895
1896 case UV_FS_OPEN:
1897 argc = 1;
1898 if (uv->uv.fs.result < 0) {
1899 ZVAL_LONG(¶ms[0], uv->uv.fs.result);
1900 } else {
1901 PHP_UV_FD_TO_ZVAL(¶ms[0], uv->uv.fs.result)
1902 PHP_UV_DEBUG_PRINT("Creating fs handle %p\n", Z_RES(params[0]));
1903 }
1904 break;
1905
1906 case UV_FS_SCANDIR:
1907 argc = 1;
1908 if (uv->uv.fs.result < 0) { /* req->ptr may be NULL here, but uv_fs_scandir_next() knows to handle it */
1909 ZVAL_LONG(¶ms[0], uv->uv.fs.result);
1910 } else {
1911 uv_dirent_t dent;
1912
1913 array_init(¶ms[0]);
1914 while (UV_EOF != uv_fs_scandir_next(req, &dent)) {
1915 add_next_index_string(¶ms[0], dent.name);
1916 }
1917 }
1918 break;
1919
1920 case UV_FS_LSTAT:
1921 case UV_FS_STAT:
1922 argc = 1;
1923 if (req->ptr != NULL) {
1924 params[0] = php_uv_make_stat((const uv_stat_t *) req->ptr);
1925 } else {
1926 ZVAL_LONG(¶ms[0], uv->uv.fs.result);
1927 }
1928 break;
1929 case UV_FS_FSTAT:
1930 argc = 2;
1931 if (req->ptr != NULL) {
1932 params[1] = php_uv_make_stat((const uv_stat_t *) req->ptr);
1933 } else {
1934 ZVAL_LONG(¶ms[1], uv->uv.fs.result);
1935 }
1936 break;
1937
1938 case UV_FS_READLINK:
1939 argc = 1;
1940 if (uv->uv.fs.result == 0) {
1941 ZVAL_STRING(¶ms[0], req->ptr);
1942 } else {
1943 ZVAL_LONG(¶ms[0], uv->uv.fs.result);
1944 }
1945 break;
1946
1947 case UV_FS_READ:
1948 argc = 2;
1949 if (uv->uv.fs.result >= 0) {
1950 ZVAL_STRINGL(¶ms[1], uv->buffer, uv->uv.fs.result);
1951 } else {
1952 ZVAL_LONG(¶ms[1], uv->uv.fs.result);
1953 }
1954 efree(uv->buffer);
1955 break;
1956
1957 case UV_FS_SENDFILE:
1958 argc = 2;
1959 ZVAL_LONG(¶ms[1], uv->uv.fs.result);
1960 break;
1961
1962 case UV_FS_WRITE:
1963 argc = 2;
1964 ZVAL_LONG(¶ms[1], uv->uv.fs.result);
1965 efree(uv->buffer);
1966 break;
1967
1968 case UV_FS_UNKNOWN:
1969 case UV_FS_CUSTOM:
1970 default:
1971 argc = 0;
1972 php_error_docref(NULL, E_ERROR, "type; %d does not support yet.", uv->uv.fs.fs_type);
1973 break;
1974 }
1975
1976 php_uv_do_callback2(&retval, uv, params, argc, PHP_UV_FS_CB TSRMLS_CC);
1977
1978 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_fs_cb, uv);
1979 for (i = 0; i < argc; i++) {
1980 zval_ptr_dtor(¶ms[i]);
1981 }
1982
1983 zval_ptr_dtor(&retval);
1984
1985 if (!Z_ISUNDEF(uv->fs_fd_alt)) {
1986 zval_ptr_dtor(&uv->fs_fd_alt);
1987 ZVAL_UNDEF(&uv->fs_fd_alt);
1988 }
1989
1990 uv_fs_req_cleanup(req);
1991
1992 clean_uv_handle(uv);
1993 OBJ_RELEASE(&uv->std);
1994 }
1995
1996 static void php_uv_fs_event_cb(uv_fs_event_t* req, const char* filename, int events, int status)
1997 {
1998 zval params[4] = {0};
1999 zval retval = {0};
2000 php_uv_t *uv = (php_uv_t*)req->data;
2001 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2002
2003 PHP_UV_DEBUG_PRINT("fs_event_cb: %s, %d\n", filename, status);
2004
2005 ZVAL_OBJ(¶ms[0], &uv->std);
2006 GC_ADDREF(&uv->std);
2007 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_fs_event_cb, uv);
2008 if (filename) {
2009 ZVAL_STRING(¶ms[1], filename);
2010 } else {
2011 ZVAL_NULL(¶ms[1]);
2012 }
2013 ZVAL_LONG(¶ms[2], events);
2014 ZVAL_LONG(¶ms[3], status);
2015
2016 php_uv_do_callback2(&retval, uv, params, 4, PHP_UV_FS_EVENT_CB TSRMLS_CC);
2017
2018 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_fs_event_cb, uv);
2019 zval_ptr_dtor(¶ms[0]);
2020 zval_ptr_dtor(¶ms[1]);
2021 zval_ptr_dtor(¶ms[2]);
2022 zval_ptr_dtor(¶ms[3]);
2023
2024 zval_ptr_dtor(&retval);
2025 }
2026
2027 static zval php_uv_stat_to_zval(const uv_stat_t *stat)
2028 {
2029 zval result = {0};
2030 array_init(&result);
2031
2032 add_assoc_long_ex(&result, ZEND_STRL("dev"), stat->st_dev);
2033 add_assoc_long_ex(&result, ZEND_STRL("ino"), stat->st_ino);
2034 add_assoc_long_ex(&result, ZEND_STRL("mode"), stat->st_mode);
2035 add_assoc_long_ex(&result, ZEND_STRL("nlink"), stat->st_nlink);
2036 add_assoc_long_ex(&result, ZEND_STRL("uid"), stat->st_uid);
2037 add_assoc_long_ex(&result, ZEND_STRL("gid"), stat->st_gid);
2038 add_assoc_long_ex(&result, ZEND_STRL("rdev"), stat->st_rdev);
2039 add_assoc_long_ex(&result, ZEND_STRL("size"), stat->st_size);
2040
2041 #ifndef PHP_WIN32
2042 add_assoc_long_ex(&result, ZEND_STRL("blksize"), stat->st_blksize);
2043 add_assoc_long_ex(&result, ZEND_STRL("blocks"), stat->st_blocks);
2044 #endif
2045
2046 add_assoc_long_ex(&result, ZEND_STRL("atime"), stat->st_atim.tv_sec);
2047 add_assoc_long_ex(&result, ZEND_STRL("mtime"), stat->st_mtim.tv_sec);
2048 add_assoc_long_ex(&result, ZEND_STRL("ctime"), stat->st_ctim.tv_sec);
2049
2050 return result;
2051 }
2052
2053 static void php_uv_fs_poll_cb(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr)
2054 {
2055 zval params[4] = {0};
2056 zval retval = {0};
2057 php_uv_t *uv = (php_uv_t*)handle->data;
2058 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2059
2060 ZVAL_OBJ(¶ms[0], &uv->std);
2061 GC_ADDREF(&uv->std);
2062 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_fs_poll_cb, uv);
2063 ZVAL_LONG(¶ms[1], status);
2064 params[2] = php_uv_stat_to_zval(prev);
2065 params[3] = php_uv_stat_to_zval(curr);
2066
2067 php_uv_do_callback2(&retval, uv, params, 4, PHP_UV_FS_POLL_CB TSRMLS_CC);
2068
2069 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_fs_poll_cb, uv);
2070 zval_ptr_dtor(¶ms[0]);
2071 zval_ptr_dtor(¶ms[1]);
2072 zval_ptr_dtor(¶ms[2]);
2073 zval_ptr_dtor(¶ms[3]);
2074
2075 zval_ptr_dtor(&retval);
2076 }
2077
2078 static void php_uv_poll_cb(uv_poll_t* handle, int status, int events)
2079 {
2080 zval params[4] = {0};
2081 zval retval = {0};
2082 php_uv_t *uv = (php_uv_t*)handle->data;
2083 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2084
2085 ZVAL_OBJ(¶ms[0], &uv->std);
2086 if (status == 0) {
2087 GC_ADDREF(&uv->std);
2088 }
2089 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_poll_cb, uv);
2090 ZVAL_LONG(¶ms[1], status);
2091 ZVAL_LONG(¶ms[2], events);
2092 if (!Z_ISUNDEF(uv->fs_fd)) {
2093 ZVAL_COPY(¶ms[3], &uv->fs_fd);
2094 } else {
2095 PHP_UV_FD_TO_ZVAL(¶ms[3], uv->sock);
2096 }
2097
2098 php_uv_do_callback2(&retval, uv, params, 4, PHP_UV_POLL_CB TSRMLS_CC);
2099
2100 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_poll_cb, uv);
2101 zval_ptr_dtor(¶ms[0]);
2102 zval_ptr_dtor(¶ms[1]);
2103 zval_ptr_dtor(¶ms[2]);
2104 zval_ptr_dtor(¶ms[3]);
2105
2106 zval_ptr_dtor(&retval);
2107 }
2108
2109
2110 static void php_uv_udp_recv_cb(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
2111 {
2112 /* TODO: is this correctly implmented? */
2113 zval retval = {0};
2114 zval params[3] = {0};
2115 php_uv_t *uv = (php_uv_t*)handle->data;
2116 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2117
2118 ZVAL_OBJ(¶ms[0], &uv->std);
2119 GC_ADDREF(&uv->std);
2120 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_udp_recv_cb, uv);
2121 if (nread < 0) {
2122 ZVAL_LONG(¶ms[1], nread);
2123 } else {
2124 ZVAL_STRINGL(¶ms[1], buf->base, nread);
2125 }
2126 ZVAL_LONG(¶ms[2], flags);
2127
2128 php_uv_do_callback2(&retval, uv, params, 3, PHP_UV_RECV_CB TSRMLS_CC);
2129
2130 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_udp_recv_cb, uv);
2131 zval_ptr_dtor(¶ms[0]);
2132 zval_ptr_dtor(¶ms[1]);
2133 zval_ptr_dtor(¶ms[2]);
2134
2135 zval_ptr_dtor(&retval);
2136
2137 if (buf->base) {
2138 efree(buf->base);
2139 }
2140 }
2141
2142 static void php_uv_read_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
2143 {
2144 buf->base = emalloc(suggested_size);
2145 buf->len = suggested_size;
2146 }
2147
2148 static void php_uv_close_cb(uv_handle_t *handle)
2149 {
2150 zval retval = {0};
2151 zval params[1] = {0};
2152
2153 php_uv_t *uv = (php_uv_t *) handle->data;
2154 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2155
2156 if (uv->callback[PHP_UV_CLOSE_CB]) {
2157 ZVAL_OBJ(¶ms[0], &uv->std);
2158
2159 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_CLOSE_CB TSRMLS_CC);
2160 zval_ptr_dtor(&retval);
2161 }
2162
2163 /* manually clean the uv handle as dtor will not be called anymore here */
2164 clean_uv_handle(uv);
2165
2166 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_close_cb, uv);
2167 OBJ_RELEASE(&uv->std);
2168 }
2169
2170 static inline zend_bool php_uv_is_handle_referenced(php_uv_t *uv) {
2171 zend_class_entry *ce = uv->std.ce;
2172
2173 return (ce == uv_signal_ce || ce == uv_timer_ce || ce == uv_idle_ce || ce == uv_udp_ce || ce == uv_tcp_ce || ce == uv_tty_ce || ce == uv_pipe_ce || ce == uv_prepare_ce || ce == uv_check_ce || ce == uv_poll_ce || ce == uv_fs_poll_ce) && uv_is_active(&uv->uv.handle);
2174 }
2175
2176 /* uv handle must not be cleaned or closed before called */
2177 static void php_uv_close(php_uv_t *uv) {
2178 ZEND_ASSERT(!uv_is_closing(&uv->uv.handle));
2179
2180 if (!php_uv_is_handle_referenced(uv)) {
2181 GC_ADDREF(&uv->std);
2182 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(php_uv_close, uv);
2183 }
2184
2185 uv_close(&uv->uv.handle, php_uv_close_cb);
2186
2187 PHP_UV_SKIP_DTOR(uv);
2188 }
2189
2190 static void php_uv_idle_cb(uv_timer_t *handle)
2191 {
2192 zval retval = {0};
2193 zval params[1] = {0};
2194
2195 php_uv_t *uv = (php_uv_t*)handle->data;
2196 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2197
2198 ZVAL_OBJ(¶ms[0], &uv->std);
2199 GC_ADDREF(&uv->std);
2200 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(php_uv_idle_cb, uv);
2201
2202 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_IDLE_CB TSRMLS_CC);
2203
2204 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(php_uv_idle_cb, uv);
2205 zval_ptr_dtor(¶ms[0]);
2206
2207 zval_ptr_dtor(&retval);
2208 }
2209
2210 static void php_uv_getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* res)
2211 {
2212 zval retval = {0};
2213 zval params[1] = {0};
2214 struct addrinfo *address;
2215 char ip[INET6_ADDRSTRLEN];
2216 const char *addr;
2217
2218 php_uv_t *uv = (php_uv_t*)handle->data;
2219 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2220
2221 if (status != 0) {
2222 ZVAL_LONG(¶ms[0], status);
2223 } else {
2224 array_init(¶ms[0]);
2225
2226 address = res;
2227 while (address) {
2228 if (address->ai_family == AF_INET) {
2229 addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
2230 uv_inet_ntop(address->ai_family, addr, ip, INET6_ADDRSTRLEN);
2231 add_next_index_string(¶ms[0], ip);
2232 }
2233
2234 address = address->ai_next;
2235 }
2236
2237 address = res;
2238 while (address) {
2239 if (address->ai_family == AF_INET6) {
2240 addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
2241 uv_inet_ntop(address->ai_family, addr, ip, INET6_ADDRSTRLEN);
2242 add_next_index_string(¶ms[0], ip);
2243 }
2244
2245 address = address->ai_next;
2246 }
2247 }
2248
2249 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_GETADDR_CB TSRMLS_CC);
2250
2251 zval_ptr_dtor(&retval);
2252 zval_ptr_dtor(¶ms[0]);
2253
2254 uv_freeaddrinfo(res);
2255 clean_uv_handle(uv);
2256 OBJ_RELEASE(&uv->std);
2257 }
2258
2259 static void php_uv_timer_cb(uv_timer_t *handle)
2260 {
2261 zval retval = {0};
2262 zval params[1] = {0};
2263 php_uv_t *uv = (php_uv_t*)handle->data;
2264 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2265
2266 ZVAL_OBJ(¶ms[0], &uv->std);
2267
2268 if (handle->repeat) {
2269 GC_ADDREF(&uv->std);
2270 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(php_uv_timer_cb, uv);
2271 }
2272
2273 php_uv_do_callback2(&retval, uv, params, 1, PHP_UV_TIMER_CB TSRMLS_CC);
2274
2275 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(php_uv_timer_cb, uv);
2276 zval_ptr_dtor(¶ms[0]);
2277
2278 zval_ptr_dtor(&retval);
2279 }
2280
2281 static void php_uv_signal_cb(uv_signal_t *handle, int sig_num)
2282 {
2283 zval retval = {0};
2284 zval params[2] = {0};
2285 php_uv_t *uv = (php_uv_t*)handle->data;
2286 TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2287
2288 ZVAL_OBJ(¶ms[0], &uv->std);
2289 GC_ADDREF(&uv->std);
2290 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(php_uv_signal_cb, uv);
2291 ZVAL_LONG(¶ms[1], sig_num);
2292
2293 php_uv_do_callback2(&retval, uv, params, 2, PHP_UV_SIGNAL_CB TSRMLS_CC);
2294
2295 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(php_uv_signal_cb, uv);
2296 zval_ptr_dtor(¶ms[0]);
2297 zval_ptr_dtor(¶ms[1]);
2298
2299 zval_ptr_dtor(&retval);
2300 }
2301
2302 void static destruct_uv_stdio(zend_object *obj)
2303 {
2304 php_uv_stdio_t *stdio = (php_uv_stdio_t *) obj;
2305
2306 zval_ptr_dtor(&stdio->stream);
2307 }
2308
2309
2310 /* common functions */
2311
2312 static void php_uv_ip_common(int ip_type, INTERNAL_FUNCTION_PARAMETERS)
2313 {
2314 php_uv_sockaddr_t *addr;
2315 char ip[INET6_ADDRSTRLEN];
2316
2317 ZEND_PARSE_PARAMETERS_START(1, 1)
2318 UV_PARAM_OBJ(addr, php_uv_sockaddr_t, (ip_type == 1) ? uv_sockaddr_ipv4_ce : uv_sockaddr_ipv6_ce)
2319 ZEND_PARSE_PARAMETERS_END();
2320
2321 if (ip_type == 1) {
2322 uv_ip4_name(PHP_UV_SOCKADDR_IPV4_P(addr), ip, INET6_ADDRSTRLEN);
2323 } else {
2324 uv_ip6_name(PHP_UV_SOCKADDR_IPV6_P(addr), ip, INET6_ADDRSTRLEN);
2325 }
2326 RETVAL_STRING(ip);
2327 }
2328
2329 static void php_uv_socket_bind(enum php_uv_socket_type ip_type, INTERNAL_FUNCTION_PARAMETERS)
2330 {
2331 php_uv_sockaddr_t *addr;
2332 php_uv_t *uv;
2333 zend_long flags = 0;
2334 int r;
2335
2336 if (ip_type & PHP_UV_UDP) {
2337 ZEND_PARSE_PARAMETERS_START(2, 3)
2338 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
2339 UV_PARAM_OBJ(addr, php_uv_sockaddr_t, (ip_type == PHP_UV_UDP_IPV4) ? uv_sockaddr_ipv4_ce : uv_sockaddr_ipv6_ce)
2340 Z_PARAM_OPTIONAL
2341 Z_PARAM_LONG(flags)
2342 ZEND_PARSE_PARAMETERS_END();
2343 } else {
2344 ZEND_PARSE_PARAMETERS_START(2, 2)
2345 UV_PARAM_OBJ(uv, php_uv_t, uv_tcp_ce)
2346 UV_PARAM_OBJ(addr, php_uv_sockaddr_t, (ip_type == PHP_UV_TCP_IPV4) ? uv_sockaddr_ipv4_ce : uv_sockaddr_ipv6_ce)
2347 ZEND_PARSE_PARAMETERS_END();
2348 }
2349
2350 switch (ip_type) {
2351 case PHP_UV_TCP_IPV4:
2352 r = uv_tcp_bind((uv_tcp_t*)&uv->uv.tcp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV4(addr), 0);
2353 break;
2354 case PHP_UV_TCP_IPV6:
2355 r = uv_tcp_bind((uv_tcp_t*)&uv->uv.tcp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV6(addr), 0);
2356 break;
2357 case PHP_UV_UDP_IPV4:
2358 r = uv_udp_bind((uv_udp_t*)&uv->uv.udp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV4(addr), flags);
2359 break;
2360 case PHP_UV_UDP_IPV6:
2361 r = uv_udp_bind((uv_udp_t*)&uv->uv.udp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV6(addr), flags);
2362 break;
2363 default:
2364 php_error_docref(NULL, E_ERROR, "unhandled type");
2365 return;
2366 }
2367
2368 if (r) {
2369 php_error_docref(NULL, E_WARNING, "bind failed");
2370 RETURN_FALSE;
2371 } else {
2372 RETURN_TRUE;
2373 }
2374 }
2375
2376 static void php_uv_socket_getname(int type, INTERNAL_FUNCTION_PARAMETERS)
2377 {
2378 php_uv_t *uv;
2379 zval result;
2380 int addr_len;
2381 struct sockaddr_storage addr;
2382 addr_len = sizeof(struct sockaddr_storage);
2383
2384 ZEND_PARSE_PARAMETERS_START(1, 1)
2385 UV_PARAM_OBJ(uv, php_uv_t, type == 3 ? uv_udp_ce : uv_tcp_ce)
2386 ZEND_PARSE_PARAMETERS_END();
2387
2388 switch (type) {
2389 case 1:
2390 uv_tcp_getsockname(&uv->uv.tcp, (struct sockaddr*)&addr, &addr_len);
2391 break;
2392 case 2:
2393 uv_tcp_getpeername(&uv->uv.tcp, (struct sockaddr*)&addr, &addr_len);
2394 break;
2395 case 3:
2396 uv_udp_getsockname(&uv->uv.udp, (struct sockaddr*)&addr, &addr_len);
2397 break;
2398 default:
2399 php_error_docref(NULL, E_ERROR, "unexpected type");
2400 break;
2401 }
2402
2403 result = php_uv_address_to_zval((struct sockaddr*)&addr);
2404 RETURN_ZVAL(&result, 0, 1);
2405 }
2406
2407 static void php_uv_handle_open(int (*open_cb)(uv_handle_t *, long), zend_class_entry *ce, INTERNAL_FUNCTION_PARAMETERS) {
2408 php_uv_t *uv;
2409 zval *zstream;
2410 zend_long fd; // file handle
2411 int error;
2412
2413 ZEND_PARSE_PARAMETERS_START(2, 2)
2414 UV_PARAM_OBJ(uv, php_uv_t, ce)
2415 Z_PARAM_ZVAL(zstream)
2416 ZEND_PARSE_PARAMETERS_END();
2417
2418 fd = php_uv_zval_to_fd(zstream);
2419 if (fd < 0) {
2420 php_error_docref(NULL, E_WARNING, "file descriptor must be unsigned value or a valid resource");
2421 RETURN_FALSE;
2422 }
2423
2424 error = open_cb(&uv->uv.handle, fd);
2425
2426 if (error) {
2427 php_error_docref(NULL, E_WARNING, "%s", php_uv_strerror(error));
2428 }
2429
2430 RETURN_LONG(error);
2431 }
2432
2433 static void php_uv_udp_send(int type, INTERNAL_FUNCTION_PARAMETERS)
2434 {
2435 zend_string *data;
2436 php_uv_t *uv;
2437 send_req_t *w;
2438 php_uv_sockaddr_t *addr;
2439 zend_fcall_info fci = empty_fcall_info;
2440 zend_fcall_info_cache fcc = empty_fcall_info_cache;
2441 php_uv_cb_t *cb;
2442
2443 ZEND_PARSE_PARAMETERS_START(3, 4)
2444 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
2445 Z_PARAM_STR(data)
2446 UV_PARAM_OBJ(addr, php_uv_sockaddr_t, (type == 1) ? uv_sockaddr_ipv4_ce : uv_sockaddr_ipv6_ce, uv_sockaddr_ipv6_ce)
2447 Z_PARAM_OPTIONAL
2448 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
2449 ZEND_PARSE_PARAMETERS_END();
2450
2451 GC_ADDREF(&uv->std);
2452 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_udp_send, uv);
2453
2454 PHP_UV_INIT_SEND_REQ(w, uv, data->val, data->len);
2455 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_SEND_CB);
2456
2457 if (addr->std.ce == uv_sockaddr_ipv4_ce) {
2458 uv_udp_send(&w->req, &uv->uv.udp, &w->buf, 1, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV4(addr), php_uv_udp_send_cb);
2459 } else {
2460 uv_udp_send(&w->req, &uv->uv.udp, &w->buf, 1, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV6(addr), php_uv_udp_send_cb);
2461 }
2462 }
2463
2464 static void php_uv_tcp_connect(enum php_uv_socket_type type, INTERNAL_FUNCTION_PARAMETERS)
2465 {
2466 php_uv_t *uv;
2467 php_uv_sockaddr_t *addr;
2468 uv_connect_t *req;
2469 zend_fcall_info fci = empty_fcall_info;
2470 zend_fcall_info_cache fcc = empty_fcall_info_cache;
2471 php_uv_cb_t *cb;
2472
2473 ZEND_PARSE_PARAMETERS_START(2, 3)
2474 UV_PARAM_OBJ(uv, php_uv_t, uv_tcp_ce)
2475 UV_PARAM_OBJ(addr, php_uv_sockaddr_t, (type == PHP_UV_TCP_IPV4) ? uv_sockaddr_ipv4_ce : uv_sockaddr_ipv6_ce, uv_sockaddr_ipv6_ce)
2476 Z_PARAM_OPTIONAL
2477 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
2478 ZEND_PARSE_PARAMETERS_END();
2479
2480 GC_ADDREF(&uv->std);
2481 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_tcp_connect, uv);
2482
2483 PHP_UV_INIT_CONNECT(req, uv)
2484 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_CONNECT_CB);
2485
2486 if (addr->std.ce == uv_sockaddr_ipv4_ce) {
2487 uv_tcp_connect(req, &uv->uv.tcp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV4(addr), php_uv_tcp_connect_cb);
2488 } else {
2489 uv_tcp_connect(req, &uv->uv.tcp, (const struct sockaddr*)&PHP_UV_SOCKADDR_IPV6(addr), php_uv_tcp_connect_cb);
2490 }
2491 }
2492
2493 /* zend */
2494
2495 static zend_function_entry php_uv_empty_methods[] = {
2496 {0}
2497 };
2498
2499 #if PHP_VERSION_ID >= 80000
2500 int php_uv_cast_object(zend_object *readobj, zval *writeobj, int type) {
2501 #else
2502 int php_uv_cast_object(zval *readobj_zv, zval *writeobj, int type) {
2503 zend_object *readobj = Z_OBJ_P(readobj_zv);
2504 #endif
2505 if (type == IS_LONG) {
2506 ZVAL_LONG(writeobj, readobj->handle);
2507 return SUCCESS;
2508 } else {
2509 #if PHP_VERSION_ID >= 80000
2510 return zend_std_cast_object_tostring(readobj, writeobj, type);
2511 #else
2512 return zend_std_cast_object_tostring(readobj_zv, writeobj, type);
2513 #endif
2514 }
2515 }
2516
2517 #if PHP_VERSION_ID >= 80000
2518 static HashTable *php_uv_get_debug_info(zend_object *object, int *is_temp) {
2519 php_uv_t *uv = (php_uv_t *) object;
2520 #else
2521 static HashTable *php_uv_get_debug_info(zval *object, int *is_temp) {
2522 php_uv_t *uv = (php_uv_t *) Z_OBJ_P(object);
2523 #endif
2524 HashTable *ht = zend_std_get_debug_info(object, is_temp);
2525 if (uv->std.ce == uv_poll_ce) {
2526 if (!*is_temp) {
2527 int fd;
2528 if (uv_fileno(&uv->uv.handle, (uv_os_fd_t *)&fd) == 0) { /* not actually a fd on windows but a handle pointr address, but okay. */
2529 *is_temp = 1;
2530 ht = zend_array_dup(ht);
2531 zval fdzv;
2532 ZVAL_LONG(&fdzv, fd);
2533 zend_hash_update(ht, zend_string_init("@fd", sizeof("@fd")-1, 0), &fdzv);
2534 }
2535 }
2536 }
2537 return ht;
2538 }
2539
2540 #if PHP_VERSION_ID >= 80000
2541 static HashTable *php_uv_get_gc(zend_object *object, zval **table, int *n) {
2542 php_uv_t *uv = (php_uv_t *) object;
2543 #else
2544 static HashTable *php_uv_get_gc(zval *object, zval **table, int *n) {
2545 php_uv_t *uv = (php_uv_t *) Z_OBJ_P(object);
2546 #endif
2547 int i;
2548
2549 if (PHP_UV_IS_DTORED(uv)) {
2550 *n = 0;
2551 return NULL;
2552 }
2553
2554 // include trailing zvals like fs_fd/_alt
2555 *n = (sizeof(php_uv_t) - XtOffsetOf(php_uv_t, gc_data)) / sizeof(zval);
2556 for (i = 0; i < PHP_UV_CB_MAX; i++) {
2557 php_uv_cb_t *cb = uv->callback[i];
2558 if (cb) {
2559 ZVAL_COPY_VALUE(&uv->gc_data[i * 2], &cb->fci.function_name);
2560 if (cb->fci.object) {
2561 ZVAL_OBJ(&uv->gc_data[i * 2 + 1], cb->fci.object);
2562 }
2563 } else {
2564 ZVAL_UNDEF(&uv->gc_data[i * 2]);
2565 ZVAL_UNDEF(&uv->gc_data[i * 2 + 1]);
2566 }
2567 }
2568 *table = uv->gc_data;
2569
2570 return uv->std.properties;
2571 }
2572
2573 static void php_uv_loop_get_gc_walk_cb(uv_handle_t* handle, void *arg) {
2574 struct { int *n; php_uv_loop_t *loop; } *data = arg;
2575 php_uv_t *uv = (php_uv_t *) handle->data;
2576
2577 if (php_uv_is_handle_referenced(uv)) {
2578 php_uv_loop_t *loop = data->loop;
2579
2580 if (*data->n == loop->gc_buffer_size) {
2581 if (loop->gc_buffer_size == 0) {
2582 loop->gc_buffer_size = 16;
2583 } else {
2584 loop->gc_buffer_size *= 2;
2585 }
2586 loop->gc_buffer = erealloc(loop->gc_buffer, loop->gc_buffer_size * sizeof(zval));
2587 }
2588
2589 ZVAL_OBJ(loop->gc_buffer + (*data->n)++, &uv->std);
2590 }
2591 }
2592
2593
2594 #if PHP_VERSION_ID >= 80000
2595 static HashTable *php_uv_loop_get_gc(zend_object *object, zval **table, int *n) {
2596 php_uv_loop_t *loop = (php_uv_loop_t *) object;
2597 #else
2598 static HashTable *php_uv_loop_get_gc(zval *object, zval **table, int *n) {
2599 php_uv_loop_t *loop = (php_uv_loop_t *) Z_OBJ_P(object);
2600 #endif
2601 struct { int *n; php_uv_loop_t *loop; } data;
2602 data.n = n;
2603 data.loop = loop;
2604
2605 *n = 0;
2606 if (!PHP_UV_IS_DTORED(loop)) {
2607 uv_walk(&loop->loop, php_uv_loop_get_gc_walk_cb, &data);
2608 *table = loop->gc_buffer;
2609 }
2610
2611 return loop->std.properties;
2612 }
2613
2614 #if PHP_VERSION_ID >= 80000
2615 static HashTable *php_uv_stdio_get_gc(zend_object *object, zval **table, int *n) {
2616 php_uv_stdio_t *stdio = (php_uv_stdio_t *) object;
2617 #else
2618 static HashTable *php_uv_stdio_get_gc(zval *object, zval **table, int *n) {
2619 php_uv_stdio_t *stdio = (php_uv_stdio_t *) Z_OBJ_P(object);
2620 #endif
2621
2622 *n = 1;
2623 *table = &stdio->stream;
2624
2625 return stdio->std.properties;
2626 }
2627
2628 static zend_object *php_uv_create_uv(zend_class_entry *ce) {
2629 php_uv_t *uv = emalloc(sizeof(php_uv_t));
2630 zend_object_std_init(&uv->std, ce);
2631 uv->std.handlers = &uv_handlers;
2632
2633 PHP_UV_INIT_ZVALS(uv);
2634 TSRMLS_SET_CTX(uv->thread_ctx);
2635
2636 uv->uv.handle.data = uv;
2637
2638 return &uv->std;
2639 }
2640
2641 static zend_object *php_uv_create_uv_loop(zend_class_entry *ce) {
2642 php_uv_loop_t *loop = emalloc(sizeof(php_uv_loop_t));
2643 zend_object_std_init(&loop->std, ce);
2644 loop->std.handlers = &uv_loop_handlers;
2645
2646 uv_loop_init(&loop->loop);
2647
2648 loop->gc_buffer_size = 0;
2649 loop->gc_buffer = NULL;
2650
2651 return &loop->std;
2652 }
2653
2654 static zend_object *php_uv_create_uv_sockaddr(zend_class_entry *ce) {
2655 php_uv_sockaddr_t *sockaddr = emalloc(sizeof(php_uv_sockaddr_t));
2656 zend_object_std_init(&sockaddr->std, ce);
2657 sockaddr->std.handlers = &uv_default_handlers;
2658
2659 return &sockaddr->std;
2660 }
2661
2662 static zend_object *php_uv_create_uv_lock(zend_class_entry *ce) {
2663 php_uv_lock_t *lock = emalloc(sizeof(php_uv_lock_t));
2664 zend_object_std_init(&lock->std, ce);
2665 lock->std.handlers = &uv_lock_handlers;
2666
2667 lock->locked = 0;
2668
2669 return &lock->std;
2670 }
2671
2672 static zend_object *php_uv_create_uv_stdio(zend_class_entry *ce) {
2673 php_uv_stdio_t *stdio = emalloc(sizeof(php_uv_stdio_t));
2674 zend_object_std_init(&stdio->std, ce);
2675 stdio->std.handlers = &uv_stdio_handlers;
2676
2677 stdio->flags = 0;
2678 ZVAL_UNDEF(&stdio->stream);
2679
2680 return &stdio->std;
2681 }
2682
2683 static zend_class_entry *php_uv_register_internal_class_ex(const char *name, zend_class_entry *parent) {
2684 zend_class_entry ce = {0}, *new;
2685
2686 ce.name = zend_new_interned_string(zend_string_init(name, strlen(name), 1));
2687 ce.info.internal.builtin_functions = php_uv_empty_methods;
2688 new = zend_register_internal_class_ex(&ce, parent);
2689 #if PHP_VERSION_ID < 80100
2690 new->serialize = zend_class_serialize_deny;
2691 new->unserialize = zend_class_unserialize_deny;
2692 #endif
2693 new->ce_flags |= ZEND_ACC_FINAL;
2694 #if PHP_VERSION_ID >= 80100
2695 new->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE ;
2696 #endif
2697 new->create_object = php_uv_create_uv;
2698
2699 return new;
2700 }
2701
2702 static zend_class_entry *php_uv_register_internal_class(const char *name) {
2703 return php_uv_register_internal_class_ex(name, NULL);
2704 }
2705
2706 static zend_function *php_uv_get_ctor(zend_object *object) {
2707 zend_throw_error(NULL, "The UV classes cannot be instantiated manually");
2708 return NULL;
2709 }
2710
2711 PHP_MINIT_FUNCTION(uv)
2712 {
2713 PHP_UV_PROBE(MINIT);
2714
2715 #if PHP_VERSION_ID >= 70300
2716 memcpy(&uv_default_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2717 #else
2718 memcpy(&uv_default_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2719 #endif
2720 uv_default_handlers.clone_obj = NULL;
2721 uv_default_handlers.get_constructor = php_uv_get_ctor;
2722 uv_default_handlers.cast_object = php_uv_cast_object;
2723
2724 uv_ce = php_uv_register_internal_class("UV");
2725 uv_ce->ce_flags |= ZEND_ACC_ABSTRACT;
2726 uv_ce->ce_flags &= ~ZEND_ACC_FINAL;
2727 memcpy(&uv_handlers, &uv_default_handlers, sizeof(zend_object_handlers));
2728 uv_handlers.get_gc = php_uv_get_gc;
2729 uv_handlers.dtor_obj = destruct_uv;
2730 uv_handlers.get_debug_info = php_uv_get_debug_info;
2731
2732 php_uv_init(uv_ce);
2733
2734 uv_stream_ce = php_uv_register_internal_class_ex("UVStream", uv_ce);
2735 uv_stream_ce->ce_flags |= ZEND_ACC_ABSTRACT;
2736 uv_stream_ce->ce_flags &= ~ZEND_ACC_FINAL;
2737
2738 uv_tcp_ce = php_uv_register_internal_class_ex("UVTcp", uv_stream_ce);
2739 uv_udp_ce = php_uv_register_internal_class_ex("UVUdp", uv_ce);
2740 uv_pipe_ce = php_uv_register_internal_class_ex("UVPipe", uv_stream_ce);
2741 uv_idle_ce = php_uv_register_internal_class_ex("UVIdle", uv_ce);
2742 uv_timer_ce = php_uv_register_internal_class_ex("UVTimer", uv_ce);
2743 uv_async_ce = php_uv_register_internal_class_ex("UVAsync", uv_ce);
2744 uv_addrinfo_ce = php_uv_register_internal_class_ex("UVAddrinfo", uv_ce);
2745 uv_process_ce = php_uv_register_internal_class_ex("UVProcess", uv_ce);
2746 uv_prepare_ce = php_uv_register_internal_class_ex("UVPrepare", uv_ce);
2747 uv_check_ce = php_uv_register_internal_class_ex("UVCheck", uv_ce);
2748 uv_work_ce = php_uv_register_internal_class_ex("UVWork", uv_ce);
2749 uv_fs_ce = php_uv_register_internal_class_ex("UVFs", uv_ce);
2750 uv_fs_event_ce = php_uv_register_internal_class_ex("UVFsEvent", uv_ce);
2751 uv_tty_ce = php_uv_register_internal_class_ex("UVTty", uv_stream_ce);
2752 uv_fs_poll_ce = php_uv_register_internal_class_ex("UVFsPoll", uv_ce);
2753 uv_poll_ce = php_uv_register_internal_class_ex("UVPoll", uv_ce);
2754 uv_signal_ce = php_uv_register_internal_class_ex("UVSignal", uv_ce);
2755
2756 uv_loop_ce = php_uv_register_internal_class("UVLoop");
2757 uv_loop_ce->create_object = php_uv_create_uv_loop;
2758 memcpy(&uv_loop_handlers, &uv_default_handlers, sizeof(zend_object_handlers));
2759 uv_loop_handlers.get_gc = php_uv_loop_get_gc;
2760 uv_loop_handlers.dtor_obj = destruct_uv_loop;
2761 uv_loop_handlers.free_obj = free_uv_loop;
2762
2763 uv_sockaddr_ce = php_uv_register_internal_class("UVSockAddr");
2764 uv_sockaddr_ce->ce_flags |= ZEND_ACC_ABSTRACT;
2765 uv_sockaddr_ce->ce_flags &= ~ZEND_ACC_FINAL;
2766 uv_sockaddr_ce->create_object = php_uv_create_uv_sockaddr;
2767
2768 uv_sockaddr_ipv4_ce = php_uv_register_internal_class_ex("UVSockAddrIPv4", uv_sockaddr_ce);
2769 uv_sockaddr_ipv4_ce->create_object = php_uv_create_uv_sockaddr;
2770
2771 uv_sockaddr_ipv6_ce = php_uv_register_internal_class_ex("UVSockAddrIPv6", uv_sockaddr_ce);
2772 uv_sockaddr_ipv6_ce->create_object = php_uv_create_uv_sockaddr;
2773
2774 uv_lock_ce = php_uv_register_internal_class("UVLock");
2775 uv_lock_ce->create_object = php_uv_create_uv_lock;
2776 memcpy(&uv_lock_handlers, &uv_default_handlers, sizeof(zend_object_handlers));
2777 uv_lock_handlers.dtor_obj = destruct_uv_lock;
2778
2779 uv_stdio_ce = php_uv_register_internal_class("UVStdio");
2780 uv_stdio_ce->create_object = php_uv_create_uv_stdio;
2781 memcpy(&uv_stdio_handlers, &uv_default_handlers, sizeof(zend_object_handlers));
2782 uv_stdio_handlers.dtor_obj = destruct_uv_stdio;
2783 uv_stdio_handlers.get_gc = php_uv_stdio_get_gc;
2784
2785 #if !defined(PHP_WIN32) && !(defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS))
2786 {
2787 zend_module_entry *sockets;
2788 if ((sockets = zend_hash_str_find_ptr(&module_registry, ZEND_STRL("sockets")))) {
2789 if (sockets->handle) { // shared
2790 # if PHP_VERSION_ID >= 80000
2791 zend_class_entry **socket_ce_ptr = (zend_class_entry **) DL_FETCH_SYMBOL(sockets->handle, "socket_ce");
2792 if (socket_ce_ptr == NULL) {
2793 socket_ce_ptr = (zend_class_entry **) DL_FETCH_SYMBOL(sockets->handle, "_socket_ce");
2794 }
2795 socket_ce = *socket_ce_ptr;
2796 # else
2797 php_sockets_le_socket_ptr = (int (*)(void)) DL_FETCH_SYMBOL(sockets->handle, "php_sockets_le_socket");
2798 if (php_sockets_le_socket_ptr == NULL) {
2799 php_sockets_le_socket_ptr = (int (*)(void)) DL_FETCH_SYMBOL(sockets->handle, "_php_sockets_le_socket");
2800 }
2801 } else {
2802 php_sockets_le_socket_ptr = &php_sockets_le_socket;
2803 #endif
2804 }
2805 }
2806 }
2807 #endif
2808
2809 return SUCCESS;
2810 }
2811
2812 PHP_RSHUTDOWN_FUNCTION(uv)
2813 {
2814 if (UV_G(default_loop)) {
2815 uv_loop_t *loop = &UV_G(default_loop)->loop;
2816
2817 /* for proper destruction: close all handles, let libuv call close callback and then close and free the loop */
2818 uv_stop(loop); /* in case we longjmp()'ed ... */
2819 uv_run(loop, UV_RUN_DEFAULT); /* invalidate the stop ;-) */
2820
2821 uv_walk(loop, destruct_uv_loop_walk_cb, NULL);
2822 uv_run(loop, UV_RUN_DEFAULT);
2823 uv_loop_close(loop);
2824 OBJ_RELEASE(&UV_G(default_loop)->std);
2825 }
2826
2827 return SUCCESS;
2828 }
2829
2830 ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0)
2831 ZEND_END_ARG_INFO()
2832
2833 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_run, 0, 0, 0)
2834 ZEND_ARG_INFO(0, loop)
2835 ZEND_ARG_INFO(0, run_mode)
2836 ZEND_END_ARG_INFO()
2837
2838 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_stop, 0, 0, 0)
2839 ZEND_ARG_INFO(0, loop)
2840 ZEND_END_ARG_INFO()
2841
2842 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_loop_delete, 0, 0, 1)
2843 ZEND_ARG_INFO(0, loop)
2844 ZEND_END_ARG_INFO()
2845
2846 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_now, 0, 0, 0)
2847 ZEND_ARG_INFO(0, loop)
2848 ZEND_END_ARG_INFO()
2849
2850 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_connect, 0, 0, 2)
2851 ZEND_ARG_INFO(0, resource)
2852 ZEND_ARG_INFO(0, sock_addr)
2853 ZEND_ARG_INFO(0, callback)
2854 ZEND_END_ARG_INFO()
2855
2856 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_connect6, 0, 0, 2)
2857 ZEND_ARG_INFO(0, resource)
2858 ZEND_ARG_INFO(0, ipv6_addr)
2859 ZEND_ARG_INFO(0, callback)
2860 ZEND_END_ARG_INFO()
2861
2862 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_init, 0, 0, 0)
2863 ZEND_ARG_INFO(0, loop)
2864 ZEND_END_ARG_INFO()
2865
2866 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_listen, 0, 0, 3)
2867 ZEND_ARG_INFO(0, resource)
2868 ZEND_ARG_INFO(0, backlog)
2869 ZEND_ARG_INFO(0, callback)
2870 ZEND_END_ARG_INFO()
2871
2872 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_accept, 0, 0, 2)
2873 ZEND_ARG_INFO(0, server)
2874 ZEND_ARG_INFO(0, client)
2875 ZEND_END_ARG_INFO()
2876
2877 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_read_start, 0, 0, 2)
2878 ZEND_ARG_INFO(0, server)
2879 ZEND_ARG_INFO(0, callback)
2880 ZEND_END_ARG_INFO()
2881
2882 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_read_stop, 0, 0, 1)
2883 ZEND_ARG_INFO(0, server)
2884 ZEND_END_ARG_INFO()
2885
2886 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_write, 0, 0, 3)
2887 ZEND_ARG_INFO(0, client)
2888 ZEND_ARG_INFO(0, data)
2889 ZEND_ARG_INFO(0, callback)
2890 ZEND_END_ARG_INFO()
2891
2892 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_write2, 0, 0, 4)
2893 ZEND_ARG_INFO(0, client)
2894 ZEND_ARG_INFO(0, data)
2895 ZEND_ARG_INFO(0, send)
2896 ZEND_ARG_INFO(0, callback)
2897 ZEND_END_ARG_INFO()
2898
2899 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_strerror, 0, 0, 1)
2900 ZEND_ARG_INFO(0, error)
2901 ZEND_END_ARG_INFO()
2902
2903 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_err_name, 0, 0, 1)
2904 ZEND_ARG_INFO(0, error)
2905 ZEND_END_ARG_INFO()
2906
2907 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_init, 0, 0, 0)
2908 ZEND_ARG_INFO(0, loop)
2909 ZEND_END_ARG_INFO()
2910
2911 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_idle_stop, 0, 0, 1)
2912 ZEND_ARG_INFO(0, idle)
2913 ZEND_END_ARG_INFO()
2914
2915 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_start, 0, 0, 3)
2916 ZEND_ARG_INFO(0, timer)
2917 ZEND_ARG_INFO(0, timeout)
2918 ZEND_ARG_INFO(0, repeat)
2919 ZEND_ARG_INFO(0, callback)
2920 ZEND_END_ARG_INFO()
2921
2922 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_stop, 0, 0, 1)
2923 ZEND_ARG_INFO(0, timer)
2924 ZEND_END_ARG_INFO()
2925
2926 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_again, 0, 0, 1)
2927 ZEND_ARG_INFO(0, timer)
2928 ZEND_END_ARG_INFO()
2929
2930 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_set_repeat, 0, 0, 2)
2931 ZEND_ARG_INFO(0, timer)
2932 ZEND_ARG_INFO(0, timeout)
2933 ZEND_END_ARG_INFO()
2934
2935 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_timer_get_repeat, 0, 0, 1)
2936 ZEND_ARG_INFO(0, timer)
2937 ZEND_END_ARG_INFO()
2938
2939 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_idle_start, 0, 0, 2)
2940 ZEND_ARG_INFO(0, timer)
2941 ZEND_ARG_INFO(0, callback)
2942 ZEND_END_ARG_INFO()
2943
2944 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_open, 0, 0, 2)
2945 ZEND_ARG_INFO(0, resource)
2946 ZEND_ARG_INFO(0, tcpfd)
2947 ZEND_END_ARG_INFO()
2948
2949 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_bind, 0, 0, 2)
2950 ZEND_ARG_INFO(0, resource)
2951 ZEND_ARG_INFO(0, address)
2952 ZEND_END_ARG_INFO()
2953
2954 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_bind6, 0, 0, 2)
2955 ZEND_ARG_INFO(0, resource)
2956 ZEND_ARG_INFO(0, address)
2957 ZEND_END_ARG_INFO()
2958
2959 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_shutdown, 0, 0, 2)
2960 ZEND_ARG_INFO(0, stream)
2961 ZEND_ARG_INFO(0, callback)
2962 ZEND_END_ARG_INFO()
2963
2964 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_close, 0, 0, 1)
2965 ZEND_ARG_INFO(0, stream)
2966 ZEND_ARG_INFO(0, callback)
2967 ZEND_END_ARG_INFO()
2968
2969 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_idle_init, 0, 0, 0)
2970 ZEND_ARG_INFO(0, loop)
2971 ZEND_END_ARG_INFO()
2972
2973 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_update_time, 0, 0, 0)
2974 ZEND_ARG_INFO(0, loop)
2975 ZEND_END_ARG_INFO()
2976
2977 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_is_active, 0, 0, 1)
2978 ZEND_ARG_INFO(0, handle)
2979 ZEND_END_ARG_INFO()
2980
2981 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_is_closing, 0, 0, 1)
2982 ZEND_ARG_INFO(0, handle)
2983 ZEND_END_ARG_INFO()
2984
2985 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_is_readable, 0, 0, 1)
2986 ZEND_ARG_INFO(0, handle)
2987 ZEND_END_ARG_INFO()
2988
2989 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_is_writable, 0, 0, 1)
2990 ZEND_ARG_INFO(0, handle)
2991 ZEND_END_ARG_INFO()
2992
2993 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_walk, 0, 0, 2)
2994 ZEND_ARG_INFO(0, loop)
2995 ZEND_ARG_INFO(0, callback)
2996 ZEND_ARG_INFO(0, opaque)
2997 ZEND_END_ARG_INFO()
2998
2999 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_guess_handle, 0, 0, 1)
3000 ZEND_ARG_INFO(0, fd)
3001 ZEND_END_ARG_INFO()
3002
3003
3004 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_ref, 0, 0, 1)
3005 ZEND_ARG_INFO(0, loop)
3006 ZEND_END_ARG_INFO()
3007
3008 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_unref, 0, 0, 1)
3009 ZEND_ARG_INFO(0, loop)
3010 ZEND_END_ARG_INFO()
3011
3012 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_nodelay, 0, 0, 2)
3013 ZEND_ARG_INFO(0, tcp)
3014 ZEND_ARG_INFO(0, enabled)
3015 ZEND_END_ARG_INFO()
3016
3017 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_ip4_addr, 0, 0, 2)
3018 ZEND_ARG_INFO(0, address)
3019 ZEND_ARG_INFO(0, port)
3020 ZEND_END_ARG_INFO()
3021
3022 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_ip6_addr, 0, 0, 2)
3023 ZEND_ARG_INFO(0, address)
3024 ZEND_ARG_INFO(0, port)
3025 ZEND_END_ARG_INFO()
3026
3027 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_init, 0, 0, 0)
3028 ZEND_ARG_INFO(0, loop)
3029 ZEND_END_ARG_INFO()
3030
3031 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_open, 0, 0, 2)
3032 ZEND_ARG_INFO(0, resource)
3033 ZEND_ARG_INFO(0, udpfd)
3034 ZEND_END_ARG_INFO()
3035
3036 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_bind, 0, 0, 2)
3037 ZEND_ARG_INFO(0, resource)
3038 ZEND_ARG_INFO(0, address)
3039 ZEND_ARG_INFO(0, flags)
3040 ZEND_END_ARG_INFO()
3041
3042 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_bind6, 0, 0, 2)
3043 ZEND_ARG_INFO(0, resource)
3044 ZEND_ARG_INFO(0, address)
3045 ZEND_ARG_INFO(0, flags)
3046 ZEND_END_ARG_INFO()
3047
3048 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_recv_start, 0, 0, 2)
3049 ZEND_ARG_INFO(0, server)
3050 ZEND_ARG_INFO(0, callback)
3051 ZEND_END_ARG_INFO()
3052
3053 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_recv_stop, 0, 0, 1)
3054 ZEND_ARG_INFO(0, server)
3055 ZEND_END_ARG_INFO()
3056
3057 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_set_multicast_loop, 0, 0, 2)
3058 ZEND_ARG_INFO(0, server)
3059 ZEND_ARG_INFO(0, enabled)
3060 ZEND_END_ARG_INFO()
3061
3062 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_set_multicast_ttl, 0, 0, 2)
3063 ZEND_ARG_INFO(0, server)
3064 ZEND_ARG_INFO(0, ttl)
3065 ZEND_END_ARG_INFO()
3066
3067 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_set_broadcast, 0, 0, 2)
3068 ZEND_ARG_INFO(0, server)
3069 ZEND_ARG_INFO(0, enabled)
3070 ZEND_END_ARG_INFO()
3071
3072 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_send, 0, 0, 3)
3073 ZEND_ARG_INFO(0, server)
3074 ZEND_ARG_INFO(0, buffer)
3075 ZEND_ARG_INFO(0, address)
3076 ZEND_ARG_INFO(0, callback)
3077 ZEND_END_ARG_INFO()
3078
3079 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_send6, 0, 0, 3)
3080 ZEND_ARG_INFO(0, server)
3081 ZEND_ARG_INFO(0, buffer)
3082 ZEND_ARG_INFO(0, address)
3083 ZEND_ARG_INFO(0, callback)
3084 ZEND_END_ARG_INFO()
3085
3086 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_open, 0, 0, 2)
3087 ZEND_ARG_INFO(0, file)
3088 ZEND_ARG_INFO(0, pipe)
3089 ZEND_END_ARG_INFO()
3090
3091 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_init, 0, 0, 0)
3092 ZEND_ARG_INFO(0, file)
3093 ZEND_ARG_INFO(0, ipc)
3094 ZEND_END_ARG_INFO()
3095
3096 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_bind, 0, 0, 2)
3097 ZEND_ARG_INFO(0, handle)
3098 ZEND_ARG_INFO(0, name)
3099 ZEND_END_ARG_INFO()
3100
3101 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_connect, 0, 0, 3)
3102 ZEND_ARG_INFO(0, handle)
3103 ZEND_ARG_INFO(0, name)
3104 ZEND_ARG_INFO(0, callback)
3105 ZEND_END_ARG_INFO()
3106
3107 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_pending_count, 0, 0, 1)
3108 ZEND_ARG_INFO(0, handle)
3109 ZEND_END_ARG_INFO()
3110
3111 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_pending_type, 0, 0, 1)
3112 ZEND_ARG_INFO(0, handle)
3113 ZEND_END_ARG_INFO()
3114
3115 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_pipe_pending_instances, 0, 0, 2)
3116 ZEND_ARG_INFO(0, handle)
3117 ZEND_ARG_INFO(0, count)
3118 ZEND_END_ARG_INFO()
3119
3120
3121 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_getaddrinfo, 0, 0, 4)
3122 ZEND_ARG_INFO(0, loop)
3123 ZEND_ARG_INFO(0, callback)
3124 ZEND_ARG_INFO(0, node)
3125 ZEND_ARG_INFO(0, service)
3126 ZEND_ARG_INFO(0, hints)
3127 ZEND_END_ARG_INFO()
3128
3129 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_spawn, 0, 0, 7)
3130 ZEND_ARG_INFO(0, loop)
3131 ZEND_ARG_INFO(0, command)
3132 ZEND_ARG_INFO(0, args)
3133 ZEND_ARG_INFO(0, stdio)
3134 ZEND_ARG_INFO(0, cwd)
3135 ZEND_ARG_INFO(0, env)
3136 ZEND_ARG_INFO(0, callback)
3137 ZEND_ARG_INFO(0, flags)
3138 ZEND_ARG_INFO(0, options)
3139 ZEND_END_ARG_INFO()
3140
3141 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_kill, 0, 0, 2)
3142 ZEND_ARG_INFO(0, pid)
3143 ZEND_ARG_INFO(0, signal)
3144 ZEND_END_ARG_INFO()
3145
3146 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_process_kill, 0, 0, 2)
3147 ZEND_ARG_INFO(0, process)
3148 ZEND_ARG_INFO(0, signal)
3149 ZEND_END_ARG_INFO()
3150
3151 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_process_get_pid, 0, 0, 1)
3152 ZEND_ARG_INFO(0, process)
3153 ZEND_END_ARG_INFO()
3154
3155 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_chdir, 0, 0, 1)
3156 ZEND_ARG_INFO(0, dir)
3157 ZEND_END_ARG_INFO()
3158
3159 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tty_get_winsize, 0, 0, 3)
3160 ZEND_ARG_INFO(0, tty)
3161 ZEND_ARG_INFO(1, width)
3162 ZEND_ARG_INFO(1, height)
3163 ZEND_END_ARG_INFO()
3164
3165 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tty_init, 0, 0, 3)
3166 ZEND_ARG_INFO(0, loop)
3167 ZEND_ARG_INFO(0, fd)
3168 ZEND_ARG_INFO(0, readable)
3169 ZEND_END_ARG_INFO()
3170
3171 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_event_init, 0, 0, 3)
3172 ZEND_ARG_INFO(0, loop)
3173 ZEND_ARG_INFO(0, path)
3174 ZEND_ARG_INFO(0, callback)
3175 ZEND_ARG_INFO(0, flags)
3176 ZEND_END_ARG_INFO()
3177
3178 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_sendfile, 0, 0, 5)
3179 ZEND_ARG_INFO(0, loop)
3180 ZEND_ARG_INFO(0, in)
3181 ZEND_ARG_INFO(0, out)
3182 ZEND_ARG_INFO(0, offset)
3183 ZEND_ARG_INFO(0, length)
3184 ZEND_ARG_INFO(0, callback)
3185 ZEND_END_ARG_INFO()
3186
3187 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_readdir, 0, 0, 3)
3188 ZEND_ARG_INFO(0, loop)
3189 ZEND_ARG_INFO(0, path)
3190 ZEND_ARG_INFO(0, flags)
3191 ZEND_ARG_INFO(0, callback)
3192 ZEND_END_ARG_INFO()
3193
3194 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_scandir, 0, 0, 3)
3195 ZEND_ARG_INFO(0, loop)
3196 ZEND_ARG_INFO(0, path)
3197 ZEND_ARG_INFO(0, flags)
3198 ZEND_ARG_INFO(0, callback)
3199 ZEND_END_ARG_INFO()
3200
3201 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_fstat, 0, 0, 2)
3202 ZEND_ARG_INFO(0, loop)
3203 ZEND_ARG_INFO(0, fd)
3204 ZEND_ARG_INFO(0, callback)
3205 ZEND_END_ARG_INFO()
3206
3207 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_lstat, 0, 0, 2)
3208 ZEND_ARG_INFO(0, loop)
3209 ZEND_ARG_INFO(0, path)
3210 ZEND_ARG_INFO(0, callback)
3211 ZEND_END_ARG_INFO()
3212
3213 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_stat, 0, 0, 2)
3214 ZEND_ARG_INFO(0, loop)
3215 ZEND_ARG_INFO(0, path)
3216 ZEND_ARG_INFO(0, callback)
3217 ZEND_END_ARG_INFO()
3218
3219 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_readlink, 0, 0, 2)
3220 ZEND_ARG_INFO(0, loop)
3221 ZEND_ARG_INFO(0, path)
3222 ZEND_ARG_INFO(0, callback)
3223 ZEND_END_ARG_INFO()
3224
3225 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_symlink, 0, 0, 4)
3226 ZEND_ARG_INFO(0, loop)
3227 ZEND_ARG_INFO(0, from)
3228 ZEND_ARG_INFO(0, to)
3229 ZEND_ARG_INFO(0, callback)
3230 ZEND_ARG_INFO(0, flags)
3231 ZEND_END_ARG_INFO()
3232
3233 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_link, 0, 0, 3)
3234 ZEND_ARG_INFO(0, loop)
3235 ZEND_ARG_INFO(0, from)
3236 ZEND_ARG_INFO(0, to)
3237 ZEND_ARG_INFO(0, callback)
3238 ZEND_END_ARG_INFO()
3239
3240 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_fchown, 0, 0, 4)
3241 ZEND_ARG_INFO(0, loop)
3242 ZEND_ARG_INFO(0, fd)
3243 ZEND_ARG_INFO(0, uid)
3244 ZEND_ARG_INFO(0, gid)
3245 ZEND_ARG_INFO(0, callback)
3246 ZEND_END_ARG_INFO()
3247
3248 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_chown, 0, 0, 4)
3249 ZEND_ARG_INFO(0, loop)
3250 ZEND_ARG_INFO(0, path)
3251 ZEND_ARG_INFO(0, uid)
3252 ZEND_ARG_INFO(0, gid)
3253 ZEND_ARG_INFO(0, callback)
3254 ZEND_END_ARG_INFO()
3255
3256 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_fchmod, 0, 0, 3)
3257 ZEND_ARG_INFO(0, loop)
3258 ZEND_ARG_INFO(0, fd)
3259 ZEND_ARG_INFO(0, mode)
3260 ZEND_ARG_INFO(0, callback)
3261 ZEND_END_ARG_INFO()
3262
3263 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_chmod, 0, 0, 3)
3264 ZEND_ARG_INFO(0, loop)
3265 ZEND_ARG_INFO(0, path)
3266 ZEND_ARG_INFO(0, mode)
3267 ZEND_ARG_INFO(0, callback)
3268 ZEND_END_ARG_INFO()
3269
3270 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_futime, 0, 0, 4)
3271 ZEND_ARG_INFO(0, loop)
3272 ZEND_ARG_INFO(0, fd)
3273 ZEND_ARG_INFO(0, utime)
3274 ZEND_ARG_INFO(0, atime)
3275 ZEND_ARG_INFO(0, callback)
3276 ZEND_END_ARG_INFO()
3277
3278 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_utime, 0, 0, 4)
3279 ZEND_ARG_INFO(0, loop)
3280 ZEND_ARG_INFO(0, path)
3281 ZEND_ARG_INFO(0, utime)
3282 ZEND_ARG_INFO(0, atime)
3283 ZEND_ARG_INFO(0, callback)
3284 ZEND_END_ARG_INFO()
3285
3286 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_open, 0, 0, 4)
3287 ZEND_ARG_INFO(0, loop)
3288 ZEND_ARG_INFO(0, path)
3289 ZEND_ARG_INFO(0, flag)
3290 ZEND_ARG_INFO(0, mode)
3291 ZEND_ARG_INFO(0, callback)
3292 ZEND_END_ARG_INFO()
3293
3294 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_read, 0, 0, 2)
3295 ZEND_ARG_INFO(0, loop)
3296 ZEND_ARG_INFO(0, fd)
3297 ZEND_ARG_INFO(0, offset)
3298 ZEND_ARG_INFO(0, size)
3299 ZEND_ARG_INFO(0, callback)
3300 ZEND_END_ARG_INFO()
3301
3302 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_close, 0, 0, 2)
3303 ZEND_ARG_INFO(0, loop)
3304 ZEND_ARG_INFO(0, fd)
3305 ZEND_ARG_INFO(0, callback)
3306 ZEND_END_ARG_INFO()
3307
3308 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_write, 0, 0, 4)
3309 ZEND_ARG_INFO(0, loop)
3310 ZEND_ARG_INFO(0, fd)
3311 ZEND_ARG_INFO(0, buffer)
3312 ZEND_ARG_INFO(0, offset)
3313 ZEND_ARG_INFO(0, callback)
3314 ZEND_END_ARG_INFO()
3315
3316 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_fsync, 0, 0, 2)
3317 ZEND_ARG_INFO(0, loop)
3318 ZEND_ARG_INFO(0, fd)
3319 ZEND_ARG_INFO(0, callback)
3320 ZEND_END_ARG_INFO()
3321
3322 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_fdatasync, 0, 0, 2)
3323 ZEND_ARG_INFO(0, loop)
3324 ZEND_ARG_INFO(0, fd)
3325 ZEND_ARG_INFO(0, callback)
3326 ZEND_END_ARG_INFO()
3327
3328 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_ftruncate, 0, 0, 3)
3329 ZEND_ARG_INFO(0, loop)
3330 ZEND_ARG_INFO(0, fd)
3331 ZEND_ARG_INFO(0, offset)
3332 ZEND_ARG_INFO(0, callback)
3333 ZEND_END_ARG_INFO()
3334
3335 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_mkdir, 0, 0, 3)
3336 ZEND_ARG_INFO(0, loop)
3337 ZEND_ARG_INFO(0, path)
3338 ZEND_ARG_INFO(0, mode)
3339 ZEND_ARG_INFO(0, callback)
3340 ZEND_END_ARG_INFO()
3341
3342 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_rmdir, 0, 0, 2)
3343 ZEND_ARG_INFO(0, loop)
3344 ZEND_ARG_INFO(0, path)
3345 ZEND_ARG_INFO(0, callback)
3346 ZEND_END_ARG_INFO()
3347
3348 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_unlink, 0, 0, 2)
3349 ZEND_ARG_INFO(0, loop)
3350 ZEND_ARG_INFO(0, path)
3351 ZEND_ARG_INFO(0, callback)
3352 ZEND_END_ARG_INFO()
3353
3354 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_rename, 0, 0, 3)
3355 ZEND_ARG_INFO(0, loop)
3356 ZEND_ARG_INFO(0, from)
3357 ZEND_ARG_INFO(0, to)
3358 ZEND_ARG_INFO(0, callback)
3359 ZEND_END_ARG_INFO()
3360
3361 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_rdlock, 0, 0, 1)
3362 ZEND_ARG_INFO(0, handle)
3363 ZEND_END_ARG_INFO()
3364
3365 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_tryrdlock, 0, 0, 1)
3366 ZEND_ARG_INFO(0, handle)
3367 ZEND_END_ARG_INFO()
3368
3369 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_rdunlock, 0, 0, 1)
3370 ZEND_ARG_INFO(0, handle)
3371 ZEND_END_ARG_INFO()
3372
3373 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_wrlock, 0, 0, 1)
3374 ZEND_ARG_INFO(0, handle)
3375 ZEND_END_ARG_INFO()
3376
3377 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_trywrlock, 0, 0, 1)
3378 ZEND_ARG_INFO(0, handle)
3379 ZEND_END_ARG_INFO()
3380
3381 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_rwlock_wrunlock, 0, 0, 1)
3382 ZEND_ARG_INFO(0, handle)
3383 ZEND_END_ARG_INFO()
3384
3385 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_mutex_lock, 0, 0, 1)
3386 ZEND_ARG_INFO(0, handle)
3387 ZEND_END_ARG_INFO()
3388
3389 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_mutex_trylock, 0, 0, 1)
3390 ZEND_ARG_INFO(0, handle)
3391 ZEND_END_ARG_INFO()
3392
3393 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_mutex_unlock, 0, 0, 1)
3394 ZEND_ARG_INFO(0, handle)
3395 ZEND_END_ARG_INFO()
3396
3397 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_sem_init, 0, 0, 1)
3398 ZEND_ARG_INFO(0, val)
3399 ZEND_END_ARG_INFO()
3400
3401 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_sem_post, 0, 0, 1)
3402 ZEND_ARG_INFO(0, resource)
3403 ZEND_END_ARG_INFO()
3404
3405 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_sem_wait, 0, 0, 1)
3406 ZEND_ARG_INFO(0, resource)
3407 ZEND_END_ARG_INFO()
3408
3409 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_sem_trywait, 0, 0, 1)
3410 ZEND_ARG_INFO(0, resource)
3411 ZEND_END_ARG_INFO()
3412
3413 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_prepare_init, 0, 0, 0)
3414 ZEND_ARG_INFO(0, loop)
3415 ZEND_END_ARG_INFO()
3416
3417 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_prepare_start, 0, 0, 2)
3418 ZEND_ARG_INFO(0, handle)
3419 ZEND_ARG_INFO(0, callback)
3420 ZEND_END_ARG_INFO()
3421
3422 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_prepare_stop, 0, 0, 1)
3423 ZEND_ARG_INFO(0, handle)
3424 ZEND_END_ARG_INFO()
3425
3426 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_check_init, 0, 0, 0)
3427 ZEND_ARG_INFO(0, loop)
3428 ZEND_END_ARG_INFO()
3429
3430 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_check_start, 0, 0, 2)
3431 ZEND_ARG_INFO(0, handle)
3432 ZEND_ARG_INFO(0, callback)
3433 ZEND_END_ARG_INFO()
3434
3435 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_check_stop, 0, 0, 1)
3436 ZEND_ARG_INFO(0, handle)
3437 ZEND_END_ARG_INFO()
3438
3439 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_async_send, 0, 0, 1)
3440 ZEND_ARG_INFO(0, handle)
3441 ZEND_END_ARG_INFO()
3442
3443 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_async_init, 0, 0, 2)
3444 ZEND_ARG_INFO(0, loop)
3445 ZEND_ARG_INFO(0, callback)
3446 ZEND_END_ARG_INFO()
3447
3448 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_getsockname, 0, 0, 1)
3449 ZEND_ARG_INFO(0, handle)
3450 ZEND_END_ARG_INFO()
3451
3452 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_getpeername, 0, 0, 1)
3453 ZEND_ARG_INFO(0, handle)
3454 ZEND_END_ARG_INFO()
3455
3456 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_getsockname, 0, 0, 1)
3457 ZEND_ARG_INFO(0, handle)
3458 ZEND_END_ARG_INFO()
3459
3460 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_tcp_simultaneous_accepts, 0, 0, 2)
3461 ZEND_ARG_INFO(0, handle)
3462 ZEND_ARG_INFO(0, enable)
3463 ZEND_END_ARG_INFO()
3464
3465 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_udp_set_membership, 0, 0, 4)
3466 ZEND_ARG_INFO(0, client)
3467 ZEND_ARG_INFO(0, multicast_addr)
3468 ZEND_ARG_INFO(0, interface_addr)
3469 ZEND_ARG_INFO(0, membership)
3470 ZEND_END_ARG_INFO()
3471
3472 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_ip6_name, 0, 0, 1)
3473 ZEND_ARG_INFO(0, handle)
3474 ZEND_END_ARG_INFO()
3475
3476 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_ip4_name, 0, 0, 1)
3477 ZEND_ARG_INFO(0, handle)
3478 ZEND_END_ARG_INFO()
3479
3480 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_poll_init, 0, 0, 0)
3481 ZEND_ARG_INFO(0, loop)
3482 ZEND_END_ARG_INFO()
3483
3484 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_poll_start, 0, 0, 4)
3485 ZEND_ARG_INFO(0, handle)
3486 ZEND_ARG_INFO(0, callback)
3487 ZEND_ARG_INFO(0, path)
3488 ZEND_ARG_INFO(0, interval)
3489 ZEND_END_ARG_INFO()
3490
3491 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_fs_poll_stop, 0, 0, 1)
3492 ZEND_ARG_INFO(0, loop)
3493 ZEND_END_ARG_INFO()
3494
3495 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_init, 0, 0, 2)
3496 ZEND_ARG_INFO(0, loop)
3497 ZEND_ARG_INFO(0, fd)
3498 ZEND_END_ARG_INFO()
3499
3500 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_start, 0, 0, 3)
3501 ZEND_ARG_INFO(0, handle)
3502 ZEND_ARG_INFO(0, events)
3503 ZEND_ARG_INFO(0, callback)
3504 ZEND_END_ARG_INFO()
3505
3506 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_stop, 0, 0, 1)
3507 ZEND_ARG_INFO(0, handle)
3508 ZEND_END_ARG_INFO()
3509
3510 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_init, 0, 0, 0)
3511 ZEND_ARG_INFO(0, loop)
3512 ZEND_END_ARG_INFO()
3513
3514 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_start, 0, 0, 3)
3515 ZEND_ARG_INFO(0, sig_handle)
3516 ZEND_ARG_INFO(0, sig_callback)
3517 ZEND_ARG_INFO(0, sig_num)
3518 ZEND_END_ARG_INFO()
3519
3520 ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_stop, 0, 0, 1)
3521 ZEND_ARG_INFO(0, sig_handle)
3522 ZEND_END_ARG_INFO()
3523
3524 /* PHP Functions */
3525
3526 /* {{{ proto void uv_unref(UV $uv_t)
3527 */
3528 PHP_FUNCTION(uv_unref)
3529 {
3530 php_uv_t *uv;
3531
3532 ZEND_PARSE_PARAMETERS_START(1, 1)
3533 UV_PARAM_OBJ(uv, php_uv_t, uv_ce)
3534 ZEND_PARSE_PARAMETERS_END();
3535
3536 uv_unref(&uv->uv.handle);
3537 }
3538 /* }}} */
3539
3540 /* {{{ proto string uv_err_name(long $error_code)
3541 */
3542 PHP_FUNCTION(uv_err_name)
3543 {
3544 zend_long error_code;
3545 const char *error_msg;
3546
3547 if (zend_parse_parameters(ZEND_NUM_ARGS(),
3548 "l", &error_code) == FAILURE) {
3549 return;
3550 }
3551
3552 if (error_code < UV_ERRNO_MAX || error_code > 0) {
3553 php_error_docref(NULL, E_NOTICE, "passes unexpected value.");
3554 RETURN_FALSE;
3555 }
3556
3557 error_msg = uv_err_name(error_code);
3558
3559 RETVAL_STRING(error_msg);
3560 }
3561 /* }}} */
3562
3563
3564 /* {{{ proto string uv_strerror(long $error_code)
3565 */
3566 PHP_FUNCTION(uv_strerror)
3567 {
3568 zend_long error_code;
3569 const char *error_msg;
3570
3571 if (zend_parse_parameters(ZEND_NUM_ARGS(),
3572 "l", &error_code) == FAILURE) {
3573 return;
3574 }
3575
3576 error_msg = php_uv_strerror(error_code);
3577 RETVAL_STRING(error_msg);
3578 }
3579 /* }}} */
3580
3581 /* {{{ proto void uv_update_time([UVLoop $uv_loop = uv_default_loop()])
3582 */
3583 PHP_FUNCTION(uv_update_time)
3584 {
3585 php_uv_loop_t *loop = NULL;
3586
3587 ZEND_PARSE_PARAMETERS_START(0, 1)
3588 Z_PARAM_OPTIONAL
3589 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
3590 ZEND_PARSE_PARAMETERS_END();
3591
3592 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
3593 uv_update_time(&loop->loop);
3594 }
3595 /* }}} */
3596
3597 /* {{{ proto void uv_ref(UV $uv_handle)
3598 */
3599 PHP_FUNCTION(uv_ref)
3600 {
3601 php_uv_t *uv;
3602
3603 ZEND_PARSE_PARAMETERS_START(1, 1)
3604 UV_PARAM_OBJ(uv, php_uv_t, uv_ce)
3605 ZEND_PARSE_PARAMETERS_END();
3606
3607 uv_ref(&uv->uv.handle);
3608 }
3609 /* }}} */
3610
3611 /* {{{ proto void uv_run([UVLoop $uv_loop = uv_default_loop(), long $run_mode = UV::RUN_DEFAULT])
3612 */
3613 PHP_FUNCTION(uv_run)
3614 {
3615 php_uv_loop_t *loop = NULL;
3616 zend_long run_mode = UV_RUN_DEFAULT;
3617
3618 ZEND_PARSE_PARAMETERS_START(0, 2)
3619 Z_PARAM_OPTIONAL
3620 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
3621 Z_PARAM_LONG(run_mode)
3622 ZEND_PARSE_PARAMETERS_END();
3623
3624 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
3625 uv_run(&loop->loop, run_mode);
3626 }
3627 /* }}} */
3628
3629 /* {{{ proto void uv_stop([UVLoop $uv_loop = uv_default_loop()])
3630 */
3631 PHP_FUNCTION(uv_stop)
3632 {
3633 php_uv_loop_t *loop = NULL;
3634
3635 ZEND_PARSE_PARAMETERS_START(0, 1)
3636 Z_PARAM_OPTIONAL
3637 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
3638 ZEND_PARSE_PARAMETERS_END();
3639
3640 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
3641 uv_stop(&loop->loop);
3642 }
3643 /* }}} */
3644
3645 /* {{{ proto resource uv_signal_init([UVLoop $uv_loop = uv_default_loop()])
3646 */
3647 PHP_FUNCTION(uv_signal_init)
3648 {
3649 php_uv_loop_t *loop = NULL;
3650 php_uv_t *uv;
3651
3652 ZEND_PARSE_PARAMETERS_START(0, 1)
3653 Z_PARAM_OPTIONAL
3654 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
3655 ZEND_PARSE_PARAMETERS_END();
3656
3657 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
3658 PHP_UV_INIT_UV_EX(uv, uv_signal_ce, uv_signal_init);
3659
3660 RETURN_OBJ(&uv->std);
3661 }
3662 /* }}} */
3663
3664 /* {{{ proto void uv_signal_start(UVSignal $sig_handle, callable(UVSignal $sig_handle, long $sig_num) $sig_callback, int $sig_num)
3665 */
3666 PHP_FUNCTION(uv_signal_start)
3667 {
3668 zend_long sig_num;
3669 php_uv_t *uv;
3670 zend_fcall_info fci = empty_fcall_info;
3671 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3672 php_uv_cb_t *cb;
3673
3674 ZEND_PARSE_PARAMETERS_START(3, 3)
3675 UV_PARAM_OBJ(uv, php_uv_t, uv_signal_ce)
3676 Z_PARAM_FUNC(fci, fcc)
3677 Z_PARAM_LONG(sig_num)
3678 ZEND_PARSE_PARAMETERS_END();
3679
3680 if (uv_is_active((uv_handle_t *) &uv->uv.signal)) {
3681 php_error_docref(NULL, E_NOTICE, "passed uv signal resource has been started. you don't have to call this method");
3682 RETURN_FALSE;
3683 }
3684
3685 GC_ADDREF(&uv->std);
3686 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_signal_start, uv);
3687
3688 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_SIGNAL_CB);
3689
3690 uv_signal_start((uv_signal_t *) &uv->uv.signal, php_uv_signal_cb, sig_num);
3691 }
3692 /* }}} */
3693
3694 /* {{{ proto int uv_signal_stop(UVSignal $sig_handle)
3695 */
3696 PHP_FUNCTION(uv_signal_stop)
3697 {
3698 php_uv_t *uv;
3699 int r = 0;
3700
3701 ZEND_PARSE_PARAMETERS_START(1, 1)
3702 UV_PARAM_OBJ(uv, php_uv_t, uv_signal_ce)
3703 ZEND_PARSE_PARAMETERS_END();
3704
3705 if (!uv_is_active((uv_handle_t *) &uv->uv.signal)) {
3706 php_error_docref(NULL, E_NOTICE, "passed uv signal resource has been stopped. you don't have to call this method");
3707 RETURN_FALSE;
3708 }
3709
3710 r = uv_signal_stop((uv_signal_t *) &uv->uv.signal);
3711
3712 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_signal_stop, uv);
3713 OBJ_RELEASE(&uv->std);
3714
3715 RETURN_LONG(r);
3716 }
3717 /* }}} */
3718
3719 /* {{{ proto void uv_loop_delete(UVLoop $uv_loop)
3720 */
3721 PHP_FUNCTION(uv_loop_delete)
3722 {
3723 php_uv_loop_t *loop;
3724
3725 ZEND_PARSE_PARAMETERS_START(1, 1)
3726 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
3727 ZEND_PARSE_PARAMETERS_END();
3728
3729 if (loop != UV_G(default_loop)) {
3730 #if PHP_VERSION_ID < 70300
3731 GC_FLAGS(&loop->std) |= IS_OBJ_DESTRUCTOR_CALLED;
3732 #else
3733 GC_ADD_FLAGS(&loop->std, IS_OBJ_DESTRUCTOR_CALLED);
3734 #endif
3735 destruct_uv_loop(&loop->std);
3736 }
3737 }
3738 /* }}} */
3739
3740 /* {{{ proto long uv_now([UVLoop $uv_loop = uv_default_loop()])
3741 */
3742 PHP_FUNCTION(uv_now)
3743 {
3744 php_uv_loop_t *loop = NULL;
3745 int64_t now;
3746
3747 ZEND_PARSE_PARAMETERS_START(0, 1)
3748 Z_PARAM_OPTIONAL
3749 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
3750 ZEND_PARSE_PARAMETERS_END();
3751
3752 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
3753 now = uv_now(&loop->loop);
3754 RETURN_LONG((long)now);
3755 }
3756 /* }}} */
3757
3758
3759 /* {{{ proto void uv_tcp_bind(UVTcp $uv_tcp, UVSockAddr $uv_sockaddr)
3760 */
3761 PHP_FUNCTION(uv_tcp_bind)
3762 {
3763 php_uv_socket_bind(PHP_UV_TCP_IPV4, INTERNAL_FUNCTION_PARAM_PASSTHRU);
3764 }
3765 /* }}} */
3766
3767 /* {{{ proto void uv_tcp_bind6(UVTcp $uv_tcp, UVSockAddr $uv_sockaddr)
3768 */
3769 PHP_FUNCTION(uv_tcp_bind6)
3770 {
3771 php_uv_socket_bind(PHP_UV_TCP_IPV6, INTERNAL_FUNCTION_PARAM_PASSTHRU);
3772 }
3773 /* }}} */
3774
3775
3776 /* {{{ proto void uv_write(UVStream $handle, string $data[, callable(UVStream $handle, long $status) $callback = function() {}])
3777 */
3778 PHP_FUNCTION(uv_write)
3779 {
3780 zend_string *data;
3781 int r;
3782 php_uv_t *uv;
3783 write_req_t *w;
3784 zend_fcall_info fci = empty_fcall_info;
3785 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3786 php_uv_cb_t *cb;
3787
3788 ZEND_PARSE_PARAMETERS_START(2, 3)
3789 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
3790 Z_PARAM_STR(data)
3791 Z_PARAM_OPTIONAL
3792 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
3793 ZEND_PARSE_PARAMETERS_END();
3794
3795 cb = php_uv_cb_init_dynamic(uv, &fci, &fcc);
3796 PHP_UV_INIT_WRITE_REQ(w, uv, data->val, data->len, cb)
3797
3798 r = uv_write(&w->req, &uv->uv.stream, &w->buf, 1, php_uv_write_cb);
3799 if (r) {
3800 php_uv_free_write_req(w);
3801 php_error_docref(NULL, E_WARNING, "write failed");
3802 } else {
3803 GC_ADDREF(&uv->std);
3804 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_write, uv);
3805 }
3806 }
3807 /* }}} */
3808
3809 /* {{{ proto void uv_write2(UvStream $handle, string $data, UVTcp|UvPipe $send, callable(UVStream $handle, long $status) $callback)
3810 */
3811 PHP_FUNCTION(uv_write2)
3812 {
3813 zend_string *data;
3814 int r;
3815 php_uv_t *uv, *send;
3816 write_req_t *w;
3817 zend_fcall_info fci = empty_fcall_info;
3818 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3819 php_uv_cb_t *cb;
3820
3821 ZEND_PARSE_PARAMETERS_START(4, 4)
3822 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
3823 Z_PARAM_STR(data)
3824 UV_PARAM_OBJ(send, php_uv_t, uv_tcp_ce, uv_pipe_ce)
3825 Z_PARAM_FUNC(fci, fcc)
3826 ZEND_PARSE_PARAMETERS_END();
3827
3828 cb = php_uv_cb_init_dynamic(uv, &fci, &fcc);
3829 PHP_UV_INIT_WRITE_REQ(w, uv, data->val, data->len, cb);
3830
3831 r = uv_write2(&w->req, &uv->uv.stream, &w->buf, 1, &send->uv.stream, php_uv_write_cb);
3832 if (r) {
3833 php_uv_free_write_req(w);
3834 php_error_docref(NULL, E_ERROR, "write2 failed");
3835 } else {
3836 GC_ADDREF(&uv->std);
3837 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_write2, uv);
3838 }
3839 }
3840 /* }}} */
3841
3842 /* {{{ proto void uv_tcp_nodelay(UVTcp $handle, bool $enable)
3843 */
3844 PHP_FUNCTION(uv_tcp_nodelay)
3845 {
3846 php_uv_t *client;
3847 zend_bool bval = 1;
3848
3849 ZEND_PARSE_PARAMETERS_START(2, 2)
3850 UV_PARAM_OBJ(client, php_uv_t, uv_tcp_ce)
3851 Z_PARAM_BOOL(bval)
3852 ZEND_PARSE_PARAMETERS_END();
3853
3854 uv_tcp_nodelay(&client->uv.tcp, bval);
3855 }
3856 /* }}} */
3857
3858 /* {{{ proto void uv_accept<T = UVTcp|UVPipe>(T $server, T $client)
3859 */
3860 PHP_FUNCTION(uv_accept)
3861 {
3862 php_uv_t *server, *client;
3863 int r;
3864
3865 ZEND_PARSE_PARAMETERS_START(2, 2)
3866 UV_PARAM_OBJ(server, php_uv_t, uv_tcp_ce, uv_pipe_ce)
3867 UV_PARAM_OBJ(client, php_uv_t, uv_tcp_ce, uv_pipe_ce)
3868 ZEND_PARSE_PARAMETERS_END();
3869
3870 if (server->std.ce != client->std.ce) {
3871 php_error_docref(NULL, E_WARNING, ".");
3872 zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s expects server and client parameters to be either both of type UVTcp or both of type UVPipe", get_active_function_name());
3873 return;
3874 }
3875
3876 r = uv_accept(&server->uv.stream, &client->uv.stream);
3877 if (r) {
3878 php_error_docref(NULL, E_WARNING, "%s", php_uv_strerror(r));
3879 RETURN_FALSE;
3880 }
3881 }
3882 /* }}} */
3883
3884
3885 /* {{{ proto void uv_shutdown(UVStream $handle, callable(UVStream $handle, long $status) $callback)
3886 */
3887 PHP_FUNCTION(uv_shutdown)
3888 {
3889 php_uv_t *uv;
3890 uv_shutdown_t *shutdown;
3891 zend_fcall_info fci = empty_fcall_info;
3892 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3893 php_uv_cb_t *cb;
3894 int r = 0;
3895
3896 ZEND_PARSE_PARAMETERS_START(1, 2)
3897 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
3898 Z_PARAM_OPTIONAL
3899 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
3900 ZEND_PARSE_PARAMETERS_END();
3901
3902 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_SHUTDOWN_CB);
3903
3904 GC_ADDREF(&uv->std);
3905 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_shutdown, uv);
3906 shutdown = emalloc(sizeof(uv_shutdown_t));
3907 shutdown->data = uv;
3908
3909 r = uv_shutdown(shutdown, &uv->uv.stream, (uv_shutdown_cb)php_uv_shutdown_cb);
3910 if (r) {
3911 php_error_docref(NULL, E_WARNING, "%s", php_uv_strerror(r));
3912 efree(&shutdown);
3913 }
3914
3915 }
3916 /* }}} */
3917
3918 /* {{{ proto void uv_close(UV $handle, callable(UV $handle) $callback)
3919 */
3920 PHP_FUNCTION(uv_close)
3921 {
3922 php_uv_t *uv;
3923 zend_fcall_info fci = empty_fcall_info;
3924 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3925 php_uv_cb_t *cb;
3926
3927 ZEND_PARSE_PARAMETERS_START(1, 2)
3928 UV_PARAM_OBJ(uv, php_uv_t, uv_ce)
3929 Z_PARAM_OPTIONAL
3930 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
3931 ZEND_PARSE_PARAMETERS_END();
3932
3933 if (!php_uv_closeable_type(uv)) {
3934 php_error_docref(NULL, E_WARNING, "passed UV handle (%s) is not closeable", ZSTR_VAL(uv->std.ce->name));
3935 RETURN_FALSE;
3936 }
3937
3938 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_CLOSE_CB);
3939
3940 php_uv_close(uv);
3941 }
3942 /* }}} */
3943
3944 /* {{{ proto void uv_read_start(UVStream $handle, callable(UVStream $handle, string|long $read) $callback)
3945 */
3946 PHP_FUNCTION(uv_read_start)
3947 {
3948 php_uv_t *uv;
3949 zend_fcall_info fci = empty_fcall_info;
3950 zend_fcall_info_cache fcc = empty_fcall_info_cache;
3951 php_uv_cb_t *cb;
3952 int r;
3953 uv_os_fd_t fd;
3954
3955 PHP_UV_DEBUG_PRINT("uv_read_start\n");
3956
3957 ZEND_PARSE_PARAMETERS_START(2, 2)
3958 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
3959 Z_PARAM_FUNC(fci, fcc)
3960 ZEND_PARSE_PARAMETERS_END();
3961
3962 if (uv_fileno(&uv->uv.handle, &fd) != 0) {
3963 php_error_docref(NULL, E_WARNING, "passed UV handle is not initialized yet");
3964 return;
3965 }
3966
3967 GC_ADDREF(&uv->std);
3968 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_read_start, uv);
3969
3970 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_READ_CB);
3971
3972 r = uv_read_start(&uv->uv.stream, php_uv_read_alloc, php_uv_read_cb);
3973 if (r) {
3974 php_error_docref(NULL, E_NOTICE, "read failed");
3975 OBJ_RELEASE(&uv->std);
3976 }
3977 }
3978 /* }}} */
3979
3980 /* {{{ proto void uv_read_stop(UVStream $handle)
3981 */
3982 PHP_FUNCTION(uv_read_stop)
3983 {
3984 php_uv_t *uv;
3985
3986 ZEND_PARSE_PARAMETERS_START(1, 1)
3987 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
3988 ZEND_PARSE_PARAMETERS_END();
3989
3990 if (!uv_is_active(&uv->uv.handle)) {
3991 return;
3992 }
3993
3994 uv_read_stop(&uv->uv.stream);
3995
3996 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_read_stop, uv);
3997 OBJ_RELEASE(&uv->std);
3998 }
3999 /* }}} */
4000
4001 /* {{{ proto UVSockAddrIPv4 uv_ip4_addr(string $ipv4_addr, long $port)
4002 */
4003 PHP_FUNCTION(uv_ip4_addr)
4004 {
4005 zend_string *address;
4006 zend_long port = 0;
4007 php_uv_sockaddr_t *sockaddr;
4008
4009 if (zend_parse_parameters(ZEND_NUM_ARGS(),
4010 "Sl", &address, &port) == FAILURE) {
4011 return;
4012 }
4013
4014 PHP_UV_SOCKADDR_IPV4_INIT(sockaddr);
4015 uv_ip4_addr(address->val, port, &PHP_UV_SOCKADDR_IPV4(sockaddr));
4016
4017 RETURN_OBJ(&sockaddr->std);
4018 }
4019 /* }}} */
4020
4021 /* {{{ proto UVSockAddrIPv6 uv_ip6_addr(string $ipv6_addr, long $port)
4022 */
4023 PHP_FUNCTION(uv_ip6_addr)
4024 {
4025 zend_string *address;
4026 zend_long port = 0;
4027 php_uv_sockaddr_t *sockaddr;
4028
4029 if (zend_parse_parameters(ZEND_NUM_ARGS(),
4030 "Sl", &address, &port) == FAILURE) {
4031 return;
4032 }
4033
4034 PHP_UV_SOCKADDR_IPV6_INIT(sockaddr);
4035 uv_ip6_addr(address->val, port, &PHP_UV_SOCKADDR_IPV6(sockaddr));
4036
4037 RETURN_OBJ(&sockaddr->std);
4038 }
4039 /* }}} */
4040
4041
4042 /* {{{ proto void uv_listen<T = UVTcp|UVPipe>(T $handle, long $backlog, callable(T $handle, long $status) $callback)
4043 */
4044 PHP_FUNCTION(uv_listen)
4045 {
4046 zend_long backlog = SOMAXCONN;
4047 php_uv_t *uv;
4048 zend_fcall_info fci = empty_fcall_info;
4049 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4050 php_uv_cb_t *cb;
4051 int r;
4052
4053 ZEND_PARSE_PARAMETERS_START(3, 3)
4054 UV_PARAM_OBJ(uv, php_uv_t, uv_tcp_ce, uv_pipe_ce)
4055 Z_PARAM_LONG(backlog)
4056 Z_PARAM_FUNC(fci, fcc)
4057 ZEND_PARSE_PARAMETERS_END();
4058
4059 GC_ADDREF(&uv->std);
4060 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_listen, uv);
4061 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_LISTEN_CB);
4062
4063 r = uv_listen(&uv->uv.stream, backlog, php_uv_listen_cb);
4064 if (r) {
4065 php_error_docref(NULL, E_WARNING, "%s", php_uv_strerror(r));
4066 OBJ_RELEASE(&uv->std);
4067 }
4068 }
4069 /* }}} */
4070
4071 /* {{{ proto void uv_tcp_connect(UVTcp $handle, UVSockAddr $sock_addr, callable(UVTcp $handle, long $status) $callback)
4072 */
4073 PHP_FUNCTION(uv_tcp_connect)
4074 {
4075 php_uv_tcp_connect(PHP_UV_TCP_IPV4, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4076 }
4077 /* }}} */
4078
4079
4080 /* {{{ proto void uv_tcp_connect6(UVTcp $handle, UVSockAddrIPv6 $ipv6_addr, callable(UVTcp $handle, long $status) $callback)
4081 */
4082 PHP_FUNCTION(uv_tcp_connect6)
4083 {
4084 php_error_docref(NULL, E_DEPRECATED, "uv_udp_send6: Use uv_udp_send() instead");
4085 php_uv_tcp_connect(PHP_UV_TCP_IPV6, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4086 }
4087 /* }}} */
4088
4089
4090 /* {{{ proto UVTimer uv_timer_init([UVLoop $loop = uv_default_loop()])
4091 */
4092 PHP_FUNCTION(uv_timer_init)
4093 {
4094 php_uv_loop_t *loop = NULL;
4095 php_uv_t *uv;
4096
4097 ZEND_PARSE_PARAMETERS_START(0, 1)
4098 Z_PARAM_OPTIONAL
4099 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
4100 ZEND_PARSE_PARAMETERS_END();
4101
4102 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4103 PHP_UV_INIT_UV_EX(uv, uv_timer_ce, uv_timer_init);
4104
4105 PHP_UV_DEBUG_PRINT("uv_timer_init: resource: %p\n", uv);
4106
4107 RETURN_OBJ(&uv->std);
4108 }
4109 /* }}} */
4110
4111 /* {{{ proto void uv_timer_start(UVTimer $timer, long $timeout, long $repeat[, callable(UVTimer $timer) $callback = function() {}])
4112 */
4113 PHP_FUNCTION(uv_timer_start)
4114 {
4115 php_uv_t *uv;
4116 zend_long timeout, repeat = 0;
4117 zend_fcall_info fci = empty_fcall_info;
4118 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4119 php_uv_cb_t *cb;
4120
4121 ZEND_PARSE_PARAMETERS_START(3, 4)
4122 UV_PARAM_OBJ(uv, php_uv_t, uv_timer_ce)
4123 Z_PARAM_LONG(timeout)
4124 Z_PARAM_LONG(repeat)
4125 Z_PARAM_OPTIONAL
4126 Z_PARAM_FUNC_EX(fci, fcc, 1, 0)
4127 ZEND_PARSE_PARAMETERS_END();
4128
4129 if (timeout < 0) {
4130 php_error_docref(NULL, E_WARNING, "timeout value have to be larger than 0. given %lld", timeout);
4131 RETURN_FALSE;
4132 }
4133
4134 if (repeat < 0) {
4135 php_error_docref(NULL, E_WARNING, "repeat value have to be larger than 0. given %lld", repeat);
4136 RETURN_FALSE;
4137 }
4138
4139 if (uv_is_active(&uv->uv.handle)) {
4140 php_error_docref(NULL, E_NOTICE, "Passed uv timer resource has been started. You don't have to call this method");
4141 RETURN_FALSE;
4142 }
4143
4144 GC_ADDREF(&uv->std);
4145 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_timer_start, uv);
4146 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_TIMER_CB);
4147
4148 uv_timer_start((uv_timer_t*)&uv->uv.timer, php_uv_timer_cb, timeout, repeat);
4149 }
4150 /* }}} */
4151
4152 /* {{{ proto void uv_timer_stop(UVTimer $timer)
4153 */
4154 PHP_FUNCTION(uv_timer_stop)
4155 {
4156 php_uv_t *uv;
4157 int r = 0;
4158
4159 ZEND_PARSE_PARAMETERS_START(1, 1)
4160 UV_PARAM_OBJ(uv, php_uv_t, uv_timer_ce)
4161 ZEND_PARSE_PARAMETERS_END();
4162
4163 if (!uv_is_active(&uv->uv.handle)) {
4164 php_error_docref(NULL, E_NOTICE, "Passed uv timer resource has been stopped. You don't have to call this method");
4165 RETURN_FALSE;
4166 }
4167
4168 PHP_UV_DEBUG_PRINT("uv_timer_stop: resource: %p\n", uv);
4169 r = uv_timer_stop(&uv->uv.timer);
4170
4171 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_timer_stop, uv);
4172 OBJ_RELEASE(&uv->std);
4173
4174 RETURN_LONG(r);
4175 }
4176 /* }}} */
4177
4178 /* {{{ proto void uv_timer_again(UVTimer $timer)
4179 */
4180 PHP_FUNCTION(uv_timer_again)
4181 {
4182 php_uv_t *uv;
4183
4184 ZEND_PARSE_PARAMETERS_START(1, 1)
4185 UV_PARAM_OBJ(uv, php_uv_t, uv_timer_ce)
4186 ZEND_PARSE_PARAMETERS_END();
4187
4188 if (uv_is_active(&uv->uv.handle)) {
4189 php_error_docref(NULL, E_NOTICE, "Passed uv timer resource has been started. You don't have to call this method");
4190 RETURN_FALSE;
4191 }
4192
4193 GC_ADDREF(&uv->std);
4194 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_timer_again, uv);
4195
4196 uv_timer_again(&uv->uv.timer);
4197 }
4198 /* }}} */
4199
4200 /* {{{ proto void uv_timer_set_repeat(UVTimer $timer, long $repeat)
4201 */
4202 PHP_FUNCTION(uv_timer_set_repeat)
4203 {
4204 php_uv_t *uv;
4205 zend_long repeat;
4206
4207 ZEND_PARSE_PARAMETERS_START(2, 2)
4208 UV_PARAM_OBJ(uv, php_uv_t, uv_timer_ce)
4209 Z_PARAM_LONG(repeat)
4210 ZEND_PARSE_PARAMETERS_END();
4211
4212 uv_timer_set_repeat(&uv->uv.timer, repeat);
4213 }
4214 /* }}} */
4215
4216 /* {{{ proto long uv_timer_get_repeat(UVTimer $timer)
4217 */
4218 PHP_FUNCTION(uv_timer_get_repeat)
4219 {
4220 php_uv_t *uv;
4221 int64_t repeat;
4222
4223 ZEND_PARSE_PARAMETERS_START(1, 1)
4224 UV_PARAM_OBJ(uv, php_uv_t, uv_timer_ce)
4225 ZEND_PARSE_PARAMETERS_END();
4226
4227 repeat = uv_timer_get_repeat(&uv->uv.timer);
4228 RETURN_LONG(repeat);
4229 }
4230 /* }}} */
4231
4232
4233 /* {{{ proto UVIdle uv_idle_init([UVLoop $loop = uv_default_loop()])
4234 */
4235 PHP_FUNCTION(uv_idle_init)
4236 {
4237 php_uv_loop_t *loop = NULL;
4238 php_uv_t *uv;
4239
4240 ZEND_PARSE_PARAMETERS_START(0, 1)
4241 Z_PARAM_OPTIONAL
4242 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
4243 ZEND_PARSE_PARAMETERS_END();
4244
4245 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4246 PHP_UV_INIT_UV_EX(uv, uv_idle_ce, uv_idle_init);
4247
4248 RETURN_OBJ(&uv->std);
4249 }
4250 /* }}} */
4251
4252 /* {{{ proto void uv_idle_start(UVIdle $idle, callable $callback)
4253 */
4254 PHP_FUNCTION(uv_idle_start)
4255 {
4256 php_uv_t *uv;
4257 zend_fcall_info fci = empty_fcall_info;
4258 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4259 php_uv_cb_t *cb;
4260 int r = 0;
4261
4262 ZEND_PARSE_PARAMETERS_START(2, 2)
4263 UV_PARAM_OBJ(uv, php_uv_t, uv_idle_ce)
4264 Z_PARAM_FUNC(fci, fcc)
4265 ZEND_PARSE_PARAMETERS_END();
4266
4267 if (uv_is_active(&uv->uv.handle)) {
4268 php_error_docref(NULL, E_WARNING, "passed uv_idle resource has already started.");
4269 RETURN_FALSE;
4270 }
4271
4272 GC_ADDREF(&uv->std);
4273 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_idle_start, uv);
4274
4275 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_IDLE_CB);
4276
4277 r = uv_idle_start(&uv->uv.idle, (uv_idle_cb) php_uv_idle_cb);
4278
4279 RETURN_LONG(r);
4280 }
4281 /* }}} */
4282
4283
4284 /* {{{ proto void uv_idle_stop(UVIdle $idle)
4285 */
4286 PHP_FUNCTION(uv_idle_stop)
4287 {
4288 php_uv_t *uv;
4289 int r = 0;
4290
4291 ZEND_PARSE_PARAMETERS_START(1, 1)
4292 UV_PARAM_OBJ(uv, php_uv_t, uv_idle_ce)
4293 ZEND_PARSE_PARAMETERS_END();
4294
4295 if (!uv_is_active(&uv->uv.handle)) {
4296 php_error_docref(NULL, E_NOTICE, "passed uv_idle resource does not start yet.");
4297 RETURN_FALSE;
4298 }
4299
4300 r = uv_idle_stop(&uv->uv.idle);
4301
4302 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_idle_stop, uv);
4303 OBJ_RELEASE(&uv->std);
4304
4305 RETURN_LONG(r);
4306 }
4307 /* }}} */
4308
4309
4310 /* {{{ proto void uv_getaddrinfo(UVLoop $loop, callable(array|long $addresses_or_error) $callback, string $node, string $service[, array $hints = []])
4311 */
4312 PHP_FUNCTION(uv_getaddrinfo)
4313 {
4314 zval *hints = NULL;
4315 php_uv_loop_t *loop;
4316 php_uv_t *uv = NULL;
4317 struct addrinfo hint = {0};
4318 zend_string *node, *service;
4319 zend_fcall_info fci = empty_fcall_info;
4320 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4321 php_uv_cb_t *cb;
4322
4323 ZEND_PARSE_PARAMETERS_START(4, 5)
4324 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
4325 Z_PARAM_FUNC(fci, fcc)
4326 Z_PARAM_STR(node)
4327 Z_PARAM_STR(service)
4328 Z_PARAM_OPTIONAL
4329 Z_PARAM_ARRAY(hints)
4330 ZEND_PARSE_PARAMETERS_END();
4331
4332 if (hints != NULL) {
4333 HashTable *h;
4334 zval *data;
4335
4336 h = Z_ARRVAL_P(hints);
4337 if ((data = zend_hash_str_find(h, ZEND_STRL("ai_family")))) {
4338 hint.ai_family = Z_LVAL_P(data);
4339 }
4340 if ((data = zend_hash_str_find(h, ZEND_STRL("ai_socktype")))) {
4341 hint.ai_socktype = Z_LVAL_P(data);
4342 }
4343 if ((data = zend_hash_str_find(h, ZEND_STRL("ai_protocol")))) {
4344 hint.ai_socktype = Z_LVAL_P(data);
4345 }
4346 if ((data = zend_hash_str_find(h, ZEND_STRL("ai_flags")))) {
4347 hint.ai_flags = Z_LVAL_P(data);
4348 }
4349 }
4350
4351 PHP_UV_INIT_UV(uv, uv_addrinfo_ce);
4352
4353 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_GETADDR_CB);
4354 uv_getaddrinfo(&loop->loop, &uv->uv.addrinfo, php_uv_getaddrinfo_cb, node->val, service->val, &hint);
4355 }
4356 /* }}} */
4357
4358 /* {{{ proto UVTcp uv_tcp_init([UVLoop $loop])
4359 */
4360 PHP_FUNCTION(uv_tcp_init)
4361 {
4362 php_uv_loop_t *loop = NULL;
4363 php_uv_t *uv;
4364
4365 ZEND_PARSE_PARAMETERS_START(0, 1)
4366 Z_PARAM_OPTIONAL
4367 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
4368 ZEND_PARSE_PARAMETERS_END();
4369
4370 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4371 PHP_UV_INIT_UV_EX(uv, uv_tcp_ce, uv_tcp_init);
4372
4373 RETURN_OBJ(&uv->std);
4374 }
4375 /* }}} */
4376
4377 /* {{{ proto int|false uv_tcp_open(UVTcp $handle, long|resource $tcpfd)
4378 */
4379 PHP_FUNCTION(uv_tcp_open)
4380 {
4381 php_uv_handle_open((int (*)(uv_handle_t *, long)) uv_tcp_open, uv_tcp_ce, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4382 }
4383 /* }}} */
4384
4385 /* {{{ proto UVLoop uv_default_loop()
4386 */
4387 PHP_FUNCTION(uv_default_loop)
4388 {
4389 php_uv_loop_t *loop = php_uv_default_loop();
4390 GC_ADDREF(&loop->std);
4391 RETURN_OBJ(&loop->std);
4392 }
4393 /* }}} */
4394
4395 /* {{{ proto UVLoop uv_loop_new()
4396 */
4397 PHP_FUNCTION(uv_loop_new)
4398 {
4399 object_init_ex(return_value, uv_loop_ce);
4400 }
4401 /* }}} */
4402
4403
4404 /* {{{ proto UVUdp uv_udp_init([UVLoop $loop])
4405 */
4406 PHP_FUNCTION(uv_udp_init)
4407 {
4408 php_uv_loop_t *loop = NULL;
4409 php_uv_t *uv;
4410
4411 ZEND_PARSE_PARAMETERS_START(0, 1)
4412 Z_PARAM_OPTIONAL
4413 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
4414 ZEND_PARSE_PARAMETERS_END();
4415
4416 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4417 PHP_UV_INIT_UV_EX(uv, uv_udp_ce, uv_udp_init);
4418
4419 RETURN_OBJ(&uv->std);
4420 }
4421 /* }}} */
4422
4423 /* {{{ proto int|false uv_udp_open(UVUdp $handle, long|resource $udpfd)
4424 */
4425 PHP_FUNCTION(uv_udp_open)
4426 {
4427 php_uv_handle_open((int (*)(uv_handle_t *, long)) uv_udp_open, uv_udp_ce, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4428 }
4429 /* }}} */
4430
4431 /* {{{ proto void uv_udp_bind(UVUdp $resource, UVSockAddr $address[, long $flags = 0])
4432 */
4433 PHP_FUNCTION(uv_udp_bind)
4434 {
4435 php_uv_socket_bind(PHP_UV_UDP_IPV4, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4436 }
4437 /* }}} */
4438
4439 /* {{{ proto void uv_udp_bind6(UVUdp $resource, UVSockAddr $address[, long $flags = 0])
4440 */
4441 PHP_FUNCTION(uv_udp_bind6)
4442 {
4443 php_uv_socket_bind(PHP_UV_UDP_IPV6, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4444 }
4445 /* }}} */
4446
4447 /* {{{ proto void uv_udp_recv_start(UVUdp $handle, callable(UVUdp $handle, string|long $read, long $flags) $callback)
4448 */
4449 PHP_FUNCTION(uv_udp_recv_start)
4450 {
4451 php_uv_t *uv;
4452 zend_fcall_info fci = empty_fcall_info;
4453 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4454 php_uv_cb_t *cb;
4455 int r;
4456
4457 ZEND_PARSE_PARAMETERS_START(2, 2)
4458 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4459 Z_PARAM_FUNC(fci, fcc)
4460 ZEND_PARSE_PARAMETERS_END();
4461
4462 if (uv_is_active(&uv->uv.handle)) {
4463 php_error_docref(NULL, E_WARNING, "passed uv_resource has already activated.");
4464 RETURN_FALSE;
4465 }
4466
4467 GC_ADDREF(&uv->std);
4468 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_udp_recv_start, uv);
4469
4470 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_RECV_CB);
4471 r = uv_udp_recv_start(&uv->uv.udp, php_uv_read_alloc, php_uv_udp_recv_cb);
4472 if (r) {
4473 php_error_docref(NULL, E_NOTICE, "read failed");
4474 OBJ_RELEASE(&uv->std);
4475 }
4476 }
4477 /* }}} */
4478
4479 /* {{{ proto void uv_udp_recv_stop(UVUdp $handle)
4480 */
4481 PHP_FUNCTION(uv_udp_recv_stop)
4482 {
4483 php_uv_t *uv;
4484
4485 ZEND_PARSE_PARAMETERS_START(1, 1)
4486 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4487 ZEND_PARSE_PARAMETERS_END();
4488
4489 if (!uv_is_active(&uv->uv.handle)) {
4490 php_error_docref(NULL, E_NOTICE, "passed uv_resource has already stopped.");
4491 RETURN_FALSE;
4492 }
4493
4494 uv_udp_recv_stop(&uv->uv.udp);
4495
4496 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_udp_recv_stop, uv);
4497 OBJ_RELEASE(&uv->std);
4498 }
4499 /* }}} */
4500
4501 /* {{{ proto long uv_udp_set_membership(UVUdp $handle, string $multicast_addr, string $interface_addr, long $membership)
4502 */
4503 PHP_FUNCTION(uv_udp_set_membership)
4504 {
4505 php_uv_t *uv;
4506 zend_string *multicast_addr, *interface_addr;
4507 int error;
4508 zend_long membership;
4509
4510 ZEND_PARSE_PARAMETERS_START(4, 4)
4511 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4512 Z_PARAM_STR(multicast_addr)
4513 Z_PARAM_STR(interface_addr)
4514 Z_PARAM_LONG(membership)
4515 ZEND_PARSE_PARAMETERS_END();
4516
4517 error = uv_udp_set_membership(&uv->uv.udp, (const char *) multicast_addr->val, (const char *) interface_addr->val, membership);
4518
4519 RETURN_LONG(error);
4520 }
4521 /* }}} */
4522
4523
4524 /* {{{ proto void uv_udp_set_multicast_loop(UVUdp $handle, bool $enabled)
4525 */
4526 PHP_FUNCTION(uv_udp_set_multicast_loop)
4527 {
4528 php_uv_t *uv;
4529 zend_bool enabled = 0;
4530 int r;
4531
4532 ZEND_PARSE_PARAMETERS_START(2, 2)
4533 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4534 Z_PARAM_BOOL(enabled)
4535 ZEND_PARSE_PARAMETERS_END();
4536
4537 r = uv_udp_set_multicast_loop((uv_udp_t*)&uv->uv.udp, enabled);
4538 if (r) {
4539 php_error_docref(NULL, E_NOTICE, "uv_udp_set_muticast_loop failed");
4540 }
4541 }
4542 /* }}} */
4543
4544 /* {{{ proto void uv_udp_set_multicast_ttl(UVUdp $handle, long $ttl)
4545 */
4546 PHP_FUNCTION(uv_udp_set_multicast_ttl)
4547 {
4548 php_uv_t *uv;
4549 zend_long ttl = 0; /* 1 through 255 */
4550 int r;
4551
4552 ZEND_PARSE_PARAMETERS_START(2, 2)
4553 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4554 Z_PARAM_LONG(ttl)
4555 ZEND_PARSE_PARAMETERS_END();
4556
4557 if (ttl > 255) {
4558 php_error_docref(NULL, E_NOTICE, "uv_udp_set_muticast_ttl: ttl parameter expected smaller than 255.");
4559 ttl = 255;
4560 } else if (ttl < 1) {
4561 php_error_docref(NULL, E_NOTICE, "uv_udp_set_muticast_ttl: ttl parameter expected larger than 0.");
4562 ttl = 1;
4563 }
4564
4565 r = uv_udp_set_multicast_ttl(&uv->uv.udp, ttl);
4566 if (r) {
4567 php_error_docref(NULL, E_NOTICE, "uv_udp_set_muticast_ttl failed");
4568 }
4569 }
4570 /* }}} */
4571
4572 /* {{{ proto void uv_udp_set_broadcast(UVUdp $handle, bool $enabled)
4573 */
4574 PHP_FUNCTION(uv_udp_set_broadcast)
4575 {
4576 php_uv_t *uv;
4577 zend_bool enabled = 0;
4578 int r;
4579
4580 ZEND_PARSE_PARAMETERS_START(2, 2)
4581 UV_PARAM_OBJ(uv, php_uv_t, uv_udp_ce)
4582 Z_PARAM_BOOL(enabled)
4583 ZEND_PARSE_PARAMETERS_END();
4584
4585 r = uv_udp_set_broadcast(&uv->uv.udp, enabled);
4586 if (r) {
4587 php_error_docref(NULL, E_NOTICE, "uv_udp_set_muticast_loop failed");
4588 }
4589 }
4590 /* }}} */
4591
4592 /* {{{ proto void uv_udp_send(UVUdp $handle, string $data, UVSockAddr $uv_addr, callable(UVUdp $handle, long $status) $callback)
4593 */
4594 PHP_FUNCTION(uv_udp_send)
4595 {
4596 php_uv_udp_send(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4597 }
4598 /* }}} */
4599
4600 /* {{{ proto void uv_udp_send6(resource $handle, string $data, UVSockAddrIPv6 $uv_addr6, callable(UVUdp $handle, long $status) $callback)
4601 */
4602 PHP_FUNCTION(uv_udp_send6)
4603 {
4604 php_error_docref(NULL, E_DEPRECATED, "uv_udp_send6: Use uv_udp_send() instead");
4605 php_uv_udp_send(2, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4606 }
4607 /* }}} */
4608
4609 /* {{{ proto bool uv_is_active(UV $handle)
4610 */
4611 PHP_FUNCTION(uv_is_active)
4612 {
4613 zval *zv;
4614 php_uv_t *uv;
4615
4616 ZEND_PARSE_PARAMETERS_START(1, 1)
4617 Z_PARAM_OBJECT_OF_CLASS(zv, uv_ce)
4618 ZEND_PARSE_PARAMETERS_END();
4619
4620 uv = (php_uv_t *) Z_OBJ_P(zv);
4621
4622 RETURN_BOOL(!PHP_UV_IS_DTORED(uv) && uv_is_active(&uv->uv.handle));
4623 }
4624 /* }}} */
4625
4626 /* {{{ proto bool uv_is_closing(UV $handle)
4627 */
4628 PHP_FUNCTION(uv_is_closing)
4629 {
4630 zval *zv;
4631 php_uv_t *uv;
4632
4633 ZEND_PARSE_PARAMETERS_START(1, 1)
4634 Z_PARAM_OBJECT_OF_CLASS(zv, uv_ce)
4635 ZEND_PARSE_PARAMETERS_END();
4636
4637 uv = (php_uv_t *) Z_OBJ_P(zv);
4638
4639 RETURN_BOOL(PHP_UV_IS_DTORED(uv));
4640 }
4641 /* }}} */
4642
4643 /* {{{ proto bool uv_is_readable(UVStream $handle)
4644 */
4645 PHP_FUNCTION(uv_is_readable)
4646 {
4647 php_uv_t *uv;
4648
4649 ZEND_PARSE_PARAMETERS_START(1, 1)
4650 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
4651 ZEND_PARSE_PARAMETERS_END();
4652
4653 RETURN_BOOL(uv_is_readable(&uv->uv.stream));
4654 }
4655 /* }}} */
4656
4657 /* {{{ proto bool uv_is_writable(UVStream $handle)
4658 */
4659 PHP_FUNCTION(uv_is_writable)
4660 {
4661 php_uv_t *uv;
4662
4663 ZEND_PARSE_PARAMETERS_START(1, 1)
4664 UV_PARAM_OBJ(uv, php_uv_t, uv_stream_ce)
4665 ZEND_PARSE_PARAMETERS_END();
4666
4667 RETURN_BOOL(uv_is_writable(&uv->uv.stream));
4668 }
4669 /* }}} */
4670
4671
4672 /* {{{ proto bool uv_walk(UVLoop $loop, callable $closure[, array $opaque])
4673 */
4674 PHP_FUNCTION(uv_walk)
4675 {
4676 zval *opaque = NULL;
4677 php_uv_loop_t *loop;
4678 zend_fcall_info fci = empty_fcall_info;
4679 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4680 //php_uv_cb_t *cb;
4681
4682 ZEND_PARSE_PARAMETERS_START(2, 3)
4683 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
4684 Z_PARAM_FUNC(fci, fcc)
4685 Z_PARAM_OPTIONAL
4686 Z_PARAM_ARRAY(opaque)
4687 ZEND_PARSE_PARAMETERS_END();
4688
4689 php_error_docref(NULL, E_ERROR, "uv_walk not yet supported");
4690
4691 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4692 uv_walk(&loop->loop, php_uv_walk_cb, NULL);
4693 }
4694 /* }}} */
4695
4696 /* {{{ proto long uv_guess_handle(resource $uv)
4697 */
4698 PHP_FUNCTION(uv_guess_handle)
4699 {
4700 zval *handle;
4701 long fd = -1;
4702 uv_handle_type type;
4703
4704 if (zend_parse_parameters(ZEND_NUM_ARGS(),
4705 "r", &handle) == FAILURE) {
4706 return;
4707 }
4708
4709 fd = php_uv_zval_to_fd(handle);
4710 if (fd < 0) {
4711 php_error_docref(NULL, E_WARNING, "invalid variable passed. can't convert to fd.");
4712 return;
4713 }
4714 type = uv_guess_handle(fd);
4715
4716 RETURN_LONG(type);
4717 }
4718 /* }}} */
4719
4720
4721 /* {{{ proto UVPipe uv_pipe_init([UVLoop $loop = uv_default_loop(), bool $ipc = false])
4722 */
4723 PHP_FUNCTION(uv_pipe_init)
4724 {
4725 php_uv_t *uv;
4726 php_uv_loop_t *loop = NULL;
4727 zend_bool ipc = 0;
4728
4729 ZEND_PARSE_PARAMETERS_START(0, 2)
4730 Z_PARAM_OPTIONAL
4731 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
4732 Z_PARAM_BOOL(ipc)
4733 ZEND_PARSE_PARAMETERS_END();
4734
4735 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
4736
4737 PHP_UV_INIT_UV_EX(uv, uv_pipe_ce, uv_pipe_init, (int) ipc);
4738
4739 RETURN_OBJ(&uv->std);
4740 }
4741 /* }}} */
4742
4743 /* {{{ proto long|false uv_pipe_open(UVPipe $handle, resource|long $pipe)
4744 */
4745 PHP_FUNCTION(uv_pipe_open)
4746 {
4747 php_uv_handle_open((int (*)(uv_handle_t *, long)) uv_pipe_open, uv_pipe_ce, INTERNAL_FUNCTION_PARAM_PASSTHRU);
4748 }
4749 /* }}} */
4750
4751 /* {{{ proto long uv_pipe_bind(UVPipe $handle, string $name)
4752 */
4753 PHP_FUNCTION(uv_pipe_bind)
4754 {
4755 php_uv_t *uv;
4756 zend_string *name;
4757 int error;
4758
4759 ZEND_PARSE_PARAMETERS_START(2, 2)
4760 UV_PARAM_OBJ(uv, php_uv_t, uv_pipe_ce)
4761 Z_PARAM_STR(name)
4762 ZEND_PARSE_PARAMETERS_END();
4763
4764 error = uv_pipe_bind(&uv->uv.pipe, name->val);
4765 if (error) {
4766 php_error_docref(NULL, E_WARNING, "%s", php_uv_strerror(error));
4767 }
4768
4769 RETURN_LONG(error);
4770 }
4771 /* }}} */
4772
4773 /* {{{ proto void uv_pipe_connect(UVPipe $handle, string $path, callable(UVPipe $handle, long $status) $callback)
4774 */
4775 PHP_FUNCTION(uv_pipe_connect)
4776 {
4777 php_uv_t *uv;
4778 zend_string *name;
4779 uv_connect_t *req;
4780 zend_fcall_info fci = empty_fcall_info;
4781 zend_fcall_info_cache fcc = empty_fcall_info_cache;
4782 php_uv_cb_t *cb;
4783
4784 ZEND_PARSE_PARAMETERS_START(3, 3)
4785 UV_PARAM_OBJ(uv, php_uv_t, uv_pipe_ce)
4786 Z_PARAM_STR(name)
4787 Z_PARAM_FUNC(fci, fcc)
4788 ZEND_PARSE_PARAMETERS_END();
4789
4790 GC_ADDREF(&uv->std);
4791 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_pipe_connect, uv);
4792
4793 req = (uv_connect_t *) emalloc(sizeof(uv_connect_t));
4794 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_PIPE_CONNECT_CB);
4795
4796 req->data = uv;
4797 uv_pipe_connect(req, &uv->uv.pipe, name->val, php_uv_pipe_connect_cb);
4798 }
4799 /* }}} */
4800
4801 /* {{{ proto void uv_pipe_pending_instances(UVPipe $handle, long $count)
4802 */
4803 PHP_FUNCTION(uv_pipe_pending_instances)
4804 {
4805 php_uv_t *uv;
4806 zend_long count;
4807
4808 ZEND_PARSE_PARAMETERS_START(2, 2)
4809 UV_PARAM_OBJ(uv, php_uv_t, uv_pipe_ce)
4810 Z_PARAM_LONG(count)
4811 ZEND_PARSE_PARAMETERS_END();
4812
4813 uv_pipe_pending_instances(&uv->uv.pipe, count);
4814 }
4815 /* }}} */
4816
4817 /* {{{ proto void uv_pipe_pending_count(UVPipe $handle)
4818 */
4819 PHP_FUNCTION(uv_pipe_pending_count)
4820 {
4821 php_uv_t *uv;
4822
4823 ZEND_PARSE_PARAMETERS_START(1, 1)
4824 UV_PARAM_OBJ(uv, php_uv_t, uv_pipe_ce)
4825 ZEND_PARSE_PARAMETERS_END();
4826
4827 RETURN_LONG(uv_pipe_pending_count(&uv->uv.pipe));
4828 }
4829 /* }}} */
4830
4831 /* {{{ proto void uv_pipe_pending_type(UVPipe $handle)
4832 */
4833 PHP_FUNCTION(uv_pipe_pending_type)
4834 {
4835 php_uv_t *uv;
4836 uv_handle_type ret;
4837
4838 ZEND_PARSE_PARAMETERS_START(1, 1)
4839 UV_PARAM_OBJ(uv, php_uv_t, uv_pipe_ce)
4840 ZEND_PARSE_PARAMETERS_END();
4841
4842 ret = uv_pipe_pending_type(&uv->uv.pipe);
4843 RETURN_LONG(ret);
4844 }
4845 /* }}} */
4846
4847 /* {{{ proto UVStdio uv_stdio_new([UV|resource|long|null $fd[, long $flags = 0]])
4848 */
4849 PHP_FUNCTION(uv_stdio_new)
4850 {
4851 php_uv_stdio_t *stdio;
4852 zval *handle;
4853 zend_long flags = 0;
4854 #if !defined(PHP_WIN32) || defined(HAVE_SOCKET)
4855 php_socket *socket;
4856 #endif
4857 php_socket_t fd = -1;
4858 php_stream *stream;
4859
4860 if (zend_parse_parameters(ZEND_NUM_ARGS(),
4861 "|zl", &handle, &flags) == FAILURE) {
4862 return;
4863 }
4864
4865 if (handle == NULL || Z_TYPE_P(handle) == IS_NULL) {
4866 flags = UV_IGNORE;
4867 } else if (Z_TYPE_P(handle) == IS_LONG) {
4868 fd = Z_LVAL_P(handle);
4869 if (flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) {
4870 php_error_docref(NULL, E_WARNING, "flags must not be UV::CREATE_PIPE or UV::INHERIT_STREAM for resources");
4871 RETURN_FALSE;
4872 }
4873 flags |= UV_INHERIT_FD;
4874 } else if (Z_TYPE_P(handle) == IS_RESOURCE) {
4875 if ((stream = (php_stream *) zend_fetch_resource_ex(handle, NULL, php_file_le_stream()))) {
4876 if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void *) &fd, 1) != SUCCESS || fd < 0) {
4877 php_error_docref(NULL, E_WARNING, "passed resource without file descriptor");
4878 RETURN_FALSE;
4879 }
4880 #if PHP_VERSION_ID < 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKET) && !defined(COMPILE_DL_SOCKETS)))
4881 } else if ((socket = (php_socket *) zend_fetch_resource_ex(handle, NULL, php_sockets_le_socket()))) {
4882 fd = socket->bsd_socket;
4883 #endif
4884 } else {
4885 php_error_docref(NULL, E_WARNING, "passed unexpected resource, expected file or socket");
4886 RETURN_FALSE;
4887 }
4888 if (flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) {
4889 php_error_docref(NULL, E_WARNING, "flags must not be UV::CREATE_PIPE or UV::INHERIT_STREAM for resources");
4890 RETURN_FALSE;
4891 }
4892 flags |= UV_INHERIT_FD;
4893 } else if (Z_TYPE_P(handle) == IS_OBJECT && instanceof_function(Z_OBJCE_P(handle), uv_ce)) {
4894 if (flags & UV_INHERIT_FD) {
4895 php_error_docref(NULL, E_WARNING, "flags must not be UV::INHERIT_FD for UV handles");
4896 RETURN_FALSE;
4897 }
4898 if ((flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) == (UV_CREATE_PIPE | UV_INHERIT_STREAM) || !(flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM))) {
4899 php_error_docref(NULL, E_WARNING, "flags must be exactly one of UV::INHERIT_STREAM or UV::CREATE_PIPE for UV handles");
4900 RETURN_FALSE;
4901 }
4902 #if PHP_VERSION_ID >= 80000 && (!defined(PHP_WIN32) || (defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS)))
4903 } else if (socket_ce && Z_TYPE_P(handle) == IS_OBJECT && Z_OBJCE_P(handle) == socket_ce && (socket = (php_socket *) ((char *)(Z_OBJ_P(handle)) - XtOffsetOf(php_socket, std)))) {
4904 fd = socket->bsd_socket;
4905 if (flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) {
4906 php_error_docref(NULL, E_WARNING, "flags must not be UV::CREATE_PIPE or UV::INHERIT_STREAM for socket objects");
4907 RETURN_FALSE;
4908 }
4909 flags |= UV_INHERIT_FD;
4910 #endif
4911 } else {
4912 php_error_docref(NULL, E_WARNING, "passed unexpected value, expected instance of UV, file resource or socket object");
4913 RETURN_FALSE;
4914 }
4915
4916 PHP_UV_INIT_GENERIC(stdio, php_uv_stdio_t, uv_stdio_ce);
4917 stdio->flags = flags;
4918 stdio->fd = fd;
4919
4920 if (Z_TYPE_P(handle) == IS_RESOURCE || Z_TYPE_P(handle) == IS_OBJECT) {
4921 ZVAL_COPY(&stdio->stream, handle);
4922 }
4923
4924 RETURN_OBJ(&stdio->std);
4925 }
4926 /* }}} */
4927
4928
4929 /* {{{ proto array uv_loadavg(void)
4930 */
4931 PHP_FUNCTION(uv_loadavg)
4932 {
4933 double average[3];
4934
4935 if (zend_parse_parameters_none() == FAILURE) {
4936 return;
4937 }
4938
4939 uv_loadavg(average);
4940
4941 array_init(return_value);
4942 add_next_index_double(return_value, average[0]);
4943 add_next_index_double(return_value, average[1]);
4944 add_next_index_double(return_value, average[2]);
4945 }
4946 /* }}} */
4947
4948 /* {{{ proto double uv_uptime(void)
4949 */
4950 PHP_FUNCTION(uv_uptime)
4951 {
4952 double uptime;
4953
4954 if (zend_parse_parameters_none() == FAILURE) {
4955 return;
4956 }
4957
4958 uv_uptime(&uptime);
4959
4960 RETURN_DOUBLE(uptime);
4961 }
4962 /* }}} */
4963
4964 /* {{{ proto long uv_get_free_memory(void)
4965 */
4966 PHP_FUNCTION(uv_get_free_memory)
4967 {
4968 if (zend_parse_parameters_none() == FAILURE) {
4969 return;
4970 }
4971
4972 RETURN_LONG(uv_get_free_memory());
4973 }
4974 /* }}} */
4975
4976 /* {{{ proto long uv_get_total_memory(void)
4977 */
4978 PHP_FUNCTION(uv_get_total_memory)
4979 {
4980 if (zend_parse_parameters_none() == FAILURE) {
4981 return;
4982 }
4983
4984 RETURN_LONG(uv_get_total_memory());
4985 }
4986 /* }}} */
4987
4988 /* {{{ proto long uv_hrtime(void)
4989 */
4990 PHP_FUNCTION(uv_hrtime)
4991 {
4992 if (zend_parse_parameters_none() == FAILURE) {
4993 return;
4994 }
4995
4996 RETURN_LONG(uv_hrtime());
4997 }
4998 /* }}} */
4999
5000 /* {{{ proto string uv_exepath(void)
5001 */
5002 PHP_FUNCTION(uv_exepath)
5003 {
5004 char buffer[MAXPATHLEN];
5005 size_t buffer_sz = sizeof(buffer) / sizeof(buffer[0]);
5006
5007 if (zend_parse_parameters_none() == FAILURE) {
5008 return;
5009 }
5010
5011 if (uv_exepath(buffer, &buffer_sz) == UV_EINVAL) {
5012 RETURN_FALSE; /* should be unreeachable */
5013 }
5014
5015 RETURN_STRINGL(buffer, buffer_sz);
5016 }
5017 /* }}} */
5018
5019 /* {{{ proto string uv_cwd(void)
5020 */
5021 PHP_FUNCTION(uv_cwd)
5022 {
5023 char buffer[MAXPATHLEN];
5024 size_t buffer_sz = sizeof(buffer) / sizeof(buffer[0]);
5025
5026 if (zend_parse_parameters_none() == FAILURE) {
5027 return;
5028 }
5029
5030 uv_cwd(buffer, &buffer_sz);
5031
5032 RETURN_STRING(buffer);
5033 }
5034 /* }}} */
5035
5036 /* {{{ proto array uv_cpu_info(void)
5037 */
5038 PHP_FUNCTION(uv_cpu_info)
5039 {
5040 uv_cpu_info_t *cpus;
5041 int error;
5042 int i, count;
5043
5044 if (zend_parse_parameters_none() == FAILURE) {
5045 return;
5046 }
5047
5048 error = uv_cpu_info(&cpus, &count);
5049 if (0 == error) {
5050 array_init(return_value);
5051
5052 for (i = 0; i < count; i++) {
5053 zval tmp, times;
5054
5055 array_init(&tmp);
5056 array_init(×);
5057
5058 add_assoc_string_ex(&tmp, ZEND_STRL("model"), cpus[i].model);
5059 add_assoc_long_ex(&tmp, ZEND_STRL("speed"), cpus[i].speed);
5060
5061 add_assoc_long_ex(×, ZEND_STRL("sys"), (size_t)cpus[i].cpu_times.sys);
5062 add_assoc_long_ex(×, ZEND_STRL("user"), (size_t)cpus[i].cpu_times.user);
5063 add_assoc_long_ex(×, ZEND_STRL("idle"), (size_t)cpus[i].cpu_times.idle);
5064 add_assoc_long_ex(×, ZEND_STRL("irq"), (size_t)cpus[i].cpu_times.irq);
5065 add_assoc_long_ex(×, ZEND_STRL("nice"), (size_t)cpus[i].cpu_times.nice);
5066 add_assoc_zval_ex(&tmp, ZEND_STRL("times"), ×);
5067
5068 add_next_index_zval(return_value, &tmp);
5069 }
5070
5071 uv_free_cpu_info(cpus, count);
5072 }
5073 }
5074 /* }}} */
5075
5076
5077 /* {{{ proto array uv_interface_addresses(void)
5078 */
5079 PHP_FUNCTION(uv_interface_addresses)
5080 {
5081 uv_interface_address_t *interfaces;
5082 int error;
5083 char buffer[512];
5084 int i, count;
5085
5086 if (zend_parse_parameters_none() == FAILURE) {
5087 return;
5088 }
5089
5090 error = uv_interface_addresses(&interfaces, &count);
5091 if (0 == error) {
5092 array_init(return_value);
5093
5094 for (i = 0; i < count; i++) {
5095 zval tmp;
5096
5097 array_init(&tmp);
5098
5099 add_assoc_string_ex(&tmp, ZEND_STRL("name"), interfaces[i].name);
5100 add_assoc_bool_ex(&tmp, ZEND_STRL("is_internal"), interfaces[i].is_internal);
5101
5102 if (interfaces[i].address.address4.sin_family == AF_INET) {
5103 uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer));
5104 } else if (interfaces[i].address.address4.sin_family == AF_INET6) {
5105 uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer));
5106 }
5107 add_assoc_string_ex(&tmp, ZEND_STRL("address"), buffer);
5108
5109 add_next_index_zval(return_value, &tmp);
5110 }
5111 uv_free_interface_addresses(interfaces, count);
5112 }
5113 }
5114 /* }}} */
5115
5116 /* {{{ proto UVProcess|long uv_spawn(UVLoop $loop, string $command, array $args, array $stdio, string $cwd, array $env, callable(UVProcess $process, long $exit_status, long $term_signal) $callback[, long $flags = 0, array $options = []])
5117 */
5118 PHP_FUNCTION(uv_spawn)
5119 {
5120 php_uv_loop_t *loop;
5121 uv_process_options_t options = {0};
5122 uv_stdio_container_t *stdio = NULL;
5123 php_uv_t *proc;
5124 zval *args, *env, *zoptions = NULL, *zstdio = NULL, *value;
5125 char **command_args, **zenv;
5126 zend_string *command, *cwd;
5127 int uid = 0, gid = 0, stdio_count = 0, ret;
5128 zend_long flags = 0;
5129 zend_fcall_info fci = empty_fcall_info;
5130 zend_fcall_info_cache fcc = empty_fcall_info_cache;
5131 php_uv_cb_t *cb;
5132
5133 ZEND_PARSE_PARAMETERS_START(7, 9)
5134 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
5135 Z_PARAM_STR(command)
5136 Z_PARAM_ARRAY(args)
5137 Z_PARAM_ARRAY(zstdio)
5138 Z_PARAM_STR(cwd)
5139 Z_PARAM_ARRAY(env)
5140 Z_PARAM_FUNC(fci, fcc)
5141 Z_PARAM_OPTIONAL
5142 Z_PARAM_LONG(flags)
5143 Z_PARAM_ARRAY(zoptions)
5144 ZEND_PARSE_PARAMETERS_END();
5145
5146 memset(&options, 0, sizeof(uv_process_options_t));
5147
5148 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5149
5150 {/* process stdio */
5151 HashTable *stdio_container;
5152 int x = 0;
5153
5154 stdio_container = Z_ARRVAL_P(zstdio);
5155 stdio_count = zend_hash_num_elements(stdio_container);
5156
5157 stdio = emalloc(sizeof(uv_stdio_container_t) * stdio_count);
5158
5159 ZEND_HASH_FOREACH_VAL(stdio_container, value) {
5160 php_uv_stdio_t *stdio_tmp;
5161
5162 if (Z_TYPE_P(value) != IS_OBJECT || Z_OBJCE_P(value) != uv_stdio_ce) {
5163 php_error_docref(NULL, E_ERROR, "must be instance of UVStdio");
5164 }
5165
5166 stdio_tmp = (php_uv_stdio_t *) Z_OBJ_P(value);
5167
5168 stdio[x].flags = stdio_tmp->flags;
5169
5170 if (stdio_tmp->flags & UV_INHERIT_FD) {
5171 stdio[x].data.fd = stdio_tmp->fd;
5172 } else if (stdio_tmp->flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) {
5173 php_uv_t *uv_pipe = (php_uv_t *) Z_OBJ(stdio_tmp->stream);
5174 stdio[x].data.stream = &uv_pipe->uv.stream;
5175 } else {
5176 php_error_docref(NULL, E_WARNING, "passes unexpected stdio flags");
5177 RETURN_FALSE;
5178 }
5179
5180 x++;
5181 } ZEND_HASH_FOREACH_END();
5182 }
5183
5184 {
5185 HashTable *h;
5186 zval *value;
5187 int n = 0;
5188 int hash_len = 0;
5189
5190 h = Z_ARRVAL_P(args);
5191
5192 hash_len = zend_hash_num_elements(h);
5193
5194 command_args = ecalloc(hash_len+2, sizeof(char**));
5195 command_args[n] = command->val;
5196
5197 n++;
5198 ZEND_HASH_FOREACH_VAL(h, value) {
5199 command_args[n] = Z_STRVAL_P(value);
5200 n++;
5201 } ZEND_HASH_FOREACH_END();
5202
5203 command_args[n] = NULL;
5204 }
5205
5206 { /* env */
5207 HashTable *tmp_env;
5208 zend_string *key;
5209 int i = 0;
5210 zval *value;
5211
5212 tmp_env = Z_ARRVAL_P(env);
5213
5214 zenv = ecalloc(zend_hash_num_elements(tmp_env)+1, sizeof(char*));
5215 ZEND_HASH_FOREACH_STR_KEY_VAL(tmp_env, key, value) {
5216 char *tmp_env_entry;
5217
5218 tmp_env_entry = emalloc(sizeof(char) * (key->len + 2 + Z_STRLEN_P(value)));
5219 slprintf(tmp_env_entry, key->len + 2 + Z_STRLEN_P(value), "%s=%s", key->val, Z_STRVAL_P(value));
5220
5221 zenv[i++] = tmp_env_entry;
5222 } ZEND_HASH_FOREACH_END();
5223 zenv[i] = NULL;
5224 }
5225
5226 if (zoptions != NULL && Z_TYPE_P(zoptions) != IS_NULL){
5227 HashTable *opts;
5228 zval *data;
5229
5230 opts = Z_ARRVAL_P(zoptions);
5231
5232 if ((data = zend_hash_str_find(opts, ZEND_STRL("uid")))) {
5233 uid = Z_LVAL_P(data);
5234 }
5235
5236 if ((data = zend_hash_str_find(opts, ZEND_STRL("gid")))) {
5237 gid = Z_LVAL_P(data);
5238 }
5239 }
5240
5241 options.file = command->val;
5242 options.stdio = stdio;
5243 options.exit_cb = php_uv_process_close_cb;
5244 options.env = zenv;
5245 options.args = command_args;
5246 options.cwd = cwd->val;
5247 options.stdio = stdio;
5248 options.stdio_count = stdio_count;
5249 options.flags = flags;
5250 options.uid = uid;
5251 options.gid = gid;
5252
5253 PHP_UV_INIT_UV(proc, uv_process_ce);
5254
5255 ret = uv_spawn(&loop->loop, &proc->uv.process, &options);
5256
5257 if (ret) {
5258 OBJ_RELEASE(&proc->std);
5259 RETVAL_LONG(ret);
5260 } else {
5261 php_uv_cb_init(&cb, proc, &fci, &fcc, PHP_UV_PROC_CLOSE_CB);
5262 GC_ADDREF(&proc->std);
5263 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_spawn, proc);
5264 RETVAL_OBJ(&proc->std);
5265 }
5266
5267 if (zenv != NULL) {
5268 char **p = zenv;
5269 while(*p != NULL) {
5270 efree(*p);
5271 p++;
5272 }
5273 efree(zenv);
5274 }
5275 if (command_args != NULL) {
5276 efree(command_args);
5277 }
5278
5279 if (stdio != NULL) {
5280 efree(stdio);
5281 }
5282 }
5283 /* }}} */
5284
5285
5286 /* {{{ proto void uv_process_kill(UVProcess $handle, long $signal)
5287 */
5288 PHP_FUNCTION(uv_process_kill)
5289 {
5290 php_uv_t *uv;
5291 zend_long signal;
5292
5293 ZEND_PARSE_PARAMETERS_START(2, 2)
5294 UV_PARAM_OBJ(uv, php_uv_t, uv_process_ce)
5295 Z_PARAM_LONG(signal)
5296 ZEND_PARSE_PARAMETERS_END();
5297
5298 uv_process_kill(&uv->uv.process, signal);
5299 }
5300 /* }}} */
5301
5302 /* {{{ proto void uv_process_get_pid(UVProcess $handle)
5303 */
5304 PHP_FUNCTION(uv_process_get_pid)
5305 {
5306 php_uv_t *uv;
5307
5308 ZEND_PARSE_PARAMETERS_START(1, 1)
5309 UV_PARAM_OBJ(uv, php_uv_t, uv_process_ce)
5310 ZEND_PARSE_PARAMETERS_END();
5311
5312 RETURN_LONG(uv_process_get_pid(&uv->uv.process));
5313 }
5314 /* }}} */
5315
5316 /* {{{ proto void uv_kill(long $pid, long $signal)
5317 */
5318 PHP_FUNCTION(uv_kill)
5319 {
5320 zend_long pid, signal;
5321
5322 if (zend_parse_parameters(ZEND_NUM_ARGS(),
5323 "ll", &pid, &signal) == FAILURE) {
5324 return;
5325 }
5326 uv_kill(pid, signal);
5327 }
5328 /* }}} */
5329
5330 /* {{{ proto bool uv_chdir(string $directory)
5331 */
5332 PHP_FUNCTION(uv_chdir)
5333 {
5334 int error;
5335 zend_string *directory;
5336
5337 if (zend_parse_parameters(ZEND_NUM_ARGS(),
5338 "S", &directory) == FAILURE) {
5339 return;
5340 }
5341 error = uv_chdir(directory->val);
5342 if (error == 0) {
5343 RETURN_TRUE;
5344 } else {
5345 RETURN_FALSE;
5346 }
5347 }
5348 /* }}} */
5349
5350
5351 /* {{{ proto UVLock uv_rwlock_init(void)
5352 */
5353 PHP_FUNCTION(uv_rwlock_init)
5354 {
5355 php_uv_lock_init(IS_UV_RWLOCK, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5356 }
5357 /* }}} */
5358
5359 /* {{{ proto null|false uv_rwlock_rdlock(UVLock $handle)
5360 */
5361 PHP_FUNCTION(uv_rwlock_rdlock)
5362 {
5363 php_uv_lock_lock(IS_UV_RWLOCK_RD, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5364 }
5365 /* }}} */
5366
5367 /* {{{ proto bool uv_rwlock_tryrdlock(UVLock $handle)
5368 */
5369 PHP_FUNCTION(uv_rwlock_tryrdlock)
5370 {
5371 php_uv_lock_trylock(IS_UV_RWLOCK_RD, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5372 }
5373 /* }}} */
5374
5375 /* {{{ proto void uv_rwlock_rdunlock(UVLock $handle)
5376 */
5377 PHP_FUNCTION(uv_rwlock_rdunlock)
5378 {
5379 php_uv_lock_unlock(IS_UV_RWLOCK_RD, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5380 }
5381 /* }}} */
5382
5383 /* {{{ proto null|false uv_rwlock_wrlock(UVLock $handle)
5384 */
5385 PHP_FUNCTION(uv_rwlock_wrlock)
5386 {
5387 php_uv_lock_lock(IS_UV_RWLOCK_WR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5388 }
5389 /* }}} */
5390
5391 /* {{{ proto bool uv_rwlock_trywrlock(UVLock $handle)
5392 */
5393 PHP_FUNCTION(uv_rwlock_trywrlock)
5394 {
5395 php_uv_lock_trylock(IS_UV_RWLOCK_WR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5396 }
5397 /* }}} */
5398
5399 /* {{{ proto void uv_rwlock_wrunlock(UVLock $handle)
5400 */
5401 PHP_FUNCTION(uv_rwlock_wrunlock)
5402 {
5403 php_uv_lock_unlock(IS_UV_RWLOCK_WR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5404 }
5405 /* }}} */
5406
5407 /* {{{ proto UVLock uv_mutex_init(void)
5408 */
5409 PHP_FUNCTION(uv_mutex_init)
5410 {
5411 php_uv_lock_init(IS_UV_MUTEX, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5412 }
5413 /* }}} */
5414
5415 /* {{{ proto void uv_mutex_lock(UVLock $lock)
5416 */
5417 PHP_FUNCTION(uv_mutex_lock)
5418 {
5419 php_uv_lock_lock(IS_UV_MUTEX, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5420 }
5421 /* }}} */
5422
5423 /* {{{ proto bool uv_mutex_trylock(UVLock $lock)
5424 */
5425 PHP_FUNCTION(uv_mutex_trylock)
5426 {
5427 php_uv_lock_trylock(IS_UV_MUTEX, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5428 }
5429 /* }}} */
5430
5431 /* {{{ void uv_mutex_unlock(UVLock $lock)
5432
5433 ##### *Description*
5434
5435 unlock mutex
5436
5437 ##### *Parameters*
5438
5439 *UVLock $lock*: uv resource handle (uv mutex)
5440
5441 ##### *Return Value*
5442
5443 *void *:
5444
5445 ##### *Example*
5446
5447 */
5448 PHP_FUNCTION(uv_mutex_unlock)
5449 {
5450 php_uv_lock_unlock(IS_UV_MUTEX, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5451 }
5452 /* }}} */
5453
5454 /* {{{ proto UVLock uv_sem_init(long $value)
5455 */
5456 PHP_FUNCTION(uv_sem_init)
5457 {
5458 php_uv_lock_init(IS_UV_SEMAPHORE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5459 }
5460 /* }}} */
5461
5462 /* {{{ proto void uv_sem_post(UVLock $sem)
5463 */
5464 PHP_FUNCTION(uv_sem_post)
5465 {
5466 php_uv_lock_lock(IS_UV_SEMAPHORE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5467 }
5468 /* }}} */
5469
5470 /* {{{ proto void uv_sem_wait(UVLock $sem)
5471 */
5472 PHP_FUNCTION(uv_sem_wait)
5473 {
5474 php_uv_lock_unlock(IS_UV_SEMAPHORE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5475 }
5476 /* }}} */
5477
5478 /* {{{ proto long uv_sem_trywait(UVLock $sem)
5479 */
5480 PHP_FUNCTION(uv_sem_trywait)
5481 {
5482 php_uv_lock_trylock(IS_UV_SEMAPHORE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5483 }
5484 /* }}} */
5485
5486 /* {{{ proto UVPrepare uv_prepare_init(UVLoop $loop)
5487 */
5488 PHP_FUNCTION(uv_prepare_init)
5489 {
5490 php_uv_loop_t *loop = NULL;
5491 php_uv_t *uv;
5492
5493 ZEND_PARSE_PARAMETERS_START(0, 1)
5494 Z_PARAM_OPTIONAL
5495 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
5496 ZEND_PARSE_PARAMETERS_END();
5497
5498 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5499 PHP_UV_INIT_UV_EX(uv, uv_prepare_ce, uv_prepare_init);
5500
5501 RETURN_OBJ(&uv->std);
5502 }
5503 /* }}} */
5504
5505 /* {{{ proto long uv_prepare_start(UVPrepare $handle, callable(UVPrepare $handle) $callback)
5506 */
5507 PHP_FUNCTION(uv_prepare_start)
5508 {
5509 php_uv_t *uv;
5510 int r;
5511 zend_fcall_info fci = empty_fcall_info;
5512 zend_fcall_info_cache fcc = empty_fcall_info_cache;
5513 php_uv_cb_t *cb;
5514
5515 PHP_UV_DEBUG_PRINT("uv_prepare_start\n");
5516
5517 ZEND_PARSE_PARAMETERS_START(2, 2)
5518 UV_PARAM_OBJ(uv, php_uv_t, uv_prepare_ce)
5519 Z_PARAM_FUNC(fci, fcc)
5520 ZEND_PARSE_PARAMETERS_END();
5521
5522 if (uv_is_active(&uv->uv.handle)) {
5523 php_error_docref(NULL, E_WARNING, "passed uv_prepare resource has been started.");
5524 RETURN_FALSE;
5525 }
5526
5527 GC_ADDREF(&uv->std);
5528 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_prepare_start, uv);
5529
5530 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_PREPARE_CB);
5531 r = uv_prepare_start(&uv->uv.prepare, php_uv_prepare_cb);
5532 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_prepare_start, uv);
5533
5534 RETURN_LONG(r);
5535 }
5536 /* }}} */
5537
5538 /* {{{ proto long uv_prepare_stop(UVPrepare $handle)
5539 */
5540 PHP_FUNCTION(uv_prepare_stop)
5541 {
5542 php_uv_t *uv;
5543 int r = 0;
5544
5545 ZEND_PARSE_PARAMETERS_START(1, 1)
5546 UV_PARAM_OBJ(uv, php_uv_t, uv_prepare_ce)
5547 ZEND_PARSE_PARAMETERS_END();
5548
5549 if (!uv_is_active(&uv->uv.handle)) {
5550 php_error_docref(NULL, E_NOTICE, "passed uv_prepare resource has been stopped.");
5551 RETURN_FALSE;
5552 }
5553
5554 r = uv_prepare_stop(&uv->uv.prepare);
5555
5556 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_prepare_stop, uv);
5557 OBJ_RELEASE(&uv->std);
5558
5559 RETURN_LONG(r);
5560 }
5561 /* }}} */
5562
5563 /* {{{ proto UVCheck uv_check_init([UVLoop $loop])
5564 */
5565 PHP_FUNCTION(uv_check_init)
5566 {
5567 php_uv_loop_t *loop = NULL;
5568 php_uv_t *uv;
5569
5570 ZEND_PARSE_PARAMETERS_START(0, 1)
5571 Z_PARAM_OPTIONAL
5572 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
5573 ZEND_PARSE_PARAMETERS_END();
5574
5575 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5576 PHP_UV_INIT_UV_EX(uv, uv_check_ce, uv_check_init);
5577
5578 RETURN_OBJ(&uv->std);
5579 }
5580 /* }}} */
5581
5582 /* {{{ proto void uv_check_start(UVCheck $handle, callable(UVCheck $handle) $callback)
5583 */
5584 PHP_FUNCTION(uv_check_start)
5585 {
5586 php_uv_t *uv;
5587 int r;
5588 zend_fcall_info fci = empty_fcall_info;
5589 zend_fcall_info_cache fcc = empty_fcall_info_cache;
5590 php_uv_cb_t *cb;
5591
5592 PHP_UV_DEBUG_PRINT("uv_check_start");
5593
5594 ZEND_PARSE_PARAMETERS_START(2, 2)
5595 UV_PARAM_OBJ(uv, php_uv_t, uv_check_ce)
5596 Z_PARAM_FUNC(fci, fcc)
5597 ZEND_PARSE_PARAMETERS_END();
5598
5599 if (uv_is_active(&uv->uv.handle)) {
5600 php_error_docref(NULL, E_WARNING, "passed uv check resource has already started");
5601 RETURN_FALSE;
5602 }
5603
5604 GC_ADDREF(&uv->std);
5605 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_check_start, uv);
5606
5607 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_CHECK_CB);
5608
5609 r = uv_check_start(&uv->uv.check, php_uv_check_cb);
5610
5611 RETURN_LONG(r);
5612 }
5613 /* }}} */
5614
5615 /* {{{ proto void uv_check_stop(UVCheck $handle)
5616 */
5617 PHP_FUNCTION(uv_check_stop)
5618 {
5619 php_uv_t *uv;
5620
5621 ZEND_PARSE_PARAMETERS_START(1, 1)
5622 UV_PARAM_OBJ(uv, php_uv_t, uv_check_ce)
5623 ZEND_PARSE_PARAMETERS_END();
5624
5625 if (!uv_is_active(&uv->uv.handle)) {
5626 php_error_docref(NULL, E_NOTICE, "passed uv_check resource hasn't start yet.");
5627 RETURN_FALSE;
5628 }
5629
5630 uv_check_stop(&uv->uv.check);
5631
5632 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_check_stop, uv);
5633 OBJ_RELEASE(&uv->std);
5634 }
5635 /* }}} */
5636
5637
5638 /* {{{ proto UVAsync uv_async_init(UVLoop $loop, callable(UVAsync $handle) $callback)
5639 */
5640 PHP_FUNCTION(uv_async_init)
5641 {
5642 php_uv_loop_t *loop;
5643 php_uv_t *uv;
5644 zend_fcall_info fci = empty_fcall_info;
5645 zend_fcall_info_cache fcc = empty_fcall_info_cache;
5646 php_uv_cb_t *cb;
5647
5648 ZEND_PARSE_PARAMETERS_START(2, 2)
5649 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
5650 Z_PARAM_FUNC(fci, fcc)
5651 ZEND_PARSE_PARAMETERS_END();
5652
5653 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5654 PHP_UV_INIT_UV_EX(uv, uv_async_ce, uv_async_init, php_uv_async_cb);
5655
5656 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_ASYNC_CB);
5657
5658 RETURN_OBJ(&uv->std);
5659 }
5660 /* }}} */
5661
5662 /* {{{ proto void uv_async_send(UVAsync $handle)
5663 */
5664 PHP_FUNCTION(uv_async_send)
5665 {
5666 php_uv_t *uv;
5667
5668 ZEND_PARSE_PARAMETERS_START(1, 1)
5669 UV_PARAM_OBJ(uv, php_uv_t, uv_async_ce)
5670 ZEND_PARSE_PARAMETERS_END();
5671
5672 uv_async_send(&uv->uv.async);
5673 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_async_send, uv);
5674 }
5675 /* }}} */
5676
5677 /* {{{ proto void uv_queue_work(UVLoop $loop, callable() $callback, callable() $after_callback)
5678 */
5679 PHP_FUNCTION(uv_queue_work)
5680 {
5681 #if defined(ZTS) && PHP_VERSION_ID < 80000
5682 int r;
5683 php_uv_loop_t *loop;
5684 php_uv_t *uv;
5685 zend_fcall_info work_fci, after_fci = empty_fcall_info;
5686 zend_fcall_info_cache work_fcc, after_fcc = empty_fcall_info_cache;
5687 php_uv_cb_t *work_cb, *after_cb;
5688
5689 ZEND_PARSE_PARAMETERS_START(3, 3)
5690 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
5691 Z_PARAM_FUNC(work_fci, work_fcc)
5692 Z_PARAM_FUNC(after_fci, after_fcc)
5693 ZEND_PARSE_PARAMETERS_END();
5694
5695 PHP_UV_INIT_UV(uv, uv_work_ce);
5696
5697 php_uv_cb_init(&work_cb, uv, &work_fci, &work_fcc, PHP_UV_WORK_CB);
5698 php_uv_cb_init(&after_cb, uv, &after_fci, &after_fcc, PHP_UV_AFTER_WORK_CB);
5699
5700 r = uv_queue_work(&loop->loop, &uv->uv.work, php_uv_work_cb, php_uv_after_work_cb);
5701
5702 if (r) {
5703 php_error_docref(NULL, E_ERROR, "uv_queue_work failed");
5704 PHP_UV_DEINIT_UV(uv);
5705 return;
5706 }
5707 #else
5708 php_error_docref(NULL, E_ERROR, "this PHP doesn't support this uv_queue_work. please rebuild with --enable-maintainer-zts");
5709 #endif
5710 }
5711 /* }}} */
5712
5713 /* {{{ proto void uv_fs_open(UVLoop $loop, string $path, long $flag, long $mode, callable(long|resource $file_or_result) $callback)
5714 */
5715 PHP_FUNCTION(uv_fs_open)
5716 {
5717 php_uv_fs_common(UV_FS_OPEN, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5718 }
5719 /* }}} */
5720
5721
5722 /* {{{ proto void uv_fs_read(UVLoop $loop, resource $fd, long $offset, long $length, callable(resource $fd, string|long $read) $callback)
5723 */
5724 PHP_FUNCTION(uv_fs_read)
5725 {
5726 php_uv_fs_common(UV_FS_READ, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5727 }
5728 /* }}} */
5729
5730
5731 /* {{{ proto void uv_fs_close(UVLoop $loop, resource $fd[, callable(bool $success) $callback])
5732 */
5733 PHP_FUNCTION(uv_fs_close)
5734 {
5735 php_uv_fs_common(UV_FS_CLOSE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5736 }
5737 /* }}} */
5738
5739
5740 /* {{{ proto void uv_fs_write(UVLoop $loop, resource $fd, string $buffer[, long $offset = -1[, callable(resource $fd, long $result) $callback]])
5741 */
5742 PHP_FUNCTION(uv_fs_write)
5743 {
5744 php_uv_fs_common(UV_FS_WRITE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5745 }
5746 /* }}} */
5747
5748 /* {{{ proto void uv_fs_fsync(UVLoop $loop, resource $fd[, callable(resource $fd, long $result) $callback])
5749 */
5750 PHP_FUNCTION(uv_fs_fsync)
5751 {
5752 php_uv_fs_common(UV_FS_FSYNC, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5753 }
5754 /* }}} */
5755
5756 /* {{{ proto void uv_fs_fdatasync(UVLoop $loop, resource $fd[, callable(resource $fd, long $result) $callback])
5757 */
5758 PHP_FUNCTION(uv_fs_fdatasync)
5759 {
5760 php_uv_fs_common(UV_FS_FDATASYNC, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5761 }
5762 /* }}} */
5763
5764 /* {{{ proto void uv_fs_ftruncate(UVLoop $loop, resource $fd, long $offset[, callable(resource $fd, long $result) $callback])
5765 */
5766 PHP_FUNCTION(uv_fs_ftruncate)
5767 {
5768 php_uv_fs_common(UV_FS_FTRUNCATE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5769 }
5770 /* }}} */
5771
5772 /* {{{ proto void uv_fs_mkdir(UVLoop $loop, string $path, long $mode[, callable(long $result) $callback])
5773 */
5774 PHP_FUNCTION(uv_fs_mkdir)
5775 {
5776 php_uv_fs_common(UV_FS_MKDIR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5777 }
5778 /* }}} */
5779
5780
5781 /* {{{ proto void uv_fs_rmdir(UVLoop $loop, string $path[, callable(long $result) $callback])
5782 */
5783 PHP_FUNCTION(uv_fs_rmdir)
5784 {
5785 php_uv_fs_common(UV_FS_RMDIR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5786 }
5787 /* }}} */
5788
5789 /* {{{ proto void uv_fs_unlink(UVLoop $loop, string $path[, callable(long $result) $callback])
5790 */
5791 PHP_FUNCTION(uv_fs_unlink)
5792 {
5793 php_uv_fs_common(UV_FS_UNLINK, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5794 }
5795 /* }}} */
5796
5797 /* {{{ proto void uv_fs_rename(UVLoop $loop, string $from, string $to[, callable(long $result) $callback])
5798 */
5799 PHP_FUNCTION(uv_fs_rename)
5800 {
5801 php_uv_fs_common(UV_FS_RENAME, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5802 }
5803 /* }}} */
5804
5805 /* {{{ proto void uv_fs_utime(UVLoop $loop, string $path, long $utime, long $atime[, callable(long $result) $callback])
5806 */
5807 PHP_FUNCTION(uv_fs_utime)
5808 {
5809 php_uv_fs_common(UV_FS_UTIME, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5810 }
5811 /* }}} */
5812
5813 /* {{{ proto void uv_fs_futime(UVLoop $loop, zval $fd, long $utime, long $atime[, callable(long $result) $callback])
5814 */
5815 PHP_FUNCTION(uv_fs_futime)
5816 {
5817 php_uv_fs_common(UV_FS_FUTIME, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5818 }
5819 /* }}} */
5820
5821 /* {{{ proto void uv_fs_chmod(UVLoop $loop, string $path, long $mode[, callable(long $result) $callback])
5822 */
5823 PHP_FUNCTION(uv_fs_chmod)
5824 {
5825 php_uv_fs_common(UV_FS_CHMOD, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5826 }
5827 /* }}} */
5828
5829
5830 /* {{{ proto void uv_fs_fchmod(UVLoop $loop, zval $fd, long $mode[, callable(long $result) $callback])
5831 */
5832 PHP_FUNCTION(uv_fs_fchmod)
5833 {
5834 php_uv_fs_common(UV_FS_FCHMOD, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5835 }
5836 /* }}} */
5837
5838
5839 /* {{{ proto void uv_fs_chown(UVLoop $loop, string $path, long $uid, long $gid[, callable(long $result) $callback])
5840 */
5841 PHP_FUNCTION(uv_fs_chown)
5842 {
5843 php_uv_fs_common(UV_FS_CHOWN, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5844 }
5845 /* }}} */
5846
5847 /* {{{ proto void uv_fs_fchown(UVLoop $loop, zval $fd, long $uid, $long $gid[, callable(long $result) $callback])
5848 */
5849 PHP_FUNCTION(uv_fs_fchown)
5850 {
5851 php_uv_fs_common(UV_FS_FCHOWN, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5852 }
5853 /* }}} */
5854
5855 /* {{{ proto void uv_fs_link(UVLoop $loop, string $from, string $to[, callable(long $result) $callback])
5856 */
5857 PHP_FUNCTION(uv_fs_link)
5858 {
5859 php_uv_fs_common(UV_FS_LINK, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5860 }
5861 /* }}} */
5862
5863
5864 /* {{{ proto void uv_fs_symlink(UVLoop $loop, string $from, string $to, long $flags[, callable(long $result) $callback])
5865 */
5866 PHP_FUNCTION(uv_fs_symlink)
5867 {
5868 php_uv_fs_common(UV_FS_SYMLINK, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5869 }
5870 /* }}} */
5871
5872 /* {{{ proto void uv_fs_readlink(UVLoop $loop, string $path, callable(string|long $result_or_link_contents) $callback)
5873 */
5874 PHP_FUNCTION(uv_fs_readlink)
5875 {
5876 php_uv_fs_common(UV_FS_READLINK, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5877 }
5878 /* }}} */
5879
5880 /* {{{ proto void uv_fs_stat(UVLoop $loop, string $path, callable(long|array $result_or_stat) $callback)
5881 */
5882 PHP_FUNCTION(uv_fs_stat)
5883 {
5884 php_uv_fs_common(UV_FS_STAT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5885 }
5886 /* }}} */
5887
5888 /* {{{ proto void uv_fs_lstat(UVLoop $loop, string $path, callable(long|array $result_or_stat) $callback)
5889 */
5890 PHP_FUNCTION(uv_fs_lstat)
5891 {
5892 php_uv_fs_common(UV_FS_LSTAT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5893 }
5894 /* }}} */
5895
5896 /* {{{ proto void uv_fs_fstat(UVLoop $loop, resource $fd, callable(resource $fd, array $stat) $callback)
5897 */
5898 PHP_FUNCTION(uv_fs_fstat)
5899 {
5900 php_uv_fs_common(UV_FS_FSTAT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5901 }
5902 /* }}} */
5903
5904
5905 /* {{{ proto void uv_fs_readdir(UVLoop $loop, string $path, callable(long|array $result_or_dir_contents) $callback[, long $flags = 0])
5906 */
5907 PHP_FUNCTION(uv_fs_readdir)
5908 {
5909 php_error_docref(NULL, E_DEPRECATED, "Use uv_fs_scandir() instead of uv_fs_readdir()");
5910 php_uv_fs_common(UV_FS_SCANDIR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5911 }
5912 /* }}} */
5913
5914 /* {{{ proto void uv_fs_scandir(UVLoop $loop, string $path, callable(long|array $result_or_dir_contents) $callback[, long $flags = 0])
5915 * */
5916 PHP_FUNCTION(uv_fs_scandir)
5917 {
5918 php_uv_fs_common(UV_FS_SCANDIR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5919 }
5920 /* }}} */
5921
5922 /* {{{ proto void uv_fs_sendfile(UVLoop $loop, resource $in_fd, resource $out_fd, long $offset, long $length[, callable(resource $out_fd, long $result) $callback])
5923 */
5924 PHP_FUNCTION(uv_fs_sendfile)
5925 {
5926 php_uv_fs_common(UV_FS_SENDFILE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
5927 }
5928 /* }}} */
5929
5930 /* {{{ proto UVFsEvent uv_fs_event_init(UVLoop $loop, string $path, callable(UVFsEvent $handle, string|null $filename, long $events, long $status) $callback[, long $flags = 0])
5931 */
5932 PHP_FUNCTION(uv_fs_event_init)
5933 {
5934 int error;
5935 php_uv_loop_t *loop;
5936 php_uv_t *uv;
5937 zend_string *path;
5938 zend_long flags = 0;
5939 zend_fcall_info fci = empty_fcall_info;
5940 zend_fcall_info_cache fcc = empty_fcall_info_cache;
5941 php_uv_cb_t *cb;
5942
5943 ZEND_PARSE_PARAMETERS_START(3, 4)
5944 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
5945 Z_PARAM_STR(path)
5946 Z_PARAM_FUNC(fci, fcc)
5947 Z_PARAM_OPTIONAL
5948 Z_PARAM_LONG(flags)
5949 ZEND_PARSE_PARAMETERS_END();
5950
5951 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5952 PHP_UV_INIT_UV_EX(uv, uv_fs_event_ce, uv_fs_event_init);
5953
5954 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_FS_EVENT_CB);
5955
5956 error = uv_fs_event_start(&uv->uv.fs_event, php_uv_fs_event_cb, path->val, flags);
5957 if (error < 0) {
5958 php_error_docref(NULL, E_ERROR, "uv_fs_event_start failed");
5959 OBJ_RELEASE(&uv->std);
5960 return;
5961 }
5962
5963 RETURN_OBJ(&uv->std);
5964 }
5965 /* }}} */
5966
5967 /* {{{ proto UVTty uv_tty_init(UVLoop $loop, resource $fd, long $readable)
5968 */
5969 PHP_FUNCTION(uv_tty_init)
5970 {
5971 zval *zstream;
5972 php_uv_loop_t *loop;
5973 php_uv_t *uv;
5974 zend_long readable = 1;
5975 unsigned long fd;
5976
5977 ZEND_PARSE_PARAMETERS_START(3, 3)
5978 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
5979 Z_PARAM_RESOURCE(zstream)
5980 Z_PARAM_LONG(readable)
5981 ZEND_PARSE_PARAMETERS_END();
5982
5983 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
5984 fd = php_uv_zval_to_fd(zstream);
5985 PHP_UV_INIT_UV_EX(uv, uv_tty_ce, uv_tty_init, fd, readable);
5986 PHP_UV_CHECK_VALID_FD(fd, zstream);
5987
5988 RETURN_OBJ(&uv->std);
5989 }
5990 /* }}} */
5991
5992
5993 /* {{{ proto long uv_tty_get_winsize(UVTty $tty, long &$width, long &$height)
5994 */
5995 PHP_FUNCTION(uv_tty_get_winsize)
5996 {
5997 php_uv_t *uv;
5998 zval *w, *h = NULL;
5999 int error, width, height = 0;
6000
6001 ZEND_PARSE_PARAMETERS_START(3, 3)
6002 UV_PARAM_OBJ(uv, php_uv_t, uv_tty_ce)
6003 Z_PARAM_ZVAL_EX(w, 0, 1)
6004 Z_PARAM_ZVAL_EX(h, 0, 1)
6005 ZEND_PARSE_PARAMETERS_END();
6006
6007 error = uv_tty_get_winsize(&uv->uv.tty, &width, &height);
6008
6009 zval_ptr_dtor(w);
6010 zval_ptr_dtor(h);
6011
6012 ZVAL_LONG(w, width);
6013 ZVAL_LONG(h, height);
6014
6015 RETURN_LONG(error);
6016 }
6017 /* }}} */
6018
6019
6020 /* {{{ proto long uv_tty_set_mode(UVTty $tty, long $mode)
6021 */
6022 PHP_FUNCTION(uv_tty_set_mode)
6023 {
6024 php_uv_t *uv;
6025 zend_long mode, error = 0;
6026
6027 ZEND_PARSE_PARAMETERS_START(2, 2)
6028 UV_PARAM_OBJ(uv, php_uv_t, uv_tty_ce)
6029 Z_PARAM_LONG(mode)
6030 ZEND_PARSE_PARAMETERS_END();
6031
6032 error = uv_tty_set_mode(&uv->uv.tty, mode);
6033 RETURN_LONG(error);
6034 }
6035 /* }}} */
6036
6037 /* {{{ proto void uv_tty_reset_mode(void)
6038 */
6039 PHP_FUNCTION(uv_tty_reset_mode)
6040 {
6041 if (zend_parse_parameters_none() == FAILURE) {
6042 return;
6043 }
6044
6045 uv_tty_reset_mode();
6046 }
6047 /* }}} */
6048
6049 /* {{{ proto void uv_tcp_simultaneous_accepts(UVTcp $handle, bool $enable)
6050 */
6051 PHP_FUNCTION(uv_tcp_simultaneous_accepts)
6052 {
6053 php_uv_t *uv;
6054 zend_bool enable;
6055 zend_long error = 0;
6056
6057 ZEND_PARSE_PARAMETERS_START(2, 2)
6058 UV_PARAM_OBJ(uv, php_uv_t, uv_tcp_ce)
6059 Z_PARAM_BOOL(enable)
6060 ZEND_PARSE_PARAMETERS_END();
6061
6062 error = uv_tcp_simultaneous_accepts(&uv->uv.tcp, enable);
6063 RETURN_LONG(error);
6064 }
6065 /* }}} */
6066
6067 /* {{{ proto string uv_tcp_getsockname(UVTcp $uv_sock)
6068 */
6069 PHP_FUNCTION(uv_tcp_getsockname)
6070 {
6071 php_uv_socket_getname(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
6072 }
6073 /* }}} */
6074
6075 /* {{{ proto string uv_tcp_getpeername(UVTcp $uv_sock)
6076 */
6077 PHP_FUNCTION(uv_tcp_getpeername)
6078 {
6079 php_uv_socket_getname(2, INTERNAL_FUNCTION_PARAM_PASSTHRU);
6080 }
6081 /* }}} */
6082
6083 /* {{{ proto string uv_udp_getsockname(UVUdp $uv_sock)
6084 */
6085 PHP_FUNCTION(uv_udp_getsockname)
6086 {
6087 php_uv_socket_getname(3, INTERNAL_FUNCTION_PARAM_PASSTHRU);
6088 }
6089 /* }}} */
6090
6091
6092 /* {{{ proto long uv_resident_set_memory(void)
6093 */
6094 PHP_FUNCTION(uv_resident_set_memory)
6095 {
6096 size_t rss;
6097
6098 if (zend_parse_parameters_none() == FAILURE) {
6099 return;
6100 }
6101
6102 uv_resident_set_memory(&rss);
6103
6104 RETURN_LONG(rss);
6105 }
6106 /* }}} */
6107
6108 /* {{{ proto string uv_ip4_name(UVSockAddr $address)
6109 */
6110 PHP_FUNCTION(uv_ip4_name)
6111 {
6112 php_uv_ip_common(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
6113 }
6114 /* }}} */
6115
6116 /* {{{ proto string uv_ip6_name(UVSockAddr $address)
6117 */
6118 PHP_FUNCTION(uv_ip6_name)
6119 {
6120 php_uv_ip_common(2, INTERNAL_FUNCTION_PARAM_PASSTHRU);
6121 }
6122 /* }}} */
6123
6124 /* {{{ proto UVPoll uv_poll_init(UVLoop $loop, resource $fd)
6125 */
6126 PHP_FUNCTION(uv_poll_init)
6127 {
6128 zval *zstream;
6129 php_uv_loop_t *loop;
6130 php_uv_t *uv;
6131 unsigned long fd = 0;
6132
6133 ZEND_PARSE_PARAMETERS_START(2, 2)
6134 UV_PARAM_OBJ(loop, php_uv_loop_t, uv_loop_ce)
6135 Z_PARAM_RESOURCE(zstream)
6136 ZEND_PARSE_PARAMETERS_END();
6137
6138 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
6139 fd = php_uv_zval_to_valid_poll_fd(zstream);
6140 #ifdef PHP_WIN32
6141 PHP_UV_INIT_UV_EX(uv, uv_poll_ce, uv_poll_init_socket, (uv_os_sock_t) fd);
6142 #else
6143 PHP_UV_INIT_UV_EX(uv, uv_poll_ce, uv_poll_init, fd);
6144 #endif
6145 PHP_UV_CHECK_VALID_FD(fd, zstream);
6146
6147 uv->sock = fd;
6148 PHP_UV_DEBUG_PRINT("uv_poll_init: resource: %p\n", uv);
6149
6150 RETURN_OBJ(&uv->std);
6151 }
6152
6153 /* }}} */
6154
6155
6156 /* {{{ proto void uv_poll_start(UVPoll $handle, long $events, callable(UVPoll $handle, long $status, long $events, resource $fd) $callback)
6157 */
6158 PHP_FUNCTION(uv_poll_start)
6159 {
6160 php_uv_t *uv;
6161 zend_long events = 0;
6162 int error;
6163 zend_fcall_info fci = empty_fcall_info;
6164 zend_fcall_info_cache fcc = empty_fcall_info_cache;
6165 php_uv_cb_t *cb;
6166
6167 ZEND_PARSE_PARAMETERS_START(3, 3)
6168 UV_PARAM_OBJ(uv, php_uv_t, uv_poll_ce)
6169 Z_PARAM_LONG(events)
6170 Z_PARAM_FUNC(fci, fcc)
6171 ZEND_PARSE_PARAMETERS_END();
6172
6173 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_POLL_CB);
6174 if (!uv_is_active(&uv->uv.handle)) {
6175 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_poll_start, uv);
6176 GC_ADDREF(&uv->std);
6177 }
6178
6179 error = uv_poll_start(&uv->uv.poll, events, php_uv_poll_cb);
6180 if (error) {
6181 php_error_docref(NULL, E_ERROR, "uv_poll_start failed");
6182 return;
6183 }
6184 }
6185 /* }}} */
6186
6187 /* {{{ proto void uv_poll_stop(UVPoll $poll)
6188 */
6189 PHP_FUNCTION(uv_poll_stop)
6190 {
6191 php_uv_t *uv;
6192
6193 ZEND_PARSE_PARAMETERS_START(1, 1)
6194 UV_PARAM_OBJ(uv, php_uv_t, uv_poll_ce)
6195 ZEND_PARSE_PARAMETERS_END();
6196
6197 if (!uv_is_active((uv_handle_t *) &uv->uv.poll)) {
6198 return;
6199 }
6200
6201 uv_poll_stop(&uv->uv.poll);
6202
6203 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_poll_stop, uv);
6204 OBJ_RELEASE(&uv->std);
6205 }
6206 /* }}} */
6207
6208 /* {{{ proto UVFsPoll uv_fs_poll_init([UVLoop $loop = uv_default_loop()])
6209 */
6210 PHP_FUNCTION(uv_fs_poll_init)
6211 {
6212 php_uv_loop_t *loop = NULL;
6213 php_uv_t *uv;
6214
6215 ZEND_PARSE_PARAMETERS_START(0, 1)
6216 Z_PARAM_OPTIONAL
6217 UV_PARAM_OBJ_NULL(loop, php_uv_loop_t, uv_loop_ce)
6218 ZEND_PARSE_PARAMETERS_END();
6219
6220 PHP_UV_FETCH_UV_DEFAULT_LOOP(loop);
6221 PHP_UV_INIT_UV_EX(uv, uv_fs_poll_ce, uv_fs_poll_init);
6222
6223 RETURN_OBJ(&uv->std);
6224 }
6225 /* }}} */
6226
6227 /* {{{ proto uv uv_fs_poll_start(UVFsPoll $handle, callable(UVFsPoll $handle, long $status, array $prev_stat, array $cur_stat) $callback, string $path, long $interval)
6228 */
6229 PHP_FUNCTION(uv_fs_poll_start)
6230 {
6231 php_uv_t *uv;
6232 zend_string *path;
6233 zend_long interval = 0;
6234 int error;
6235 zend_fcall_info fci = empty_fcall_info;
6236 zend_fcall_info_cache fcc = empty_fcall_info_cache;
6237 php_uv_cb_t *cb;
6238
6239 ZEND_PARSE_PARAMETERS_START(4, 4)
6240 UV_PARAM_OBJ(uv, php_uv_t, uv_fs_poll_ce)
6241 Z_PARAM_FUNC(fci, fcc)
6242 Z_PARAM_STR(path)
6243 Z_PARAM_LONG(interval)
6244 ZEND_PARSE_PARAMETERS_END();
6245
6246 php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_FS_POLL_CB);
6247 GC_ADDREF(&uv->std);
6248 PHP_UV_DEBUG_OBJ_ADD_REFCOUNT(uv_fs_poll_start, uv);
6249
6250 error = uv_fs_poll_start(&uv->uv.fs_poll, php_uv_fs_poll_cb, (const char*)path->val, interval);
6251 if (error) {
6252 php_error_docref(NULL, E_ERROR, "uv_fs_poll_start failed");
6253 OBJ_RELEASE(&uv->std);
6254 }
6255 }
6256 /* }}} */
6257
6258 /* {{{ proto void uv_fs_poll_stop(UVFsPoll $poll)
6259 */
6260 PHP_FUNCTION(uv_fs_poll_stop)
6261 {
6262 php_uv_t *uv;
6263
6264 ZEND_PARSE_PARAMETERS_START(1, 1)
6265 UV_PARAM_OBJ(uv, php_uv_t, uv_fs_poll_ce)
6266 ZEND_PARSE_PARAMETERS_END();
6267
6268 if (!uv_is_active(&uv->uv.handle)) {
6269 return;
6270 }
6271
6272 uv_fs_poll_stop(&uv->uv.fs_poll);
6273
6274 PHP_UV_DEBUG_OBJ_DEL_REFCOUNT(uv_fs_poll_stop, uv);
6275 OBJ_RELEASE(&uv->std);
6276 }
6277 /* }}} */
6278
6279
6280
6281
6282 static zend_function_entry uv_functions[] = {
6283 /* general */
6284 PHP_FE(uv_update_time, arginfo_uv_update_time)
6285 PHP_FE(uv_ref, arginfo_uv_ref)
6286 PHP_FE(uv_unref, arginfo_uv_unref)
6287 PHP_FE(uv_loop_new, arginfo_void)
6288 PHP_FE(uv_default_loop, arginfo_void)
6289 PHP_FE(uv_stop, arginfo_uv_stop)
6290 PHP_FE(uv_run, arginfo_uv_run)
6291 PHP_FE(uv_ip4_addr, arginfo_uv_ip4_addr)
6292 PHP_FE(uv_ip6_addr, arginfo_uv_ip6_addr)
6293 PHP_FE(uv_ip4_name, arginfo_uv_ip4_name)
6294 PHP_FE(uv_ip6_name, arginfo_uv_ip6_name)
6295 PHP_FE(uv_write, arginfo_uv_write)
6296 PHP_FE(uv_write2, arginfo_uv_write2)
6297 PHP_FE(uv_shutdown, arginfo_uv_shutdown)
6298 PHP_FE(uv_close, arginfo_uv_close)
6299 PHP_FE(uv_now, arginfo_uv_now)
6300 PHP_FE(uv_loop_delete, arginfo_uv_loop_delete)
6301 PHP_FE(uv_read_start, arginfo_uv_read_start)
6302 PHP_FE(uv_read_stop, arginfo_uv_read_stop)
6303 PHP_FE(uv_err_name, arginfo_uv_err_name)
6304 PHP_FE(uv_strerror, arginfo_uv_strerror)
6305 PHP_FE(uv_is_active, arginfo_uv_is_active)
6306 PHP_FE(uv_is_closing, arginfo_uv_is_closing)
6307 PHP_FE(uv_is_readable, arginfo_uv_is_readable)
6308 PHP_FE(uv_is_writable, arginfo_uv_is_writable)
6309 PHP_FE(uv_walk, arginfo_uv_walk)
6310 PHP_FE(uv_guess_handle, arginfo_uv_guess_handle)
6311 /* idle */
6312 PHP_FE(uv_idle_init, arginfo_uv_idle_init)
6313 PHP_FE(uv_idle_start, arginfo_uv_idle_start)
6314 PHP_FE(uv_idle_stop, arginfo_uv_idle_stop)
6315 /* timer */
6316 PHP_FE(uv_timer_init, arginfo_uv_timer_init)
6317 PHP_FE(uv_timer_start, arginfo_uv_timer_start)
6318 PHP_FE(uv_timer_stop, arginfo_uv_timer_stop)
6319 PHP_FE(uv_timer_again, arginfo_uv_timer_again)
6320 PHP_FE(uv_timer_set_repeat, arginfo_uv_timer_set_repeat)
6321 PHP_FE(uv_timer_get_repeat, arginfo_uv_timer_get_repeat)
6322 /* tcp */
6323 PHP_FE(uv_tcp_init, arginfo_uv_tcp_init)
6324 PHP_FE(uv_tcp_open, arginfo_uv_tcp_open)
6325 PHP_FE(uv_tcp_nodelay, arginfo_uv_tcp_nodelay)
6326 PHP_FE(uv_tcp_bind, arginfo_uv_tcp_bind)
6327 PHP_FE(uv_tcp_bind6, arginfo_uv_tcp_bind6)
6328 PHP_FE(uv_listen, arginfo_uv_listen)
6329 PHP_FE(uv_accept, arginfo_uv_accept)
6330 PHP_FE(uv_tcp_connect, arginfo_uv_tcp_connect)
6331 PHP_FE(uv_tcp_connect6, arginfo_uv_tcp_connect6)
6332 /* udp */
6333 PHP_FE(uv_udp_init, arginfo_uv_udp_init)
6334 PHP_FE(uv_udp_open, arginfo_uv_udp_open)
6335 PHP_FE(uv_udp_bind, arginfo_uv_udp_bind)
6336 PHP_FE(uv_udp_bind6, arginfo_uv_udp_bind6)
6337 PHP_FE(uv_udp_set_multicast_loop, arginfo_uv_udp_set_multicast_loop)
6338 PHP_FE(uv_udp_set_multicast_ttl, arginfo_uv_udp_set_multicast_ttl)
6339 PHP_FE(uv_udp_send, arginfo_uv_udp_send)
6340 PHP_FE(uv_udp_send6, arginfo_uv_udp_send6)
6341 PHP_FE(uv_udp_recv_start, arginfo_uv_udp_recv_start)
6342 PHP_FE(uv_udp_recv_stop, arginfo_uv_udp_recv_stop)
6343 PHP_FE(uv_udp_set_membership, arginfo_uv_udp_set_membership)
6344 PHP_FE(uv_udp_set_broadcast, arginfo_uv_udp_set_broadcast)
6345 /* poll */
6346 PHP_FE(uv_poll_init, arginfo_uv_poll_init)
6347 PHP_FALIAS(uv_poll_init_socket, uv_poll_init, arginfo_uv_poll_init)
6348 PHP_FE(uv_poll_start, arginfo_uv_poll_start)
6349 PHP_FE(uv_poll_stop, arginfo_uv_poll_stop)
6350 PHP_FE(uv_fs_poll_init, arginfo_uv_fs_poll_init)
6351 PHP_FE(uv_fs_poll_start, arginfo_uv_fs_poll_start)
6352 PHP_FE(uv_fs_poll_stop, arginfo_uv_fs_poll_stop)
6353 /* other network functions */
6354 PHP_FE(uv_tcp_getsockname, arginfo_uv_tcp_getsockname)
6355 PHP_FE(uv_tcp_getpeername, arginfo_uv_tcp_getpeername)
6356 PHP_FE(uv_udp_getsockname, arginfo_uv_udp_getsockname)
6357 PHP_FE(uv_tcp_simultaneous_accepts, arginfo_uv_tcp_simultaneous_accepts)
6358 /* pipe */
6359 PHP_FE(uv_pipe_init, arginfo_uv_pipe_init)
6360 PHP_FE(uv_pipe_bind, arginfo_uv_pipe_bind)
6361 PHP_FE(uv_pipe_open, arginfo_uv_pipe_open)
6362 PHP_FE(uv_pipe_connect, arginfo_uv_pipe_connect)
6363 PHP_FE(uv_pipe_pending_instances, arginfo_uv_pipe_pending_instances)
6364 PHP_FE(uv_pipe_pending_count, arginfo_uv_pipe_pending_count)
6365 PHP_FE(uv_pipe_pending_type, arginfo_uv_pipe_pending_type)
6366 PHP_FE(uv_stdio_new, arginfo_void)
6367 /* spawn */
6368 PHP_FE(uv_spawn, arginfo_uv_spawn)
6369 PHP_FE(uv_process_kill, arginfo_uv_process_kill)
6370 PHP_FE(uv_process_get_pid, arginfo_uv_process_get_pid)
6371 PHP_FE(uv_kill, arginfo_uv_kill)
6372 /* c-ares */
6373 PHP_FE(uv_getaddrinfo, arginfo_uv_getaddrinfo)
6374 /* rwlock */
6375 PHP_FE(uv_rwlock_init, arginfo_void)
6376 PHP_FE(uv_rwlock_rdlock, arginfo_uv_rwlock_rdlock)
6377 PHP_FE(uv_rwlock_tryrdlock, arginfo_uv_rwlock_tryrdlock)
6378 PHP_FE(uv_rwlock_rdunlock, arginfo_uv_rwlock_rdunlock)
6379 PHP_FE(uv_rwlock_wrlock, arginfo_uv_rwlock_wrlock)
6380 PHP_FE(uv_rwlock_trywrlock, arginfo_uv_rwlock_trywrlock)
6381 PHP_FE(uv_rwlock_wrunlock, arginfo_uv_rwlock_wrunlock)
6382 /* mutex */
6383 PHP_FE(uv_mutex_init, arginfo_void)
6384 PHP_FE(uv_mutex_lock, arginfo_uv_mutex_lock)
6385 PHP_FE(uv_mutex_trylock, arginfo_uv_mutex_trylock)
6386 PHP_FE(uv_mutex_unlock, arginfo_uv_mutex_unlock)
6387 /* semaphore */
6388 PHP_FE(uv_sem_init, arginfo_uv_sem_init)
6389 PHP_FE(uv_sem_post, arginfo_uv_sem_post)
6390 PHP_FE(uv_sem_wait, arginfo_uv_sem_wait)
6391 PHP_FE(uv_sem_trywait, arginfo_uv_sem_trywait)
6392 /* prepare (before poll hook) */
6393 PHP_FE(uv_prepare_init, arginfo_uv_prepare_init)
6394 PHP_FE(uv_prepare_start, arginfo_uv_prepare_start)
6395 PHP_FE(uv_prepare_stop, arginfo_uv_prepare_stop)
6396 /* check (after poll hook) */
6397 PHP_FE(uv_check_init, arginfo_uv_check_init)
6398 PHP_FE(uv_check_start, arginfo_uv_check_start)
6399 PHP_FE(uv_check_stop, arginfo_uv_check_stop)
6400 /* async */
6401 PHP_FE(uv_async_init, arginfo_uv_async_init)
6402 PHP_FE(uv_async_send, arginfo_uv_async_send)
6403 /* queue (does not work yet) */
6404 #if PHP_VERSION_ID < 80000
6405 PHP_FE(uv_queue_work, NULL)
6406 #endif
6407 /* fs */
6408 PHP_FE(uv_fs_open, arginfo_uv_fs_open)
6409 PHP_FE(uv_fs_read, arginfo_uv_fs_read)
6410 PHP_FE(uv_fs_write, arginfo_uv_fs_write)
6411 PHP_FE(uv_fs_close, arginfo_uv_fs_close)
6412 PHP_FE(uv_fs_fsync, arginfo_uv_fs_fsync)
6413 PHP_FE(uv_fs_fdatasync, arginfo_uv_fs_fdatasync)
6414 PHP_FE(uv_fs_ftruncate, arginfo_uv_fs_ftruncate)
6415 PHP_FE(uv_fs_mkdir, arginfo_uv_fs_mkdir)
6416 PHP_FE(uv_fs_rmdir, arginfo_uv_fs_rmdir)
6417 PHP_FE(uv_fs_unlink, arginfo_uv_fs_unlink)
6418 PHP_FE(uv_fs_rename, arginfo_uv_fs_rename)
6419 PHP_FE(uv_fs_utime, arginfo_uv_fs_utime)
6420 PHP_FE(uv_fs_futime, arginfo_uv_fs_futime)
6421 PHP_FE(uv_fs_chmod, arginfo_uv_fs_chmod)
6422 PHP_FE(uv_fs_fchmod, arginfo_uv_fs_fchmod)
6423 PHP_FE(uv_fs_chown, arginfo_uv_fs_chown)
6424 PHP_FE(uv_fs_fchown, arginfo_uv_fs_fchown)
6425 PHP_FE(uv_fs_link, arginfo_uv_fs_link)
6426 PHP_FE(uv_fs_symlink, arginfo_uv_fs_symlink)
6427 PHP_FE(uv_fs_readlink, arginfo_uv_fs_readlink)
6428 PHP_FE(uv_fs_stat, arginfo_uv_fs_stat)
6429 PHP_FE(uv_fs_lstat, arginfo_uv_fs_lstat)
6430 PHP_FE(uv_fs_fstat, arginfo_uv_fs_fstat)
6431 PHP_FE(uv_fs_readdir, arginfo_uv_fs_readdir)
6432 PHP_FE(uv_fs_scandir, arginfo_uv_fs_scandir)
6433 PHP_FE(uv_fs_sendfile, arginfo_uv_fs_sendfile)
6434 PHP_FE(uv_fs_event_init, arginfo_uv_fs_event_init)
6435 /* tty */
6436 PHP_FE(uv_tty_init, arginfo_uv_tty_init)
6437 PHP_FE(uv_tty_get_winsize, arginfo_uv_tty_get_winsize)
6438 PHP_FE(uv_tty_set_mode, arginfo_void)
6439 PHP_FE(uv_tty_reset_mode, arginfo_void)
6440 /* info */
6441 PHP_FE(uv_loadavg, arginfo_void)
6442 PHP_FE(uv_uptime, arginfo_void)
6443 PHP_FE(uv_cpu_info, arginfo_void)
6444 PHP_FE(uv_interface_addresses, arginfo_void)
6445 PHP_FE(uv_get_free_memory, arginfo_void)
6446 PHP_FE(uv_get_total_memory, arginfo_void)
6447 PHP_FE(uv_hrtime, arginfo_void)
6448 PHP_FE(uv_exepath, arginfo_void)
6449 PHP_FE(uv_cwd, arginfo_void)
6450 PHP_FE(uv_chdir, arginfo_uv_chdir)
6451 PHP_FE(uv_resident_set_memory, arginfo_void)
6452 /* signal handling */
6453 PHP_FE(uv_signal_init, arginfo_uv_signal_init)
6454 PHP_FE(uv_signal_start, arginfo_uv_signal_start)
6455 PHP_FE(uv_signal_stop, arginfo_uv_signal_stop)
6456 {0}
6457 };
6458
6459 PHP_MINFO_FUNCTION(uv)
6460 {
6461 char uv_version[20];
6462
6463 sprintf(uv_version, "%d.%d",UV_VERSION_MAJOR, UV_VERSION_MINOR);
6464
6465 php_printf("PHP libuv Extension\n");
6466 php_info_print_table_start();
6467 php_info_print_table_header(2,"libuv Support", "enabled");
6468 php_info_print_table_row(2,"Version", PHP_UV_VERSION);
6469 php_info_print_table_row(2,"libuv Version", uv_version);
6470 php_info_print_table_end();
6471 }
6472
6473 static PHP_GINIT_FUNCTION(uv)
6474 {
6475 #if defined(COMPILE_DL_UV) && defined(ZTS)
6476 ZEND_TSRMLS_CACHE_UPDATE();
6477 #endif
6478 uv_globals->default_loop = NULL;
6479 }
6480
6481 zend_module_entry uv_module_entry = {
6482 STANDARD_MODULE_HEADER,
6483 "uv",
6484 uv_functions, /* Functions */
6485 PHP_MINIT(uv), /* MINIT */
6486 NULL, /* MSHUTDOWN */
6487 NULL, /* RINIT */
6488 PHP_RSHUTDOWN(uv), /* RSHUTDOWN */
6489 PHP_MINFO(uv), /* MINFO */
6490 PHP_UV_VERSION,
6491 PHP_MODULE_GLOBALS(uv),
6492 PHP_GINIT(uv),
6493 NULL,
6494 NULL,
6495 STANDARD_MODULE_PROPERTIES_EX
6496 };
6497
6498
6499 #ifdef COMPILE_DL_UV
6500 ZEND_GET_MODULE(uv)
6501 #endif
6502