diff options
author | Wez Furlong <wez@php.net> | 2003-02-27 17:43:38 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2003-02-27 17:43:38 +0000 |
commit | fd61f69077f6156ca71dde60ecfd9ed9765a02db (patch) | |
tree | 7285ad393cdb5a85107a3329d1ab2bcafe89f051 /main/streams/plain_wrapper.c | |
parent | 560e33968de93250377606782949f5004affca83 (diff) | |
download | php-git-fd61f69077f6156ca71dde60ecfd9ed9765a02db.tar.gz |
Another big commit (tm).
Main Changes:
- Implement a socket transport layer for use by all code that needs to open
some kind of "special" socket for network or IPC.
- Extensions can register (and override) transports.
- Implement ftruncate() on streams via the ioctl-alike option interface.
- Implement mmap() on streams via the ioctl-alike option interface.
- Implement generic crypto API via the ioctl-alike option interface.
(currently only supports OpenSSL, but could support other SSL toolkits,
and other crypto transport protocols).
Impact:
- tcp sockets can be overloaded by the openssl capable sockets at runtime,
removing the link-time requirement for ssl:// and https:// sockets and
streams.
- checking stream types using PHP_STREAM_IS_SOCKET is deprecated, since
there are now a range of possible socket-type streams.
Working towards:
- socket servers using the new transport layer
- mmap support under win32
- Cleaner code.
# I will be updating the win32 build to add the new files shortly
# after this commit.
Diffstat (limited to 'main/streams/plain_wrapper.c')
-rw-r--r-- | main/streams/plain_wrapper.c | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index f73c2642aa..f121b8ce15 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -32,6 +32,9 @@ #if HAVE_SYS_FILE_H #include <sys/file.h> #endif +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif #include "php_streams_int.h" @@ -135,12 +138,17 @@ typedef struct { int fd; /* underlying file descriptor */ int is_process_pipe; /* use pclose instead of fclose */ int is_pipe; /* don't try and seek */ - int lock_flag; /* stores the lock state */ + int lock_flag; /* stores the lock state */ char *temp_file_name; /* if non-null, this is the path to a temporary file that * is to be deleted when the stream is closed */ #if HAVE_FLUSHIO char last_op; #endif + +#if HAVE_MMAP + char *last_mapped_addr; + size_t last_mapped_len; +#endif } php_stdio_stream_data; PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC) @@ -348,6 +356,13 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; assert(data != NULL); + +#if HAVE_MMAP + if (data->last_mapped_addr) { + munmap(data->last_mapped_addr, data->last_mapped_len); + data->last_mapped_addr = NULL; + } +#endif if (close_handle) { if (data->lock_flag != LOCK_UN) { @@ -572,8 +587,76 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void } break; + case PHP_STREAM_OPTION_MMAP_API: +#if HAVE_MMAP + { + php_stream_mmap_range *range = (php_stream_mmap_range*)ptrparam; + struct stat sbuf; + int prot, flags; + + switch (value) { + case PHP_STREAM_MMAP_SUPPORTED: + return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_MMAP_MAP_RANGE: + fstat(fd, &sbuf); + if (range->length == 0 || range->length > sbuf.st_size) { + range->length = sbuf.st_size; + } + switch (range->mode) { + case PHP_STREAM_MAP_MODE_READONLY: + prot = PROT_READ; + flags = MAP_PRIVATE; + break; + case PHP_STREAM_MAP_MODE_READWRITE: + prot = PROT_READ | PROT_WRITE; + flags = MAP_PRIVATE; + break; + case PHP_STREAM_MAP_MODE_SHARED_READONLY: + prot = PROT_READ; + flags = MAP_SHARED; + break; + case PHP_STREAM_MAP_MODE_SHARED_READWRITE: + prot = PROT_READ | PROT_WRITE; + flags = MAP_SHARED; + break; + default: + return PHP_STREAM_OPTION_RETURN_ERR; + } + range->mapped = (char*)mmap(NULL, range->length, prot, flags, fd, range->offset); + if (range->mapped == (char*)MAP_FAILED) { + range->mapped = NULL; + return PHP_STREAM_OPTION_RETURN_ERR; + } + /* remember the mapping */ + data->last_mapped_addr = range->mapped; + data->last_mapped_len = range->length; + return PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_MMAP_UNMAP: + if (data->last_mapped_addr) { + munmap(data->last_mapped_addr, data->last_mapped_len); + data->last_mapped_addr = NULL; + + return PHP_STREAM_OPTION_RETURN_OK; + } + return PHP_STREAM_OPTION_RETURN_ERR; + } + } +#endif + return PHP_STREAM_OPTION_RETURN_NOTIMPL; + + case PHP_STREAM_OPTION_TRUNCATE_API: + switch (value) { + case PHP_STREAM_TRUNCATE_SUPPORTED: + return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_TRUNCATE_SET_SIZE: + return ftruncate(fd, *(size_t*)ptrparam) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; + } + default: - return -1; + return PHP_STREAM_OPTION_RETURN_NOTIMPL; } } @@ -588,6 +671,7 @@ PHPAPI php_stream_ops php_stream_stdio_ops = { }; /* }}} */ +/* {{{ plain files opendir/readdir implementation */ static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { DIR *dir = (DIR*)stream->abstract; @@ -658,7 +742,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char return stream; } - +/* }}} */ static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode, |