cvs: php4 /ext/standard file.c /main network.c php_network.h php_streams.h streams.c
| From: | Wez Furlong | Date: | Mon, 19 Aug 2002 22:59:10 +0000 |
| Subject: | cvs: php4 /ext/standard file.c /main network.c php_network.h php_streams.h streams.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-13478@lists.php.net to get a copy of this message | ||
wez Mon Aug 19 18:59:10 2002 EDT
Modified files:
/php4/ext/standard file.c
/php4/main network.c php_network.h php_streams.h streams.c
Log:
Remove php_stream_sock_set_blocking and replace with
php_stream_set_option which can be used in a similar way as ioctl()
to set options for streams.
Current options include buffering and blocking support.
o Buffer control is support for stdio based streams.
o Blocking/non-blocking is supported for stdio and socket based streams.
Index: php4/ext/standard/file.c diff -u php4/ext/standard/file.c:1.244 php4/ext/standard/file.c:1.245 --- php4/ext/standard/file.c:1.244 Sun Aug 18 03:54:33 2002 +++ php4/ext/standard/file.c Mon Aug 19 18:59:09 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.244 2002/08/18 07:54:33 iliaa Exp $ */ +/* $Id: file.c,v 1.245 2002/08/19 22:59:09 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -957,7 +957,7 @@ /* }}} */ /* {{{ proto bool socket_set_blocking(resource socket, int mode) - Set blocking/non-blocking mode on a socket */ + Set blocking/non-blocking mode on a socket or stream */ PHP_FUNCTION(socket_set_blocking) { zval **arg1, **arg2; @@ -974,11 +974,9 @@ convert_to_long_ex(arg2); block = Z_LVAL_PP(arg2); - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - php_stream_sock_set_blocking((php_stream*)what, block == 0 ? 0 : 1 TSRMLS_CC); - RETURN_TRUE; - } - RETURN_FALSE; + if (php_stream_set_option((php_stream*)what, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1) + RETURN_FALSE; + RETURN_TRUE; } /* }}} */ @@ -1344,9 +1342,9 @@ PHP_FUNCTION(set_file_buffer) { zval **arg1, **arg2; - int ret, type, buff; + int ret, type; + size_t buff; php_stream *stream; - FILE * fp; switch (ZEND_NUM_ARGS()) { case 2: @@ -1359,21 +1357,18 @@ /* NOTREACHED */ break; } - + stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); ZEND_VERIFY_RESOURCE(stream); - if (!php_stream_is(stream, PHP_STREAM_IS_STDIO) || FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) { - RETURN_FALSE; - } convert_to_long_ex(arg2); buff = Z_LVAL_PP(arg2); /* if buff is 0 then set to non-buffered */ - if (buff == 0){ - ret = setvbuf(fp, NULL, _IONBF, 0); + if (buff == 0) { + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } else { - ret = setvbuf(fp, NULL, _IOFBF, buff); + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); } RETURN_LONG(ret); Index: php4/main/network.c diff -u php4/main/network.c:1.60 php4/main/network.c:1.61 --- php4/main/network.c:1.60 Sat Aug 17 09:56:39 2002 +++ php4/main/network.c Mon Aug 19 18:59:10 2002 @@ -13,9 +13,10 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stig Venaas <venaas@uninett.no> | + | Streams work by Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.60 2002/08/17 13:56:39 venaas Exp $ */ +/* $Id: network.c,v 1.61 2002/08/19 22:59:10 wez Exp $ */ /*#define DEBUG_MAIN_NETWORK 1*/ #define MAX_CHUNKS_PER_READ 10 @@ -668,28 +669,6 @@ return ret; } -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC) -{ - int oldmode; - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) - return 0; - - oldmode = sock->is_blocked; - - /* no need to change anything */ - if (mode == oldmode) - return oldmode; - - if (SUCCESS == php_set_sock_blocking(sock->socket, mode TSRMLS_CC)) { - sock->is_blocked = mode; - return oldmode; - } - - return -1; -} - PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC) { size_t oldsize; @@ -887,9 +866,9 @@ * socket is still active, try to read a chunk of data, * but lets not block. */ sock->timeout_event = 0; - save_blocked = php_stream_sock_set_blocking(stream, 1 TSRMLS_CC); + save_blocked = php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, 0, NULL); php_sock_stream_read_internal(stream, sock TSRMLS_CC); - php_stream_sock_set_blocking(stream, save_blocked TSRMLS_CC); + php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, save_blocked, NULL); if (sock->eof) return EOF; @@ -961,6 +940,32 @@ return fstat(sock->socket, &ssb->sb); } +static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + int oldmode; + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + + oldmode = sock->is_blocked; + + /* no need to change anything */ + if (value == oldmode) + return oldmode; + + if (SUCCESS == php_set_sock_blocking(sock->socket, value TSRMLS_CC)) { + sock->is_blocked = value; + return oldmode; + } + + return -1; + + default: + return -1; + } +} + static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -1065,7 +1070,8 @@ "socket", NULL, php_sockop_gets, php_sockop_cast, - php_sockop_stat + php_sockop_stat, + php_sockop_set_option }; Index: php4/main/php_network.h diff -u php4/main/php_network.h:1.23 php4/main/php_network.h:1.24 --- php4/main/php_network.h:1.23 Mon Jul 22 14:46:26 2002 +++ php4/main/php_network.h Mon Aug 19 18:59:10 2002 @@ -15,7 +15,7 @@ | Author: Stig Venaas <venaas@uninett.no> | +----------------------------------------------------------------------+ */ -/* $Id: php_network.h,v 1.23 2002/07/22 18:46:26 jason Exp $ */ +/* $Id: php_network.h,v 1.24 2002/08/19 22:59:10 wez Exp $ */ #ifndef _PHP_NETWORK_H #define _PHP_NETWORK_H @@ -144,7 +144,6 @@ /* }}} */ PHPAPI void php_stream_sock_set_timeout(php_stream *stream, struct timeval *timeout TSRMLS_DC); -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC); /* set the chunk size for the stream; return the old chunk size */ PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC); Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.37 php4/main/php_streams.h:1.38 --- php4/main/php_streams.h:1.37 Fri Aug 16 05:50:23 2002 +++ php4/main/php_streams.h Mon Aug 19 18:59:10 2002 @@ -101,7 +101,7 @@ typedef struct _php_stream_statbuf { struct stat sb; /* regular info */ - /* extended info to go here some day */ + /* extended info to go here some day: content-type etc. etc. */ } php_stream_statbuf; typedef struct _php_stream_dirent { @@ -147,6 +147,7 @@ char *(*gets)(php_stream *stream, char *buf, size_t size TSRMLS_DC); int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); } php_stream_ops; typedef struct _php_stream_wrapper_ops { @@ -283,6 +284,19 @@ #define php_stream_closedir(dirstream) php_stream_close((dirstream)) #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); +#define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) + +/* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */ +#define PHP_STREAM_OPTION_BLOCKING 1 + +/* change the buffering mode of stream. value is a PHP_STREAM_BUFFER_XXXX value, ptrparam is a ptr to a size_t holding + * the required buffer size */ +#define PHP_STREAM_OPTION_BUFFER 2 + +#define PHP_STREAM_BUFFER_NONE 0 /* unbuffered */ +#define PHP_STREAM_BUFFER_LINE 1 /* line buffered */ +#define PHP_STREAM_BUFFER_FULL 2 /* fully buffered */ /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ @@ -419,6 +433,7 @@ PHPAPI php_stream_notifier *php_stream_notification_alloc(void); PHPAPI void php_stream_notification_free(php_stream_notifier *notifier); +/* not all notification codes are implemented */ #define PHP_STREAM_NOTIFY_RESOLVE 1 #define PHP_STREAM_NOTIFY_CONNECT 2 #define PHP_STREAM_NOTIFY_AUTH_REQUIRED 3 Index: php4/main/streams.c diff -u php4/main/streams.c:1.62 php4/main/streams.c:1.63 --- php4/main/streams.c:1.62 Fri Aug 16 08:02:42 2002 +++ php4/main/streams.c Mon Aug 19 18:59:10 2002 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.62 2002/08/16 12:02:42 wez Exp $ */ +/* $Id: streams.c,v 1.63 2002/08/19 22:59:10 wez Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -33,6 +33,8 @@ #include <sys/mman.h> #endif +#include <fcntl.h> + #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif @@ -311,6 +313,13 @@ return -1; } +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + if (stream->ops->set_option) + return stream->ops->set_option(stream, option, value, ptrparam TSRMLS_CC); + return -1; +} + PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) { size_t bcount = 0; @@ -742,13 +751,68 @@ return fstat(fd, &ssb->sb); } +static int php_stdiop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; + size_t size; + int fd; + int flags; + int oldval; + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + fd = fileno(data->file); + + if (fd == -1) + return -1; +#ifdef O_NONBLOCK + flags = fcntl(fd, F_GETFL, 0); + oldval = (flags & O_NONBLOCK) ? 0 : 1; + if (value) + flags ^= O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (-1 == fcntl(fd, F_SETFL, flags)) + return -1; + return oldval; +#else + return -1; /* not yet implemented */ +#endif + + case PHP_STREAM_OPTION_BUFFER: + if (ptrparam) + size = *(size_t *)ptrparam; + else + size = BUFSIZ; + + switch(value) { + case PHP_STREAM_BUFFER_NONE: + return setvbuf(data->file, NULL, _IONBF, 0); + + case PHP_STREAM_BUFFER_LINE: + return setvbuf(data->file, NULL, _IOLBF, size); + + case PHP_STREAM_BUFFER_FULL: + return setvbuf(data->file, NULL, _IOFBF, size); + + default: + return -1; + } + break; + default: + return -1; + } +} + PHPAPI php_stream_ops php_stream_stdio_ops = { php_stdiop_write, php_stdiop_read, php_stdiop_close, php_stdiop_flush, "STDIO", php_stdiop_seek, php_stdiop_gets, php_stdiop_cast, - php_stdiop_stat + php_stdiop_stat, + php_stdiop_set_option }; /* }}} */
Index: php4/ext/standard/file.c diff -u php4/ext/standard/file.c:1.244 php4/ext/standard/file.c:1.245 --- php4/ext/standard/file.c:1.244 Sun Aug 18 03:54:33 2002 +++ php4/ext/standard/file.c Mon Aug 19 18:59:09 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.244 2002/08/18 07:54:33 iliaa Exp $ */ +/* $Id: file.c,v 1.245 2002/08/19 22:59:09 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -957,7 +957,7 @@ /* }}} */ /* {{{ proto bool socket_set_blocking(resource socket, int mode) - Set blocking/non-blocking mode on a socket */ + Set blocking/non-blocking mode on a socket or stream */ PHP_FUNCTION(socket_set_blocking) { zval **arg1, **arg2; @@ -974,11 +974,9 @@ convert_to_long_ex(arg2); block = Z_LVAL_PP(arg2); - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - php_stream_sock_set_blocking((php_stream*)what, block == 0 ? 0 : 1 TSRMLS_CC); - RETURN_TRUE; - } - RETURN_FALSE; + if (php_stream_set_option((php_stream*)what, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1) + RETURN_FALSE; + RETURN_TRUE; } /* }}} */ @@ -1344,9 +1342,9 @@ PHP_FUNCTION(set_file_buffer) { zval **arg1, **arg2; - int ret, type, buff; + int ret, type; + size_t buff; php_stream *stream; - FILE * fp; switch (ZEND_NUM_ARGS()) { case 2: @@ -1359,21 +1357,18 @@ /* NOTREACHED */ break; } - + stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); ZEND_VERIFY_RESOURCE(stream); - if (!php_stream_is(stream, PHP_STREAM_IS_STDIO) || FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) { - RETURN_FALSE; - } convert_to_long_ex(arg2); buff = Z_LVAL_PP(arg2); /* if buff is 0 then set to non-buffered */ - if (buff == 0){ - ret = setvbuf(fp, NULL, _IONBF, 0); + if (buff == 0) { + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } else { - ret = setvbuf(fp, NULL, _IOFBF, buff); + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); } RETURN_LONG(ret); Index: php4/main/network.c diff -u php4/main/network.c:1.60 php4/main/network.c:1.61 --- php4/main/network.c:1.60 Sat Aug 17 09:56:39 2002 +++ php4/main/network.c Mon Aug 19 18:59:10 2002 @@ -13,9 +13,10 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stig Venaas <venaas@uninett.no> | + | Streams work by Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.60 2002/08/17 13:56:39 venaas Exp $ */ +/* $Id: network.c,v 1.61 2002/08/19 22:59:10 wez Exp $ */ /*#define DEBUG_MAIN_NETWORK 1*/ #define MAX_CHUNKS_PER_READ 10 @@ -668,28 +669,6 @@ return ret; } -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC) -{ - int oldmode; - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) - return 0; - - oldmode = sock->is_blocked; - - /* no need to change anything */ - if (mode == oldmode) - return oldmode; - - if (SUCCESS == php_set_sock_blocking(sock->socket, mode TSRMLS_CC)) { - sock->is_blocked = mode; - return oldmode; - } - - return -1; -} - PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC) { size_t oldsize; @@ -887,9 +866,9 @@ * socket is still active, try to read a chunk of data, * but lets not block. */ sock->timeout_event = 0; - save_blocked = php_stream_sock_set_blocking(stream, 1 TSRMLS_CC); + save_blocked = php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, 0, NULL); php_sock_stream_read_internal(stream, sock TSRMLS_CC); - php_stream_sock_set_blocking(stream, save_blocked TSRMLS_CC); + php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, save_blocked, NULL); if (sock->eof) return EOF; @@ -961,6 +940,32 @@ return fstat(sock->socket, &ssb->sb); } +static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + int oldmode; + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + + oldmode = sock->is_blocked; + + /* no need to change anything */ + if (value == oldmode) + return oldmode; + + if (SUCCESS == php_set_sock_blocking(sock->socket, value TSRMLS_CC)) { + sock->is_blocked = value; + return oldmode; + } + + return -1; + + default: + return -1; + } +} + static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -1065,7 +1070,8 @@ "socket", NULL, php_sockop_gets, php_sockop_cast, - php_sockop_stat + php_sockop_stat, + php_sockop_set_option }; Index: php4/main/php_network.h diff -u php4/main/php_network.h:1.23 php4/main/php_network.h:1.24 --- php4/main/php_network.h:1.23 Mon Jul 22 14:46:26 2002 +++ php4/main/php_network.h Mon Aug 19 18:59:10 2002 @@ -15,7 +15,7 @@ | Author: Stig Venaas <venaas@uninett.no> | +----------------------------------------------------------------------+ */ -/* $Id: php_network.h,v 1.23 2002/07/22 18:46:26 jason Exp $ */ +/* $Id: php_network.h,v 1.24 2002/08/19 22:59:10 wez Exp $ */ #ifndef _PHP_NETWORK_H #define _PHP_NETWORK_H @@ -144,7 +144,6 @@ /* }}} */ PHPAPI void php_stream_sock_set_timeout(php_stream *stream, struct timeval *timeout TSRMLS_DC); -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC); /* set the chunk size for the stream; return the old chunk size */ PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC); Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.37 php4/main/php_streams.h:1.38 --- php4/main/php_streams.h:1.37 Fri Aug 16 05:50:23 2002 +++ php4/main/php_streams.h Mon Aug 19 18:59:10 2002 @@ -101,7 +101,7 @@ typedef struct _php_stream_statbuf { struct stat sb; /* regular info */ - /* extended info to go here some day */ + /* extended info to go here some day: content-type etc. etc. */ } php_stream_statbuf; typedef struct _php_stream_dirent { @@ -147,6 +147,7 @@ char *(*gets)(php_stream *stream, char *buf, size_t size TSRMLS_DC); int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); } php_stream_ops; typedef struct _php_stream_wrapper_ops { @@ -283,6 +284,19 @@ #define php_stream_closedir(dirstream) php_stream_close((dirstream)) #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); +#define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) + +/* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */ +#define PHP_STREAM_OPTION_BLOCKING 1 + +/* change the buffering mode of stream. value is a PHP_STREAM_BUFFER_XXXX value, ptrparam is a ptr to a size_t holding + * the required buffer size */ +#define PHP_STREAM_OPTION_BUFFER 2 + +#define PHP_STREAM_BUFFER_NONE 0 /* unbuffered */ +#define PHP_STREAM_BUFFER_LINE 1 /* line buffered */ +#define PHP_STREAM_BUFFER_FULL 2 /* fully buffered */ /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ @@ -419,6 +433,7 @@ PHPAPI php_stream_notifier *php_stream_notification_alloc(void); PHPAPI void php_stream_notification_free(php_stream_notifier *notifier); +/* not all notification codes are implemented */ #define PHP_STREAM_NOTIFY_RESOLVE 1 #define PHP_STREAM_NOTIFY_CONNECT 2 #define PHP_STREAM_NOTIFY_AUTH_REQUIRED 3 Index: php4/main/streams.c diff -u php4/main/streams.c:1.62 php4/main/streams.c:1.63 --- php4/main/streams.c:1.62 Fri Aug 16 08:02:42 2002 +++ php4/main/streams.c Mon Aug 19 18:59:10 2002 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.62 2002/08/16 12:02:42 wez Exp $ */ +/* $Id: streams.c,v 1.63 2002/08/19 22:59:10 wez Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -33,6 +33,8 @@ #include <sys/mman.h> #endif +#include <fcntl.h> + #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif @@ -311,6 +313,13 @@ return -1; } +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + if (stream->ops->set_option) + return stream->ops->set_option(stream, option, value, ptrparam TSRMLS_CC); + return -1; +} + PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) { size_t bcount = 0; @@ -742,13 +751,68 @@ return fstat(fd, &ssb->sb); } +static int php_stdiop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; + size_t size; + int fd; + int flags; + int oldval; + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + fd = fileno(data->file); + + if (fd == -1) + return -1; +#ifdef O_NONBLOCK + flags = fcntl(fd, F_GETFL, 0); + oldval = (flags & O_NONBLOCK) ? 0 : 1; + if (value) + flags ^= O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (-1 == fcntl(fd, F_SETFL, flags)) + return -1; + return oldval; +#else + return -1; /* not yet implemented */ +#endif + + case PHP_STREAM_OPTION_BUFFER: + if (ptrparam) + size = *(size_t *)ptrparam; + else + size = BUFSIZ; + + switch(value) { + case PHP_STREAM_BUFFER_NONE: + return setvbuf(data->file, NULL, _IONBF, 0); + + case PHP_STREAM_BUFFER_LINE: + return setvbuf(data->file, NULL, _IOLBF, size); + + case PHP_STREAM_BUFFER_FULL: + return setvbuf(data->file, NULL, _IOFBF, size); + + default: + return -1; + } + break; + default: + return -1; + } +} + PHPAPI php_stream_ops php_stream_stdio_ops = { php_stdiop_write, php_stdiop_read, php_stdiop_close, php_stdiop_flush, "STDIO", php_stdiop_seek, php_stdiop_gets, php_stdiop_cast, - php_stdiop_stat + php_stdiop_stat, + php_stdiop_set_option }; /* }}} */