Re: readfile() improvements

From: Date: Tue, 08 Jun 2004 09:32:25 +0000
Subject: Re: readfile() improvements
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-10309@lists.php.net to get a copy of this message
On Mon, 7 Jun 2004 20:02:54 +0400, Antony Dovgal <tony2001@phpclub.net> wrote:
On Mon, 07 Jun 2004 18:55:52 +0300 "Alexander Valyalkin" <valyala@tut.by> wrote:
On Mon, 07 Jun 2004 17:07:06 +0300, Andi Gutmans <andi@zend.com> wrote:
Can you send a unified diff? cvs diff -u, plz or diff -u --- WBR, Antony Dovgal aka tony2001 tony2001@phpclub.net || antony@dovgal.com
==============cut================ --- streams.c Wed May 12 13:46:30 2004 +++ streams_new.c Tue Jun 08 12:31:22 2004 @@ -1062,48 +1062,56 @@ 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;
-
+        /* get the length of local file connected to descriptor fd */
        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;
+        if (errno) {
+             /* 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);
+            munmap(p, buf_len); /* try to unmap allocated memory */
+            if (errno) {
+                /* 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/

« previous php.internals (#10309) next »