PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/Zend - zend_stream.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 155
Code covered: 73.5 % Executed lines: 114
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend license,     |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Wez Furlong <wez@thebrainroom.com>                          |
      16                 :    |          Scott MacVicar <scottmac@php.net>                           |
      17                 :    |          Nuno Lopes <nlopess@php.net>                                |
      18                 :    |          Marcus Boerger <helly@php.net>                              |
      19                 :    +----------------------------------------------------------------------+
      20                 : */
      21                 : 
      22                 : /* $Id: zend_stream.c 282162 2009-06-15 14:06:30Z pajoye $ */
      23                 : 
      24                 : 
      25                 : #include "zend.h"
      26                 : #include "zend_compile.h"
      27                 : 
      28                 : #include <sys/types.h>
      29                 : #include <sys/stat.h>
      30                 : #if HAVE_SYS_MMAN_H
      31                 : # include <sys/mman.h>
      32                 : # ifndef PAGE_SIZE
      33                 : #  define PAGE_SIZE 4096
      34                 : # endif
      35                 : #endif
      36                 : 
      37                 : ZEND_DLIMPORT int isatty(int fd);
      38                 : 
      39                 : static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
      40              28 : {
      41              28 :         return fread(buf, 1, len, (FILE*)handle);
      42                 : }
      43                 : /* }}} */
      44                 : 
      45                 : static void zend_stream_stdio_closer(void *handle TSRMLS_DC) /* {{{ */
      46           67568 : {
      47           67568 :         if (handle && (FILE*)handle != stdin) {
      48           67554 :                 fclose((FILE*)handle);
      49                 :         }
      50           67568 : }
      51                 : /* }}} */
      52                 : 
      53                 : static size_t zend_stream_stdio_fsizer(void *handle TSRMLS_DC) /* {{{ */
      54               0 : {
      55                 :         struct stat buf;
      56               0 :         if (handle && fstat(fileno((FILE*)handle), &buf) == 0) {
      57                 : #ifdef S_ISREG
      58               0 :                 if (!S_ISREG(buf.st_mode)) {
      59               0 :                         return 0;
      60                 :                 }
      61                 : #endif
      62               0 :                 return buf.st_size;
      63                 :         }
      64               0 :         return 0;
      65                 : }
      66                 : /* }}} */
      67                 : 
      68           68130 : static void zend_stream_unmap(zend_stream *stream TSRMLS_DC) { /* {{{ */
      69                 : #if HAVE_MMAP
      70           68130 :         if (stream->mmap.map) {
      71           67550 :                 munmap(stream->mmap.map, stream->mmap.len);
      72                 :         } else
      73                 : #endif
      74             580 :         if (stream->mmap.buf) {
      75             580 :                 efree(stream->mmap.buf);
      76                 :         }
      77           68130 :         stream->mmap.len = 0;
      78           68130 :         stream->mmap.pos = 0;
      79           68130 :         stream->mmap.map = 0;
      80           68130 :         stream->mmap.buf = 0;
      81           68130 :         stream->handle   = stream->mmap.old_handle;
      82           68130 : } /* }}} */
      83                 : 
      84                 : static void zend_stream_mmap_closer(zend_stream *stream TSRMLS_DC) /* {{{ */
      85           68130 : {
      86           68130 :         zend_stream_unmap(stream TSRMLS_CC);
      87           68130 :         if (stream->mmap.old_closer && stream->handle) {
      88           68126 :                 stream->mmap.old_closer(stream->handle TSRMLS_CC);
      89                 :         }
      90           68130 : } /* }}} */
      91                 : 
      92           69282 : static inline int zend_stream_is_mmap(zend_file_handle *file_handle) { /* {{{ */
      93           69282 :         return file_handle->type == ZEND_HANDLE_MAPPED;
      94                 : } /* }}} */
      95                 : 
      96                 : static size_t zend_stream_fsize(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
      97           68130 : {
      98                 :         struct stat buf;
      99                 : 
     100           68130 :         if (zend_stream_is_mmap(file_handle)) {
     101               0 :                 return file_handle->handle.stream.mmap.len;
     102                 :         }
     103           68130 :         if (file_handle->type == ZEND_HANDLE_STREAM || file_handle->type == ZEND_HANDLE_MAPPED) {
     104             562 :                 return file_handle->handle.stream.fsizer(file_handle->handle.stream.handle TSRMLS_CC);
     105                 :         }
     106           67568 :         if (file_handle->handle.fp && fstat(fileno(file_handle->handle.fp), &buf) == 0) {
     107                 : #ifdef S_ISREG
     108           67568 :                 if (!S_ISREG(buf.st_mode)) {
     109              14 :                         return 0;
     110                 :                 }
     111                 : #endif
     112           67554 :                 return buf.st_size;
     113                 :         }
     114                 : 
     115               0 :         return -1;
     116                 : } /* }}} */
     117                 : 
     118                 : ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */
     119           15050 : {
     120           15050 :         if (zend_stream_open_function) {
     121           15050 :                 return zend_stream_open_function(filename, handle TSRMLS_CC);
     122                 :         }
     123               0 :         handle->type = ZEND_HANDLE_FP;
     124               0 :         handle->opened_path = NULL;
     125               0 :         handle->handle.fp = zend_fopen(filename, &handle->opened_path TSRMLS_CC);
     126               0 :         handle->filename = (char *)filename;
     127               0 :         handle->free_filename = 0;
     128               0 :         memset(&handle->handle.stream.mmap, 0, sizeof(zend_mmap));
     129                 : 
     130               0 :         return (handle->handle.fp) ? SUCCESS : FAILURE;
     131                 : }
     132                 : /* }}} */
     133                 : 
     134                 : ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
     135               0 : {
     136                 :         char buf;
     137               0 :         if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
     138               0 :                 return (int)buf;
     139                 :         }
     140               0 :         return EOF;
     141                 : }
     142                 : /* }}} */
     143                 : 
     144                 : static size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
     145            1152 : {
     146            1152 :         if (!zend_stream_is_mmap(file_handle) && file_handle->handle.stream.isatty) {
     147               0 :                 int c = '*';
     148                 :                 size_t n;
     149                 : 
     150                 : #ifdef NETWARE
     151                 :                 /*
     152                 :                         c != 4 check is there as fread of a character in NetWare LibC gives 4 upon ^D character.
     153                 :                         Ascii value 4 is actually EOT character which is not defined anywhere in the LibC
     154                 :                         or else we can use instead of hardcoded 4.
     155                 :                 */
     156                 :                 for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n) {
     157                 : #else
     158               0 :                 for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n)  {
     159                 : #endif
     160               0 :                         buf[n] = (char)c;
     161                 :                 }
     162               0 :                 if (c == '\n') {
     163               0 :                         buf[n++] = (char)c; 
     164                 :                 }
     165                 : 
     166               0 :                 return n;
     167                 :         }
     168            1152 :         return file_handle->handle.stream.reader(file_handle->handle.stream.handle, buf, len TSRMLS_CC);
     169                 : }
     170                 : /* }}} */
     171                 : 
     172                 : ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len TSRMLS_DC) /* {{{ */
     173           82728 : {
     174                 :         size_t size;
     175                 :         zend_stream_type old_type;
     176                 : 
     177           82728 :         if (file_handle->type == ZEND_HANDLE_FILENAME) {
     178            5618 :                 if (zend_stream_open(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
     179             108 :                         return FAILURE;
     180                 :                 }
     181                 :         }
     182                 : 
     183           82620 :         switch (file_handle->type) {         
     184                 :                 case ZEND_HANDLE_FD:
     185               0 :                         file_handle->type = ZEND_HANDLE_FP;
     186               0 :                         file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
     187                 :                         /* no break; */                 
     188                 :                 case ZEND_HANDLE_FP:
     189           67568 :                         if (!file_handle->handle.fp) {
     190               0 :                                 return FAILURE;
     191                 :                         }
     192           67568 :                         memset(&file_handle->handle.stream.mmap, 0, sizeof(zend_mmap));
     193           67568 :                         file_handle->handle.stream.isatty     = isatty(fileno((FILE *)file_handle->handle.stream.handle)) ? 1 : 0;
     194           67568 :                         file_handle->handle.stream.reader     = (zend_stream_reader_t)zend_stream_stdio_reader;
     195           67568 :                         file_handle->handle.stream.closer     = (zend_stream_closer_t)zend_stream_stdio_closer;
     196           67568 :                         file_handle->handle.stream.fsizer     = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
     197           67568 :                         memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
     198                 :                         /* no break; */                 
     199                 :                 case ZEND_HANDLE_STREAM:
     200                 :                         /* nothing to do */
     201                 :                         break;
     202                 :                 
     203                 :                 case ZEND_HANDLE_MAPPED:
     204           14490 :                         file_handle->handle.stream.mmap.pos = 0;
     205           14490 :                         *buf = file_handle->handle.stream.mmap.buf;
     206           14490 :                         *len = file_handle->handle.stream.mmap.len;
     207           14490 :                         return SUCCESS;
     208                 :                         
     209                 :                 default:
     210               0 :                         return FAILURE;
     211                 :         }
     212                 : 
     213           68130 :         size = zend_stream_fsize(file_handle TSRMLS_CC);
     214           68130 :         if (size == (size_t)-1) {
     215               0 :                 return FAILURE;
     216                 :         }
     217                 : 
     218           68130 :         old_type = file_handle->type;
     219           68130 :         file_handle->type = ZEND_HANDLE_STREAM;  /* we might still be _FP but we need fsize() work */
     220                 : 
     221           68134 :         if (old_type == ZEND_HANDLE_FP && !file_handle->handle.stream.isatty && size) {
     222                 : #if HAVE_MMAP
     223           67554 :                 if (file_handle->handle.fp &&
     224                 :                     size != 0 &&
     225                 :                     ((size - 1) % PAGE_SIZE) <= PAGE_SIZE - ZEND_MMAP_AHEAD) {
     226                 :                         /*  *buf[size] is zeroed automatically by the kernel */
     227           67550 :                         *buf = mmap(0, size + ZEND_MMAP_AHEAD, PROT_READ, MAP_PRIVATE, fileno(file_handle->handle.fp), 0);
     228           67550 :                         if (*buf != MAP_FAILED) {
     229           67550 :                                 long offset = ftell(file_handle->handle.fp);
     230           67550 :                                 file_handle->handle.stream.mmap.map = *buf;
     231                 : 
     232           67550 :                                 if (offset != -1) {
     233           67550 :                                         *buf += offset;
     234           67550 :                                         size -= offset;
     235                 :                                 }
     236           67550 :                                 file_handle->handle.stream.mmap.buf = *buf;
     237           67550 :                                 file_handle->handle.stream.mmap.len = size;
     238                 : 
     239           67550 :                                 goto return_mapped;
     240                 :                         }
     241                 :                 }
     242                 : #endif
     243               4 :                 file_handle->handle.stream.mmap.map = 0;
     244               4 :                 file_handle->handle.stream.mmap.buf = *buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD);
     245               4 :                 file_handle->handle.stream.mmap.len = zend_stream_read(file_handle, *buf, size TSRMLS_CC);
     246                 :         } else {
     247             576 :                 size_t read, remain = 4*1024;
     248             576 :                 *buf = emalloc(remain);
     249             576 :                 size = 0;
     250                 : 
     251            1724 :                 while ((read = zend_stream_read(file_handle, *buf + size, remain TSRMLS_CC)) > 0) {
     252             572 :                         size   += read;
     253             572 :                         remain -= read;
     254                 : 
     255             572 :                         if (remain == 0) {
     256               6 :                                 *buf   = safe_erealloc(*buf, size, 2, 0);
     257               6 :                                 remain = size;
     258                 :                         }
     259                 :                 }
     260             576 :                 file_handle->handle.stream.mmap.map = 0;
     261             576 :                 file_handle->handle.stream.mmap.len = size;
     262             576 :                 if (size && remain < ZEND_MMAP_AHEAD) {
     263               0 :                         *buf = safe_erealloc(*buf, size, 1, ZEND_MMAP_AHEAD);
     264                 :                 }
     265             576 :                 file_handle->handle.stream.mmap.buf = *buf;
     266                 :         }
     267                 : 
     268             580 :         if (file_handle->handle.stream.mmap.len == 0) {
     269               4 :                 *buf = erealloc(*buf, ZEND_MMAP_AHEAD);
     270               4 :                 file_handle->handle.stream.mmap.buf = *buf;
     271                 :         }
     272                 : 
     273                 :         if (ZEND_MMAP_AHEAD) {
     274             580 :                 memset(file_handle->handle.stream.mmap.buf + file_handle->handle.stream.mmap.len, 0, ZEND_MMAP_AHEAD);
     275                 :         }
     276                 : 
     277                 : #if HAVE_MMAP
     278           68130 : return_mapped:
     279                 : #endif
     280           68130 :         file_handle->type = ZEND_HANDLE_MAPPED;
     281           68130 :         file_handle->handle.stream.mmap.pos        = 0;
     282           68130 :         file_handle->handle.stream.mmap.old_handle = file_handle->handle.stream.handle;
     283           68130 :         file_handle->handle.stream.mmap.old_closer = file_handle->handle.stream.closer;
     284           68130 :         file_handle->handle.stream.handle          = &file_handle->handle.stream;
     285           68130 :         file_handle->handle.stream.closer          = (zend_stream_closer_t)zend_stream_mmap_closer;
     286                 : 
     287           68130 :         *buf = file_handle->handle.stream.mmap.buf;
     288           68130 :         *len = file_handle->handle.stream.mmap.len;
     289                 : 
     290           68130 :         return SUCCESS;
     291                 : }
     292                 : /* }}} */
     293                 : 
     294                 : ZEND_API void zend_file_handle_dtor(zend_file_handle *fh TSRMLS_DC) /* {{{ */
     295           82632 :  {
     296           82632 :         switch (fh->type) {
     297                 :                 case ZEND_HANDLE_FD:
     298                 :                         /* nothing to do */
     299               0 :                         break;
     300                 :                 case ZEND_HANDLE_FP:
     301               0 :                         fclose(fh->handle.fp);
     302               0 :                         break;
     303                 :                 case ZEND_HANDLE_STREAM:
     304                 :                 case ZEND_HANDLE_MAPPED:
     305           82632 :                         if (fh->handle.stream.closer && fh->handle.stream.handle) {
     306           82632 :                                 fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC);
     307                 :                         }
     308           82632 :                         fh->handle.stream.handle = NULL;
     309                 :                         break;
     310                 :                 case ZEND_HANDLE_FILENAME:
     311                 :                         /* We're only supposed to get here when destructing the used_files hash,
     312                 :                          * which doesn't really contain open files, but references to their names/paths
     313                 :                          */
     314                 :                         break;
     315                 :         }
     316           82632 :         if (fh->opened_path) {
     317           48770 :                 efree(fh->opened_path);
     318           48770 :                 fh->opened_path = NULL;
     319                 :         }
     320           82632 :         if (fh->free_filename && fh->filename) {
     321               0 :                 efree(fh->filename);
     322               0 :                 fh->filename = NULL;
     323                 :         }
     324           82632 : }
     325                 : /* }}} */
     326                 : 
     327                 : ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) /* {{{ */
     328           48336 :  {
     329           48336 :         if (fh1->type != fh2->type) {
     330               0 :                 return 0;
     331                 :         }
     332           48336 :         switch (fh1->type) {
     333                 :                 case ZEND_HANDLE_FD:
     334               0 :                         return fh1->handle.fd == fh2->handle.fd;
     335                 :                 case ZEND_HANDLE_FP:
     336               0 :                         return fh1->handle.fp == fh2->handle.fp;
     337                 :                 case ZEND_HANDLE_STREAM:
     338               0 :                         return fh1->handle.stream.handle == fh2->handle.stream.handle;
     339                 :                 case ZEND_HANDLE_MAPPED:
     340           48336 :                         return (fh1->handle.stream.handle == &fh1->handle.stream &&
     341                 :                                 fh2->handle.stream.handle == &fh2->handle.stream &&
     342                 :                                 fh1->handle.stream.mmap.old_handle == fh2->handle.stream.mmap.old_handle)
     343                 :                                 || fh1->handle.stream.handle == fh2->handle.stream.handle;
     344                 :                 default:
     345               0 :                         return 0;
     346                 :         }
     347                 :         return 0;
     348                 : }
     349                 : /* }}} */
     350                 : 
     351                 : /*
     352                 :  * Local variables:
     353                 :  * tab-width: 4
     354                 :  * c-basic-offset: 4
     355                 :  * indent-tabs-mode: t
     356                 :  * End:
     357                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:23 +0000 (36 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.