Back to index

php5  5.3.10
Functions
zend_stream.c File Reference
#include "zend.h"
#include "zend_compile.h"
#include <sys/types.h>
#include <sys/stat.h>

Go to the source code of this file.

Functions

ZEND_DLIMPORT int isatty (int fd)
static size_t zend_stream_stdio_reader (void *handle, char *buf, size_t len TSRMLS_DC)
static void zend_stream_stdio_closer (void *handle TSRMLS_DC)
static size_t zend_stream_stdio_fsizer (void *handle TSRMLS_DC)
static void zend_stream_unmap (zend_stream *stream TSRMLS_DC)
static void zend_stream_mmap_closer (zend_stream *stream TSRMLS_DC)
static int zend_stream_is_mmap (zend_file_handle *file_handle)
static size_t zend_stream_fsize (zend_file_handle *file_handle TSRMLS_DC)
ZEND_API int zend_stream_open (const char *filename, zend_file_handle *handle TSRMLS_DC)
static int zend_stream_getc (zend_file_handle *file_handle TSRMLS_DC)
static size_t zend_stream_read (zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC)
ZEND_API int zend_stream_fixup (zend_file_handle *file_handle, char **buf, size_t *len TSRMLS_DC)
ZEND_API void zend_file_handle_dtor (zend_file_handle *fh TSRMLS_DC)
ZEND_API int zend_compare_file_handles (zend_file_handle *fh1, zend_file_handle *fh2)

Function Documentation

Here is the caller graph for this function:

Definition at line 337 of file zend_stream.c.

{
       if (fh1->type != fh2->type) {
              return 0;
       }
       switch (fh1->type) {
              case ZEND_HANDLE_FD:
                     return fh1->handle.fd == fh2->handle.fd;
              case ZEND_HANDLE_FP:
                     return fh1->handle.fp == fh2->handle.fp;
              case ZEND_HANDLE_STREAM:
                     return fh1->handle.stream.handle == fh2->handle.stream.handle;
              case ZEND_HANDLE_MAPPED:
                     return (fh1->handle.stream.handle == &fh1->handle.stream &&
                             fh2->handle.stream.handle == &fh2->handle.stream &&
                             fh1->handle.stream.mmap.old_handle == fh2->handle.stream.mmap.old_handle)
                            || fh1->handle.stream.handle == fh2->handle.stream.handle;
              default:
                     return 0;
       }
       return 0;
} /* }}} */

Here is the caller graph for this function:

Definition at line 304 of file zend_stream.c.

{
       switch (fh->type) {
              case ZEND_HANDLE_FD:
                     /* nothing to do */
                     break;
              case ZEND_HANDLE_FP:
                     fclose(fh->handle.fp);
                     break;
              case ZEND_HANDLE_STREAM:
              case ZEND_HANDLE_MAPPED:
                     if (fh->handle.stream.closer && fh->handle.stream.handle) {
                            fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC);
                     }
                     fh->handle.stream.handle = NULL;
                     break;
              case ZEND_HANDLE_FILENAME:
                     /* We're only supposed to get here when destructing the used_files hash,
                      * which doesn't really contain open files, but references to their names/paths
                      */
                     break;
       }
       if (fh->opened_path) {
              efree(fh->opened_path);
              fh->opened_path = NULL;
       }
       if (fh->free_filename && fh->filename) {
              efree(fh->filename);
              fh->filename = NULL;
       }
}

Here is the caller graph for this function:

ZEND_API int zend_stream_fixup ( zend_file_handle file_handle,
char **  buf,
size_t *len  TSRMLS_DC 
)

Definition at line 181 of file zend_stream.c.

{
       size_t size;
       zend_stream_type old_type;

       if (file_handle->type == ZEND_HANDLE_FILENAME) {
              if (zend_stream_open(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
                     return FAILURE;
              }
       }

       switch (file_handle->type) {              
              case ZEND_HANDLE_FD:
                     file_handle->type = ZEND_HANDLE_FP;
                     file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
                     /* no break; */                    
              case ZEND_HANDLE_FP:
                     if (!file_handle->handle.fp) {
                            return FAILURE;
                     }
                     memset(&file_handle->handle.stream.mmap, 0, sizeof(zend_mmap));
                     file_handle->handle.stream.isatty     = isatty(fileno((FILE *)file_handle->handle.stream.handle)) ? 1 : 0;
                     file_handle->handle.stream.reader     = (zend_stream_reader_t)zend_stream_stdio_reader;
                     file_handle->handle.stream.closer     = (zend_stream_closer_t)zend_stream_stdio_closer;
                     file_handle->handle.stream.fsizer     = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
                     memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
                     /* no break; */                    
              case ZEND_HANDLE_STREAM:
                     /* nothing to do */
                     break;
              
              case ZEND_HANDLE_MAPPED:
                     file_handle->handle.stream.mmap.pos = 0;
                     *buf = file_handle->handle.stream.mmap.buf;
                     *len = file_handle->handle.stream.mmap.len;
                     return SUCCESS;
                     
              default:
                     return FAILURE;
       }

       size = zend_stream_fsize(file_handle TSRMLS_CC);
       if (size == (size_t)-1) {
              return FAILURE;
       }

       old_type = file_handle->type;
       file_handle->type = ZEND_HANDLE_STREAM;  /* we might still be _FP but we need fsize() work */

       if (old_type == ZEND_HANDLE_FP && !file_handle->handle.stream.isatty && size) {
#if HAVE_MMAP
              size_t page_size = REAL_PAGE_SIZE;

              if (file_handle->handle.fp &&
                  size != 0 &&
                  ((size - 1) % page_size) <= page_size - ZEND_MMAP_AHEAD) {
                     /*  *buf[size] is zeroed automatically by the kernel */
                     *buf = mmap(0, size + ZEND_MMAP_AHEAD, PROT_READ, MAP_PRIVATE, fileno(file_handle->handle.fp), 0);
                     if (*buf != MAP_FAILED) {
                            long offset = ftell(file_handle->handle.fp);
                            file_handle->handle.stream.mmap.map = *buf;

                            if (offset != -1) {
                                   *buf += offset;
                                   size -= offset;
                            }
                            file_handle->handle.stream.mmap.buf = *buf;
                            file_handle->handle.stream.mmap.len = size;

                            goto return_mapped;
                     }
              }
#endif
              file_handle->handle.stream.mmap.map = 0;
              file_handle->handle.stream.mmap.buf = *buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD);
              file_handle->handle.stream.mmap.len = zend_stream_read(file_handle, *buf, size TSRMLS_CC);
       } else {
              size_t read, remain = 4*1024;
              *buf = emalloc(remain);
              size = 0;

              while ((read = zend_stream_read(file_handle, *buf + size, remain TSRMLS_CC)) > 0) {
                     size   += read;
                     remain -= read;

                     if (remain == 0) {
                            *buf   = safe_erealloc(*buf, size, 2, 0);
                            remain = size;
                     }
              }
              file_handle->handle.stream.mmap.map = 0;
              file_handle->handle.stream.mmap.len = size;
              if (size && remain < ZEND_MMAP_AHEAD) {
                     *buf = safe_erealloc(*buf, size, 1, ZEND_MMAP_AHEAD);
              }
              file_handle->handle.stream.mmap.buf = *buf;
       }

       if (file_handle->handle.stream.mmap.len == 0) {
              *buf = erealloc(*buf, ZEND_MMAP_AHEAD);
              file_handle->handle.stream.mmap.buf = *buf;
       }

       if (ZEND_MMAP_AHEAD) {
              memset(file_handle->handle.stream.mmap.buf + file_handle->handle.stream.mmap.len, 0, ZEND_MMAP_AHEAD);
       }

#if HAVE_MMAP
return_mapped:
#endif
       file_handle->type = ZEND_HANDLE_MAPPED;
       file_handle->handle.stream.mmap.pos        = 0;
       file_handle->handle.stream.mmap.old_handle = file_handle->handle.stream.handle;
       file_handle->handle.stream.mmap.old_closer = file_handle->handle.stream.closer;
       file_handle->handle.stream.handle          = &file_handle->handle.stream;
       file_handle->handle.stream.closer          = (zend_stream_closer_t)zend_stream_mmap_closer;

       *buf = file_handle->handle.stream.mmap.buf;
       *len = file_handle->handle.stream.mmap.len;

       return SUCCESS;
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static size_t zend_stream_fsize ( zend_file_handle *file_handle  TSRMLS_DC) [static]

Definition at line 107 of file zend_stream.c.

{
       struct stat buf;

       if (zend_stream_is_mmap(file_handle)) {
              return file_handle->handle.stream.mmap.len;
       }
       if (file_handle->type == ZEND_HANDLE_STREAM || file_handle->type == ZEND_HANDLE_MAPPED) {
              return file_handle->handle.stream.fsizer(file_handle->handle.stream.handle TSRMLS_CC);
       }
       if (file_handle->handle.fp && fstat(fileno(file_handle->handle.fp), &buf) == 0) {
#ifdef S_ISREG
              if (!S_ISREG(buf.st_mode)) {
                     return 0;
              }
#endif
              return buf.st_size;
       }

       return -1;
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static int zend_stream_getc ( zend_file_handle *file_handle  TSRMLS_DC) [static]

Definition at line 144 of file zend_stream.c.

{
       char buf;

       if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
              return (int)buf;
       }
       return EOF;
} /* }}} */

Here is the caller graph for this function:

static int zend_stream_is_mmap ( zend_file_handle file_handle) [inline, static]

Definition at line 103 of file zend_stream.c.

                                                                     { /* {{{ */
       return file_handle->type == ZEND_HANDLE_MAPPED;
} /* }}} */

Here is the caller graph for this function:

static void zend_stream_mmap_closer ( zend_stream *stream  TSRMLS_DC) [static]

Definition at line 95 of file zend_stream.c.

{
       zend_stream_unmap(stream TSRMLS_CC);
       if (stream->mmap.old_closer && stream->handle) {
              stream->mmap.old_closer(stream->handle TSRMLS_CC);
       }
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

ZEND_API int zend_stream_open ( const char *  filename,
zend_file_handle *handle  TSRMLS_DC 
)

Definition at line 129 of file zend_stream.c.

{
       if (zend_stream_open_function) {
              return zend_stream_open_function(filename, handle TSRMLS_CC);
       }
       handle->type = ZEND_HANDLE_FP;
       handle->opened_path = NULL;
       handle->handle.fp = zend_fopen(filename, &handle->opened_path TSRMLS_CC);
       handle->filename = (char *)filename;
       handle->free_filename = 0;
       memset(&handle->handle.stream.mmap, 0, sizeof(zend_mmap));
       
       return (handle->handle.fp) ? SUCCESS : FAILURE;
} /* }}} */

Here is the caller graph for this function:

static size_t zend_stream_read ( zend_file_handle file_handle,
char *  buf,
size_t len  TSRMLS_DC 
) [static]

Definition at line 154 of file zend_stream.c.

{
       if (!zend_stream_is_mmap(file_handle) && file_handle->handle.stream.isatty) {
              int c = '*';
              size_t n;

#ifdef NETWARE
              /*
                     c != 4 check is there as fread of a character in NetWare LibC gives 4 upon ^D character.
                     Ascii value 4 is actually EOT character which is not defined anywhere in the LibC
                     or else we can use instead of hardcoded 4.
              */
              for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n) {
#else
              for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n)  {
#endif
                     buf[n] = (char)c;
              }
              if (c == '\n') {
                     buf[n++] = (char)c; 
              }

              return n;
       }
       return file_handle->handle.stream.reader(file_handle->handle.stream.handle, buf, len TSRMLS_CC);
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static void zend_stream_stdio_closer ( void *handle  TSRMLS_DC) [static]

Definition at line 58 of file zend_stream.c.

{
       if (handle && (FILE*)handle != stdin) {
              fclose((FILE*)handle);
       }
} /* }}} */

Here is the caller graph for this function:

static size_t zend_stream_stdio_fsizer ( void *handle  TSRMLS_DC) [static]

Definition at line 65 of file zend_stream.c.

{
       struct stat buf;
       if (handle && fstat(fileno((FILE*)handle), &buf) == 0) {
#ifdef S_ISREG
              if (!S_ISREG(buf.st_mode)) {
                     return 0;
              }
#endif
              return buf.st_size;
       }
       return 0;
} /* }}} */

Here is the caller graph for this function:

static size_t zend_stream_stdio_reader ( void *  handle,
char *  buf,
size_t len  TSRMLS_DC 
) [static]

Definition at line 53 of file zend_stream.c.

{
       return fread(buf, 1, len, (FILE*)handle);
} /* }}} */

Here is the caller graph for this function:

static void zend_stream_unmap ( zend_stream *stream  TSRMLS_DC) [static]

Definition at line 79 of file zend_stream.c.

                                                             { /* {{{ */
#if HAVE_MMAP
       if (stream->mmap.map) {
              munmap(stream->mmap.map, stream->mmap.len);
       } else
#endif
       if (stream->mmap.buf) {
              efree(stream->mmap.buf);
       }
       stream->mmap.len = 0;
       stream->mmap.pos = 0;
       stream->mmap.map = 0;
       stream->mmap.buf = 0;
       stream->handle   = stream->mmap.old_handle;
} /* }}} */

Here is the caller graph for this function: