src/java.base/share/native/libzip/zip_util.c

Print this page


   1 /*
   2  * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 106         OPEN_EXISTING;
 107     const DWORD  maybeWriteThrough =
 108         (flags & (O_SYNC | O_DSYNC)) ?
 109         FILE_FLAG_WRITE_THROUGH :
 110         FILE_ATTRIBUTE_NORMAL;
 111     const DWORD maybeDeleteOnClose =
 112         (flags & O_TEMPORARY) ?
 113         FILE_FLAG_DELETE_ON_CLOSE :
 114         FILE_ATTRIBUTE_NORMAL;
 115     const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;
 116 
 117     return (jlong) CreateFile(
 118         fname,          /* Wide char path name */
 119         access,         /* Read and/or write permission */
 120         sharing,        /* File sharing flags */
 121         NULL,           /* Security attributes */
 122         disposition,        /* creation disposition */
 123         flagsAndAttributes, /* flags and attributes */
 124         NULL);
 125 #else
 126     return JVM_Open(fname, flags, 0);
 127 #endif
 128 }
 129 
 130 /*
 131  * The io_util_md.h files do not provide IO_CLOSE, hence we use platform
 132  * specifics.
 133  */
 134 static void
 135 ZFILE_Close(ZFILE zfd) {
 136 #ifdef WIN32
 137     CloseHandle((HANDLE) zfd);
 138 #else
 139     JVM_Close(zfd);
 140 #endif
 141 }
 142 
 143 static int
 144 ZFILE_read(ZFILE zfd, char *buf, jint nbytes) {
 145 #ifdef WIN32
 146     return (int) IO_Read(zfd, buf, nbytes);
 147 #else
 148     /*
 149      * Calling JVM_Read will return JVM_IO_INTR when Thread.interrupt is called
 150      * only on Solaris. Continue reading jar file in this case is the best
 151      * thing to do since zip file reading is relatively fast and it is very onerous
 152      * for a interrupted thread to deal with this kind of hidden I/O. However, handling
 153      * JVM_IO_INTR is tricky and could cause undesired side effect. So we decided
 154      * to simply call "read" on Solaris/Linux. See details in bug 6304463.
 155      */
 156     return read(zfd, buf, nbytes);
 157 #endif
 158 }
 159 
 160 /*
 161  * Initialize zip file support. Return 0 if successful otherwise -1
 162  * if could not be initialized.
 163  */
 164 static jint
 165 InitializeZip()
 166 {
 167     static jboolean inited = JNI_FALSE;
 168 
 169     // Initialize errno to 0.  It may be set later (e.g. during memory
 170     // allocation) but we can disregard previous values.
 171     errno = 0;
 172 
 173     if (inited)
 174         return 0;
 175     zfiles_lock = MCREATE();


 181     return 0;
 182 }
 183 
 184 /*
 185  * Reads len bytes of data into buf.
 186  * Returns 0 if all bytes could be read, otherwise returns -1.
 187  */
 188 static int
 189 readFully(ZFILE zfd, void *buf, jlong len) {
 190   char *bp = (char *) buf;
 191 
 192   while (len > 0) {
 193         jlong limit = ((((jlong) 1) << 31) - 1);
 194         jint count = (len < limit) ?
 195             (jint) len :
 196             (jint) limit;
 197         jint n = ZFILE_read(zfd, bp, count);
 198         if (n > 0) {
 199             bp += n;
 200             len -= n;
 201         } else if (n == JVM_IO_ERR && errno == EINTR) {
 202           /* Retry after EINTR (interrupted by signal).
 203              We depend on the fact that JVM_IO_ERR == -1. */
 204             continue;
 205         } else { /* EOF or IO error */
 206             return -1;
 207         }
 208     }
 209     return 0;
 210 }
 211 
 212 /*
 213  * Reads len bytes of data from the specified offset into buf.
 214  * Returns 0 if all bytes could be read, otherwise returns -1.
 215  */
 216 static int
 217 readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset)
 218 {
 219     if (IO_Lseek(zfd, offset, SEEK_SET) == -1) {
 220         return -1; /* lseek failure. */
 221     }
 222 
 223     return readFully(zfd, buf, len);


 811 
 812 jzfile *
 813 ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
 814                  jboolean usemmap)
 815 {
 816     char errbuf[256];
 817     jlong len;
 818     jzfile *zip;
 819 
 820     if ((zip = allocZip(name)) == NULL) {
 821         return NULL;
 822     }
 823 
 824 #ifdef USE_MMAP
 825     zip->usemmap = usemmap;
 826 #endif
 827     zip->refs = 1;
 828     zip->lastModified = lastModified;
 829 
 830     if (zfd == -1) {
 831         if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
 832             *pmsg = strdup(errbuf);
 833         freeZip(zip);
 834         return NULL;
 835     }
 836 
 837     // Assumption, zfd refers to start of file. Trivially, reuse errbuf.
 838     if (readFully(zfd, errbuf, 4) != -1) {  // errors will be handled later
 839         if (GETSIG(errbuf) == LOCSIG)
 840             zip->locsig = JNI_TRUE;
 841         else
 842             zip->locsig = JNI_FALSE;
 843     }
 844 
 845     len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
 846     if (len <= 0) {
 847         if (len == 0) { /* zip file is empty */
 848             if (pmsg) {
 849                 *pmsg = strdup("zip file is empty");
 850             }
 851         } else { /* error */
 852             if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
 853                 *pmsg = strdup(errbuf);
 854         }
 855         ZFILE_Close(zfd);
 856         freeZip(zip);
 857         return NULL;
 858     }
 859 
 860     zip->zfd = zfd;
 861     if (readCEN(zip, -1) < 0) {
 862         /* An error occurred while trying to read the zip file */
 863         if (pmsg != 0) {
 864             /* Set the zip error message */
 865             if (zip->msg != NULL)
 866                 *pmsg = strdup(zip->msg);
 867         }
 868         freeZip(zip);
 869         return NULL;
 870     }
 871     MLOCK(zfiles_lock);
 872     zip->next = zfiles;


   1 /*
   2  * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 106         OPEN_EXISTING;
 107     const DWORD  maybeWriteThrough =
 108         (flags & (O_SYNC | O_DSYNC)) ?
 109         FILE_FLAG_WRITE_THROUGH :
 110         FILE_ATTRIBUTE_NORMAL;
 111     const DWORD maybeDeleteOnClose =
 112         (flags & O_TEMPORARY) ?
 113         FILE_FLAG_DELETE_ON_CLOSE :
 114         FILE_ATTRIBUTE_NORMAL;
 115     const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;
 116 
 117     return (jlong) CreateFile(
 118         fname,          /* Wide char path name */
 119         access,         /* Read and/or write permission */
 120         sharing,        /* File sharing flags */
 121         NULL,           /* Security attributes */
 122         disposition,        /* creation disposition */
 123         flagsAndAttributes, /* flags and attributes */
 124         NULL);
 125 #else
 126     return open(fname, flags, 0);
 127 #endif
 128 }
 129 
 130 /*
 131  * The io_util_md.h files do not provide IO_CLOSE, hence we use platform
 132  * specifics.
 133  */
 134 static void
 135 ZFILE_Close(ZFILE zfd) {
 136 #ifdef WIN32
 137     CloseHandle((HANDLE) zfd);
 138 #else
 139     close(zfd);
 140 #endif
 141 }
 142 
 143 static int
 144 ZFILE_read(ZFILE zfd, char *buf, jint nbytes) {
 145 #ifdef WIN32
 146     return (int) IO_Read(zfd, buf, nbytes);
 147 #else








 148     return read(zfd, buf, nbytes);
 149 #endif
 150 }
 151 
 152 /*
 153  * Initialize zip file support. Return 0 if successful otherwise -1
 154  * if could not be initialized.
 155  */
 156 static jint
 157 InitializeZip()
 158 {
 159     static jboolean inited = JNI_FALSE;
 160 
 161     // Initialize errno to 0.  It may be set later (e.g. during memory
 162     // allocation) but we can disregard previous values.
 163     errno = 0;
 164 
 165     if (inited)
 166         return 0;
 167     zfiles_lock = MCREATE();


 173     return 0;
 174 }
 175 
 176 /*
 177  * Reads len bytes of data into buf.
 178  * Returns 0 if all bytes could be read, otherwise returns -1.
 179  */
 180 static int
 181 readFully(ZFILE zfd, void *buf, jlong len) {
 182   char *bp = (char *) buf;
 183 
 184   while (len > 0) {
 185         jlong limit = ((((jlong) 1) << 31) - 1);
 186         jint count = (len < limit) ?
 187             (jint) len :
 188             (jint) limit;
 189         jint n = ZFILE_read(zfd, bp, count);
 190         if (n > 0) {
 191             bp += n;
 192             len -= n;
 193         } else if (n == -1 && errno == EINTR) {
 194           /* Retry after EINTR (interrupted by signal). */

 195             continue;
 196         } else { /* EOF or IO error */
 197             return -1;
 198         }
 199     }
 200     return 0;
 201 }
 202 
 203 /*
 204  * Reads len bytes of data from the specified offset into buf.
 205  * Returns 0 if all bytes could be read, otherwise returns -1.
 206  */
 207 static int
 208 readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset)
 209 {
 210     if (IO_Lseek(zfd, offset, SEEK_SET) == -1) {
 211         return -1; /* lseek failure. */
 212     }
 213 
 214     return readFully(zfd, buf, len);


 802 
 803 jzfile *
 804 ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
 805                  jboolean usemmap)
 806 {
 807     char errbuf[256];
 808     jlong len;
 809     jzfile *zip;
 810 
 811     if ((zip = allocZip(name)) == NULL) {
 812         return NULL;
 813     }
 814 
 815 #ifdef USE_MMAP
 816     zip->usemmap = usemmap;
 817 #endif
 818     zip->refs = 1;
 819     zip->lastModified = lastModified;
 820 
 821     if (zfd == -1) {
 822         if (pmsg && getLastErrorString(errbuf, sizeof(errbuf)) > 0)
 823             *pmsg = strdup(errbuf);
 824         freeZip(zip);
 825         return NULL;
 826     }
 827 
 828     // Assumption, zfd refers to start of file. Trivially, reuse errbuf.
 829     if (readFully(zfd, errbuf, 4) != -1) {  // errors will be handled later
 830         if (GETSIG(errbuf) == LOCSIG)
 831             zip->locsig = JNI_TRUE;
 832         else
 833             zip->locsig = JNI_FALSE;
 834     }
 835 
 836     len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
 837     if (len <= 0) {
 838         if (len == 0) { /* zip file is empty */
 839             if (pmsg) {
 840                 *pmsg = strdup("zip file is empty");
 841             }
 842         } else { /* error */
 843             if (pmsg && getLastErrorString(errbuf, sizeof(errbuf)) > 0)
 844                 *pmsg = strdup(errbuf);
 845         }
 846         ZFILE_Close(zfd);
 847         freeZip(zip);
 848         return NULL;
 849     }
 850 
 851     zip->zfd = zfd;
 852     if (readCEN(zip, -1) < 0) {
 853         /* An error occurred while trying to read the zip file */
 854         if (pmsg != 0) {
 855             /* Set the zip error message */
 856             if (zip->msg != NULL)
 857                 *pmsg = strdup(zip->msg);
 858         }
 859         freeZip(zip);
 860         return NULL;
 861     }
 862     MLOCK(zfiles_lock);
 863     zip->next = zfiles;