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_5_3/Zend - zend_stream.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 155
Code covered: 74.2 % Executed lines: 115
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 277834 2009-03-26 17:28:49Z dmitry $ */
      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              26 : {
      41              26 :         return fread(buf, 1, len, (FILE*)handle);
      42                 : } /* }}} */
      43                 : 
      44                 : static void zend_stream_stdio_closer(void *handle TSRMLS_DC) /* {{{ */
      45           70070 : {
      46           70070 :         if (handle && (FILE*)handle != stdin) {
      47           70058 :                 fclose((FILE*)handle);
      48                 :         }
      49           70070 : } /* }}} */
      50                 : 
      51                 : static size_t zend_stream_stdio_fsizer(void *handle TSRMLS_DC) /* {{{ */
      52               0 : {
      53                 :         struct stat buf;
      54               0 :         if (handle && fstat(fileno((FILE*)handle), &buf) == 0) {
      55                 : #ifdef S_ISREG
      56               0 :                 if (!S_ISREG(buf.st_mode)) {
      57               0 :                         return 0;
      58                 :                 }
      59                 : #endif
      60               0 :                 return buf.st_size;
      61                 :         }
      62               0 :         return 0;
      63                 : } /* }}} */
      64                 : 
      65           70640 : static void zend_stream_unmap(zend_stream *stream TSRMLS_DC) { /* {{{ */
      66                 : #if HAVE_MMAP
      67           70640 :         if (stream->mmap.map) {
      68           70052 :                 munmap(stream->mmap.map, stream->mmap.len);
      69                 :         } else
      70                 : #endif
      71             588 :         if (stream->mmap.buf) {
      72             588 :                 efree(stream->mmap.buf);
      73                 :         }
      74           70640 :         stream->mmap.len = 0;
      75           70640 :         stream->mmap.pos = 0;
      76           70640 :         stream->mmap.map = 0;
      77           70640 :         stream->mmap.buf = 0;
      78           70640 :         stream->handle   = stream->mmap.old_handle;
      79           70640 : } /* }}} */
      80                 : 
      81                 : static void zend_stream_mmap_closer(zend_stream *stream TSRMLS_DC) /* {{{ */
      82           70640 : {
      83           70640 :         zend_stream_unmap(stream TSRMLS_CC);
      84           70640 :         if (stream->mmap.old_closer && stream->handle) {
      85           70636 :                 stream->mmap.old_closer(stream->handle TSRMLS_CC);
      86                 :         }
      87           70640 : } /* }}} */
      88                 : 
      89           71810 : static inline int zend_stream_is_mmap(zend_file_handle *file_handle) { /* {{{ */
      90           71810 :         return file_handle->type == ZEND_HANDLE_MAPPED;
      91                 : } /* }}} */
      92                 : 
      93                 : static size_t zend_stream_fsize(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
      94           70640 : {
      95                 :         struct stat buf;
      96                 : 
      97           70640 :         if (zend_stream_is_mmap(file_handle)) {
      98               0 :                 return file_handle->handle.stream.mmap.len;
      99                 :         }
     100           70640 :         if (file_handle->type == ZEND_HANDLE_STREAM || file_handle->type == ZEND_HANDLE_MAPPED) {
     101             570 :                 return file_handle->handle.stream.fsizer(file_handle->handle.stream.handle TSRMLS_CC);
     102                 :         }
     103           70070 :         if (file_handle->handle.fp && fstat(fileno(file_handle->handle.fp), &buf) == 0) {
     104                 : #ifdef S_ISREG
     105           70070 :                 if (!S_ISREG(buf.st_mode)) {
     106              12 :                         return 0;
     107                 :                 }
     108                 : #endif
     109           70058 :                 return buf.st_size;
     110                 :         }
     111                 : 
     112               0 :         return -1;
     113                 : } /* }}} */
     114                 : 
     115                 : ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */
     116           15714 : {
     117           15714 :         if (zend_stream_open_function) {
     118           15714 :                 return zend_stream_open_function(filename, handle TSRMLS_CC);
     119                 :         }
     120               0 :         handle->type = ZEND_HANDLE_FP;
     121               0 :         handle->opened_path = NULL;
     122               0 :         handle->handle.fp = zend_fopen(filename, &handle->opened_path TSRMLS_CC);
     123               0 :         handle->filename = (char *)filename;
     124               0 :         handle->free_filename = 0;
     125               0 :         memset(&handle->handle.stream.mmap, 0, sizeof(zend_mmap));
     126                 :         
     127               0 :         return (handle->handle.fp) ? SUCCESS : FAILURE;
     128                 : } /* }}} */
     129                 : 
     130                 : static int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
     131               0 : {
     132                 :         char buf;
     133                 : 
     134               0 :         if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
     135               0 :                 return (int)buf;
     136                 :         }
     137               0 :         return EOF;
     138                 : } /* }}} */
     139                 : 
     140                 : static size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
     141            1170 : {
     142            1170 :         if (!zend_stream_is_mmap(file_handle) && file_handle->handle.stream.isatty) {
     143               0 :                 int c = '*';
     144                 :                 size_t n;
     145                 : 
     146                 : #ifdef NETWARE
     147                 :                 /*
     148                 :                         c != 4 check is there as fread of a character in NetWare LibC gives 4 upon ^D character.
     149                 :                         Ascii value 4 is actually EOT character which is not defined anywhere in the LibC
     150                 :                         or else we can use instead of hardcoded 4.
     151                 :                 */
     152                 :                 for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n) {
     153                 : #else
     154               0 :                 for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n)  {
     155                 : #endif
     156               0 :                         buf[n] = (char)c;
     157                 :                 }
     158               0 :                 if (c == '\n') {
     159               0 :                         buf[n++] = (char)c; 
     160                 :                 }
     161                 : 
     162               0 :                 return n;
     163                 :         }
     164            1170 :         return file_handle->handle.stream.reader(file_handle->handle.stream.handle, buf, len TSRMLS_CC);
     165                 : } /* }}} */
     166                 : 
     167                 : ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len TSRMLS_DC) /* {{{ */
     168           85894 : {
     169                 :         size_t size;
     170                 :         zend_stream_type old_type;
     171                 : 
     172           85894 :         if (file_handle->type == ZEND_HANDLE_FILENAME) {
     173            5690 :                 if (zend_stream_open(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
     174              98 :                         return FAILURE;
     175                 :                 }
     176                 :         }
     177                 : 
     178           85796 :         switch (file_handle->type) {         
     179                 :                 case ZEND_HANDLE_FD:
     180               0 :                         file_handle->type = ZEND_HANDLE_FP;
     181               0 :                         file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
     182                 :                         /* no break; */                 
     183                 :                 case ZEND_HANDLE_FP:
     184           70070 :                         if (!file_handle->handle.fp) {
     185               0 :                                 return FAILURE;
     186                 :                         }
     187           70070 :                         memset(&file_handle->handle.stream.mmap, 0, sizeof(zend_mmap));
     188           70070 :                         file_handle->handle.stream.isatty     = isatty(fileno((FILE *)file_handle->handle.stream.handle)) ? 1 : 0;
     189           70070 :                         file_handle->handle.stream.reader     = (zend_stream_reader_t)zend_stream_stdio_reader;
     190           70070 :                         file_handle->handle.stream.closer     = (zend_stream_closer_t)zend_stream_stdio_closer;
     191           70070 :                         file_handle->handle.stream.fsizer     = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
     192           70070 :                         memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
     193                 :                         /* no break; */                 
     194                 :                 case ZEND_HANDLE_STREAM:
     195                 :                         /* nothing to do */
     196                 :                         break;
     197                 :                 
     198                 :                 case ZEND_HANDLE_MAPPED:
     199           15156 :                         file_handle->handle.stream.mmap.pos = 0;
     200           15156 :                         *buf = file_handle->handle.stream.mmap.buf;
     201           15156 :                         *len = file_handle->handle.stream.mmap.len;
     202           15156 :                         return SUCCESS;
     203                 :                         
     204                 :                 default:
     205               0 :                         return FAILURE;
     206                 :         }
     207                 : 
     208           70640 :         size = zend_stream_fsize(file_handle TSRMLS_CC);
     209           70640 :         if (size == (size_t)-1) {
     210               0 :                 return FAILURE;
     211                 :         }
     212                 : 
     213           70640 :         old_type = file_handle->type;
     214           70640 :         file_handle->type = ZEND_HANDLE_STREAM;  /* we might still be _FP but we need fsize() work */
     215                 : 
     216           70646 :         if (old_type == ZEND_HANDLE_FP && !file_handle->handle.stream.isatty && size) {
     217                 : #if HAVE_MMAP
     218           70058 :                 if (file_handle->handle.fp &&
     219                 :                     size != 0 &&
     220                 :                     ((size - 1) % PAGE_SIZE) <= PAGE_SIZE - ZEND_MMAP_AHEAD) {
     221                 :                         /*  *buf[size] is zeroed automatically by the kernel */
     222           70052 :                         *buf = mmap(0, size + ZEND_MMAP_AHEAD, PROT_READ, MAP_PRIVATE, fileno(file_handle->handle.fp), 0);
     223           70052 :                         if (*buf != MAP_FAILED) {
     224           70052 :                                 long offset = ftell(file_handle->handle.fp);
     225           70052 :                                 file_handle->handle.stream.mmap.map = *buf;
     226                 : 
     227           70052 :                                 if (offset != -1) {
     228           70052 :                                         *buf += offset;
     229           70052 :                                         size -= offset;
     230                 :                                 }
     231           70052 :                                 file_handle->handle.stream.mmap.buf = *buf;
     232           70052 :                                 file_handle->handle.stream.mmap.len = size;
     233                 : 
     234           70052 :                                 goto return_mapped;
     235                 :                         }
     236                 :                 }
     237                 : #endif
     238               6 :                 file_handle->handle.stream.mmap.map = 0;
     239               6 :                 file_handle->handle.stream.mmap.buf = *buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD);
     240               6 :                 file_handle->handle.stream.mmap.len = zend_stream_read(file_handle, *buf, size TSRMLS_CC);
     241                 :         } else {
     242             582 :                 size_t read, remain = 4*1024;
     243             582 :                 *buf = emalloc(remain);
     244             582 :                 size = 0;
     245                 : 
     246            1746 :                 while ((read = zend_stream_read(file_handle, *buf + size, remain TSRMLS_CC)) > 0) {
     247             582 :                         size   += read;
     248             582 :                         remain -= read;
     249                 : 
     250             582 :                         if (remain == 0) {
     251               4 :                                 *buf   = safe_erealloc(*buf, size, 2, 0);
     252               4 :                                 remain = size;
     253                 :                         }
     254                 :                 }
     255             582 :                 file_handle->handle.stream.mmap.map = 0;
     256             582 :                 file_handle->handle.stream.mmap.len = size;
     257             582 :                 if (size && remain < ZEND_MMAP_AHEAD) {
     258               8 :                         *buf = safe_erealloc(*buf, size, 1, ZEND_MMAP_AHEAD);
     259                 :                 }
     260             582 :                 file_handle->handle.stream.mmap.buf = *buf;
     261                 :         }
     262                 : 
     263             588 :         if (file_handle->handle.stream.mmap.len == 0) {
     264               4 :                 *buf = erealloc(*buf, ZEND_MMAP_AHEAD);
     265               4 :                 file_handle->handle.stream.mmap.buf = *buf;
     266                 :         }
     267                 : 
     268                 :         if (ZEND_MMAP_AHEAD) {
     269             588 :                 memset(file_handle->handle.stream.mmap.buf + file_handle->handle.stream.mmap.len, 0, ZEND_MMAP_AHEAD);
     270                 :         }
     271                 : 
     272           70640 : return_mapped:
     273           70640 :         file_handle->type = ZEND_HANDLE_MAPPED;
     274           70640 :         file_handle->handle.stream.mmap.pos        = 0;
     275           70640 :         file_handle->handle.stream.mmap.old_handle = file_handle->handle.stream.handle;
     276           70640 :         file_handle->handle.stream.mmap.old_closer = file_handle->handle.stream.closer;
     277           70640 :         file_handle->handle.stream.handle          = &file_handle->handle.stream;
     278           70640 :         file_handle->handle.stream.closer          = (zend_stream_closer_t)zend_stream_mmap_closer;
     279                 : 
     280           70640 :         *buf = file_handle->handle.stream.mmap.buf;
     281           70640 :         *len = file_handle->handle.stream.mmap.len;
     282                 : 
     283           70640 :         return SUCCESS;
     284                 : } /* }}} */
     285                 : 
     286                 : ZEND_API void zend_file_handle_dtor(zend_file_handle *fh TSRMLS_DC) /* {{{ */
     287           85808 : {
     288           85808 :         switch (fh->type) {
     289                 :                 case ZEND_HANDLE_FD:
     290                 :                         /* nothing to do */
     291               0 :                         break;
     292                 :                 case ZEND_HANDLE_FP:
     293               0 :                         fclose(fh->handle.fp);
     294               0 :                         break;
     295                 :                 case ZEND_HANDLE_STREAM:
     296                 :                 case ZEND_HANDLE_MAPPED:
     297           85808 :                         if (fh->handle.stream.closer && fh->handle.stream.handle) {
     298           85808 :                                 fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC);
     299                 :                         }
     300           85808 :                         fh->handle.stream.handle = NULL;
     301                 :                         break;
     302                 :                 case ZEND_HANDLE_FILENAME:
     303                 :                         /* We're only supposed to get here when destructing the used_files hash,
     304                 :                          * which doesn't really contain open files, but references to their names/paths
     305                 :                          */
     306                 :                         break;
     307                 :         }
     308           85808 :         if (fh->opened_path) {
     309           50704 :                 efree(fh->opened_path);
     310           50704 :                 fh->opened_path = NULL;
     311                 :         }
     312           85808 :         if (fh->free_filename && fh->filename) {
     313               0 :                 efree(fh->filename);
     314               0 :                 fh->filename = NULL;
     315                 :         }
     316           85808 : }
     317                 : /* }}} */
     318                 : 
     319                 : ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) /* {{{ */
     320           50282 : {
     321           50282 :         if (fh1->type != fh2->type) {
     322               0 :                 return 0;
     323                 :         }
     324           50282 :         switch (fh1->type) {
     325                 :                 case ZEND_HANDLE_FD:
     326               0 :                         return fh1->handle.fd == fh2->handle.fd;
     327                 :                 case ZEND_HANDLE_FP:
     328               0 :                         return fh1->handle.fp == fh2->handle.fp;
     329                 :                 case ZEND_HANDLE_STREAM:
     330               0 :                         return fh1->handle.stream.handle == fh2->handle.stream.handle;
     331                 :                 case ZEND_HANDLE_MAPPED:
     332           50282 :                         return (fh1->handle.stream.handle == &fh1->handle.stream &&
     333                 :                                 fh2->handle.stream.handle == &fh2->handle.stream &&
     334                 :                                 fh1->handle.stream.mmap.old_handle == fh2->handle.stream.mmap.old_handle)
     335                 :                                 || fh1->handle.stream.handle == fh2->handle.stream.handle;
     336                 :                 default:
     337               0 :                         return 0;
     338                 :         }
     339                 :         return 0;
     340                 : } /* }}} */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:26:55 +0000 (3 days ago)

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