From 6d0f0e0acb95c23a476510726bf7c5fe6fb840bf Mon Sep 17 00:00:00 2001
From: Andy Cedilnik <andy.cedilnik@kitware.com>
Date: Fri, 30 Dec 2005 14:22:46 -0500
Subject: COMP: Fix support for gzip on non-32 bit platforms

---
 Source/cmSystemTools.cxx | 74 +++++++++++++++++++++++++++++++++++++++---------
 Utilities/cmtar/handle.c | 40 +++++++++++++++-----------
 Utilities/cmtar/libtar.c | 50 ++++++++++++++++++++++++++------
 Utilities/cmtar/libtar.h | 19 +++++++++----
 4 files changed, 138 insertions(+), 45 deletions(-)

diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index f7ea1ef..7caafd0 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1365,12 +1365,22 @@ bool cmSystemTools::IsPathToFramework(const char* path)
 #  include <fcntl.h>
 #  include <cmzlib/zlib.h>
 
-static int gzopen_frontend(char *pathname, int oflags, int mode)
+struct cmSystemToolsGZStruct
+{
+  gzFile GZFile;
+  static int Open(void* call_data, const char *pathname, int oflags, mode_t mode);
+  static int Close(void* call_data, int fd);
+  static ssize_t Read(void* call_data, int fd, void* buf, size_t count);
+  static ssize_t Write(void* call_data, int fd, const void* buf, size_t count);
+};
+
+int cmSystemToolsGZStruct::Open(void* call_data, const char *pathname, int oflags, mode_t mode)
 {
   char *gzoflags;
-  gzFile gzf;
   int fd;
 
+  cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
+
   switch (oflags & O_ACCMODE)
   {
   case O_WRONLY:
@@ -1398,14 +1408,35 @@ static int gzopen_frontend(char *pathname, int oflags, int mode)
     }
 #endif
 
-  gzf = cm_zlib_gzdopen(fd, gzoflags);
-  if (!gzf)
+  gzf->GZFile = cm_zlib_gzdopen(fd, gzoflags);
+  if (!gzf->GZFile)
   {
     errno = ENOMEM;
     return -1;
   }
 
-  return (int)gzf;
+  return fd;
+}
+
+int cmSystemToolsGZStruct::Close(void* call_data, int fd)
+{
+  (void)fd;
+  cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
+  return cm_zlib_gzclose(gzf->GZFile);
+}
+
+ssize_t cmSystemToolsGZStruct::Read(void* call_data, int fd, void* buf, size_t count)
+{
+  (void)fd;
+  cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
+  return cm_zlib_gzread(gzf->GZFile, buf, count);
+}
+
+ssize_t cmSystemToolsGZStruct::Write(void* call_data, int fd, const void* buf, size_t count)
+{
+  (void)fd;
+  cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
+  return cm_zlib_gzwrite(gzf->GZFile, (void*)buf, count);
 }
 
 #endif
@@ -1416,9 +1447,14 @@ bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdSt
   TAR *t;
   char buf[TAR_MAXPATHLEN];
   char pathname[TAR_MAXPATHLEN];
-
-  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) cm_zlib_gzclose,
-    (readfunc_t) cm_zlib_gzread, (writefunc_t) cm_zlib_gzwrite
+  cmSystemToolsGZStruct gzs;
+
+  tartype_t gztype = {
+    cmSystemToolsGZStruct::Open,
+    cmSystemToolsGZStruct::Close,
+    cmSystemToolsGZStruct::Read,
+    cmSystemToolsGZStruct::Write,
+    &gzs
   };
 
   // Ok, this libtar is not const safe. for now use auto_ptr hack
@@ -1476,9 +1512,14 @@ bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdS
   (void)files;
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   TAR *t;
-
-  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) cm_zlib_gzclose,
-    (readfunc_t) cm_zlib_gzread, (writefunc_t) cm_zlib_gzwrite
+  cmSystemToolsGZStruct gzs;
+
+  tartype_t gztype = {
+    cmSystemToolsGZStruct::Open,
+    cmSystemToolsGZStruct::Close,
+    cmSystemToolsGZStruct::Read,
+    cmSystemToolsGZStruct::Write,
+    &gzs
   };
 
   // Ok, this libtar is not const safe. for now use auto_ptr hack
@@ -1520,9 +1561,14 @@ bool cmSystemTools::ListTar(const char* outFileName, std::vector<cmStdString>& f
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   TAR *t;
-
-  tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) cm_zlib_gzclose,
-    (readfunc_t) cm_zlib_gzread, (writefunc_t) cm_zlib_gzwrite
+  cmSystemToolsGZStruct gzs;
+
+  tartype_t gztype = {
+    cmSystemToolsGZStruct::Open,
+    cmSystemToolsGZStruct::Close,
+    cmSystemToolsGZStruct::Read,
+    cmSystemToolsGZStruct::Write,
+    &gzs
   };
 
   // Ok, this libtar is not const safe. for now use auto_ptr hack
diff --git a/Utilities/cmtar/handle.c b/Utilities/cmtar/handle.c
index 3bf4c28..6770b2b 100644
--- a/Utilities/cmtar/handle.c
+++ b/Utilities/cmtar/handle.c
@@ -34,23 +34,29 @@
 
 const char libtar_version[] = PACKAGE_VERSION;
 
-#define libtar_symbol(name, ret, args, callargs) \
-  static ret libtar_##name args \
-  { \
-    return name callargs; \
-  }
-
-#if defined(__BORLANDC__)
-libtar_symbol(open, int, (const char* pathname, int flags, mode_t mode), (pathname, flags, mode));
-libtar_symbol(close, int, (int fd), (fd));
-libtar_symbol(read, ssize_t, (int fd, void* buf, size_t count), (fd, buf, count));
-libtar_symbol(write, ssize_t, (int fd, void* buf, size_t count), (fd, buf, count));
+static int libtar_open(void* call_data, const char* pathname, int flags, mode_t mode)
+{
+  (void)call_data;
+  return open(pathname, flags, mode);
+}
 
-static tartype_t default_type = { libtar_open, libtar_close, libtar_read, libtar_write };
-#else
-static tartype_t default_type = { open, close, read, write };
-#endif
+static int libtar_close(void* call_data, int fd)
+{
+  (void)call_data;
+  return close(fd);
+}
+static ssize_t libtar_read(void* call_data, int fd, void* buf, size_t count)
+{
+  (void)call_data;
+  return read(fd, buf, count);
+}
+static ssize_t libtar_write(void* call_data, int fd, const void* buf, size_t count)
+{
+  (void)call_data;
+  return write(fd, buf, count);
+}
 
+static tartype_t default_type = { libtar_open, libtar_close, libtar_read, libtar_write, 0 };
 
 static int
 tar_init(TAR **t, char *pathname, tartype_t *type,
@@ -102,7 +108,7 @@ tar_open(TAR **t, char *pathname, tartype_t *type,
   oflags |= O_BINARY;
 #endif
 
-  (*t)->fd = (*((*t)->type->openfunc))(pathname, oflags, mode);
+  (*t)->fd = (*((*t)->type->openfunc))((*t)->type->call_data, pathname, oflags, mode);
   if ((*t)->fd == -1)
   {
     free(*t);
@@ -138,7 +144,7 @@ tar_close(TAR *t)
 {
   int i;
 
-  i = (*(t->type->closefunc))(t->fd);
+  i = (*(t->type->closefunc))(t->type->call_data, t->fd);
 
   if (t->h != NULL)
     libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY
diff --git a/Utilities/cmtar/libtar.c b/Utilities/cmtar/libtar.c
index 91fed5c..58326b0 100644
--- a/Utilities/cmtar/libtar.c
+++ b/Utilities/cmtar/libtar.c
@@ -61,12 +61,17 @@ segv_handler(int sig)
 
 int use_zlib = 0;
 
-int
-gzopen_frontend(char *pathname, int oflags, int mode)
+struct gzStruct
+{
+  gzFile* GZFile;
+};
+struct gzStruct GZStruct;
+
+int libtar_gzopen(void* call_data, const char *pathname, int oflags, mode_t mode)
 {
   char *gzoflags;
-  gzFile gzf;
   int fd;
+  struct gzStruct* gzf = (struct gzStruct*)call_data;
 
   switch (oflags & O_ACCMODE)
   {
@@ -84,25 +89,54 @@ gzopen_frontend(char *pathname, int oflags, int mode)
 
   fd = open(pathname, oflags, mode);
   if (fd == -1)
+    {
     return -1;
+    }
 
 #if !defined(_WIN32) || defined(__CYGWIN__)
   if ((oflags & O_CREAT) && fchmod(fd, mode))
+    {
     return -1;
+    }
 #endif
 
-  gzf = gzdopen(fd, gzoflags);
-  if (!gzf)
+  gzf->GZFile = cm_zlib_gzdopen(fd, gzoflags);
+  if (!gzf->GZFile)
   {
     errno = ENOMEM;
     return -1;
   }
 
-  return (int)gzf;
+  return fd;
+}
+
+int libtar_gzclose(void* call_data, int fd)
+{
+  struct gzStruct* gzf = (struct gzStruct*)call_data;
+  (void)fd;
+  return cm_zlib_gzclose(gzf->GZFile);
+}
+
+ssize_t libtar_gzread(void* call_data, int fd, void* buf, size_t count)
+{
+  struct gzStruct* gzf = (struct gzStruct*)call_data;
+  (void)fd;
+  return cm_zlib_gzread(gzf->GZFile, buf, count);
+}
+
+ssize_t libtar_gzwrite(void* call_data, int fd, const void* buf, size_t count)
+{
+  struct gzStruct* gzf = (struct gzStruct*)call_data;
+  (void)fd;
+  return cm_zlib_gzwrite(gzf->GZFile, (void*)buf, count);
 }
 
-tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
-  (readfunc_t) gzread, (writefunc_t) gzwrite
+tartype_t gztype = { 
+  libtar_gzopen,
+  libtar_gzclose,
+  libtar_gzread,
+  libtar_gzwrite,
+  &GZStruct
 };
 
 #endif /* HAVE_LIBZ */
diff --git a/Utilities/cmtar/libtar.h b/Utilities/cmtar/libtar.h
index ef822ea..9990a97 100644
--- a/Utilities/cmtar/libtar.h
+++ b/Utilities/cmtar/libtar.h
@@ -62,10 +62,10 @@ struct tar_header
 
 /***** handle.c ************************************************************/
 
-typedef int (*openfunc_t)(const char *, int, ...);
-typedef int (*closefunc_t)(int);
-typedef ssize_t (*readfunc_t)(int, void *, size_t);
-typedef ssize_t (*writefunc_t)(int, const void *, size_t);
+typedef int (*openfunc_t)(void* call_data, const char *, int, mode_t);
+typedef int (*closefunc_t)(void* call_data, int);
+typedef ssize_t (*readfunc_t)(void* call_data, int, void *, size_t);
+typedef ssize_t (*writefunc_t)(void* call_data, int, const void *, size_t);
 
 typedef struct
 {
@@ -73,6 +73,7 @@ typedef struct
   closefunc_t closefunc;
   readfunc_t readfunc;
   writefunc_t writefunc;
+  void* call_data;
 }
 tartype_t;
 
@@ -114,6 +115,12 @@ int tar_fdopen(TAR **t, int fd, char *pathname, tartype_t *type,
 /* returns the descriptor associated with t */
 int tar_fd(TAR *t);
 
+/* returns the descriptor associated with t */
+void* tar_call_data(TAR *t);
+
+/* returns the descriptor associated with t */
+void tar_set_call_data(TAR *t, void* cd);
+
 /* close tarfile handle */
 int tar_close(TAR *t);
 
@@ -145,9 +152,9 @@ int tar_append_regfile(TAR *t, char *realname);
 
 /* macros for reading/writing tarchive blocks */
 #define tar_block_read(t, buf) \
-  (*((t)->type->readfunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
+  (*((t)->type->readfunc))((t)->type->call_data, (t)->fd, (char *)(buf), T_BLOCKSIZE)
 #define tar_block_write(t, buf) \
-  (*((t)->type->writefunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
+  (*((t)->type->writefunc))((t)->type->call_data, (t)->fd, (char *)(buf), T_BLOCKSIZE)
 
 /* read/write a header block */
 int th_read(TAR *t);
-- 
cgit v0.12