1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 8                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2021 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    | Author: Ruslan Osmanov <osmanov@php.net>                             |
16    +----------------------------------------------------------------------+
17 */
18 #include "watcher.h"
19 
20 /* {{{ php_ev_stat_to_zval */
php_ev_stat_to_zval(const ev_statdata * st,zval * z)21 static void php_ev_stat_to_zval(const ev_statdata *st, zval *z)
22 {
23 	array_init(z);
24 
25 	add_assoc_long(z, "dev",   st->st_dev);
26 	add_assoc_long(z, "ino",   st->st_ino);
27 	add_assoc_long(z, "mode",  st->st_mode);
28 	add_assoc_long(z, "nlink", st->st_nlink);
29 	add_assoc_long(z, "uid",   st->st_uid);
30 	add_assoc_long(z, "size",  st->st_size);
31 	add_assoc_long(z, "gid",   st->st_gid);
32 #ifdef HAVE_ST_RDEV
33 	add_assoc_long(z, "rdev", st->st_rdev);
34 #else
35 	add_assoc_long(z, "rdev", -1);
36 #endif
37 #ifdef HAVE_ST_BLKSIZE
38 	add_assoc_long(z, "blksize", st->st_blksize);
39 #else
40 	add_assoc_long(z, "blksize", -1);
41 #endif
42 #ifdef HAVE_ST_BLOCKS
43 	add_assoc_long(z, "blocks", st->st_blocks);
44 #else
45 	add_assoc_long(z, "blocks", -1);
46 #endif
47 	add_assoc_long(z, "atime", st->st_atime);
48 	add_assoc_long(z, "mtime", st->st_mtime);
49 	add_assoc_long(z, "ctime", st->st_ctime);
50 }
51 /* }}} */
52 
53 /* {{{ php_ev_stat_object_ctor */
php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAMETERS,zval * zloop,zend_bool ctor,zend_bool start)54 void php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *zloop, zend_bool ctor, zend_bool start)
55 {
56 	zval          *self;
57 	zval          *callback;
58 	zval          *data     = NULL;
59 	php_ev_object *o_self;
60 	ev_stat       *w;
61 	php_ev_stat   *stat_ptr;
62 	zend_long      priority = 0;
63 	char          *path;
64 	size_t         path_len;
65 	double         interval;
66 
67 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "pdz|z!l",
68 				&path, &path_len, &interval,
69 				&callback, &data, &priority) == FAILURE) {
70 		return;
71 	}
72 
73 	if (ctor) {
74 		self = getThis();
75 	} else {
76 		object_init_ex(return_value, ev_stat_class_entry_ptr);
77 		self = return_value;
78 	}
79 
80 	stat_ptr = ecalloc(1, sizeof(php_ev_stat));
81 	if (UNEXPECTED(stat_ptr == NULL)) {
82 		php_error_docref(NULL, E_ERROR, "Failed to allocate memory: php_ev_stat");
83 		return;
84 	}
85 	w = &stat_ptr->stat;
86 
87 	if (!zloop) {
88 		zloop = php_ev_default_loop();
89 	}
90 
91 	if (php_ev_set_watcher((ev_watcher *)w, EV_STAT, self,
92 				zloop, callback, data, priority) == FAILURE) {
93 		efree(stat_ptr);
94 		zend_throw_exception_ex(zend_ce_exception, 0, "Watcher configuration failed");
95 		return;
96 	}
97 
98 	stat_ptr->path = estrndup(path, path_len);
99 	ev_stat_set(w, stat_ptr->path, interval);
100 
101 	o_self = Z_EV_OBJECT_P(self);
102 	o_self->ptr = (void *)stat_ptr;
103 
104 	if (start) {
105 		PHP_EV_WATCHER_START(ev_stat, w);
106 	}
107 }
108 /* }}} */
109 
110 /* {{{ proto EvStat::__construct(string path, double interval, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvStat,__construct)111 PHP_METHOD(EvStat, __construct)
112 {
113 	PHP_EV_WATCHER_CTOR(stat, NULL);
114 }
115 /* }}} */
116 
117 /* {{{ proto EvStat::createStopped(string path, double interval, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvStat,createStopped)118 PHP_METHOD(EvStat, createStopped)
119 {
120 	PHP_EV_WATCHER_FACTORY_NS(stat, NULL);
121 }
122 /* }}} */
123 
124 /* {{{ proto void EvStat::set(string path, double interval) */
PHP_METHOD(EvStat,set)125 PHP_METHOD(EvStat, set)
126 {
127 	char        *path;
128 	size_t       path_len;
129 	double       interval;
130 	ev_stat     *w;
131 	php_ev_stat *stat_ptr;
132 
133 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "pd", &path, &path_len, &interval) == FAILURE) {
134 		return;
135 	}
136 
137 	stat_ptr = (php_ev_stat *)PHP_EV_WATCHER_FETCH_FROM_OBJECT(Z_EV_OBJECT_P(getThis()));
138 	PHP_EV_ASSERT(stat_ptr);
139 	PHP_EV_ASSERT(stat_ptr->path);
140 	w = (ev_stat *)stat_ptr;
141 
142 	efree(stat_ptr->path);
143 	stat_ptr->path = estrndup(path, path_len);
144 
145 	PHP_EV_WATCHER_RESET(ev_stat, w, (w, stat_ptr->path, interval));
146 }
147 /* }}} */
148 
149 /* {{{ proto mixed EvStat::attr(void) */
PHP_METHOD(EvStat,attr)150 PHP_METHOD(EvStat, attr)
151 {
152 	ev_stat     *w;
153 	ev_statdata *st;
154 
155 	if (zend_parse_parameters_none() == FAILURE) {
156 		return;
157 	}
158 
159 	w  = (ev_stat *)PHP_EV_WATCHER_FETCH_FROM_THIS();
160 	st = &w->attr;
161 
162 	if (!st->st_nlink) {
163 		RETURN_FALSE;
164 	}
165 
166 	php_ev_stat_to_zval(st, return_value);
167 }
168 /* }}} */
169 
170 /* {{{ proto mixed EvStat::prev(void) */
PHP_METHOD(EvStat,prev)171 PHP_METHOD(EvStat, prev)
172 {
173 	ev_stat     *w;
174 	ev_statdata *st;
175 
176 	if (zend_parse_parameters_none() == FAILURE) {
177 		return;
178 	}
179 
180 	w  = (ev_stat *)PHP_EV_WATCHER_FETCH_FROM_THIS();
181 	st = &w->prev;
182 
183 	if (!st->st_nlink) {
184 		RETURN_FALSE;
185 	}
186 
187 	php_ev_stat_to_zval(st, return_value);
188 }
189 /* }}} */
190 
191 /* {{{ proto bool EvStat::stat(void) */
PHP_METHOD(EvStat,stat)192 PHP_METHOD(EvStat, stat)
193 {
194 	php_ev_object *ev_obj;
195 	ev_stat       *w;
196 	ev_statdata   *st;
197 
198 	if (zend_parse_parameters_none() == FAILURE) {
199 		return;
200 	}
201 
202 	ev_obj = Z_EV_OBJECT_P(getThis());
203 	w      = (ev_stat *)PHP_EV_WATCHER_FETCH_FROM_OBJECT(ev_obj);
204 
205 	st = &w->attr;
206 
207 	ev_stat_stat(PHP_EV_LOOP_FETCH_FROM_OBJECT(ev_obj), w);
208 
209 	if (st->st_nlink) {
210 		RETURN_TRUE;
211 	}
212 	RETURN_FALSE;
213 }
214 /* }}} */
215 
216 /*
217  * Local variables:
218  * tab-width: 4
219  * c-basic-offset: 4
220  * End:
221  * vim600: noet sw=4 ts=4 sts=4 fdm=marker
222  * vim<600: noet sw=4 ts=4 sts=4
223  */
224