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;
|