Skip to content

Commit

Permalink
8343342: java/io/File/GetXSpace.java fails on Windows with CD-ROM drive
Browse files Browse the repository at this point in the history
Reviewed-by: bpb, aturbanov
  • Loading branch information
kurashige23 committed Jan 8, 2025
1 parent 021c476 commit 40f0a39
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 5 deletions.
56 changes: 52 additions & 4 deletions test/jdk/java/io/File/GetXSpace.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public class GetXSpace {
System.loadLibrary("GetXSpace");
}

private static final Pattern DF_PATTERN = Pattern.compile("([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+\\d+%\\s+([^\\s].*)\n");

private static int fail = 0;
private static int pass = 0;
private static Throwable first;
Expand Down Expand Up @@ -104,8 +106,17 @@ private static class Space {
Space(String name) {
this.name = name;
long[] sizes = new long[4];
if (getSpace0(name, sizes))
System.err.println("WARNING: total space is estimated");
if (Platform.isWindows() & isCDDrive(name)) {
try {
getCDDriveSpace(name, sizes);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("can't get CDDrive sizes");
}
} else {
if (getSpace0(name, sizes))
System.err.println("WARNING: total space is estimated");
}
this.size = sizes[0];
this.total = sizes[1];
this.free = sizes[2];
Expand Down Expand Up @@ -167,7 +178,8 @@ private static void compare(Space s) {

out.format("%s (%d):%n", s.name(), s.size());
String fmt = " %-4s total = %12d free = %12d usable = %12d%n";
out.format(fmt, "getSpace0", s.total(), s.free(), s.available());
String method = Platform.isWindows() & isCDDrive(s.name()) ? "getCDDriveSpace" : "getSpace0";
out.format(fmt, method, s.total(), s.free(), s.available());
out.format(fmt, "getXSpace", ts, fs, us);

// If the file system can dynamically change size, this check will fail.
Expand Down Expand Up @@ -324,7 +336,7 @@ private static int testFile(Path dir) {
private static int testVolumes() {
out.println("--- Testing volumes");
// Find all of the partitions on the machine and verify that the sizes
// returned by File::getXSpace are equivalent to those from getSpace0
// returned by File::getXSpace are equivalent to those from getSpace0 or getCDDriveSpace
ArrayList<String> l;
try {
l = paths();
Expand Down Expand Up @@ -397,4 +409,40 @@ public static void main(String[] args) throws Exception {
// size[3] usable space: number of bytes available to the caller
//
private static native boolean getSpace0(String root, long[] space);

private static native boolean isCDDrive(String root);

private static void getCDDriveSpace(String root, long[] sizes)
throws IOException {
String[] cmd = new String[] {"df", "-k", "-P", root};
Process p = Runtime.getRuntime().exec(cmd);
StringBuilder sb = new StringBuilder();

try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String s;
int i = 0;
while ((s = in.readLine()) != null) {
// skip header
if (i++ == 0) continue;
sb.append(s).append("\n");
}
}
out.println(sb);

Matcher m = DF_PATTERN.matcher(sb);
int j = 0;
while (j < sb.length()) {
if (m.find(j)) {
sizes[0] = Long.parseLong(m.group(2)) * 1024;
sizes[1] = Long.parseLong(m.group(3)) * 1024;
sizes[2] = sizes[0] - sizes[1];
sizes[3] = Long.parseLong(m.group(4)) * 1024;
j = m.end();
} else {
throw new RuntimeException("unrecognized df output format: "
+ "charAt(" + j + ") = '"
+ sb.charAt(j) + "'");
}
}
}
}
29 changes: 28 additions & 1 deletion test/jdk/java/io/File/libGetXSpace.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -159,6 +159,33 @@ Java_GetXSpace_getSpace0
(*env)->SetLongArrayRegion(env, sizes, 0, 4, array);
return totalSpaceIsEstimated;
}

JNIEXPORT jboolean JNICALL
Java_GetXSpace_isCDDrive
(JNIEnv *env, jclass cls, jstring root)
{
#ifdef WINDOWS
const jchar* strchars = (*env)->GetStringChars(env, root, NULL);
if (strchars == NULL) {
JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException",
"GetStringChars");
return JNI_FALSE;
}

LPCWSTR path = (LPCWSTR)strchars;
UINT driveType = GetDriveTypeW(path);

(*env)->ReleaseStringChars(env, root, strchars);

if (driveType != DRIVE_CDROM) {
return JNI_FALSE;
}

return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
#ifdef __cplusplus
}
#endif

0 comments on commit 40f0a39

Please sign in to comment.