### Eclipse Workspace Patch 1.0 #P org.eclipse.core.filesystem Index: natives/unix/localfile.c =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/natives/unix/localfile.c,v retrieving revision 1.4 diff -u -r1.4 localfile.c --- natives/unix/localfile.c 12 Oct 2005 20:26:34 -0000 1.4 +++ natives/unix/localfile.c 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Red Hat Incorporated - get/setResourceAttribute code + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ #include #include @@ -17,6 +18,10 @@ #include #include "../localfile.h" #include +#ifdef LINUX +#include +#include +#endif /* * Get a null-terminated byte array from a java byte array. @@ -36,6 +41,24 @@ return result; } +#ifdef LINUX +/* + * Get a Java String from a java byte array, using the default charset. + * Uses Convert.fromPlatformBytes([B). + */ +jobject getString(JNIEnv *env, jbyteArray source) { + static jclass clsConvert = NULL; + static jmethodID midFromPlatformBytes = 0; + if (midFromPlatformBytes == 0) { + clsConvert = (*env)->FindClass(env, "org.eclipse.core.internal.filesystem.local.Convert"); + if (clsConvert == 0) return NULL; + midFromPlatformBytes = (*env)->GetStaticMethodID(env, clsConvert, "fromPlatformBytes", "([B)Ljava/lang/String;"); + if (midFromPlatformBytes == 0) return NULL; + } + return (*env)->CallStaticObjectMethod(env, clsConvert, midFromPlatformBytes, source); +} +#endif + /* * Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives * Method: internalIsUnicode @@ -50,7 +73,7 @@ /* * Converts a stat structure to IFileInfo */ -jboolean convertStatToFileInfo (JNIEnv *env, struct stat info, jobject fileInfo) { +jboolean convertStatToFileInfo (JNIEnv *env, struct stat info, jobject fileInfo, jobject linkTarget) { jclass cls; jmethodID mid; @@ -94,12 +117,18 @@ (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_EXECUTABLE, JNI_TRUE); } +#ifdef LINUX // sym link? -// if ((info.st_mode & S_IFLNK) == S_IFLNK) { -// mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V"); -// if (mid == 0) return JNI_FALSE; -// (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_LINK, JNI_TRUE); -// } + if (linkTarget != NULL) { + mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V"); + if (mid == 0) return JNI_FALSE; + (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_SYMLINK, JNI_TRUE); + + mid = (*env)->GetMethodID(env, cls, "setStringAttribute", "(Ljava/lang/String;)V"); + if (mid == 0) return JNI_FALSE; + (*env)->CallVoidMethod(env, fileInfo, mid, linkTarget); + } +#endif return JNI_TRUE; } @@ -114,16 +143,40 @@ jlong result; jint code; jbyte *name; + jobject linkTarget = NULL; /* get stat */ name = getByteArray(env, target); +#ifdef LINUX + //do an lstat first to see if it is a symbolic link + code = lstat((const char*)name, &info); + if (code == 0 && (info.st_mode & S_IFLNK) == S_IFLNK) { + //symbolic link: stat link target + code = stat((const char*)name, &info); + //read link target + if (code == 0) { + char buf[PATH_MAX]; + int len; + jbyteArray linkTargetArr; + len = readlink((const char*)name, buf, PATH_MAX); + if (len>0) { + linkTargetArr = (*env)->NewByteArray(env, len); + (*env)->SetByteArrayRegion(env, linkTargetArr, 0, len, (jbyte *)buf); + } else { + linkTargetArr = (*env)->NewByteArray(env, 0); + } + linkTarget = getString(env, linkTargetArr); + } + } +#else code = stat((const char*)name, &info); +#endif free(name); /* test if an error occurred */ if (code == -1) return 0; - return convertStatToFileInfo(env, info, fileInfo); + return convertStatToFileInfo(env, info, fileInfo, linkTarget); } /* Index: src/org/eclipse/core/filesystem/EFS.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/EFS.java,v retrieving revision 1.13 diff -u -r1.13 EFS.java --- src/org/eclipse/core/filesystem/EFS.java 9 Nov 2006 22:16:49 -0000 1.13 +++ src/org/eclipse/core/filesystem/EFS.java 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ package org.eclipse.core.filesystem; @@ -146,6 +147,38 @@ public static final int ATTRIBUTE_HIDDEN = 1 << 4; /** + * Attribute constant (value 1 <<5) indicating that a + * file is a symbolic link. + * + * If this attribute is true for a given {@link IFileInfo} + * instance, a String value may be associated with the attribute + * holding the symbolic link target. This link target can be + * retrieved with {@link IFileInfo#getStringAttribute()}. + * + * Symbolic links are handled transparently, as implemented by the + * underlying operating system. This means, that all other attributes + * of a {@link IFileInfo} apply to the link target instead of the link. + * Reading or writing a file, or changing attributes applies to the + * link target and not the link itself. In case a symbolic link points + * to another symbolic link, the chain of links is transparently followed + * and operations apply to the actual file or directory being referenced + * by the chain of symbolic links. For broken symbolic links (which do + * not reference any valid file or directory), such operations throw + * a "file not found" exception. + * + * The only operation that does not transparently work on the link target, + * is deletion: {@link IFileStore#delete(int, IProgressMonitor)} + * deletes the symbolic link but not the link target. + * + * @see IFileStore#fetchInfo() + * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor) + * @see IFileInfo#getAttribute(int) + * @see IFileInfo#setAttribute(int, boolean) + * @since org.eclipse.core.filesystem 1.1 + */ + public static final int ATTRIBUTE_SYMLINK = 1 << 5; + + /** * Scheme constant (value "file") indicating the local file system scheme. * @see EFS#getLocalFileSystem() */ Index: src/org/eclipse/core/filesystem/IFileInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/IFileInfo.java,v retrieving revision 1.14 diff -u -r1.14 IFileInfo.java --- src/org/eclipse/core/filesystem/IFileInfo.java 9 Nov 2006 22:16:49 -0000 1.14 +++ src/org/eclipse/core/filesystem/IFileInfo.java 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ package org.eclipse.core.filesystem; @@ -51,6 +52,24 @@ public abstract boolean getAttribute(int attribute); /** + * Returns the extended String attribute for this file. + * + * Interpretation of the extended String attribute depends on the + * kind of attributes associated with this IFileInfo. Currently, + * the only defined meaning is to return the symbolic link target + * in case {@link EFS#ATTRIBUTE_SYMLINK} is set with the attributes. + * + * Returns null if no String attribute is associated with + * this file info, the attribute could not be accessed, or the + * attribute does not apply to this file system. + * + * @return the value of the extended String attribute for this file. + * @see IFileSystem#attributes() + * @since org.eclipse.core.filesystem 1.1 + */ + public abstract String getStringAttribute(); + + /** * Returns the last modified time for this file, or {@link EFS#NONE} * if the file does not exist or the last modified time could not be computed. *

Index: src/org/eclipse/core/internal/filesystem/local/LocalFileSystem.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/LocalFileSystem.java,v retrieving revision 1.10 diff -u -r1.10 LocalFileSystem.java --- src/org/eclipse/core/internal/filesystem/local/LocalFileSystem.java 19 Dec 2006 22:18:35 -0000 1.10 +++ src/org/eclipse/core/internal/filesystem/local/LocalFileSystem.java 29 Jan 2007 15:00:18 -0000 @@ -87,7 +87,9 @@ String os = getOS(); if (os.equals(Platform.OS_WIN32)) attributes |= EFS.ATTRIBUTE_ARCHIVE | EFS.ATTRIBUTE_HIDDEN; - else if (os.equals(Platform.OS_LINUX) || os.equals(Platform.OS_MACOSX)) + else if (os.equals(Platform.OS_LINUX)) + attributes |= EFS.ATTRIBUTE_EXECUTABLE | EFS.ATTRIBUTE_SYMLINK; + else if (os.equals(Platform.OS_MACOSX)) attributes |= EFS.ATTRIBUTE_EXECUTABLE; return attributes; } Index: src/org/eclipse/core/internal/filesystem/local/Convert.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Convert.java,v retrieving revision 1.3 diff -u -r1.3 Convert.java --- src/org/eclipse/core/internal/filesystem/local/Convert.java 21 Nov 2006 18:43:10 -0000 1.3 +++ src/org/eclipse/core/internal/filesystem/local/Convert.java 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ package org.eclipse.core.internal.filesystem.local; @@ -69,6 +70,24 @@ } /** + * Calling new String(byte[] s) creates a new encoding object and other garbage. + * This can be avoided by calling new String(byte[] s, String encoding) instead. + * @since org.eclipse.core.filesystem 1.1 + */ + public static String fromPlatformBytes(byte[] source) { + if (defaultEncoding == null) + return new String(source); + // try to use the default encoding + try { + return new String(source, defaultEncoding); + } catch (UnsupportedEncodingException e) { + // null the default encoding so we don't try it again + defaultEncoding = null; + return new String(source); + } + } + + /** * Calling String.getBytes() creates a new encoding object and other garbage. * This can be avoided by calling String.getBytes(String encoding) instead. */ Index: src/org/eclipse/core/internal/filesystem/local/LocalFileNatives.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/LocalFileNatives.java,v retrieving revision 1.9 diff -u -r1.9 LocalFileNatives.java --- src/org/eclipse/core/internal/filesystem/local/LocalFileNatives.java 21 Nov 2006 18:43:10 -0000 1.9 +++ src/org/eclipse/core/internal/filesystem/local/LocalFileNatives.java 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ package org.eclipse.core.internal.filesystem.local; Index: natives/localfile.h =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/natives/localfile.h,v retrieving revision 1.3 diff -u -r1.3 localfile.h --- natives/localfile.h 12 Oct 2005 20:27:58 -0000 1.3 +++ natives/localfile.h 29 Jan 2007 15:00:18 -0000 @@ -1,9 +1,13 @@ /* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API */ /* DO NOT EDIT THIS FILE - it is machine generated */ #include @@ -15,7 +19,7 @@ extern "C" { #endif -//values from IFileStoreConstants +//values from EFS #undef ATTRIBUTE_DIRECTORY #define ATTRIBUTE_DIRECTORY 0x01l #undef ATTRIBUTE_READ_ONLY @@ -26,6 +30,8 @@ #define ATTRIBUTE_ARCHIVE 0x08l #undef ATTRIBUTE_HIDDEN #define ATTRIBUTE_HIDDEN 0x10l +#undef ATTRIBUTE_SYMLINK +#define ATTRIBUTE_SYMLINK 0x20l #undef SET_ATTRIBUTES #define SET_ATTRIBUTES 0x01l #undef SET_LAST_MODIFIED Index: src/org/eclipse/core/filesystem/provider/FileInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/provider/FileInfo.java,v retrieving revision 1.8 diff -u -r1.8 FileInfo.java --- src/org/eclipse/core/filesystem/provider/FileInfo.java 9 Nov 2006 22:16:49 -0000 1.8 +++ src/org/eclipse/core/filesystem/provider/FileInfo.java 29 Jan 2007 15:00:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API *******************************************************************************/ package org.eclipse.core.filesystem.provider; @@ -17,7 +18,7 @@ * This class should be used by file system providers in their implementation * of API methods that return {@link IFileInfo} objects. *

- * This class is not intended to be subclassed. + * This class is not intended to be subclassed by clients. *

* @since org.eclipse.core.filesystem 1.0 */ @@ -53,6 +54,12 @@ private String name = ""; //$NON-NLS-1$ /** + * The extra String attribute, e.g. symbolic link target. + * @since org.eclipse.core.filesystem 1.1 + */ + private String stringAttr = null; //$NON-NLS-1$ + + /** * Creates a new file information object with default values. */ public FileInfo() { @@ -112,6 +119,13 @@ } /* (non-Javadoc) + * @see org.eclipse.core.filesystem.IFileInfo#getStringAttribute(int) + */ + public String getStringAttribute() { + return this.stringAttr; + } + + /* (non-Javadoc) * @see org.eclipse.core.filesystem.IFileInfo#lastModified() */ public long getLastModified() { @@ -212,6 +226,16 @@ } /** + * Sets or clears the String attribute, e.g. symbolic link target. + * + * @param attr The String attribute + * @since org.eclipse.core.filesystem 1.1 + */ + public void setStringAttribute(String attr) { + this.stringAttr = attr; + } + + /** * For debugging purposes only. */ public String toString() {