1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 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: Wez Furlong (wez@thebrainroom.com) | |
16 | +----------------------------------------------------------------------+ |
17 | */ |
18 | |
19 | /* $Id$ */ |
20 | |
21 | #ifndef PHP_STREAMS_H |
22 | #define PHP_STREAMS_H |
23 | |
24 | #ifdef HAVE_SYS_TIME_H |
25 | #include <sys/time.h> |
26 | #endif |
27 | #include <sys/types.h> |
28 | #include <sys/stat.h> |
29 | |
30 | BEGIN_EXTERN_C() |
31 | PHPAPI int php_file_le_stream(void); |
32 | PHPAPI int php_file_le_pstream(void); |
33 | PHPAPI int php_file_le_stream_filter(void); |
34 | END_EXTERN_C() |
35 | |
36 | /* {{{ Streams memory debugging stuff */ |
37 | |
38 | #if ZEND_DEBUG |
39 | /* these have more of a dependency on the definitions of the zend macros than |
40 | * I would prefer, but doing it this way saves loads of idefs :-/ */ |
41 | # define STREAMS_D int __php_stream_call_depth ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC |
42 | # define STREAMS_C 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC |
43 | # define STREAMS_REL_C __php_stream_call_depth + 1 ZEND_FILE_LINE_CC, \ |
44 | __php_stream_call_depth ? __zend_orig_filename : __zend_filename, \ |
45 | __php_stream_call_depth ? __zend_orig_lineno : __zend_lineno |
46 | |
47 | # define STREAMS_DC , STREAMS_D |
48 | # define STREAMS_CC , STREAMS_C |
49 | # define STREAMS_REL_CC , STREAMS_REL_C |
50 | |
51 | #else |
52 | # define STREAMS_D |
53 | # define STREAMS_C |
54 | # define STREAMS_REL_C |
55 | # define STREAMS_DC |
56 | # define STREAMS_CC |
57 | # define STREAMS_REL_CC |
58 | #endif |
59 | |
60 | /* these functions relay the file/line number information. They are depth aware, so they will pass |
61 | * the ultimate ancestor, which is useful, because there can be several layers of calls */ |
62 | #define php_stream_alloc_rel(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_REL_CC TSRMLS_CC) |
63 | |
64 | #define php_stream_copy_to_mem_rel(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_REL_CC TSRMLS_CC) |
65 | |
66 | #define php_stream_fopen_rel(filename, mode, opened, options) _php_stream_fopen((filename), (mode), (opened), (options) STREAMS_REL_CC TSRMLS_CC) |
67 | |
68 | #define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC TSRMLS_CC) |
69 | |
70 | #define php_stream_fopen_from_fd_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_REL_CC TSRMLS_CC) |
71 | #define php_stream_fopen_from_file_rel(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC TSRMLS_CC) |
72 | |
73 | #define php_stream_fopen_from_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC TSRMLS_CC) |
74 | |
75 | #define php_stream_fopen_tmpfile_rel() _php_stream_fopen_tmpfile(0 STREAMS_REL_CC TSRMLS_CC) |
76 | |
77 | #define php_stream_fopen_temporary_file_rel(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_REL_CC TSRMLS_CC) |
78 | |
79 | #define php_stream_open_wrapper_rel(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_REL_CC TSRMLS_CC) |
80 | #define php_stream_open_wrapper_ex_rel(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_REL_CC TSRMLS_CC) |
81 | |
82 | #define php_stream_make_seekable_rel(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_REL_CC TSRMLS_CC) |
83 | |
84 | /* }}} */ |
85 | |
86 | /* The contents of the php_stream_ops and php_stream should only be accessed |
87 | * using the functions/macros in this header. |
88 | * If you need to get at something that doesn't have an API, |
89 | * drop me a line <wez@thebrainroom.com> and we can sort out a way to do |
90 | * it properly. |
91 | * |
92 | * The only exceptions to this rule are that stream implementations can use |
93 | * the php_stream->abstract pointer to hold their context, and streams |
94 | * opened via stream_open_wrappers can use the zval ptr in |
95 | * php_stream->wrapperdata to hold meta data for php scripts to |
96 | * retrieve using file_get_wrapper_data(). */ |
97 | |
98 | typedef struct _php_stream php_stream; |
99 | typedef struct _php_stream_wrapper php_stream_wrapper; |
100 | typedef struct _php_stream_context php_stream_context; |
101 | typedef struct _php_stream_filter php_stream_filter; |
102 | |
103 | #include "streams/php_stream_context.h" |
104 | #include "streams/php_stream_filter_api.h" |
105 | |
106 | typedef struct _php_stream_statbuf { |
107 | struct stat sb; /* regular info */ |
108 | /* extended info to go here some day: content-type etc. etc. */ |
109 | } php_stream_statbuf; |
110 | |
111 | typedef struct _php_stream_dirent { |
112 | char d_name[MAXPATHLEN]; |
113 | } php_stream_dirent; |
114 | |
115 | /* operations on streams that are file-handles */ |
116 | typedef struct _php_stream_ops { |
117 | /* stdio like functions - these are mandatory! */ |
118 | size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC); |
119 | size_t (*read)(php_stream *stream, char *buf, size_t count TSRMLS_DC); |
120 | int (*close)(php_stream *stream, int close_handle TSRMLS_DC); |
121 | int (*flush)(php_stream *stream TSRMLS_DC); |
122 | |
123 | const char *label; /* label for this ops structure */ |
124 | |
125 | /* these are optional */ |
126 | int (*seek)(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC); |
127 | int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); |
128 | int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); |
129 | int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); |
130 | } php_stream_ops; |
131 | |
132 | typedef struct _php_stream_wrapper_ops { |
133 | /* open/create a wrapped stream */ |
134 | php_stream *(*stream_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, |
135 | int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); |
136 | /* close/destroy a wrapped stream */ |
137 | int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); |
138 | /* stat a wrapped stream */ |
139 | int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); |
140 | /* stat a URL */ |
141 | int (*url_stat)(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); |
142 | /* open a "directory" stream */ |
143 | php_stream *(*dir_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, |
144 | int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); |
145 | |
146 | const char *label; |
147 | |
148 | /* delete a file */ |
149 | int (*unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); |
150 | |
151 | /* rename a file */ |
152 | int (*rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); |
153 | |
154 | /* Create/Remove directory */ |
155 | int (*stream_mkdir)(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC); |
156 | int (*stream_rmdir)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); |
157 | /* Metadata handling */ |
158 | int (*stream_metadata)(php_stream_wrapper *wrapper, const char *url, int options, void *value, php_stream_context *context TSRMLS_DC); |
159 | } php_stream_wrapper_ops; |
160 | |
161 | struct _php_stream_wrapper { |
162 | php_stream_wrapper_ops *wops; /* operations the wrapper can perform */ |
163 | void *abstract; /* context for the wrapper */ |
164 | int is_url; /* so that PG(allow_url_fopen) can be respected */ |
165 | }; |
166 | |
167 | #define PHP_STREAM_FLAG_NO_SEEK 1 |
168 | #define PHP_STREAM_FLAG_NO_BUFFER 2 |
169 | |
170 | #define PHP_STREAM_FLAG_EOL_UNIX 0 /* also includes DOS */ |
171 | #define PHP_STREAM_FLAG_DETECT_EOL 4 |
172 | #define PHP_STREAM_FLAG_EOL_MAC 8 |
173 | |
174 | /* set this when the stream might represent "interactive" data. |
175 | * When set, the read buffer will avoid certain operations that |
176 | * might otherwise cause the read to block for much longer than |
177 | * is strictly required. */ |
178 | #define PHP_STREAM_FLAG_AVOID_BLOCKING 16 |
179 | |
180 | #define PHP_STREAM_FLAG_NO_CLOSE 32 |
181 | |
182 | #define PHP_STREAM_FLAG_IS_DIR 64 |
183 | |
184 | #define PHP_STREAM_FLAG_NO_FCLOSE 128 |
185 | |
186 | struct _php_stream { |
187 | php_stream_ops *ops; |
188 | void *abstract; /* convenience pointer for abstraction */ |
189 | |
190 | php_stream_filter_chain readfilters, writefilters; |
191 | |
192 | php_stream_wrapper *wrapper; /* which wrapper was used to open the stream */ |
193 | void *wrapperthis; /* convenience pointer for a instance of a wrapper */ |
194 | zval *wrapperdata; /* fgetwrapperdata retrieves this */ |
195 | |
196 | int fgetss_state; /* for fgetss to handle multiline tags */ |
197 | int is_persistent; |
198 | char mode[16]; /* "rwb" etc. ala stdio */ |
199 | int rsrc_id; /* used for auto-cleanup */ |
200 | int in_free; /* to prevent recursion during free */ |
201 | /* so we know how to clean it up correctly. This should be set to |
202 | * PHP_STREAM_FCLOSE_XXX as appropriate */ |
203 | int fclose_stdiocast; |
204 | FILE *stdiocast; /* cache this, otherwise we might leak! */ |
205 | #if ZEND_DEBUG |
206 | int __exposed; /* non-zero if exposed as a zval somewhere */ |
207 | #endif |
208 | char *orig_path; |
209 | |
210 | php_stream_context *context; |
211 | int flags; /* PHP_STREAM_FLAG_XXX */ |
212 | |
213 | /* buffer */ |
214 | off_t position; /* of underlying stream */ |
215 | unsigned char *readbuf; |
216 | size_t readbuflen; |
217 | off_t readpos; |
218 | off_t writepos; |
219 | |
220 | /* how much data to read when filling buffer */ |
221 | size_t chunk_size; |
222 | |
223 | int eof; |
224 | |
225 | #if ZEND_DEBUG |
226 | const char *open_filename; |
227 | uint open_lineno; |
228 | #endif |
229 | |
230 | struct _php_stream *enclosing_stream; /* this is a private stream owned by enclosing_stream */ |
231 | }; /* php_stream */ |
232 | |
233 | /* state definitions when closing down; these are private to streams.c */ |
234 | #define PHP_STREAM_FCLOSE_NONE 0 |
235 | #define PHP_STREAM_FCLOSE_FDOPEN 1 |
236 | #define PHP_STREAM_FCLOSE_FOPENCOOKIE 2 |
237 | |
238 | /* allocate a new stream for a particular ops */ |
239 | BEGIN_EXTERN_C() |
240 | PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, |
241 | const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC); |
242 | END_EXTERN_C() |
243 | #define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC) |
244 | |
245 | #define php_stream_get_resource_id(stream) ((php_stream *)(stream))->rsrc_id |
246 | #if ZEND_DEBUG |
247 | /* use this to tell the stream that it is OK if we don't explicitly close it */ |
248 | # define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } |
249 | /* use this to assign the stream to a zval and tell the stream that is |
250 | * has been exported to the engine; it will expect to be closed automatically |
251 | * when the resources are auto-destructed */ |
252 | # define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); (stream)->__exposed++; } |
253 | #else |
254 | # define php_stream_auto_cleanup(stream) /* nothing */ |
255 | # define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); } |
256 | #endif |
257 | |
258 | #define php_stream_from_zval(xstr, ppzval) ZEND_FETCH_RESOURCE2((xstr), php_stream *, (ppzval), -1, "stream", php_file_le_stream(), php_file_le_pstream()) |
259 | #define php_stream_from_zval_no_verify(xstr, ppzval) (xstr) = (php_stream*)zend_fetch_resource((ppzval) TSRMLS_CC, -1, "stream", NULL, 2, php_file_le_stream(), php_file_le_pstream()) |
260 | |
261 | BEGIN_EXTERN_C() |
262 | PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed); |
263 | #define php_stream_free_enclosed(stream_enclosed, close_options) _php_stream_free_enclosed((stream_enclosed), (close_options) TSRMLS_CC) |
264 | PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC); |
265 | |
266 | PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC); |
267 | #define PHP_STREAM_PERSISTENT_SUCCESS 0 /* id exists */ |
268 | #define PHP_STREAM_PERSISTENT_FAILURE 1 /* id exists but is not a stream! */ |
269 | #define PHP_STREAM_PERSISTENT_NOT_EXIST 2 /* id does not exist */ |
270 | |
271 | #define PHP_STREAM_FREE_CALL_DTOR 1 /* call ops->close */ |
272 | #define PHP_STREAM_FREE_RELEASE_STREAM 2 /* pefree(stream) */ |
273 | #define PHP_STREAM_FREE_PRESERVE_HANDLE 4 /* tell ops->close to not close it's underlying handle */ |
274 | #define PHP_STREAM_FREE_RSRC_DTOR 8 /* called from the resource list dtor */ |
275 | #define PHP_STREAM_FREE_PERSISTENT 16 /* manually freeing a persistent connection */ |
276 | #define PHP_STREAM_FREE_IGNORE_ENCLOSING 32 /* don't close the enclosing stream instead */ |
277 | #define PHP_STREAM_FREE_CLOSE (PHP_STREAM_FREE_CALL_DTOR | PHP_STREAM_FREE_RELEASE_STREAM) |
278 | #define PHP_STREAM_FREE_CLOSE_CASTED (PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PRESERVE_HANDLE) |
279 | #define PHP_STREAM_FREE_CLOSE_PERSISTENT (PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PERSISTENT) |
280 | |
281 | PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC); |
282 | #define php_stream_free(stream, close_options) _php_stream_free((stream), (close_options) TSRMLS_CC) |
283 | #define php_stream_close(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE TSRMLS_CC) |
284 | #define php_stream_pclose(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE_PERSISTENT TSRMLS_CC) |
285 | |
286 | PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC); |
287 | #define php_stream_rewind(stream) _php_stream_seek((stream), 0L, SEEK_SET TSRMLS_CC) |
288 | #define php_stream_seek(stream, offset, whence) _php_stream_seek((stream), (offset), (whence) TSRMLS_CC) |
289 | |
290 | PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC); |
291 | #define php_stream_tell(stream) _php_stream_tell((stream) TSRMLS_CC) |
292 | |
293 | PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC); |
294 | #define php_stream_read(stream, buf, count) _php_stream_read((stream), (buf), (count) TSRMLS_CC) |
295 | |
296 | PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC); |
297 | #define php_stream_write_string(stream, str) _php_stream_write(stream, str, strlen(str) TSRMLS_CC) |
298 | #define php_stream_write(stream, buf, count) _php_stream_write(stream, (buf), (count) TSRMLS_CC) |
299 | |
300 | PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC); |
301 | #define php_stream_fill_read_buffer(stream, size) _php_stream_fill_read_buffer((stream), (size) TSRMLS_CC) |
302 | |
303 | #ifdef ZTS |
304 | PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); |
305 | #else |
306 | PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); |
307 | #endif |
308 | |
309 | /* php_stream_printf macro & function require TSRMLS_CC */ |
310 | #define php_stream_printf _php_stream_printf |
311 | |
312 | PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC); |
313 | #define php_stream_eof(stream) _php_stream_eof((stream) TSRMLS_CC) |
314 | |
315 | PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC); |
316 | #define php_stream_getc(stream) _php_stream_getc((stream) TSRMLS_CC) |
317 | |
318 | PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC); |
319 | #define php_stream_putc(stream, c) _php_stream_putc((stream), (c) TSRMLS_CC) |
320 | |
321 | PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC); |
322 | #define php_stream_flush(stream) _php_stream_flush((stream), 0 TSRMLS_CC) |
323 | |
324 | PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, size_t *returned_len TSRMLS_DC); |
325 | #define php_stream_gets(stream, buf, maxlen) _php_stream_get_line((stream), (buf), (maxlen), NULL TSRMLS_CC) |
326 | |
327 | #define php_stream_get_line(stream, buf, maxlen, retlen) _php_stream_get_line((stream), (buf), (maxlen), (retlen) TSRMLS_CC) |
328 | PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC); |
329 | |
330 | /* CAREFUL! this is equivalent to puts NOT fputs! */ |
331 | PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC); |
332 | #define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf) TSRMLS_CC) |
333 | |
334 | PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); |
335 | #define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) |
336 | |
337 | PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); |
338 | #define php_stream_stat_path(path, ssb) _php_stream_stat_path((path), 0, (ssb), NULL TSRMLS_CC) |
339 | #define php_stream_stat_path_ex(path, flags, ssb, context) _php_stream_stat_path((path), (flags), (ssb), (context) TSRMLS_CC) |
340 | |
341 | PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC); |
342 | #define php_stream_mkdir(path, mode, options, context) _php_stream_mkdir(path, mode, options, context TSRMLS_CC) |
343 | |
344 | PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC); |
345 | #define php_stream_rmdir(path, options, context) _php_stream_rmdir(path, options, context TSRMLS_CC) |
346 | |
347 | PHPAPI php_stream *_php_stream_opendir(const char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); |
348 | #define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC) |
349 | PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC); |
350 | #define php_stream_readdir(dirstream, dirent) _php_stream_readdir((dirstream), (dirent) TSRMLS_CC) |
351 | #define php_stream_closedir(dirstream) php_stream_close((dirstream)) |
352 | #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) |
353 | |
354 | PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b); |
355 | PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b); |
356 | |
357 | PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, |
358 | int (*compare) (const char **a, const char **b) TSRMLS_DC); |
359 | #define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare) TSRMLS_CC) |
360 | |
361 | PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); |
362 | #define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) |
363 | |
364 | #define php_stream_set_chunk_size(stream, size) _php_stream_set_option((stream), PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL TSRMLS_CC) |
365 | |
366 | END_EXTERN_C() |
367 | |
368 | |
369 | /* Flags for mkdir method in wrapper ops */ |
370 | #define PHP_STREAM_MKDIR_RECURSIVE 1 |
371 | /* define REPORT ERRORS 8 (below) */ |
372 | |
373 | /* Flags for rmdir method in wrapper ops */ |
374 | /* define REPORT_ERRORS 8 (below) */ |
375 | |
376 | /* Flags for url_stat method in wrapper ops */ |
377 | #define PHP_STREAM_URL_STAT_LINK 1 |
378 | #define PHP_STREAM_URL_STAT_QUIET 2 |
379 | #define PHP_STREAM_URL_STAT_NOCACHE 4 |
380 | |
381 | /* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */ |
382 | #define PHP_STREAM_OPTION_BLOCKING 1 |
383 | |
384 | /* change the buffering mode of stream. value is a PHP_STREAM_BUFFER_XXXX value, ptrparam is a ptr to a size_t holding |
385 | * the required buffer size */ |
386 | #define PHP_STREAM_OPTION_READ_BUFFER 2 |
387 | #define PHP_STREAM_OPTION_WRITE_BUFFER 3 |
388 | |
389 | #define PHP_STREAM_BUFFER_NONE 0 /* unbuffered */ |
390 | #define PHP_STREAM_BUFFER_LINE 1 /* line buffered */ |
391 | #define PHP_STREAM_BUFFER_FULL 2 /* fully buffered */ |
392 | |
393 | /* set the timeout duration for reads on the stream. ptrparam is a pointer to a struct timeval * */ |
394 | #define PHP_STREAM_OPTION_READ_TIMEOUT 4 |
395 | #define PHP_STREAM_OPTION_SET_CHUNK_SIZE 5 |
396 | |
397 | /* set or release lock on a stream */ |
398 | #define PHP_STREAM_OPTION_LOCKING 6 |
399 | |
400 | /* whether or not locking is supported */ |
401 | #define PHP_STREAM_LOCK_SUPPORTED 1 |
402 | |
403 | #define php_stream_supports_lock(stream) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, 0, (void *) PHP_STREAM_LOCK_SUPPORTED TSRMLS_CC) == 0 ? 1 : 0 |
404 | #define php_stream_lock(stream, mode) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, (mode), (void *) NULL TSRMLS_CC) |
405 | |
406 | /* option code used by the php_stream_xport_XXX api */ |
407 | #define PHP_STREAM_OPTION_XPORT_API 7 /* see php_stream_transport.h */ |
408 | #define PHP_STREAM_OPTION_CRYPTO_API 8 /* see php_stream_transport.h */ |
409 | #define PHP_STREAM_OPTION_MMAP_API 9 /* see php_stream_mmap.h */ |
410 | #define PHP_STREAM_OPTION_TRUNCATE_API 10 |
411 | |
412 | #define PHP_STREAM_TRUNCATE_SUPPORTED 0 |
413 | #define PHP_STREAM_TRUNCATE_SET_SIZE 1 /* ptrparam is a pointer to a size_t */ |
414 | |
415 | #define php_stream_truncate_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SUPPORTED, NULL TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) |
416 | |
417 | BEGIN_EXTERN_C() |
418 | PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize TSRMLS_DC); |
419 | #define php_stream_truncate_set_size(stream, size) _php_stream_truncate_set_size((stream), (size) TSRMLS_CC) |
420 | END_EXTERN_C() |
421 | |
422 | #define PHP_STREAM_OPTION_META_DATA_API 11 /* ptrparam is a zval* to which to add meta data information */ |
423 | #define php_stream_populate_meta_data(stream, zv) (_php_stream_set_option((stream), PHP_STREAM_OPTION_META_DATA_API, 0, zv TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) |
424 | |
425 | /* Check if the stream is still "live"; for sockets/pipes this means the socket |
426 | * is still connected; for files, this does not really have meaning */ |
427 | #define PHP_STREAM_OPTION_CHECK_LIVENESS 12 /* no parameters */ |
428 | |
429 | #define PHP_STREAM_OPTION_RETURN_OK 0 /* option set OK */ |
430 | #define PHP_STREAM_OPTION_RETURN_ERR -1 /* problem setting option */ |
431 | #define PHP_STREAM_OPTION_RETURN_NOTIMPL -2 /* underlying stream does not implement; streams can handle it instead */ |
432 | |
433 | /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, |
434 | * copy until eof(src). */ |
435 | #define PHP_STREAM_COPY_ALL ((size_t)-1) |
436 | |
437 | BEGIN_EXTERN_C() |
438 | ZEND_ATTRIBUTE_DEPRECATED |
439 | PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC); |
440 | #define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC) |
441 | PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC); |
442 | #define php_stream_copy_to_stream_ex(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC) |
443 | |
444 | |
445 | /* read all data from stream and put into a buffer. Caller must free buffer |
446 | * when done. */ |
447 | PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, |
448 | int persistent STREAMS_DC TSRMLS_DC); |
449 | #define php_stream_copy_to_mem(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_CC TSRMLS_CC) |
450 | |
451 | /* output all data from a stream */ |
452 | PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC TSRMLS_DC); |
453 | #define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC TSRMLS_CC) |
454 | END_EXTERN_C() |
455 | |
456 | #include "streams/php_stream_transport.h" |
457 | #include "streams/php_stream_plain_wrapper.h" |
458 | #include "streams/php_stream_glob_wrapper.h" |
459 | #include "streams/php_stream_userspace.h" |
460 | #include "streams/php_stream_mmap.h" |
461 | |
462 | /* coerce the stream into some other form */ |
463 | /* cast as a stdio FILE * */ |
464 | #define PHP_STREAM_AS_STDIO 0 |
465 | /* cast as a POSIX fd or socketd */ |
466 | #define PHP_STREAM_AS_FD 1 |
467 | /* cast as a socketd */ |
468 | #define PHP_STREAM_AS_SOCKETD 2 |
469 | /* cast as fd/socket for select purposes */ |
470 | #define PHP_STREAM_AS_FD_FOR_SELECT 3 |
471 | |
472 | /* try really, really hard to make sure the cast happens (avoid using this flag if possible) */ |
473 | #define PHP_STREAM_CAST_TRY_HARD 0x80000000 |
474 | #define PHP_STREAM_CAST_RELEASE 0x40000000 /* stream becomes invalid on success */ |
475 | #define PHP_STREAM_CAST_INTERNAL 0x20000000 /* stream cast for internal use */ |
476 | #define PHP_STREAM_CAST_MASK (PHP_STREAM_CAST_TRY_HARD | PHP_STREAM_CAST_RELEASE | PHP_STREAM_CAST_INTERNAL) |
477 | BEGIN_EXTERN_C() |
478 | PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err TSRMLS_DC); |
479 | END_EXTERN_C() |
480 | /* use this to check if a stream can be cast into another form */ |
481 | #define php_stream_can_cast(stream, as) _php_stream_cast((stream), (as), NULL, 0 TSRMLS_CC) |
482 | #define php_stream_cast(stream, as, ret, show_err) _php_stream_cast((stream), (as), (ret), (show_err) TSRMLS_CC) |
483 | |
484 | /* use this to check if a stream is of a particular type: |
485 | * PHPAPI int php_stream_is(php_stream *stream, php_stream_ops *ops); */ |
486 | #define php_stream_is(stream, anops) ((stream)->ops == anops) |
487 | #define PHP_STREAM_IS_STDIO &php_stream_stdio_ops |
488 | |
489 | #define php_stream_is_persistent(stream) (stream)->is_persistent |
490 | |
491 | /* Wrappers support */ |
492 | |
493 | #define IGNORE_PATH 0x00000000 |
494 | #define USE_PATH 0x00000001 |
495 | #define IGNORE_URL 0x00000002 |
496 | #define REPORT_ERRORS 0x00000008 |
497 | #define ENFORCE_SAFE_MODE 0 /* for BC only */ |
498 | |
499 | /* If you don't need to write to the stream, but really need to |
500 | * be able to seek, use this flag in your options. */ |
501 | #define STREAM_MUST_SEEK 0x00000010 |
502 | /* If you are going to end up casting the stream into a FILE* or |
503 | * a socket, pass this flag and the streams/wrappers will not use |
504 | * buffering mechanisms while reading the headers, so that HTTP |
505 | * wrapped streams will work consistently. |
506 | * If you omit this flag, streams will use buffering and should end |
507 | * up working more optimally. |
508 | * */ |
509 | #define STREAM_WILL_CAST 0x00000020 |
510 | |
511 | /* this flag applies to php_stream_locate_url_wrapper */ |
512 | #define STREAM_LOCATE_WRAPPERS_ONLY 0x00000040 |
513 | |
514 | /* this flag is only used by include/require functions */ |
515 | #define STREAM_OPEN_FOR_INCLUDE 0x00000080 |
516 | |
517 | /* this flag tells streams to ONLY open urls */ |
518 | #define STREAM_USE_URL 0x00000100 |
519 | |
520 | /* this flag is used when only the headers from HTTP request are to be fetched */ |
521 | #define 0x00000200 |
522 | |
523 | /* don't apply open_basedir checks */ |
524 | #define STREAM_DISABLE_OPEN_BASEDIR 0x00000400 |
525 | |
526 | /* get (or create) a persistent version of the stream */ |
527 | #define STREAM_OPEN_PERSISTENT 0x00000800 |
528 | |
529 | /* use glob stream for directory open in plain files stream */ |
530 | #define STREAM_USE_GLOB_DIR_OPEN 0x00001000 |
531 | |
532 | /* don't check allow_url_fopen and allow_url_include */ |
533 | #define STREAM_DISABLE_URL_PROTECTION 0x00002000 |
534 | |
535 | /* assume the path passed in exists and is fully expanded, avoiding syscalls */ |
536 | #define STREAM_ASSUME_REALPATH 0x00004000 |
537 | |
538 | /* Antique - no longer has meaning */ |
539 | #define IGNORE_URL_WIN 0 |
540 | |
541 | int php_init_stream_wrappers(int module_number TSRMLS_DC); |
542 | int php_shutdown_stream_wrappers(int module_number TSRMLS_DC); |
543 | void php_shutdown_stream_hashes(TSRMLS_D); |
544 | PHP_RSHUTDOWN_FUNCTION(streams); |
545 | |
546 | BEGIN_EXTERN_C() |
547 | PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); |
548 | PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC); |
549 | PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); |
550 | PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC); |
551 | PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); |
552 | PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC); |
553 | PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC); |
554 | |
555 | #define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC TSRMLS_CC) |
556 | #define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC TSRMLS_CC) |
557 | |
558 | #define php_stream_get_from_zval(stream, zstream, mode, options, opened, context) \ |
559 | if (Z_TYPE_PP((zstream)) == IS_RESOURCE) { \ |
560 | php_stream_from_zval((stream), (zstream)); \ |
561 | } else (stream) = Z_TYPE_PP((zstream)) == IS_STRING ? \ |
562 | php_stream_open_wrapper_ex(Z_STRVAL_PP((zstream)), (mode), (options), (opened), (context)) : NULL |
563 | |
564 | /* pushes an error message onto the stack for a wrapper instance */ |
565 | #ifdef ZTS |
566 | PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); |
567 | #else |
568 | PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); |
569 | #endif |
570 | |
571 | #define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ |
572 | #define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ |
573 | #define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ |
574 | #define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ |
575 | #define PHP_STREAM_NO_PREFERENCE 0 |
576 | #define PHP_STREAM_PREFER_STDIO 1 |
577 | #define PHP_STREAM_FORCE_CONVERSION 2 |
578 | /* DO NOT call this on streams that are referenced by resources! */ |
579 | PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC); |
580 | #define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC TSRMLS_CC) |
581 | |
582 | /* Give other modules access to the url_stream_wrappers_hash and stream_filters_hash */ |
583 | PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D); |
584 | #define php_stream_get_url_stream_wrappers_hash() _php_stream_get_url_stream_wrappers_hash(TSRMLS_C) |
585 | PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void); |
586 | PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D); |
587 | #define php_get_stream_filters_hash() _php_get_stream_filters_hash(TSRMLS_C) |
588 | PHPAPI HashTable *php_get_stream_filters_hash_global(void); |
589 | extern php_stream_wrapper_ops *php_stream_user_wrapper_ops; |
590 | END_EXTERN_C() |
591 | #endif |
592 | |
593 | /* Definitions for user streams */ |
594 | #define PHP_STREAM_IS_URL 1 |
595 | |
596 | /* Stream metadata definitions */ |
597 | /* Create if referred resource does not exist */ |
598 | #define PHP_STREAM_META_TOUCH 1 |
599 | #define PHP_STREAM_META_OWNER_NAME 2 |
600 | #define PHP_STREAM_META_OWNER 3 |
601 | #define PHP_STREAM_META_GROUP_NAME 4 |
602 | #define PHP_STREAM_META_GROUP 5 |
603 | #define PHP_STREAM_META_ACCESS 6 |
604 | /* |
605 | * Local variables: |
606 | * tab-width: 4 |
607 | * c-basic-offset: 4 |
608 | * End: |
609 | * vim600: sw=4 ts=4 fdm=marker |
610 | * vim<600: sw=4 ts=4 |
611 | */ |
612 | |