summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-09-11 15:53:17 (EDT)
committer John Arthorne2012-09-26 15:32:00 (EDT)
commitded2429478f74f10e906b63a82e665e593cee70a (patch)
treebd2aa2940747660ebb1bddc49063b0f65e530494
parent1ee7648e5251c89243cc020a6f22e0cf3d1b73cb (diff)
downloadeclipse.platform.resources-ded2429478f74f10e906b63a82e665e593cee70a.zip
eclipse.platform.resources-ded2429478f74f10e906b63a82e665e593cee70a.tar.gz
eclipse.platform.resources-ded2429478f74f10e906b63a82e665e593cee70a.tar.bz2
Fix for bug 379193 - Eclipse doesn't distinguish between I/O errors and
-rw-r--r--bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dllbin47616 -> 75078 bytes
-rw-r--r--bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.core.filesystem/natives/localfile.h4
-rw-r--r--bundles/org.eclipse.core.filesystem/natives/win32/localfile.c23
-rw-r--r--bundles/org.eclipse.core.filesystem/pom.xml2
-rw-r--r--bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java20
-rw-r--r--bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java28
-rw-r--r--bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java13
-rw-r--r--bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java2
-rw-r--r--bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java2
-rw-r--r--bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java13
11 files changed, 98 insertions, 11 deletions
diff --git a/bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dll b/bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dll
index 4952788..41793d2 100644
--- a/bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dll
+++ b/bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dll
Binary files differ
diff --git a/bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF
index 00861e3..7adad0f 100644
--- a/bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.core.filesystem; singleton:=true
-Bundle-Version: 1.3.200.qualifier
+Bundle-Version: 1.4.0.qualifier
Bundle-Localization: plugin
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.2.0,4.0.0)",
org.eclipse.equinox.registry;bundle-version="[3.2.0,4.0.0)",
diff --git a/bundles/org.eclipse.core.filesystem/natives/localfile.h b/bundles/org.eclipse.core.filesystem/natives/localfile.h
index a7469c2..02572ac 100644
--- a/bundles/org.eclipse.core.filesystem/natives/localfile.h
+++ b/bundles/org.eclipse.core.filesystem/natives/localfile.h
@@ -40,6 +40,10 @@ extern "C" {
#undef SET_LAST_MODIFIED
#define SET_LAST_MODIFIED 0x02l
+// From FileInfo.java
+#undef ATTRIBUTE_IO_ERROR
+#define ATTRIBUTE_IO_ERROR 0x20000
+
/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: nativeAttributes
diff --git a/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c b/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
index f428b60..d74e993 100644
--- a/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
+++ b/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
@@ -47,8 +47,6 @@ typedef struct _REPARSE_DATA_BUFFER {
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
-
-
/*
* Converts a FILETIME in a java long (milliseconds).
*/
@@ -380,6 +378,20 @@ jboolean fillEmptyDirectory(JNIEnv *env, jobject fileInfo) {
}
/*
+ * Sets FileInfo.ATTRIBUTE_IO_ERROR flag.
+ */
+jboolean setIOError(JNIEnv *env, jobject fileInfo) {
+ jclass cls;
+ jmethodID mid;
+ cls = (*env)->GetObjectClass(env, fileInfo);
+ if (cls != 0) return JNI_FALSE;
+ mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
+ if (mid == 0) return JNI_FALSE;
+ (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_IO_ERROR, JNI_TRUE);
+ return JNI_TRUE;
+}
+
+/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfo
* Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
@@ -402,8 +414,11 @@ JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_Local
}
handle = FindFirstFile(name, &info);
free(name);
- if (handle == INVALID_HANDLE_VALUE)
+ if (handle == INVALID_HANDLE_VALUE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ setIOError(env, fileInfo);
return JNI_FALSE;
+ }
FindClose(handle);
return convertFindDataToFileInfo(env, info, fileInfo);
}
@@ -433,6 +448,8 @@ JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_Local
handle = FindFirstFileW(name, &info);
if (handle == INVALID_HANDLE_VALUE) {
free(name);
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ setIOError(env, fileInfo);
return JNI_FALSE;
}
diff --git a/bundles/org.eclipse.core.filesystem/pom.xml b/bundles/org.eclipse.core.filesystem/pom.xml
index bc7e068..cfc85ea 100644
--- a/bundles/org.eclipse.core.filesystem/pom.xml
+++ b/bundles/org.eclipse.core.filesystem/pom.xml
@@ -21,6 +21,6 @@
</parent>
<groupId>eclipse.platform.resources</groupId>
<artifactId>org.eclipse.core.filesystem</artifactId>
- <version>1.3.200-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java
index 913bd64..33b1290 100644
--- a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java
+++ b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java
@@ -27,16 +27,34 @@ import org.eclipse.core.runtime.IProgressMonitor;
* implementations should use the concrete class {@link org.eclipse.core.filesystem.provider.FileStore}
*/
public interface IFileInfo extends Comparable, Cloneable {
+ /**
+ * The constant indicating that file information was retrieved successfully.
+ * @since 1.4
+ */
+ public static final int NONE = 0;
+ /**
+ * The constant indicating that an I/O error was encountered while retrieving file information.
+ * @since 1.4
+ */
+ public static final int IO_ERROR = 5; // The value is chosen to match EIO Linux errno value.
/**
* Returns whether this file or directory exists.
*
* @return <code>true</code> if this file exists, and <code>false</code>
- * otherwise.
+ * if the file does not exist or an I/O error was encountered.
*/
public abstract boolean exists();
/**
+ * Checks whether an I/O error was encountered while accessing this file or directory.
+ *
+ * @return {@link #IO_ERROR} if an I/O error was encountered, or {@link #NONE} otherwise.
+ * @since 1.4
+ */
+ public abstract int getError();
+
+ /**
* Returns the value of the specified attribute for this file. The attribute
* must be one of the <code>EFS#ATTRIBUTE_*</code>
* constants. Returns <code>false</code> if this file does not exist,
diff --git a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java
index 48e00e4..b27ac1a 100644
--- a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java
+++ b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java
@@ -34,6 +34,12 @@ public class FileInfo implements IFileInfo {
private static final int ATTRIBUTE_EXISTS = 1 << 16;
/**
+ * Internal attribute indicating that an I/O error was encountered while retrieving
+ * the file information.
+ */
+ private static final int ATTRIBUTE_IO_ERROR = 1 << 17;
+
+ /**
* Bit field of file attributes. Initialized to specify a writable resource.
*/
private int attributes = EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ;
@@ -113,6 +119,14 @@ public class FileInfo implements IFileInfo {
return getAttribute(ATTRIBUTE_EXISTS);
}
+ /**
+ * @since 1.4
+ * @see IFileInfo#getError()
+ */
+ public int getError() {
+ return getAttribute(ATTRIBUTE_IO_ERROR) ? IO_ERROR : NONE;
+ }
+
public boolean getAttribute(int attribute) {
if (attribute == EFS.ATTRIBUTE_READ_ONLY && isAttributeSuported(EFS.ATTRIBUTE_OWNER_WRITE))
return (!isSet(EFS.ATTRIBUTE_OWNER_WRITE)) || isSet(EFS.ATTRIBUTE_IMMUTABLE);
@@ -222,6 +236,20 @@ public class FileInfo implements IFileInfo {
clear(ATTRIBUTE_EXISTS);
}
+ /**
+ * Sets a flag indicating that an I/O error was encountered when accessing the file.
+ *
+ * @param value <code>true</code> if this file has an I/O error, and <code>false</code>
+ * otherwise.
+ * @since 1.4
+ */
+ public void setError(boolean value) {
+ if (value)
+ set(ATTRIBUTE_IO_ERROR);
+ else
+ clear(ATTRIBUTE_IO_ERROR);
+ }
+
/* (non-Javadoc)
* @see org.eclipse.core.filesystem.IFileInfo#setLastModified(long)
*/
diff --git a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java
index e0d52bf..d936852 100644
--- a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java
+++ b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java
@@ -25,6 +25,7 @@ public abstract class UnixFileNatives {
private static final String LIBRARY_NAME = "unixfile_1_0_0"; //$NON-NLS-1$
private static final int UNICODE_SUPPORTED = 1 << 0;
private static final int CHFLAGS_SUPPORTED = 1 << 1;
+ private static final int ENOENT = 2; // errno value for "No such file or directory"
private static final boolean usingNatives;
private static final int libattr;
@@ -72,10 +73,13 @@ public abstract class UnixFileNatives {
StructStat stat = new StructStat();
if (lstat(name, stat) == 0) {
if ((stat.st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFLNK) {
- if (stat(name, stat) == 0)
+ if (stat(name, stat) == 0) {
info = stat.toFileInfo();
- else
+ } else {
info = new FileInfo();
+ if (getErrno() != ENOENT)
+ info.setError(true);
+ }
info.setAttribute(EFS.ATTRIBUTE_SYMLINK, true);
byte target[] = new byte[UnixFileFlags.PATH_MAX];
int length = readlink(name, target, target.length);
@@ -83,8 +87,11 @@ public abstract class UnixFileNatives {
info.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, bytesToFileName(target, length));
} else
info = stat.toFileInfo();
- } else
+ } else {
info = new FileInfo();
+ if (getErrno() != ENOENT)
+ info.setError(true);
+ }
return info;
}
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java
index f350e6f..45e17d8 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java
@@ -149,6 +149,8 @@ public class CopyVisitor implements IUnifiedTreeVisitor {
/* virtual resources are always deemed as being synchronized */
if (node.getResource().isVirtual())
return true;
+ if (node.isErrorInFileSystem())
+ return true; // Assume synchronized unless proven otherwise
/* does the resource exist in workspace and file system? */
if (!node.existsInWorkspace() || !node.existsInFileSystem())
return false;
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java
index 3e52238..20670fd 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java
@@ -262,6 +262,8 @@ public class RefreshLocalVisitor implements IUnifiedTreeVisitor, ILocalStoreCons
public boolean visit(UnifiedTreeNode node) throws CoreException {
Policy.checkCanceled(monitor);
try {
+ if (node.isErrorInFileSystem())
+ return false; // Don't visit children if we encountered an I/O error
Resource target = (Resource) node.getResource();
int targetType = target.getType();
if (targetType == IResource.PROJECT)
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java
index 764748b..be26202 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java
@@ -41,6 +41,14 @@ public class UnifiedTreeNode implements ILocalStoreConstants {
return fileInfo != null && fileInfo.exists();
}
+ /**
+ * Returns <code>true</code> if an I/O error was encountered while accessing
+ * the file or the directory in the file system.
+ */
+ public boolean isErrorInFileSystem() {
+ return fileInfo != null && fileInfo.getError() != IFileInfo.NONE;
+ }
+
public boolean existsInWorkspace() {
return existsWorkspace;
}
@@ -89,7 +97,7 @@ public class UnifiedTreeNode implements ILocalStoreConstants {
public boolean isFolder() {
return fileInfo == null ? false : fileInfo.isDirectory();
}
-
+
public boolean isSymbolicLink() {
return fileInfo == null ? false : fileInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK);
}
@@ -109,7 +117,7 @@ public class UnifiedTreeNode implements ILocalStoreConstants {
this.fileInfo = info;
this.existsWorkspace = existsInWorkspace;
}
-
+
/**
* Releases elements that won't be needed any more for garbage collection.
* Should be called before adding a node to the free list.
@@ -133,6 +141,7 @@ public class UnifiedTreeNode implements ILocalStoreConstants {
this.resource = resource;
}
+ @Override
public String toString() {
String s = resource == null ? "null" : resource.getFullPath().toString(); //$NON-NLS-1$
return "Node: " + s; //$NON-NLS-1$