Skip to content

Commit 077fe52

Browse files
committed
This seems to resolve the issues with fgets.
I've moved EOF detection into the streams layer; a stream reader implementation should set stream->eof when it detects EOF. Fixed test for user streams - it still fails but that is due to an output buffering bug.
1 parent 945ccfa commit 077fe52

File tree

8 files changed

+149
-130
lines changed

8 files changed

+149
-130
lines changed

ext/standard/php_fopen_wrapper.c

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static size_t php_stream_output_write(php_stream *stream, const char *buf, size_
3939

4040
static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
4141
{
42+
stream->eof = 1;
4243
return 0;
4344
}
4445

ext/standard/tests/file/userstreams.phpt

+4-3
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,12 @@ foreach($line_lengths as $line_length) {
243243

244244
printf("\n--[%d] whence=%s offset=%d line_length=%d position_should_be=%d --\n",
245245
$j, $whence_names[$whence], $offset, $line_length, $position);
246-
printf("REAL: pos=(%d,%d,%d) ret=%d line=`%s'\n", $rpb, $rpa, ftell($tf), $rr, $rline);
247-
printf("USER: pos=(%d,%d,%d) ret=%d line=`%s'\n", $upb, $upa, ftell($fp), $ur, $uline);
246+
printf("REAL: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $rpb, $rpa, ftell($tf), $rr, strlen($rline), $rline);
247+
printf("USER: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $upb, $upa, ftell($fp), $ur, strlen($uline), $uline);
248248

249249
if ($rr != $ur || $rline != $uline || $rpa != $position || $upa != $position) {
250250
$fail_count++;
251+
echo "###################################### FAIL!\n";
251252
$dat = stream_get_meta_data($fp);
252253
var_dump($dat);
253254
break;
@@ -273,7 +274,7 @@ fseek($tf, $DATALEN / 2, SEEK_SET);
273274

274275
while(!feof($fp)) {
275276
$uline = fgets($fp, 1024);
276-
$rline = fgets($fp, 1024);
277+
$rline = fgets($tf, 1024);
277278

278279
if ($uline != $rline) {
279280
echo "FGETS: FAIL\nuser=$uline\nreal=$rline\n";

ext/zlib/zlib_fopen_wrapper.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ struct php_gz_stream_data_t {
3232
static size_t php_gziop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
3333
{
3434
struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *)stream->abstract;
35+
size_t ret;
36+
37+
ret = gzread(self->gz_file, buf, count);
3538

36-
if (buf == NULL && count == 0) {
37-
if (gzeof(self->gz_file))
38-
return EOF;
39-
return 0;
40-
}
39+
if (ret == 0 && gzeof(self->gz_file))
40+
stream->eof = 1;
4141

42-
return gzread(self->gz_file, buf, count);
42+
return ret;
4343
}
4444

4545
static size_t php_gziop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)

main/memory_streams.c

+2-8
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,6 @@ static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count
8989
ms = stream->abstract;
9090
assert(ms != NULL);
9191

92-
if (buf == NULL && count == 0) {
93-
/* check for EOF condition */
94-
if (ms->fpos >= ms->fsize) {
95-
return EOF;
96-
}
97-
return 0;
98-
}
99-
10092
if (ms->fpos + count > ms->fsize) {
10193
count = ms->fsize - ms->fpos;
10294
}
@@ -105,6 +97,8 @@ static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count
10597
assert(buf!= NULL);
10698
memcpy(buf, ms->data+ms->fpos, count);
10799
ms->fpos += count;
100+
} else {
101+
stream->eof = 1;
108102
}
109103
return count;
110104
}

main/network.c

+1-27
Original file line numberDiff line numberDiff line change
@@ -767,32 +767,6 @@ static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS
767767
php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract;
768768
size_t nr_bytes = 0;
769769

770-
if (buf == NULL && count == 0) {
771-
/* check for EOF condition */
772-
773-
DUMP_SOCK_STATE("check for EOF", sock);
774-
775-
if (sock->eof)
776-
return EOF;
777-
778-
/* no data in the buffer - lets examine the socket */
779-
#if HAVE_SYS_POLL_H && HAVE_POLL
780-
{
781-
struct pollfd topoll;
782-
783-
topoll.fd = sock->socket;
784-
topoll.events = POLLIN;
785-
topoll.revents = 0;
786-
787-
if (poll(&topoll, 1, 0) == 1) {
788-
return topoll.revents & POLLHUP ? EOF : 0;
789-
}
790-
}
791-
#endif
792-
/* presume that we are not yet at the eof */
793-
return 0;
794-
}
795-
796770
if(sock->is_blocked) {
797771
php_sock_stream_wait_for_data(stream, sock TSRMLS_CC);
798772
if (sock->timeout_event)
@@ -811,7 +785,7 @@ DUMP_SOCK_STATE("check for EOF", sock);
811785
php_stream_notify_progress_increment(stream->context, nr_bytes, 0);
812786

813787
if(nr_bytes == 0 || (nr_bytes < 0 && streams_socket_errno != EWOULDBLOCK)) {
814-
sock->eof = 1;
788+
stream->eof = 1;
815789
}
816790

817791
return nr_bytes;

main/php_streams.h

+2
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ struct _php_stream {
269269
/* how much data to read when filling buffer */
270270
size_t chunk_size;
271271

272+
int eof;
273+
272274
}; /* php_stream */
273275
/* state definitions when closing down; these are private to streams.c */
274276
#define PHP_STREAM_FCLOSE_NONE 0

0 commit comments

Comments
 (0)