You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by le...@apache.org on 2007/08/14 08:13:54 UTC

svn commit: r565635 - in /harmony/enhanced/classlib/branches/java6/modules/luni/src: main/java/java/io/ main/native/luni/shared/ main/native/luni/unix/ main/native/luni/windows/ test/api/common/tests/api/java/io/ test/api/unix/org/apache/harmony/luni/t...

Author: leoli
Date: Mon Aug 13 23:13:53 2007
New Revision: 565635

URL: http://svn.apache.org/viewvc?view=rev&rev=565635
Log:
Apply patch for HARMONY-4611 ([classlib][luni][java6]Add new methods and testcases in java.io.File for java6).

Modified:
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/File.java
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/file.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c
    harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h
    harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/tests/api/java/io/FileTest.java
    harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java
    harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/File.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/File.java?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/File.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/File.java Mon Aug 13 23:13:53 2007
@@ -657,6 +657,60 @@
     public String getPath() {
         return path;
     }
+    
+	/**
+	 * Answers the partition size indicated by the path name.
+	 * 
+	 * @return the partition size counted in bytes, 0L if the path does not
+	 *         exist
+	 */
+	public long getTotalSpace() {
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+			security.checkPermission(new RuntimePermission(
+					"getFileSystemAttributes")); //$NON-NLS-1$
+		}
+		return getTotalSpaceImpl(properPath(true));
+	}
+
+	private native long getTotalSpaceImpl(byte[] filePath);
+	
+	/**
+	 * Answers the available bytes of the partition indicated by the path name.
+	 * This method checks write permission and other restrictions and offers a
+	 * more precise estimate than getFreeSpace(). If the operating system does
+	 * not support this information, the result will be the same as the one
+	 * returned by getFreeSpace().
+	 * 
+	 * @return the available bytes of the partition considering platform
+	 *         dependent permissions
+	 */
+	public long getUsableSpace() {
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+			security.checkPermission(new RuntimePermission(
+					"getFileSystemAttributes")); //$NON-NLS-1$
+		}
+		return getUsableSpaceImpl(properPath(true));
+	}
+
+	private native long getUsableSpaceImpl(byte[] filePath);
+
+	/**
+	 * Answers the available bytes of the partition indicated by the path name.
+	 * 
+	 * @return the available bytes of the partition
+	 */
+	public long getFreeSpace() {
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+			security.checkPermission(new RuntimePermission(
+					"getFileSystemAttributes")); //$NON-NLS-1$
+		}
+		return getFreeSpaceImpl(properPath(true));
+	}
+
+	private native long getFreeSpaceImpl(byte[] filePath);
 
     /**
      * Answers an integer hash code for the receiver. Any two objects which
@@ -826,6 +880,104 @@
 
     private native boolean setReadOnlyImpl(byte[] path);
 
+    /**
+	 * Manipulates the read permission of the abstract path designated by this
+	 * file object.
+	 * 
+	 * @param readable
+	 *            To allow read permission if true, otherwise disallow
+	 * @param ownerOnly
+	 *            To manipulate read permission only for owner if true,
+	 *            otherwise for everyone. The manipulation will apply to
+	 *            everyone regardless of this value if the underlying system
+	 *            does not distinguish owner and other users.
+	 * @return true if and only if the operation succeeded. If the user does not
+	 *         have permission to change the access permissions of this abstract
+	 *         pathname the operation will fail. If the underlying file system
+	 *         does not support read permission and the value of readable is
+	 *         false, this operation will fail.
+	 * @throws SecurityException -
+	 *             If a security manager exists and
+	 *             SecurityManager.checkWrite(java.lang.String) disallows write
+	 *             permission to this file object
+	 * @since 1.6
+	 */
+	public boolean setReadable(boolean readable, boolean ownerOnly) {
+		checkWrite();
+		return (setReadableImpl(properPath(true), readable, ownerOnly));
+	}
+
+	/**
+	 * A convenience method for setReadable(boolean, boolean). An invocation of
+	 * this method is the same as file.setReadable(readable, true).
+	 * 
+	 * @param readable
+	 *            To allow read permission if true, otherwise disallow
+	 * @return true if and only if the operation succeeded. If the user does not
+	 *         have permission to change the access permissions of this abstract
+	 *         pathname the operation will fail. If the underlying file system
+	 *         does not support read permission and the value of readable is
+	 *         false, this operation will fail.
+	 * @throws SecurityException -
+	 *             If a security manager exists and
+	 *             SecurityManager.checkWrite(java.lang.String) disallows write
+	 *             permission to this file object
+	 * @since 1.6
+	 */
+	public boolean setReadable(boolean readable) {
+		return setReadable(readable, true);
+	}
+	
+	private native boolean setReadableImpl(byte[] path, boolean readable,
+			boolean ownerOnly);
+	
+	/**
+	 * Manipulates the write permission of the abstract path designated by this
+	 * file object.
+	 * 
+	 * @param writable
+	 *            To allow write permission if true, otherwise disallow
+	 * @param ownerOnly
+	 *            To manipulate write permission only for owner if true,
+	 *            otherwise for everyone. The manipulation will apply to
+	 *            everyone regardless of this value if the underlying system
+	 *            does not distinguish owner and other users.
+	 * @return true if and only if the operation succeeded. If the user does not
+	 *         have permission to change the access permissions of this abstract
+	 *         pathname the operation will fail.
+	 * @throws SecurityException -
+	 *             If a security manager exists and
+	 *             SecurityManager.checkWrite(java.lang.String) disallows write
+	 *             permission to this file object
+	 * @since 1.6
+	 */
+	public boolean setWritable(boolean writable, boolean ownerOnly) {
+		checkWrite();
+		return (setWritableImpl(properPath(true), writable, ownerOnly));
+	}
+
+	private native boolean setWritableImpl(byte[] path, boolean writable,
+			boolean ownerOnly);
+
+	/**
+	 * A convenience method for setWritable(boolean, boolean). An invocation of
+	 * this method is the same as file.setWritable(writable, true).
+	 * 
+	 * @param writable
+	 *            To allow write permission if true, otherwise disallow
+	 * @return true if and only if the operation succeeded. If the user does not
+	 *         have permission to change the access permissions of this abstract
+	 *         pathname the operation will fail.
+	 * @throws SecurityException -
+	 *             If a security manager exists and
+	 *             SecurityManager.checkWrite(java.lang.String) disallows write
+	 *             permission to this file object
+	 * @since 1.6
+	 */
+	public boolean setWritable(boolean writable) {
+		return setWritable(writable, true);
+	}
+	
     /**
      * Answers the length of this File in bytes.
      * 

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/file.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/file.c?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/file.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/shared/file.c Mon Aug 13 23:13:53 2007
@@ -181,6 +181,57 @@
   return result >= 0;
 }
 
+JNIEXPORT jlong JNICALL
+Java_java_io_File_getTotalSpaceImpl (JNIEnv * env, jobject recv, jbyteArray path)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  char pathCopy[HyMaxPath];
+  jsize length = (*env)->GetArrayLength (env, path);
+  if(!Java_java_io_File_existsImpl(env, recv, path)) {
+	return 0l;
+  }
+  
+  length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+  ((*env)->GetByteArrayRegion (env, path, 0, length, (jbyte *)pathCopy));
+  pathCopy[length] = '\0';
+  ioh_convertToPlatform (pathCopy);
+  return getPlatformTotal(env, pathCopy);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_File_getFreeSpaceImpl (JNIEnv * env, jobject recv, jbyteArray path)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  char pathCopy[HyMaxPath];
+  jsize length = (*env)->GetArrayLength (env, path);
+  if(!Java_java_io_File_existsImpl(env, recv, path)) {
+	return 0l;
+  }
+  
+  length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+  ((*env)->GetByteArrayRegion (env, path, 0, length, (jbyte *)pathCopy));
+  pathCopy[length] = '\0';
+  ioh_convertToPlatform (pathCopy);
+  return getPlatformFreeTotal(env, pathCopy);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_File_getUsableSpaceImpl (JNIEnv * env, jobject recv, jbyteArray path)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  char pathCopy[HyMaxPath];
+  jsize length = (*env)->GetArrayLength (env, path);
+  if(!Java_java_io_File_existsImpl(env, recv, path)) {
+	return 0l;
+  }
+  
+  length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+  ((*env)->GetByteArrayRegion (env, path, 0, length, (jbyte *)pathCopy));
+  pathCopy[length] = '\0';
+  ioh_convertToPlatform (pathCopy);
+  return getPlatformUsableTotal(env, pathCopy);
+}
+
 JNIEXPORT jboolean JNICALL
 Java_java_io_File_isFileImpl (JNIEnv * env, jobject recv, jbyteArray path)
 {
@@ -436,6 +487,36 @@
   pathCopy[length] = '\0';
   ioh_convertToPlatform (pathCopy);
   return setPlatformReadOnly (env, pathCopy);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_File_setReadableImpl (JNIEnv * env, jobject recv,
+                                   jbyteArray path, jboolean readable, jboolean ownerOnly)
+{
+#if (defined(WIN32))
+   return readable;
+#else
+  jsize length = (*env)->GetArrayLength (env, path);
+  char pathCopy[HyMaxPath];
+  length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+  ((*env)->GetByteArrayRegion (env, path, 0, length, (jbyte *)pathCopy));
+  pathCopy[length] = '\0';
+  ioh_convertToPlatform (pathCopy);
+  return setPlatformReadable (env, pathCopy, readable, ownerOnly);
+#endif
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_File_setWritableImpl (JNIEnv * env, jobject recv,
+                                   jbyteArray path, jboolean writable, jboolean ownerOnly)
+{
+  jsize length = (*env)->GetArrayLength (env, path);
+  char pathCopy[HyMaxPath];
+  length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+  ((*env)->GetByteArrayRegion (env, path, 0, length, (jbyte *)pathCopy));
+  pathCopy[length] = '\0';
+  ioh_convertToPlatform (pathCopy);
+  return setPlatformWritable (env, pathCopy, writable, ownerOnly);
 }
 
 JNIEXPORT void JNICALL

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/exports.txt Mon Aug 13 23:13:53 2007
@@ -24,7 +24,10 @@
 Java_java_io_File_deleteFileImpl
 Java_java_io_File_existsImpl
 Java_java_io_File_getCanonImpl
+Java_java_io_File_getFreeSpaceImpl
 Java_java_io_File_getLinkImpl
+Java_java_io_File_getUsableSpaceImpl
+Java_java_io_File_getTotalSpaceImpl
 Java_java_io_File_isAbsoluteImpl
 Java_java_io_File_isCaseSensitiveImpl
 Java_java_io_File_isDirectoryImpl
@@ -42,7 +45,9 @@
 Java_java_io_File_renameToImpl
 Java_java_io_File_rootsImpl
 Java_java_io_File_setLastModifiedImpl
+Java_java_io_File_setReadableImpl
 Java_java_io_File_setReadOnlyImpl
+Java_java_io_File_setWritableImpl
 Java_java_io_FileDescriptor_oneTimeInitialization
 Java_java_io_FileDescriptor_syncImpl
 Java_java_io_FileDescriptor_valid

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.c Mon Aug 13 23:13:53 2007
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/vfs.h>
 
 #include <utime.h>
 
@@ -147,6 +148,54 @@
 }
 
 /**
+ * Answer 1 if the path is now readable, 0 otherwise even in fail cases.
+ */
+I_32
+setPlatformReadable (JNIEnv * env, char *path, jboolean readable, jboolean ownerOnly)
+{
+  struct stat buffer;
+  mode_t mode;
+  if (stat (path, &buffer))
+    {
+      return 0;
+    }
+  mode = buffer.st_mode;
+  if (readable && ownerOnly)
+	  mode |= S_IRUSR;
+  else if (readable) 
+	  mode |= (S_IRUSR | S_IRGRP | S_IROTH);
+  else if (ownerOnly)
+  	  mode &= (~S_IRUSR);
+  else
+      mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);
+  return chmod (path, mode) == 0;
+}
+
+/**
+ * Answer 1 if the path is now writable, 0 otherwise even in fail cases.
+ */
+I_32
+setPlatformWritable (JNIEnv * env, char *path, jboolean writable, jboolean ownerOnly)
+{
+	
+  struct stat buffer;
+  mode_t mode;
+  if (stat (path, &buffer))
+    {
+      return 0;
+    }
+  mode = buffer.st_mode;
+  if (writable && ownerOnly)
+	  mode |= S_IWUSR;
+  else if (writable) 
+	  mode |= (S_IWUSR | S_IWGRP | S_IWOTH);
+  else if (ownerOnly)
+  	  mode &= (~S_IWUSR);
+  else
+      mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+  return chmod (path, mode) == 0;
+}
+/**
  * Answer 1 if the file length was set, 0 otherwise even in fail cases.
  */
 I_32
@@ -178,20 +227,7 @@
 I_32
 getPlatformIsReadOnly (JNIEnv * env, char *path)
 {
-  I_32 result;
-  struct stat buffer;
-
-  result = stat (path, &buffer);
-  if (result == -1)
-    return 0;
-
-  if (buffer.st_uid == geteuid ())
-    return (buffer.st_mode & S_IWUSR) == 0;
-  else if (buffer.st_gid == getegid ())
-    return (buffer.st_mode & S_IWGRP) == 0;
-
-  return (buffer.st_mode & S_IWOTH) == 0;
-
+	return access(path, W_OK) !=0;
 }
 
 /**
@@ -200,20 +236,46 @@
 I_32
 getPlatformIsWriteOnly (JNIEnv * env, char *path)
 {
-  I_32 result;
-  struct stat buffer;
-
-  result = stat (path, &buffer);
-  if (result == -1)
-    return 0;
-
-  if (buffer.st_uid == geteuid ())
-    return (buffer.st_mode & S_IRUSR) == 0;
-  else if (buffer.st_gid == getegid ())
-    return (buffer.st_mode & S_IRGRP) == 0;
-
-  return (buffer.st_mode & S_IROTH) == 0;
+  return access(path, R_OK) !=0;
+}
 
+jlong getPlatformTotal (JNIEnv * env, char *path) {
+	struct statfs fs_buf;
+	jlong total_size;
+	int ret;
+	if((ret = statfs(path, &fs_buf) < 0))
+	{
+		return 0l;
+	}
+	total_size = fs_buf.f_blocks*(fs_buf.f_bsize/1024.0);
+	total_size *= 1024;
+	return total_size;
+}
+
+jlong getPlatformUsableTotal (JNIEnv * env, char *path) {
+    struct statfs fs_buf;
+	jlong total_size;
+	int ret;
+	if((ret = statfs(path, &fs_buf) < 0))
+	{
+		return 0l;
+	}
+	total_size = fs_buf.f_bavail*(fs_buf.f_bsize/1024.0);
+	total_size *= 1024;
+	return total_size;
+}
+
+jlong getPlatformFreeTotal (JNIEnv * env, char *path) {
+	struct statfs fs_buf;
+	jlong total_size;
+	int ret;
+	if((ret = statfs(path, &fs_buf) < 0))
+	{
+		return 0l;
+	}
+	total_size = fs_buf.f_bfree*(fs_buf.f_bsize/1024.0);
+	total_size *= 1024;
+	return total_size;
 }
 
 /* Resolve link if it is a symbolic link and put the result in link. */

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/helpers.h Mon Aug 13 23:13:53 2007
@@ -52,6 +52,11 @@
 void setPlatformBindOptions (JNIEnv * env, hysocket_t socketP);
 I_32 setPlatformLastModified (JNIEnv * env, char *path, I_64 time);
 I_32 setPlatformReadOnly (JNIEnv * env, char *path);
+I_32 setPlatformReadable (JNIEnv * env, char *path, jboolean readable, jboolean ownerOnly);
+I_32 setPlatformWritable (JNIEnv * env, char *path, jboolean writable, jboolean ownerOnly);
+jlong getPlatformTotal (JNIEnv * env, char *path);
+jlong getPlatformUsableTotal (JNIEnv * env, char *path);
+jlong getPlatformFreeTotal (JNIEnv * env, char *path);
 int portCmp (const void **a, const void **b);
 char* convertInterfaceName(JNIEnv * env, jstring ifname);
 jboolean getPlatformNetworkInterfaceAttribute(JNIEnv * env, jstring ifname, u_long iiFlag);

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.c Mon Aug 13 23:13:53 2007
@@ -53,7 +53,9 @@
 void setPlatformBindOptions (JNIEnv * env, hysocket_t socketP);
 I_32 setPlatformLastModified (JNIEnv * env, char *path, I_64 time);
 I_32 setPlatformReadOnly (JNIEnv * env, char *path);
-
+jlong getPlatformTotal (JNIEnv * env, char *path);
+jlong getPlatformUsableTotal (JNIEnv * env, char *path);
+jlong getPlatformFreeTotal (JNIEnv * env, char *path);
 UDATA platformFindfirst (char *path, char *resultbuf);
 int portCmp (const void **a, const void **b);
 static void unmangle (JNIEnv * env, LPWSTR data);
@@ -189,6 +191,29 @@
 }
 
 /**
+ * Answer 1 if the writable attribute was set, 0 otherwise even in fail cases.
+ */
+I_32
+setPlatformWritable (JNIEnv * env, char *path, jboolean writable, jboolean ownerOnly)
+{
+  PORT_ACCESS_FROM_ENV (env);
+  I_32 attrs, result;
+
+  char *unicodePath;
+  unicodePath = path;
+
+  attrs = GetFileAttributes (unicodePath);
+  if(writable)
+      attrs &= (~FILE_ATTRIBUTE_READONLY);
+  else
+      attrs |= FILE_ATTRIBUTE_READONLY;
+
+  result = SetFileAttributes (unicodePath, attrs);
+
+  return result;
+}
+
+/**
  * Answer 1 if the file length was set, 0 otherwise even in fail cases.
  */
 I_32
@@ -205,6 +230,160 @@
   return SetEndOfFile ((HANDLE) descriptor);
 }
 
+/**
+ * Answers the total bytes of the partition designated by path.
+ */
+typedef BOOL (WINAPI *PGETDISKFREESPACEEX)(LPCSTR,
+   PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
+jlong getPlatformTotal (JNIEnv * env, char *path){
+	PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
+   __int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
+   
+   DWORD dwSectPerClust, 
+         dwBytesPerSect, 
+         dwFreeClusters, 
+         dwTotalClusters;
+
+   BOOL fResult;
+
+   LPCSTR drive;
+
+   pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( 
+                           GetModuleHandle("kernel32.dll"),
+                          "GetDiskFreeSpaceExA");
+   drive = strtok(path, "\\");
+
+   if (pGetDiskFreeSpaceEx)
+   {
+      fResult = pGetDiskFreeSpaceEx (drive,
+                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
+                 (PULARGE_INTEGER)&i64TotalBytes,
+                 (PULARGE_INTEGER)&i64FreeBytes);
+
+      // Process GetDiskFreeSpaceEx results.
+      if(fResult) 
+      {
+         return i64TotalBytes;
+      }
+   }
+
+   else 
+   {
+      fResult = GetDiskFreeSpaceA (drive, 
+                 &dwSectPerClust, 
+                 &dwBytesPerSect,
+                 &dwFreeClusters, 
+                 &dwTotalClusters);
+
+   // Process GetDiskFreeSpace results.
+      if(fResult) 
+      {
+         return
+             dwTotalClusters*dwSectPerClust*dwBytesPerSect;
+      }
+   }
+	return (__int64)0;
+}
+
+jlong getPlatformUsableTotal (JNIEnv * env, char *path) {
+    PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
+   __int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
+   
+   DWORD dwSectPerClust, 
+         dwBytesPerSect, 
+         dwFreeClusters, 
+         dwTotalClusters;
+
+   BOOL fResult;
+
+   LPCSTR drive;
+
+   pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( 
+                           GetModuleHandle("kernel32.dll"),
+                          "GetDiskFreeSpaceExA");
+   drive = strtok(path, "\\");
+
+   if (pGetDiskFreeSpaceEx)
+   {
+      fResult = pGetDiskFreeSpaceEx (drive,
+                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
+                 (PULARGE_INTEGER)&i64TotalBytes,
+                 (PULARGE_INTEGER)&i64FreeBytes);
+
+      // Process GetDiskFreeSpaceEx results.
+      if(fResult) 
+      {
+         return i64FreeBytesToCaller;
+      }
+   }
+
+   else 
+   {
+      fResult = GetDiskFreeSpaceA (drive, 
+                 &dwSectPerClust, 
+                 &dwBytesPerSect,
+                 &dwFreeClusters, 
+                 &dwTotalClusters);
+
+   // Process GetDiskFreeSpace results.
+      if(fResult) 
+      {
+         return
+             dwFreeClusters*dwSectPerClust*dwBytesPerSect;
+      }
+   }
+	return (__int64)0;
+}
+
+jlong getPlatformFreeTotal (JNIEnv * env, char *path) {
+	PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
+   __int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
+   
+   DWORD dwSectPerClust, 
+         dwBytesPerSect, 
+         dwFreeClusters, 
+         dwTotalClusters;
+
+   BOOL fResult;
+
+   LPCSTR drive;
+
+   pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( 
+                           GetModuleHandle("kernel32.dll"),
+                          "GetDiskFreeSpaceExA");
+   drive = strtok(path, "\\");
+
+   if (pGetDiskFreeSpaceEx)
+   {
+      fResult = pGetDiskFreeSpaceEx (drive,
+                 (PULARGE_INTEGER)&i64FreeBytesToCaller,
+                 (PULARGE_INTEGER)&i64TotalBytes,
+                 (PULARGE_INTEGER)&i64FreeBytes);
+
+      // Process GetDiskFreeSpaceEx results.
+      if(fResult) 
+      {
+         return i64FreeBytes;
+      }
+   }
+
+   else 
+   {
+      fResult = GetDiskFreeSpaceA (drive, 
+                 &dwSectPerClust, 
+                 &dwBytesPerSect,
+                 &dwFreeClusters, 
+                 &dwTotalClusters);
+
+   // Process GetDiskFreeSpace results.
+      if(fResult) 
+      {
+         return
+             dwFreeClusters*dwSectPerClust*dwBytesPerSect;
+      }
+   }
+	return (__int64)0;
+}
 jbyteArray
 getPlatformPath (JNIEnv * env, jbyteArray path)
 {

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/helpers.h Mon Aug 13 23:13:53 2007
@@ -51,6 +51,10 @@
 void setPlatformBindOptions (JNIEnv * env, hysocket_t socketP);
 I_32 setPlatformLastModified (JNIEnv * env, char *path, I_64 time);
 I_32 setPlatformReadOnly (JNIEnv * env, char *path);
+I_32 setPlatformWritable (JNIEnv * env, char *path, jboolean writable, jboolean ownerOnly);
+jlong getPlatformTotal (JNIEnv * env, char *path);
+jlong getPlatformUsableTotal (JNIEnv * env, char *path);
+jlong getPlatformFreeTotal (JNIEnv * env, char *path);
 char* convertInterfaceName(JNIEnv * env, jstring ifname);
 jboolean getPlatformIsUp(JNIEnv * env, jstring ifname, jint index);
 jboolean getPlatformIsLoopback(JNIEnv * env, jstring ifname, jint index);

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/tests/api/java/io/FileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/tests/api/java/io/FileTest.java?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/tests/api/java/io/FileTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/tests/api/java/io/FileTest.java Mon Aug 13 23:13:53 2007
@@ -1996,6 +1996,10 @@
 		File f1 = null;
 		File f2 = null;
 		try {
+			// if the user is 'root' on linux platform.
+			boolean root = System.getProperty("user.name").equals("root")
+			               && System.getProperty("os.name").equalsIgnoreCase("linux");
+			
 			f1 = File.createTempFile("hyts_tf", ".tmp");
 			f2 = File.createTempFile("hyts_tf", ".tmp");
 			// Assert is flawed because canWrite does not work.
@@ -2003,11 +2007,14 @@
 			f1.setReadOnly();
 			// Assert is flawed because canWrite does not work.
 			// assertTrue("File f1 Is Not Set To ReadOnly." , !f1.canWrite());
-			try {
-				// Attempt to write to a file that is setReadOnly.
-				new FileOutputStream(f1);
-				fail("IOException not thrown.");
-			} catch (IOException e) {
+			if (!root){
+				try {
+					// Attempt to write to a file that is setReadOnly.
+					new FileOutputStream(f1);
+					fail("IOException not thrown.");
+				} catch (IOException e) {
+					// expected
+				}				
 			}
 			Runtime r = Runtime.getRuntime();
 			Process p;
@@ -2041,13 +2048,16 @@
 			f2.setReadOnly();
 			// Assert is flawed because canWrite does not work.
 			// assertTrue("File f2 Is Not Set To ReadOnly." , !f2.canWrite());
-			try {
-				// Attempt to write to a file that has previously been written
-				// to.
-				// and is now set to read only.
-				fos = new FileOutputStream(f2);
-				fail("IOException not thrown.");
-			} catch (IOException e) {
+			if (!root) {
+				try {
+					// Attempt to write to a file that has previously been written
+					// to.
+					// and is now set to read only.
+					fos = new FileOutputStream(f2);
+					fail("IOException not thrown.");
+				} catch (IOException e) {
+					// expected
+				}
 			}
 			r = Runtime.getRuntime();
 			if (onUnix)

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java Mon Aug 13 23:13:53 2007
@@ -1,6 +1,10 @@
 package org.apache.harmony.luni.tests.java.io;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 
 import junit.framework.TestCase;
 
@@ -15,7 +19,92 @@
 	private File testFile;
 
 	private File testDir;
+	
+	private static final int TOTAL_SPACE_NUM = 0;
+
+	private static final int FREE_SPACE_NUM = 1;
+
+	private static final int USABLE_SPACE_NUM = 2;
+
+	private static class ConsoleResulter extends Thread {
+		Process proc;
+
+		InputStream is;
+
+		String resStr;
+
+		ConsoleResulter(Process p, InputStream in) {
+			proc = p;
+			is = in;
+		}
+
+		@Override
+		public void run() {
+			StringBuffer result = new StringBuffer();
+			synchronized (result) {
+				try {
+					BufferedReader br = new BufferedReader(
+							new InputStreamReader(is));
+					String line;
+					while ((line = br.readLine()) != null) {
+						result.append(line);
+					}
+					if (result.length() != 0) {
+						resStr = result.toString();
+					}
+
+					br.close();
+				} catch (IOException ioe) {
+					result = null;
+				}
+				synchronized (proc) {
+					proc.notifyAll();
+				}
+			}
+		}
+	}
+
+	private static long getLinuxSpace(int index, File file) throws Exception {
+		long[] result = new long[3];
+		String par = file.getAbsolutePath();
+		String osName = System.getProperty("os.name");
+		// in case the test case will run under other OS.
+		if (osName.toLowerCase().indexOf("linux") != -1) {
+			String[] cmd = new String[2];
+			cmd[0] = "df";
+			cmd[1] = par; // get the total space of file
+			Runtime rt = Runtime.getRuntime();
+
+			Process proc = rt.exec(cmd);
+			// get output from the command
+			ConsoleResulter outputResult = new ConsoleResulter(proc, proc
+					.getInputStream());
+
+			synchronized (proc) {
+				outputResult.start();
+				proc.wait();
+			}
+			// If there is no error, obtain the result
+			if (outputResult.resStr != null) {
+				// exit the subprocess safely
+				proc.waitFor();
+
+				// filter unnecessary information
+				String[] txtResult = outputResult.resStr
+						.split("\\D|\\p{javaLowerCase}|\\p{javaUpperCase}");
+				for (int i = 0, j = 0; i < txtResult.length; i++) {
+					if (txtResult[i].length() > 3) {
+						result[j++] = Long.parseLong(txtResult[i]) * 1024L;
+					}
+				}
+			}
+		}
 
+		// calculate free spaces according to df command
+		result[1] = result[0] - result[1];
+		return result[index];
+	}
+	
 	/**
 	 * @tests java.io.File#canExecute()
 	 * 
@@ -47,8 +136,58 @@
 		assertTrue(testDir.setExecutable(true, false));
 		assertTrue(testDir.canExecute());
 	}
+	
+	/**
+	 * @tests java.io.File#getFreeSpace()
+	 * 
+	 * @since 1.6
+	 */
+	public void test_getFreeSpace() throws Exception {
+		long fileSpace = getLinuxSpace(FREE_SPACE_NUM, testFile);
+		long dirSpace = getLinuxSpace(FREE_SPACE_NUM, testDir);
+		// in case we cannot fetch the value from command line
+		if (fileSpace > 0) {
+			assertEquals(fileSpace, testFile.getFreeSpace());			
+		}
+		
+		if (dirSpace > 0) {
+			assertEquals(dirSpace, testDir.getFreeSpace());		
+		}		
+	}
+
+	/**
+	 * @tests java.io.File#getTotalSpace()
+	 * 
+	 * @since 1.6
+	 */
+	public void test_getTotalSpace() throws Exception {
+		long fileSpace = getLinuxSpace(TOTAL_SPACE_NUM, testFile);
+		long dirSpace = getLinuxSpace(TOTAL_SPACE_NUM, testDir);
+		if (fileSpace > 0) {
+			assertEquals(fileSpace, testFile.getTotalSpace());
+		}
+		if (dirSpace > 0) {
+			assertEquals(dirSpace, testDir.getTotalSpace());			
+		}
+	}
 
 	/**
+	 * @tests java.io.File#getUsableSpace()
+	 * 
+	 * @since 1.6
+	 */
+	public void test_getUsableSpace() throws Exception {
+		long fileSpace = getLinuxSpace(USABLE_SPACE_NUM, testFile);
+		long dirSpace = getLinuxSpace(USABLE_SPACE_NUM, testDir);
+		if (fileSpace > 0) {
+			assertEquals(fileSpace, testFile.getUsableSpace());
+		}
+		if (dirSpace > 0) {
+			assertEquals(dirSpace, testDir.getUsableSpace());			
+		}
+	}
+	
+	/**
 	 * @tests java.io.File#setExecutable(boolean, boolean)
 	 * 
 	 * @since 1.6
@@ -116,6 +255,96 @@
 		}		
 		assertTrue(testDir.setExecutable(true));
 		assertTrue(testDir.canExecute());
+	}
+	
+	/**
+	 * @tests java.io.File#setReadable(boolean, boolean)
+	 * 
+	 * @since 1.6
+	 */
+	public void test_setReadableZZ() throws Exception {
+		// setReadable(false, false/true) succeeds on Linux
+		// However, canRead() always returns true when the user is 'root'.
+		assertTrue(testFile.canRead());
+		assertTrue(testFile.setReadable(false, false));
+		if (root) {
+			assertTrue(testFile.canRead());
+		} else {
+			assertFalse(testFile.canRead());			
+		}
+		assertTrue(testFile.setReadable(false, true));
+		if (root) {
+			assertTrue(testFile.canRead());
+		} else {
+			assertFalse(testFile.canRead());			
+		}
+
+		// tests directory, setReadable(false, true/false)
+		assertTrue(testDir.canRead());
+		assertTrue(testDir.setReadable(false, true));
+		if (root) {
+			assertTrue(testDir.canRead());
+		} else {
+			assertFalse(testDir.canRead());			
+		}
+		assertTrue(testDir.setReadable(false, false));
+		if (root) {
+			assertTrue(testDir.canRead());
+		} else {
+			assertFalse(testDir.canRead());			
+		}
+
+		// setReadable(true, false/true) and set them in turn
+		assertTrue(testFile.setReadable(true, false));
+		assertTrue(testFile.canRead());
+		assertTrue(testFile.setReadable(false, true));
+		if (root) {
+			assertTrue(testFile.canRead());
+		} else {
+			assertFalse(testFile.canRead());			
+		}
+		assertTrue(testFile.setReadable(true, true));
+		assertTrue(testFile.canRead());
+		assertTrue(testFile.setReadable(false, true));
+		if (root) {
+			assertTrue(testFile.canRead());
+		} else {
+			assertFalse(testFile.canRead());			
+		}
+
+		// tests directory, setReadable(true, true/false)
+		assertTrue(testDir.setReadable(true, false));
+		assertTrue(testDir.canRead());
+		assertTrue(testDir.setReadable(true, true));
+		assertTrue(testDir.canRead());		
+	}
+
+	/**
+	 * @tests java.io.File#setReadable(boolean)
+	 * 
+	 * @since 1.6
+	 */
+	public void test_setReadableZ() {
+		// So far this method only deals with the situation that the user is the
+		// owner of the file. setReadable(false) succeeds on Linux
+		// However, canRead() always returns true when the user is 'root'.		
+		assertTrue(testFile.canRead());
+		assertTrue(testFile.setReadable(false));
+		if (root) {
+			assertTrue(testFile.canRead());
+		} else {
+			assertFalse(testFile.canRead());			
+		}		
+		assertTrue(testFile.setReadable(true));
+		assertTrue(testFile.canRead());
+
+		assertTrue(testDir.canRead());	
+		assertTrue(testDir.setReadable(false));
+		if (root) {
+			assertTrue(testDir.canRead());
+		} else {
+			assertFalse(testDir.canRead());			
+		}
 	}
 
 	@Override

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java?view=diff&rev=565635&r1=565634&r2=565635
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java Mon Aug 13 23:13:53 2007
@@ -155,6 +155,62 @@
 		assertTrue(testDir.canExecute());
 	}
 
+	/**
+	 * @tests java.io.File#setReadable(boolean, boolean)
+	 * 
+	 * @since 1.6
+	 */
+	public void test_setReadableZZ() throws Exception {
+		// setReadable(false, false/true) fails on Windows. Files on windows are
+		// always readable.
+		assertTrue(testFile.canRead());
+		assertFalse(testFile.setReadable(false, false));
+		assertTrue(testFile.canRead());
+		assertFalse(testFile.setReadable(false, true));
+		assertTrue(testFile.canRead());
+
+		assertFalse(testDir.setReadable(false, true));
+		assertFalse(testDir.setReadable(false, false));
+		assertTrue(testDir.canRead());
+
+		// setReadable(true, false/true) and set them in turn
+		assertTrue(testFile.setReadable(true, false));
+		assertTrue(testFile.canRead());
+		// setReadable(false) does not take effects on Windows.
+		assertFalse(testFile.setReadable(false, true));
+		assertTrue(testFile.canRead());
+		assertTrue(testFile.setReadable(true, true));
+		assertTrue(testFile.canRead());
+		assertFalse(testFile.setReadable(false, false));
+		assertTrue(testFile.canRead());
+
+		assertTrue(testDir.setReadable(true, false));
+		assertTrue(testDir.canRead());
+		assertTrue(testDir.setReadable(true, true));
+		assertTrue(testDir.canRead());
+	}
+
+	/**
+	 * @tests java.io.File#setReadable(boolean)
+	 * 
+	 * @since 1.6
+	 */
+	public void test_setReadableZ() {
+		// So far this method only deals with the situation that the user is the
+		// owner of the file
+		// setReadable(false) fails on Windows. canRead() always returns true.
+		assertFalse(testFile.setReadable(false));
+		assertTrue(testFile.canRead());
+		assertFalse(testDir.setReadable(false));
+		assertTrue(testDir.canRead());
+
+		// setReadable(true)
+		assertTrue(testFile.setReadable(true));
+		assertTrue(testFile.canRead());
+		assertTrue(testDir.setReadable(true));
+		assertTrue(testDir.canRead());
+	}
+
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();