Back to index

php5  5.3.10
Classes | Defines | Typedefs | Enumerations | Functions
zend_stream.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _zend_mmap
struct  _zend_stream
struct  _zend_file_handle
union  _zend_file_handle.handle

Defines

#define ZEND_MMAP_AHEAD   32

Typedefs

typedef size_t(* zend_stream_fsizer_t )(void *handle TSRMLS_DC)
typedef size_t(* zend_stream_reader_t )(void *handle, char *buf, size_t len TSRMLS_DC)
typedef void(* zend_stream_closer_t )(void *handle TSRMLS_DC)
typedef struct _zend_mmap zend_mmap
typedef struct _zend_stream zend_stream
typedef struct _zend_file_handle zend_file_handle

Enumerations

enum  zend_stream_type {
  ZEND_HANDLE_FILENAME, ZEND_HANDLE_FD, ZEND_HANDLE_FP, ZEND_HANDLE_STREAM,
  ZEND_HANDLE_MAPPED
}

Functions

ZEND_API int zend_stream_open (const char *filename, zend_file_handle *handle 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)

Class Documentation

struct _zend_mmap

Definition at line 44 of file zend_stream.h.

Class Members
char * buf
size_t len
void * map
zend_stream_closer_t old_closer
void * old_handle
size_t pos
struct _zend_stream

Definition at line 53 of file zend_stream.h.

Collaboration diagram for _zend_stream:
Class Members
zend_stream_closer_t closer
zend_stream_fsizer_t fsizer
void * handle
int isatty
zend_mmap mmap
zend_stream_reader_t reader
struct _zend_file_handle

Definition at line 62 of file zend_stream.h.

Class Members
char * filename
zend_bool free_filename
union _zend_file_handle handle
char * opened_path
zend_stream_type type
union _zend_file_handle.handle

Definition at line 66 of file zend_stream.h.

Class Members
int fd
FILE * fp
zend_stream stream

Define Documentation

#define ZEND_MMAP_AHEAD   32

Definition at line 34 of file zend_stream.h.


Typedef Documentation

typedef struct _zend_mmap zend_mmap
typedef struct _zend_stream zend_stream
typedef void(* zend_stream_closer_t)(void *handle TSRMLS_DC)

Definition at line 32 of file zend_stream.h.

typedef size_t(* zend_stream_fsizer_t)(void *handle TSRMLS_DC)

Definition at line 30 of file zend_stream.h.

typedef size_t(* zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC)

Definition at line 31 of file zend_stream.h.


Enumeration Type Documentation

Enumerator:
ZEND_HANDLE_FILENAME 
ZEND_HANDLE_FD 
ZEND_HANDLE_FP 
ZEND_HANDLE_STREAM 
ZEND_HANDLE_MAPPED 

Definition at line 36 of file zend_stream.h.


Function Documentation

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;
} /* }}} */

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:

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: