aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-11-12 04:48:09 (EST)
committerSzymon Brandys2012-11-12 04:48:09 (EST)
commit68a3d79704300b9646e96031906187d1cb10b11c (patch)
tree05e33e16ee353a8a3fbc68bbe7bee4db1cc66144
parentf075a0283ece947837bfff4207787db770e494bd (diff)
downloadeclipse.platform.resources-68a3d79704300b9646e96031906187d1cb10b11c.zip
eclipse.platform.resources-68a3d79704300b9646e96031906187d1cb10b11c.tar.gz
eclipse.platform.resources-68a3d79704300b9646e96031906187d1cb10b11c.tar.bz2
Fix for bug 379193 - Eclipse doesn't distinguish between I/O errors andv20121112-094809refs/changes/99/6599/5
-rw-r--r--bundles/org.eclipse.core.filesystem.win32.x86/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.core.filesystem.win32.x86/os/win32/x86/localfile_1_0_0.dllbin47616 -> 45056 bytes
-rw-r--r--bundles/org.eclipse.core.filesystem.win32.x86/pom.xml2
-rw-r--r--bundles/org.eclipse.core.filesystem/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.core.filesystem/natives/win32/localfile.c27
-rw-r--r--bundles/org.eclipse.core.filesystem/pom.xml2
-rw-r--r--bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java22
-rw-r--r--bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java21
-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
12 files changed, 95 insertions, 15 deletions
diff --git a/bundles/org.eclipse.core.filesystem.win32.x86/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.filesystem.win32.x86/META-INF/MANIFEST.MF
index 5fd2b17..88901e9 100644
--- a/bundles/org.eclipse.core.filesystem.win32.x86/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.filesystem.win32.x86/META-INF/MANIFEST.MF
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %fragmentName
Bundle-SymbolicName: org.eclipse.core.filesystem.win32.x86; singleton:=true
-Bundle-Version: 1.1.300.qualifier
+Bundle-Version: 1.4.0.qualifier
Bundle-Vendor: %providerName
-Fragment-Host: org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)"
+Fragment-Host: org.eclipse.core.filesystem;bundle-version="[1.4.0,2.0.0)"
Bundle-Localization: fragment
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
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..9e8c65c 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.win32.x86/pom.xml b/bundles/org.eclipse.core.filesystem.win32.x86/pom.xml
index 18ff6aa..98a5c87 100644
--- a/bundles/org.eclipse.core.filesystem.win32.x86/pom.xml
+++ b/bundles/org.eclipse.core.filesystem.win32.x86/pom.xml
@@ -22,7 +22,7 @@
</parent>
<groupId>eclipse.platform.resources</groupId>
<artifactId>org.eclipse.core.filesystem.win32.x86</artifactId>
- <version>1.1.300-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
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/win32/localfile.c b/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
index f428b60..bd73012 100644
--- a/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
+++ b/bundles/org.eclipse.core.filesystem/natives/win32/localfile.c
@@ -21,6 +21,10 @@
#define IO_REPARSE_TAG_SYMLINK 0xA000000C
#endif
+// From IFileInfo.java
+#undef IO_ERROR
+#define IO_ERROR 5
+
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
@@ -47,8 +51,6 @@ typedef struct _REPARSE_DATA_BUFFER {
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
-
-
/*
* Converts a FILETIME in a java long (milliseconds).
*/
@@ -380,6 +382,20 @@ jboolean fillEmptyDirectory(JNIEnv *env, jobject fileInfo) {
}
/*
+ * Calls FileInfo.setError(IFileInfo.IO_ERROR).
+ */
+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", "(I)V");
+ if (mid == 0) return JNI_FALSE;
+ (*env)->CallVoidMethod(env, fileInfo, mid, IO_ERROR);
+ return JNI_TRUE;
+}
+
+/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfo
* Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
@@ -402,8 +418,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 +452,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..f5c3edd 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,
@@ -50,7 +68,7 @@ public interface IFileInfo extends Comparable, Cloneable {
public abstract boolean getAttribute(int attribute);
/**
- * Returns the value of the specified attribute for this file. The attribute
+ * Returns the value of the specified attribute for this file. The attribute
* must be one of the <code>EFS#ATTRIBUTE_*</code>
* constants. Returns <code>null</code> if this file does not exist,
* could not be accessed, or the provided attribute does not apply to this
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..4387a6c 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
@@ -38,6 +38,8 @@ public class FileInfo implements IFileInfo {
*/
private int attributes = EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ;
+ private int errorCode = NONE;
+
/**
* The last modified time.
*/
@@ -113,6 +115,14 @@ public class FileInfo implements IFileInfo {
return getAttribute(ATTRIBUTE_EXISTS);
}
+ /**
+ * @since 1.4
+ * @see IFileInfo#getError()
+ */
+ public int getError() {
+ return errorCode;
+ }
+
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 +232,17 @@ public class FileInfo implements IFileInfo {
clear(ATTRIBUTE_EXISTS);
}
+ /**
+ * Sets the error code indicating whether an I/O error was encountered when accessing the file.
+ *
+ * @param errorCode {@link IFileInfo#IO_ERROR} if this file has an I/O error,
+ * and {@link IFileInfo#NONE} otherwise.
+ * @since 1.4
+ */
+ public void setError(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
/* (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..6df08a5 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(IFileInfo.IO_ERROR);
+ }
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(IFileInfo.IO_ERROR);
+ }
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$