diff options
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 5fd2b17ce..88901e9e6 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 Binary files differindex 4952788c4..9e8c65c04 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 diff --git a/bundles/org.eclipse.core.filesystem.win32.x86/pom.xml b/bundles/org.eclipse.core.filesystem.win32.x86/pom.xml index 18ff6aa1b..98a5c87a3 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 00861e313..7adad0f45 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 f428b604b..bd73012c4 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 bc7e06815..cfc85ea1a 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 913bd6476..f5c3edd84 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 48e00e438..4387a6c9d 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 e0d52bf89..6df08a542 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 f350e6f39..45e17d8d6 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 3e522389b..20670fd07 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 764748b30..be26202af 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$ |