@@ -1566,29 +1566,48 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size
15661566
15671567 if (php_stream_mmap_possible (src )) {
15681568 char * p ;
1569- size_t mapped ;
15701569
1571- p = php_stream_mmap_range (src , php_stream_tell (src ), maxlen , PHP_STREAM_MAP_MODE_SHARED_READONLY , & mapped );
1570+ do {
1571+ size_t chunk_size = (maxlen == 0 || maxlen > PHP_STREAM_MMAP_MAX ) ? PHP_STREAM_MMAP_MAX : maxlen ;
1572+ size_t mapped ;
15721573
1573- if (p ) {
1574- ssize_t didwrite = php_stream_write (dest , p , mapped );
1575- if (didwrite < 0 ) {
1576- * len = 0 ;
1577- return FAILURE ;
1578- }
1574+ p = php_stream_mmap_range (src , php_stream_tell (src ), chunk_size , PHP_STREAM_MAP_MODE_SHARED_READONLY , & mapped );
1575+
1576+ if (p ) {
1577+ ssize_t didwrite ;
1578+
1579+ if (php_stream_seek (src , mapped , SEEK_CUR ) != 0 ) {
1580+ php_stream_mmap_unmap (src );
1581+ break ;
1582+ }
1583+
1584+ didwrite = php_stream_write (dest , p , mapped );
1585+ if (didwrite < 0 ) {
1586+ * len = haveread ;
1587+ return FAILURE ;
1588+ }
15791589
1580- php_stream_mmap_unmap_ex (src , mapped );
1590+ php_stream_mmap_unmap (src );
15811591
1582- * len = didwrite ;
1592+ * len = haveread + = didwrite ;
15831593
1584- /* we've got at least 1 byte to read
1585- * less than 1 is an error
1586- * AND read bytes match written */
1587- if (mapped > 0 && mapped == didwrite ) {
1588- return SUCCESS ;
1594+ /* we've got at least 1 byte to read
1595+ * less than 1 is an error
1596+ * AND read bytes match written */
1597+ if (mapped == 0 || mapped != didwrite ) {
1598+ return FAILURE ;
1599+ }
1600+ if (mapped < chunk_size ) {
1601+ return SUCCESS ;
1602+ }
1603+ if (maxlen != 0 ) {
1604+ maxlen -= mapped ;
1605+ if (maxlen == 0 ) {
1606+ return SUCCESS ;
1607+ }
1608+ }
15891609 }
1590- return FAILURE ;
1591- }
1610+ } while (p );
15921611 }
15931612
15941613 while (1 ) {
0 commit comments