On Tue, 2004-06-08 at 11:32, Alexander Valyalkin wrote:[snip]+ /* get the length of local file connected to descriptor fd */ fstat(fd, &sbuf);+ if (errno) {
Oh-oh! You need to check the return value of fstat(). Errno is only set if fstat() fails (returns -1), otherwise errno keeps its old (junk) value.
Best regards, Morten
Thanks for useful remark. Here is corrected code & unified diff:
=====================cut===================
PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC)
{
size_t bcount = 0; /* counter of printed out bytes */
int is_mapped = 0;
char buf[8192];
size_t buf_len = sizeof(buf);
#ifdef HAVE_MMAP
int fd;
if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)
&& stream->filterhead == NULL
&& php_stream_tell(stream) == 0
&& SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 0))
{
is_mapped = 1;
buf_len = 1024 * 1024; /* default length of the mapped memory */
struct stat sbuf;
void *p; /* pinter to the mapped part of file */
size_t len;
/* get the length of local file connected to descriptor fd */
if (fstat(fd, &sbuf)) {
/* cannot get length of file */
php_error_docref(NULL TSRMLS_CC, E_ERROR, "cannot get length of the file");
return bcount;
}
len = (size_t) sbuf.st_size;
/* print to the output buffer file contents */
while (bcount < len) {
if (len - bcount < buf_len) buf_len = len - bcount;
p = mmap(NULL, buf_len, PROT_READ, MAP_SHARED, fd, (off_t) bcount); /* try to map part of the file to memory */
if (p == (void *) MAP_FAILED) {
/* error when mapping part of the file to memory */
php_error_docref(NULL TSRMLS_CC, E_ERROR, "mmap error: cannot map part of the file to memory");
break;
}
PHPWRITE(p, buf_len);
if (munmap(p, buf_len)) {
/* error when unmapping memory */
php_error_docref(NULL TSRMLS_CC, E_ERROR, "mmap error: cannot unmap allocated memory");
break;
}
bcount += buf_len;
}
}
#endif
if (!is_mapped) {
/* print to the output buffer stream contents */
while ((buf_len = php_stream_read(stream, buf, sizeof(buf))) > 0) {
PHPWRITE(buf, buf_len);
bcount += buf_len;
}
}
return bcount;
}
=====================cut===================
unfified diff
=====================cut=================== --- streams.c Wed May 12 13:46:30 2004 +++ streams_new.c Wed Jun 09 12:37:31 2004 @@ -1062,48 +1062,54 @@
PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC)
{
- size_t bcount = 0;
- int ready = 0;
+ size_t bcount = 0; /* counter of printed out bytes */
+ int is_mapped = 0;
char buf[8192];
+ size_t buf_len = sizeof(buf);
#ifdef HAVE_MMAP
int fd;
-#endif
-#ifdef HAVE_MMAP
if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)
&& stream->filterhead == NULL
&& php_stream_tell(stream) == 0
&& SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 0))
{
+ is_mapped = 1;
+ buf_len = 1024 * 1024; /* default length of the mapped memory */
struct stat sbuf;
- off_t off;
- void *p;
+ void *p; /* pinter to the mapped part of file */
size_t len;
-
- fstat(fd, &sbuf);
-
- if (sbuf.st_size > sizeof(buf)) {
- off = php_stream_tell(stream);
- len = sbuf.st_size - off;
- p = mmap(0, len, PROT_READ, MAP_SHARED, fd, off);
- if (p != (void *) MAP_FAILED) {
- BG(mmap_file) = p;
- BG(mmap_len) = len;
- PHPWRITE(p, len);
- BG(mmap_file) = NULL;
- munmap(p, len);
- bcount += len;
- ready = 1;
+ /* get the length of local file connected to descriptor fd */
+ if (fstat(fd, &sbuf)) {
+ /* cannot get length of file */
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "cannot get length of the file");
+ return bcount;
+ }
+ len = (size_t) sbuf.st_size;
+ /* print to the output buffer file contents */
+ while (bcount < len) {
+ if (len - bcount < buf_len) buf_len = len - bcount;
+ p = mmap(NULL, buf_len, PROT_READ, MAP_SHARED, fd, (off_t) bcount); /* try to map part of the file to memory */
+ if (p == (void *) MAP_FAILED) {
+ /* error when mapping part of the file to memory */
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "mmap error: cannot map part of the file to memory");
+ break;
+ }
+ PHPWRITE(p, buf_len);
+ if (munmap(p, buf_len)) {
+ /* error when unmapping memory */
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "mmap error: cannot unmap allocated memory");
+ break;
}
+ bcount += buf_len;
}
}
#endif
- if(!ready) {
- int b;
-
- while ((b = php_stream_read(stream, buf, sizeof(buf))) > 0) {
- PHPWRITE(buf, b);
- bcount += b;
+ if (!is_mapped) {
+ /* print to the output buffer stream contents */
+ while ((buf_len = php_stream_read(stream, buf, sizeof(buf))) > 0) {
+ PHPWRITE(buf, buf_len);
+ bcount += buf_len;
}
}
return bcount;
=====================cut===================
-- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php