summaryrefslogtreecommitdiff
path: root/ext/zlib
diff options
context:
space:
mode:
authorHartmut Holzgraefe <hholzgra@php.net>2000-10-11 22:40:22 +0000
committerHartmut Holzgraefe <hholzgra@php.net>2000-10-11 22:40:22 +0000
commit5423a08558e6be4658461d86c3496e3292471de0 (patch)
treeac2a1e96e202647b4bab5a6e46f7345e9173a2bd /ext/zlib
parent2b3333f53e7c31ad16faedeb483bc64a89648ed6 (diff)
downloadphp-git-5423a08558e6be4658461d86c3496e3292471de0.tar.gz
@ -read and write .gz-files transparently on glibc based systems
@ using the 'zlib:' fopen wrapper (Hartmut)
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/config.m42
-rw-r--r--ext/zlib/zlib.c86
2 files changed, 88 insertions, 0 deletions
diff --git a/ext/zlib/config.m4 b/ext/zlib/config.m4
index d9b5dd66fb..1c4df2eee7 100644
--- a/ext/zlib/config.m4
+++ b/ext/zlib/config.m4
@@ -41,4 +41,6 @@ if test "$PHP_ZLIB" != "no"; then
AC_ADD_LIBRARY_WITH_PATH(z, $ZLIB_LIBDIR, ZLIB_SHARED_LIBADD)
AC_ADD_INCLUDE($ZLIB_INCDIR)
+
+ AC_CHECK_FUNC(fopencookie, [AC_DEFINE(HAVE_FOPENCOOKIE,1,[ ])])
fi
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index d62a994e29..4e160f506d 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -19,8 +19,17 @@
/* $Id$ */
#define IS_EXT_MODULE
+#include "php_config.h"
+
+#if HAVE_FOPENCOOKIE
+#define _GNU_SOURCE
+#include "libio.h"
+#endif
+
#include "php.h"
+
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -74,6 +83,9 @@ int zlib_globals_id;
static php_zlib_globals zlib_globals;
#endif
+#if HAVE_FOPENCOOKIE
+static FILE *zlib_fopen_wrapper(const char *path, char *mode, int options, int *issock, int *socketd, char **opened_path);
+#endif
/* True globals, no need for thread safety */
static int le_zp;
@@ -133,11 +145,20 @@ PHP_MINIT_FUNCTION(zlib)
ZLIBG(gzgetss_state)=0;
#endif
le_zp = register_list_destructors(phpi_destructor_gzclose,NULL);
+
+#if HAVE_FOPENCOOKIE
+ php_register_url_wrapper("zlib",zlib_fopen_wrapper);
+#endif
+
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(zlib)
{
+#if HAVE_FOPENCOOKIE
+ php_unregister_url_wrapper("zlib");
+#endif
+
return SUCCESS;
}
@@ -145,6 +166,9 @@ PHP_MINFO_FUNCTION(zlib)
{
php_info_print_table_start();
php_info_print_table_row(2, "ZLib Support", "enabled");
+#if HAVE_FOPENCOOKIE
+ php_info_print_table_row(2, "'zlib:' fopen wrapper", "enabled");
+#endif
php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION );
php_info_print_table_row(2, "Linked Version", (char *)zlibVersion() );
php_info_print_table_end();
@@ -735,6 +759,68 @@ PHP_FUNCTION(gzuncompress)
}
/* }}} */
+#if HAVE_FOPENCOOKIE
+struct gz_cookie {
+ gzFile gz_file;
+};
+
+static ssize_t gz_reader(void *cookie, char *buffer, size_t size)
+{
+ return gzread(((struct gz_cookie *)cookie)->gz_file,buffer,size);
+}
+
+static ssize_t gz_writer(void *cookie, char *buffer, size_t size) {
+ return gzwrite(((struct gz_cookie *)cookie)->gz_file,buffer,size);
+}
+
+static int gz_seeker(void *cookie,fpos_t *position, int whence) {
+ return (*position=gzseek(((struct gz_cookie *)cookie)->gz_file,*position,whence));
+}
+
+static int gz_cleaner(void *cookie) {
+ gzclose(((struct gz_cookie *)cookie)->gz_file);
+ efree(cookie);
+ cookie=NULL;
+}
+
+
+static cookie_io_functions_t gz_cookie_functions =
+{ gz_reader
+, gz_writer
+, gz_seeker
+, gz_cleaner
+};
+
+static FILE *zlib_fopen_wrapper(const char *path, char *mode, int options, int *issock, int *socketd, char **opened_path)
+{
+ struct gz_cookie *gc = NULL;
+
+ gc = (struct gz_cookie *)emalloc(sizeof(struct gz_cookie));
+
+ if(gc) {
+ *issock = 0;
+
+ while(*path!=':')
+ path++;
+
+ path++;
+
+ gc->gz_file = gzopen(path,mode);
+
+ if(gc->gz_file) {
+ return fopencookie(gc,mode,gz_cookie_functions);
+ } else {
+ efree(gc);
+ return NULL;
+ }
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+
+#endif
+
#endif /* HAVE_ZLIB */