summaryrefslogtreecommitdiff
path: root/main/streams/plain_wrapper.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-02-27 17:43:38 +0000
committerWez Furlong <wez@php.net>2003-02-27 17:43:38 +0000
commitfd61f69077f6156ca71dde60ecfd9ed9765a02db (patch)
tree7285ad393cdb5a85107a3329d1ab2bcafe89f051 /main/streams/plain_wrapper.c
parent560e33968de93250377606782949f5004affca83 (diff)
downloadphp-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.c90
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,