diff options
Diffstat (limited to 'main/streams')
| -rw-r--r-- | main/streams/glob_wrapper.c | 4 | ||||
| -rw-r--r-- | main/streams/memory.c | 10 | ||||
| -rw-r--r-- | main/streams/plain_wrapper.c | 34 | ||||
| -rw-r--r-- | main/streams/streams.c | 181 | ||||
| -rw-r--r-- | main/streams/userspace.c | 29 | ||||
| -rw-r--r-- | main/streams/xp_socket.c | 26 |
6 files changed, 176 insertions, 108 deletions
diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index 0386d72255..0e72558a2a 100644 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -127,7 +127,7 @@ static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int ge } /* }}} */ -static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */ +static ssize_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; php_stream_dirent *ent = (php_stream_dirent*)buf; @@ -147,7 +147,7 @@ static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) } } - return 0; + return -1; } /* }}} */ diff --git a/main/streams/memory.c b/main/streams/memory.c index b63ed77255..4b92fc2ffd 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -44,13 +44,13 @@ typedef struct { /* {{{ */ -static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count) +static ssize_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); if (ms->mode & TEMP_STREAM_READONLY) { - return 0; + return (ssize_t) -1; } else if (ms->mode & TEMP_STREAM_APPEND) { ms->fpos = ms->fsize; } @@ -77,7 +77,7 @@ static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_ /* {{{ */ -static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_stream_memory_read(php_stream *stream, char *buf, size_t count) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); @@ -368,7 +368,7 @@ typedef struct { /* {{{ */ -static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count) +static ssize_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; assert(ts != NULL); @@ -398,7 +398,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t /* {{{ */ -static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_stream_temp_read(php_stream *stream, char *buf, size_t count) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; size_t got; diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 83681c0d88..3c6a9afb28 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -335,7 +335,7 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE return stream; } -static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count) +static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t count) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; @@ -343,16 +343,15 @@ static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count if (data->fd >= 0) { #ifdef PHP_WIN32 - int bytes_written; + ssize_t bytes_written; if (ZEND_SIZE_T_UINT_OVFL(count)) { count = UINT_MAX; } bytes_written = _write(data->fd, buf, (unsigned int)count); #else - int bytes_written = write(data->fd, buf, count); + ssize_t bytes_written = write(data->fd, buf, count); #endif - if (bytes_written < 0) return 0; - return (size_t) bytes_written; + return bytes_written; } else { #if HAVE_FLUSHIO @@ -362,14 +361,14 @@ static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count data->last_op = 'w'; #endif - return fwrite(buf, 1, count, data->file); + return (ssize_t) fwrite(buf, 1, count, data->file); } } -static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; - size_t ret; + ssize_t ret; assert(data != NULL); @@ -411,7 +410,20 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count) ret = read(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); } - stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK && errno != EINTR && errno != EBADF)); + if (ret < 0) { + if (errno == EWOULDBLOCK || errno == EAGAIN) { + /* Not an error. */ + ret = 0; + } else if (errno == EINTR) { + /* An error, but not EOF */ + } else if (errno == EBADF) { + /* TODO: Remove this special-case? */ + } else { + stream->eof = 1; + } + } else if (ret == 0) { + stream->eof = 1; + } } else { #if HAVE_FLUSHIO @@ -921,7 +933,7 @@ PHPAPI php_stream_ops php_stream_stdio_ops = { /* }}} */ /* {{{ plain files opendir/readdir implementation */ -static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count) { DIR *dir = (DIR*)stream->abstract; struct dirent *result; @@ -929,7 +941,7 @@ static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size /* avoid problems if someone mis-uses the stream */ if (count != sizeof(php_stream_dirent)) - return 0; + return -1; result = readdir(dir); if (result) { diff --git a/main/streams/streams.c b/main/streams/streams.c index 5f467c12ce..296bf9600e 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -525,13 +525,12 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov /* {{{ generic stream operations */ -PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) +PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size) { /* allocate/fill the buffer */ if (stream->readfilters.head) { char *chunk_buf; - int err_flag = 0; php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL }; php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap; @@ -542,8 +541,8 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) /* allocate a buffer for reading chunks */ chunk_buf = emalloc(stream->chunk_size); - while (!stream->eof && !err_flag && (stream->writepos - stream->readpos < (zend_off_t)size)) { - size_t justread = 0; + while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)size)) { + ssize_t justread = 0; int flags; php_stream_bucket *bucket; php_stream_filter_status_t status = PSFS_ERR_FATAL; @@ -551,7 +550,10 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) /* read a chunk into a bucket */ justread = stream->ops->read(stream, chunk_buf, stream->chunk_size); - if (justread && justread != (size_t)-1) { + if (justread < 0 && stream->writepos == stream->readpos) { + efree(chunk_buf); + return FAILURE; + } else if (justread > 0) { bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0); /* after this call, bucket is owned by the brigade */ @@ -607,31 +609,28 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) /* when a filter needs feeding, there is no brig_out to deal with. * we simply continue the loop; if the caller needs more data, * we will read again, otherwise out job is done here */ - if (justread == 0) { - /* there is no data */ - err_flag = 1; - break; - } - continue; + break; case PSFS_ERR_FATAL: /* some fatal error. Theoretically, the stream is borked, so all * further reads should fail. */ - err_flag = 1; - break; + stream->eof = 1; + efree(chunk_buf); + return FAILURE; } - if (justread == 0 || justread == (size_t)-1) { + if (justread <= 0) { break; } } efree(chunk_buf); + return SUCCESS; } else { /* is there enough data in the buffer ? */ if (stream->writepos - stream->readpos < (zend_off_t)size) { - size_t justread = 0; + ssize_t justread = 0; /* reduce buffer memory consumption if possible, to avoid a realloc */ if (stream->readbuf && stream->readbuflen - stream->writepos < stream->chunk_size) { @@ -653,17 +652,18 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) justread = stream->ops->read(stream, (char*)stream->readbuf + stream->writepos, stream->readbuflen - stream->writepos ); - - if (justread != (size_t)-1) { - stream->writepos += justread; + if (justread < 0) { + return FAILURE; } + stream->writepos += justread; } + return SUCCESS; } } -PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size) +PHPAPI ssize_t _php_stream_read(php_stream *stream, char *buf, size_t size) { - size_t toread = 0, didread = 0; + ssize_t toread = 0, didread = 0; while (size > 0) { @@ -692,15 +692,24 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size) if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1)) { toread = stream->ops->read(stream, buf, size); - if (toread == (size_t) -1) { - /* e.g. underlying read(2) returned -1 */ + if (toread < 0) { + /* Report an error if the read failed and we did not read any data + * before that. Otherwise return the data we did read. */ + if (didread == 0) { + return toread; + } break; } } else { - php_stream_fill_read_buffer(stream, size); + if (php_stream_fill_read_buffer(stream, size) != SUCCESS) { + if (didread == 0) { + return -1; + } + break; + } toread = stream->writepos - stream->readpos; - if (toread > size) { + if ((size_t) toread > size) { toread = size; } @@ -733,6 +742,26 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size) return didread; } +/* Like php_stream_read(), but reading into a zend_string buffer. This has some similarity + * to the copy_to_mem() operation, but only performs a single direct read. */ +PHPAPI zend_string *php_stream_read_to_str(php_stream *stream, size_t len) +{ + zend_string *str = zend_string_alloc(len, 0); + ssize_t read = php_stream_read(stream, ZSTR_VAL(str), len); + if (read < 0) { + zend_string_efree(str); + return NULL; + } + + ZSTR_LEN(str) = read; + ZSTR_VAL(str)[read] = 0; + + if ((size_t) read < len / 2) { + return zend_string_truncate(str, read, 0); + } + return str; +} + PHPAPI int _php_stream_eof(php_stream *stream) { /* if there is data in the buffer, it's not EOF */ @@ -776,7 +805,7 @@ PHPAPI int _php_stream_puts(php_stream *stream, const char *buf) char newline[2] = "\n"; /* is this OK for Win? */ len = strlen(buf); - if (len > 0 && php_stream_write(stream, buf, len) && php_stream_write(stream, newline, 1)) { + if (len > 0 && php_stream_write(stream, buf, len) > 0 && php_stream_write(stream, newline, 1) > 0) { return 1; } return 0; @@ -1074,9 +1103,9 @@ PHPAPI zend_string *php_stream_get_record(php_stream *stream, size_t maxlen, con } /* Writes a buffer directly to a stream, using multiple of the chunk size */ -static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count) +static ssize_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count) { - size_t didwrite = 0, towrite, justwrote; + ssize_t didwrite = 0, justwrote; /* if we have a seekable stream we need to ensure that data is written at the * current stream->position. This means invalidating the read buffer and then @@ -1089,29 +1118,32 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size while (count > 0) { - towrite = count; + size_t towrite = count; if (towrite > stream->chunk_size) towrite = stream->chunk_size; justwrote = stream->ops->write(stream, buf, towrite); + if (justwrote <= 0) { + /* If we already successfully wrote some bytes and a write error occurred + * later, report the successfully written bytes. */ + if (didwrite == 0) { + return justwrote; + } + return didwrite; + } - /* convert justwrote to an integer, since normally it is unsigned */ - if ((int)justwrote > 0) { - buf += justwrote; - count -= justwrote; - didwrite += justwrote; + buf += justwrote; + count -= justwrote; + didwrite += justwrote; - /* Only screw with the buffer if we can seek, otherwise we lose data - * buffered from fifos and sockets */ - if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { - stream->position += justwrote; - } - } else { - break; + /* Only screw with the buffer if we can seek, otherwise we lose data + * buffered from fifos and sockets */ + if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { + stream->position += justwrote; } } - return didwrite; + return didwrite; } /* push some data through the write filter chain. @@ -1119,7 +1151,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size * This may trigger a real write to the stream. * Returns the number of bytes consumed from buf by the first filter in the chain. * */ -static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags) +static ssize_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags) { size_t consumed = 0; php_stream_bucket *bucket; @@ -1157,7 +1189,10 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si * underlying stream */ while (brig_inp->head) { bucket = brig_inp->head; - _php_stream_write_buffer(stream, bucket->buf, bucket->buflen); + if (_php_stream_write_buffer(stream, bucket->buf, bucket->buflen) < 0) { + consumed = (ssize_t) -1; + } + /* Potential error situation - eg: no space on device. Perhaps we should keep this brigade * hanging around and try to write it later. * At the moment, we just drop it on the floor @@ -1174,7 +1209,7 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si case PSFS_ERR_FATAL: /* some fatal error. Theoretically, the stream is borked, so all * further writes should fail. */ - break; + return (ssize_t) -1; } return consumed; @@ -1197,14 +1232,18 @@ PHPAPI int _php_stream_flush(php_stream *stream, int closing) return ret; } -PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count) +PHPAPI ssize_t _php_stream_write(php_stream *stream, const char *buf, size_t count) { - size_t bytes; + ssize_t bytes; - if (buf == NULL || count == 0 || stream->ops->write == NULL) { + if (count == 0) { return 0; } + if (buf == NULL || stream->ops->write == NULL) { + return (ssize_t) -1; + } + if (stream->writefilters.head) { bytes = _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL); } else { @@ -1218,9 +1257,9 @@ PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t coun return bytes; } -PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) +PHPAPI ssize_t _php_stream_printf(php_stream *stream, const char *fmt, ...) { - size_t count; + ssize_t count; char *buf; va_list ap; @@ -1229,7 +1268,7 @@ PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) va_end(ap); if (!buf) { - return 0; /* error condition */ + return -1; /* error condition */ } count = php_stream_write(stream, buf, count); @@ -1306,9 +1345,9 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) /* emulate forward moving seeks with reads */ if (whence == SEEK_CUR && offset >= 0) { char tmp[1024]; - size_t didread; - while(offset > 0) { - if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) == 0) { + ssize_t didread; + while (offset > 0) { + if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) <= 0) { return -1; } offset -= didread; @@ -1361,11 +1400,11 @@ PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize) return php_stream_set_option(stream, PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SET_SIZE, &newsize); } -PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC) +PHPAPI ssize_t _php_stream_passthru(php_stream * stream STREAMS_DC) { size_t bcount = 0; char buf[8192]; - size_t b; + ssize_t b; if (php_stream_mmap_possible(stream)) { char *p; @@ -1392,13 +1431,17 @@ PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC) bcount += b; } + if (b < 0 && bcount == 0) { + return b; + } + return bcount; } PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC) { - size_t ret = 0; + ssize_t ret = 0; char *ptr; size_t len = 0, max_len; int step = CHUNK_SIZE; @@ -1419,7 +1462,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int ptr = ZSTR_VAL(result); while ((len < maxlen) && !php_stream_eof(src)) { ret = php_stream_read(src, ptr, maxlen - len); - if (!ret) { + if (ret <= 0) { + // TODO: Propagate error? break; } len += ret; @@ -1450,7 +1494,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int result = zend_string_alloc(max_len, persistent); ptr = ZSTR_VAL(result); - while ((ret = php_stream_read(src, ptr, max_len - len))) { + // TODO: Propagate error? + while ((ret = php_stream_read(src, ptr, max_len - len)) > 0){ len += ret; if (len + min_room >= max_len) { result = zend_string_extend(result, max_len + step, persistent); @@ -1475,9 +1520,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC) { char buf[CHUNK_SIZE]; - size_t readchunk; size_t haveread = 0; - size_t didread, didwrite, towrite; + size_t towrite; size_t dummy; php_stream_statbuf ssbuf; @@ -1512,7 +1556,11 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size p = php_stream_mmap_range(src, php_stream_tell(src), maxlen, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped); if (p) { - didwrite = php_stream_write(dest, p, mapped); + ssize_t didwrite = php_stream_write(dest, p, mapped); + if (didwrite < 0) { + *len = 0; + return FAILURE; + } php_stream_mmap_unmap_ex(src, mapped); @@ -1529,7 +1577,8 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size } while(1) { - readchunk = sizeof(buf); + size_t readchunk = sizeof(buf); + ssize_t didread; if (maxlen && (maxlen - haveread) < readchunk) { readchunk = maxlen - haveread; @@ -1537,7 +1586,7 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size didread = php_stream_read(src, buf, readchunk); - if (didread) { + if (didread > 0) { /* extra paranoid */ char *writeptr; @@ -1545,9 +1594,9 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size writeptr = buf; haveread += didread; - while(towrite) { - didwrite = php_stream_write(dest, writeptr, towrite); - if (didwrite == 0) { + while (towrite) { + ssize_t didwrite = php_stream_write(dest, writeptr, towrite); + if (didwrite <= 0) { *len = haveread - (didread - towrite); return FAILURE; } diff --git a/main/streams/userspace.c b/main/streams/userspace.c index bdd9b1b48e..de3e8591e6 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -588,14 +588,14 @@ PHP_FUNCTION(stream_wrapper_restore) } /* }}} */ -static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count) +static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count) { zval func_name; zval retval; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; zval args[1]; - size_t didwrite = 0; + ssize_t didwrite; assert(us != NULL); @@ -612,18 +612,21 @@ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t zval_ptr_dtor(&args[0]); zval_ptr_dtor(&func_name); - didwrite = 0; - if (EG(exception)) { - return 0; + return -1; } if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - convert_to_long(&retval); - didwrite = Z_LVAL(retval); - } else if (call_result == FAILURE) { + if (Z_TYPE(retval) == IS_FALSE) { + didwrite = -1; + } else { + convert_to_long(&retval); + didwrite = Z_LVAL(retval); + } + } else { php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", us->wrapper->classname); + didwrite = -1; } /* don't allow strange buffer overruns due to bogus return */ @@ -639,7 +642,7 @@ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t return didwrite; } -static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count) { zval func_name; zval retval; @@ -669,6 +672,10 @@ static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count) } if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { + if (Z_TYPE(retval) == IS_FALSE) { + return -1; + } + if (!try_convert_to_string(&retval)) { return -1; } @@ -1401,7 +1408,7 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i } -static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count) +static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count) { zval func_name; zval retval; @@ -1412,7 +1419,7 @@ static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t cou /* avoid problems if someone mis-uses the stream */ if (count != sizeof(php_stream_dirent)) - return 0; + return -1; ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1); diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index f79fa16d5f..511e1570d1 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -56,10 +56,10 @@ const php_stream_ops php_stream_unixdg_socket_ops; static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam); /* {{{ Generic socket stream operations */ -static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count) +static ssize_t php_sockop_write(php_stream *stream, const char *buf, size_t count) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - int didwrite; + ssize_t didwrite; struct timeval *ptimeout; if (!sock || sock->socket == -1) { @@ -109,10 +109,6 @@ retry: php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), didwrite, 0); } - if (didwrite < 0) { - didwrite = 0; - } - return didwrite; } @@ -146,14 +142,14 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data } } -static size_t php_sockop_read(php_stream *stream, char *buf, size_t count) +static ssize_t php_sockop_read(php_stream *stream, char *buf, size_t count) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; ssize_t nr_bytes = 0; int err; if (!sock || sock->socket == -1) { - return 0; + return -1; } if (sock->is_blocked) { @@ -165,16 +161,20 @@ static size_t php_sockop_read(php_stream *stream, char *buf, size_t count) nr_bytes = recv(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && sock->timeout.tv_sec != -1) ? MSG_DONTWAIT : 0); err = php_socket_errno(); - stream->eof = (nr_bytes == 0 || (nr_bytes == -1 && err != EWOULDBLOCK && err != EAGAIN)); + if (nr_bytes < 0) { + if (err == EAGAIN || err == EWOULDBLOCK) { + nr_bytes = 0; + } else { + stream->eof = 1; + } + } else if (nr_bytes == 0) { + stream->eof = 1; + } if (nr_bytes > 0) { php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0); } - if (nr_bytes < 0) { - nr_bytes = 0; - } - return nr_bytes; } |
