Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/instrument/FileSystemSupport_md.c
32285 views
1
/*
2
* Copyright (c) 2004, 2018 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
23
* questions.
24
*/
25
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <malloc.h>
30
31
#include "FileSystemSupport_md.h"
32
33
/*
34
* Windows implementation of file system support functions
35
*/
36
37
#define slash '\\'
38
#define altSlash '/'
39
40
static int isSlash(char c) {
41
return (c == '\\') || (c == '/');
42
}
43
44
static int isLetter(char c) {
45
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
46
}
47
48
char pathSeparator() {
49
return ';';
50
}
51
52
/* filename are case insensitive on windows */
53
int filenameStrcmp(const char* s1, const char* s2) {
54
return strcasecmp(s1, s2);
55
}
56
57
char* basePath(const char* path) {
58
char* pos = strchr(path, slash);
59
char* last = NULL;
60
while (pos != NULL) {
61
last = pos;
62
pos++;
63
pos = strchr(pos, slash);
64
}
65
if (last == NULL) {
66
return (char*)path;
67
} else {
68
int len = (int)(last - path);
69
char* str = (char*)malloc(len+1);
70
if (str == NULL) {
71
fprintf(stderr, "OOM error in native tmp buffer allocation");
72
return NULL;
73
}
74
if (len > 0) {
75
memcpy(str, path, len);
76
}
77
str[len] = '\0';
78
return str;
79
}
80
}
81
82
83
84
/* -- Normalization - src/windows/classes/java/io/Win32FileSystem.java */
85
86
87
/* A normal Win32 pathname contains no duplicate slashes, except possibly
88
* for a UNC prefix, and does not end with a slash. It may be the empty
89
* string. Normalized Win32 pathnames have the convenient property that
90
* the length of the prefix almost uniquely identifies the type of the path
91
* and whether it is absolute or relative:
92
*
93
* 0 relative to both drive and directory
94
* 1 drive-relative (begins with '\\')
95
* 2 absolute UNC (if first char is '\\'),
96
* else directory-relative (has form "z:foo")
97
* 3 absolute local pathname (begins with "z:\\")
98
*/
99
static int normalizePrefix(const char* path, int len, char* sb, int* sbLen) {
100
char c;
101
int src = 0;
102
while ((src < len) && isSlash(path[src])) src++;
103
if ((len - src >= 2)
104
&& isLetter(c = path[src])
105
&& path[src + 1] == ':') {
106
/* Remove leading slashes if followed by drive specifier.
107
This hack is necessary to support file URLs containing drive
108
specifiers (e.g., "file://c:/path"). As a side effect,
109
"/c:/path" can be used as an alternative to "c:/path". */
110
sb[(*sbLen)++] = c;
111
sb[(*sbLen)++] = ':';
112
src += 2;
113
} else {
114
src = 0;
115
if ((len >= 2)
116
&& isSlash(path[0])
117
&& isSlash(path[1])) {
118
/* UNC pathname: Retain first slash; leave src pointed at
119
second slash so that further slashes will be collapsed
120
into the second slash. The result will be a pathname
121
beginning with "\\\\" followed (most likely) by a host
122
name. */
123
src = 1;
124
sb[(*sbLen)++] = slash;
125
}
126
}
127
return src;
128
}
129
130
/*
131
* Normalize the given pathname, whose length is len, starting at the given
132
* offset; everything before this offset is already normal.
133
*/
134
static char* normalizePath(const char* path, int len, int off) {
135
int src;
136
char* sb;
137
int sbLen;
138
139
if (len == 0) return (char*)path;
140
if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
141
142
sb = (char*)malloc(len+1);
143
if (sb == NULL) {
144
fprintf(stderr, "OOM error in native tmp buffer allocation");
145
return NULL;
146
}
147
sbLen = 0;
148
149
if (off == 0) {
150
/* Complete normalization, including prefix */
151
src = normalizePrefix(path, len, sb, &sbLen);
152
} else {
153
/* Partial normalization */
154
src = off;
155
memcpy(sb+sbLen, path, off);
156
sbLen += off;
157
}
158
159
/* Remove redundant slashes from the remainder of the path, forcing all
160
slashes into the preferred slash */
161
while (src < len) {
162
char c = path[src++];
163
if (isSlash(c)) {
164
while ((src < len) && isSlash(path[src])) src++;
165
if (src == len) {
166
/* Check for trailing separator */
167
if ((sbLen == 2) && (sb[1] == ':')) {
168
/* "z:\\" */
169
sb[sbLen++] = slash;
170
break;
171
}
172
if (sbLen == 0) {
173
/* "\\" */
174
sb[sbLen++] = slash;
175
break;
176
}
177
if ((sbLen == 1) && (isSlash(sb[0]))) {
178
/* "\\\\" is not collapsed to "\\" because "\\\\" marks
179
the beginning of a UNC pathname. Even though it is
180
not, by itself, a valid UNC pathname, we leave it as
181
is in order to be consistent with the win32 APIs,
182
which treat this case as an invalid UNC pathname
183
rather than as an alias for the root directory of
184
the current drive. */
185
sb[sbLen++] = slash;
186
break;
187
}
188
/* Path does not denote a root directory, so do not append
189
trailing slash */
190
break;
191
} else {
192
sb[sbLen++] = slash;
193
}
194
} else {
195
sb[sbLen++] = c;
196
}
197
}
198
199
sb[sbLen] = '\0';
200
return sb;
201
}
202
203
/*
204
* Check that the given pathname is normal. If not, invoke the real
205
* normalizer on the part of the pathname that requires normalization.
206
* This way we iterate through the whole pathname string only once.
207
*/
208
char* normalize(char* path) {
209
int n = (int)strlen(path);
210
int i;
211
char c = 0;
212
int prev = 0;
213
for (i = 0; i < n; i++) {
214
char c = path[i];
215
if (c == altSlash)
216
return normalizePath(path, n, (prev == slash) ? i - 1 : i);
217
if ((c == slash) && (prev == slash) && (i > 1))
218
return normalizePath(path, n, i - 1);
219
if ((c == ':') && (i > 1))
220
return normalizePath(path, n, 0);
221
prev = c;
222
}
223
if (prev == slash)
224
return normalizePath(path, n, n - 1);
225
return path;
226
}
227
228
229
/* -- Resolution - src/windows/classes/java/io/Win32FileSystem.java */
230
231
232
char* resolve(const char* parent, const char* child) {
233
char* c;
234
char* theChars;
235
int parentEnd, childStart, len;
236
237
int pn = (int)strlen(parent);
238
int cn = (int)strlen(child);
239
240
if (pn == 0) return (char*)child;
241
if (cn == 0) return (char*)parent;
242
243
c = (char*)child;
244
childStart = 0;
245
parentEnd = pn;
246
247
if ((cn > 1) && (c[0] == slash)) {
248
if (c[1] == slash) {
249
/* Drop prefix when child is a UNC pathname */
250
childStart = 2;
251
} else {
252
/* Drop prefix when child is drive-relative */
253
childStart = 1;
254
255
}
256
if (cn == childStart) { // Child is double slash
257
if (parent[pn - 1] == slash) {
258
char* str = strdup(parent);
259
str[pn-1] = '\0';
260
return str;
261
}
262
return (char*)parent;
263
}
264
}
265
266
if (parent[pn - 1] == slash)
267
parentEnd--;
268
269
len = parentEnd + cn - childStart;
270
271
if (child[childStart] == slash) {
272
theChars = (char*)malloc(len+1);
273
if (theChars == NULL) {
274
fprintf(stderr, "OOM error in native tmp buffer allocation");
275
return NULL;
276
}
277
memcpy(theChars, parent, parentEnd);
278
memcpy(theChars+parentEnd, child+childStart, (cn-childStart));
279
theChars[len] = '\0';
280
} else {
281
theChars = (char*)malloc(len+2);
282
if (theChars == NULL) {
283
fprintf(stderr, "OOM error in native tmp buffer allocation");
284
return NULL;
285
}
286
memcpy(theChars, parent, parentEnd);
287
theChars[parentEnd] = slash;
288
memcpy(theChars+parentEnd+1, child+childStart, (cn-childStart));
289
theChars[len+1] = '\0';
290
}
291
return theChars;
292
}
293
294
295
static int prefixLength(const char* path) {
296
char c0, c1;
297
298
int n = (int)strlen(path);
299
if (n == 0) return 0;
300
c0 = path[0];
301
c1 = (n > 1) ? path[1] : 0;
302
if (c0 == slash) {
303
if (c1 == slash) return 2; /* Absolute UNC pathname "\\\\foo" */
304
return 1; /* Drive-relative "\\foo" */
305
}
306
if (isLetter(c0) && (c1 == ':')) {
307
if ((n > 2) && (path[2] == slash))
308
return 3; /* Absolute local pathname "z:\\foo" */
309
return 2; /* Directory-relative "z:foo" */
310
}
311
return 0; /* Completely relative */
312
}
313
314
315
int isAbsolute(const char* path) {
316
int pl = prefixLength(path);
317
return (((pl == 2) && (path[0] == slash)) || (pl == 3));
318
}
319
320
321
char* fromURIPath(const char* path) {
322
int start = 0;
323
int len = (int)strlen(path);
324
325
if ((len > 2) && (path[2] == ':')) {
326
// "/c:/foo" --> "c:/foo"
327
start = 1;
328
// "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
329
if ((len > 3) && path[len-1] == '/')
330
len--;
331
} else if ((len > 1) && path[len-1] == '/') {
332
// "/foo/" --> "/foo"
333
len--;
334
}
335
336
if (start == 0 && len == (int)strlen(path)) {
337
return (char*)path;
338
} else {
339
char* p = (char*)malloc(len+1);
340
if (p == NULL) {
341
fprintf(stderr, "OOM error in native tmp buffer allocation");
342
return NULL;
343
}
344
memcpy(p, path+start, len);
345
p[len] = '\0';
346
return p;
347
}
348
}
349
350