]> granicus.if.org Git - php/commitdiff
Remove php_stream_sock_set_blocking and replace with
authorWez Furlong <wez@php.net>
Mon, 19 Aug 2002 22:59:10 +0000 (22:59 +0000)
committerWez Furlong <wez@php.net>
Mon, 19 Aug 2002 22:59:10 +0000 (22:59 +0000)
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.

ext/standard/file.c
main/network.c
main/php_network.h
main/php_streams.h
main/streams.c

index 15c2e902c487171205c27a3893094790c94296f0..0404fa0a1b683c8f90d077df969af25c903d3439 100644 (file)
@@ -957,7 +957,7 @@ PHPAPI PHP_FUNCTION(feof)
 /* }}} */
 
 /* {{{ 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 @@ PHP_FUNCTION(socket_set_blocking)
        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 @@ PHPAPI PHP_FUNCTION(fflush)
 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 @@ PHP_FUNCTION(set_file_buffer)
                /* 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 3fe7e9a152dd8217b390170c7ac06566b9cb59dc..769fe2a8c448fffda743777c0f745e042605b4db 100644 (file)
@@ -13,6 +13,7 @@
    | 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$ */
@@ -668,28 +669,6 @@ PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC)
       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 @@ DUMP_SOCK_STATE("check for EOF", sock);
                 * 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 @@ static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC
        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 @@ php_stream_ops php_stream_socket_ops = {
        "socket",
        NULL, php_sockop_gets,
        php_sockop_cast,
-       php_sockop_stat
+       php_sockop_stat,
+       php_sockop_set_option
 };
 
 
index 70e7ad5a9c35597120650e4ff052a5f2dce2bf68..56ec549d0b7f2a83925bb8da42b1f382724b1d2f 100644 (file)
@@ -144,7 +144,6 @@ PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int
 /* }}} */
 
 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 3b83d2638f58335601ef05133a5b14911195ea80..e226d93195bc95f0f0cc59483dd989adaab5ec14 100755 (executable)
@@ -101,7 +101,7 @@ typedef void (*php_stream_notification_func)(php_stream_context *context,
 
 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 @@ typedef struct _php_stream_ops  {
        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 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_
 #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 int php_stream_context_set_option(php_stream_context *context,
 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 3b05145043c4450bbda0b5bb5f39dafe33915932..50b2099d63c13a58629abe4c4b1ad546678dd7ee 100755 (executable)
@@ -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 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
        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 @@ static int php_stdiop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC
        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
 };
 /* }}} */