[m-rev.] diff: reimplement io.check_file_accessibility for java

Peter Wang novalazy at gmail.com
Tue Feb 9 14:40:22 AEDT 2010


Branches: main

library/io.m:
        Reimplement `io.check_file_accessibility' for Java.  The old version
        would not work if a security manager was not set, which is the default.
        On an error it could return a null error string, which is invalid.

tests/hard_coded/dir_test.m:
        Call `io.check_file_accessibility' with `execute' access type.

diff --git a/library/io.m b/library/io.m
index 95657f8..443f3e6 100644
--- a/library/io.m
+++ b/library/io.m
@@ -3397,38 +3397,46 @@ io.check_file_accessibility(FileName, AccessTypes, Result, !IO) :-
     [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
         may_not_duplicate],
 "
-    java.lang.String permissions = null;
+    java.io.File file = new java.io.File(FileName);
+    try {
+        boolean ok = true;
 
-    if (ML_access_types_includes_read(AccessTypes)) {
-        permissions = ""read"";
-    }
+        if (ML_access_types_includes_read(AccessTypes)) {
+            ok = file.canRead();
+        }
 
-    if (ML_access_types_includes_write(AccessTypes)) {
-        if (permissions == null) {
-            permissions = ""write"";
-        } else {
-            permissions = ""read,write"";
+        if (ok && ML_access_types_includes_write(AccessTypes)) {
+            ok = file.canWrite();
         }
-    }
 
-    if (ML_access_types_includes_execute(AccessTypes))
-    {
-        if (permissions == null) {
-            permissions = ""execute"";
-        } else {
-            permissions = permissions + "",execute"";
+        if (ok && ML_access_types_includes_execute(AccessTypes)) {
+            // File.canExecute() was added in Java 1.6 but we only require
+            // Java 1.5.
+            try {
+                java.lang.reflect.Method canExecute =
+                    file.getClass().getMethod(""canExecute"");
+                ok = (Boolean) canExecute.invoke(file);
+            }
+            catch (java.lang.NoSuchMethodException e) {
+                // Assume the file is executable.
+            }
+            catch (java.lang.IllegalAccessException e) {
+                // Assume the file is executable.
+            }
+            catch (java.lang.reflect.InvocationTargetException e) {
+                ok = false;
+            }
         }
-    }
 
-    try {
-        if (permissions != null) {
-            java.lang.System.getSecurityManager().checkPermission(
-                new java.io.FilePermission(FileName, permissions));
+        if (ok) {
+            Result = ML_make_io_res_0_ok();
+        } else {
+            Result = ML_make_io_res_0_error_msg(
+                ""file not accessible: Permission denied"");
         }
-        Result = ML_make_io_res_0_ok();
     }
-    catch (java.lang.Exception e) {
-        Result = ML_make_io_res_0_error_msg(e.getMessage());
+    catch (java.lang.SecurityException e) {
+        Result = ML_make_io_res_0_error_msg(e.toString());
     }
 ").
 
diff --git a/tests/hard_coded/dir_test.m b/tests/hard_coded/dir_test.m
index 860ba63..a452ee8 100644
--- a/tests/hard_coded/dir_test.m
+++ b/tests/hard_coded/dir_test.m
@@ -60,6 +60,11 @@ main -->
 		"unwritable file found to be unwritable\n")
 	),
 
+	% Execute permissions are not handled correctly on all platforms so
+	% just check that it doesn't crash.
+	io__check_file_accessibility("unwritable",
+		[execute], _ExecuteResult),
+
 	dir__current_directory(CwdResult),
 	(
 	    { CwdResult = ok(Cwd) },

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list