Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,14 @@ private void checkTargetIsNotWritable(File target, Throwable exception) throws C
}
}

@Override
public IFileInfo[] childInfos(int options, IProgressMonitor monitor) {
return LocalFileNativesManager.listDirectoryAndGetFileInfos(filePath);
}

@Override
public String[] childNames(int options, IProgressMonitor monitor) {
String[] names = file.list();
return (names == null ? EMPTY_STRING_ARRAY : names);
return LocalFileNativesManager.listDirectoryNames(filePath);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,12 @@ public static boolean putFileInfo(String fileName, IFileInfo info, int options)
return HANDLER.putFileInfo(fileName, info, options);
}

public static IFileInfo[] listDirectoryAndGetFileInfos(String fileName) {
return HANDLER.listDirectoryAndGetFileInfos(fileName);
}

public static String[] listDirectoryNames(String fileName) {
return HANDLER.listDirectoryNames(fileName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*******************************************************************************/
package org.eclipse.core.internal.filesystem.local;

import java.io.File;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.provider.FileInfo;

Expand All @@ -25,4 +26,21 @@ public abstract class NativeHandler {
public abstract FileInfo fetchFileInfo(String fileName);

public abstract boolean putFileInfo(String fileName, IFileInfo info, int options);

protected static final String[] EMPTY_STRING_ARRAY = {};

public String[] listDirectoryNames(String fileName) {
String[] names = new File(fileName).list();
return names == null ? EMPTY_STRING_ARRAY : names;
}

public IFileInfo[] listDirectoryAndGetFileInfos(String fileName) {
var directoryContents = listDirectoryNames(fileName);
var result = new IFileInfo[directoryContents.length];
for (int i = 0; i < directoryContents.length; i++) {
result[i] = fetchFileInfo(fileName + File.separator + directoryContents[i]);
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
package org.eclipse.core.internal.filesystem.local.unix;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.provider.FileInfo;

/**
* This class mirrors relevant fields of native struct stat
* and is used by JNI calls wrapping OS file related functions.
*/
public class StructStat {
/** errno value for "No such file or directory" */
public static final int ENOENT = 2;

private static final boolean USE_MILLISECOND_RESOLUTION = Boolean.parseBoolean(System.getProperty("eclipse.filesystem.useNatives.modificationTimestampMillisecondsResolution", "true")); //$NON-NLS-1$ //$NON-NLS-2$

Expand All @@ -29,10 +32,20 @@ public class StructStat {
public long st_mtime;
public long st_mtime_msec; // millisecond component of the file timestamp, filled on Linux systems
public long st_flags; // Filled only on Mac OS X
public int errno;
public String name;
public String linkFile; // Filled target for symbolic links

public FileInfo toFileInfo() {
FileInfo info = new FileInfo();
info.setExists(true);
if (errno != 0 && errno != ENOENT) {
info.setError(IFileInfo.IO_ERROR);
return info;
}
info.setExists(errno != ENOENT);
if (name != null) {
info.setName(name);
}
info.setLength(st_size);
long lastModified = (st_mtime * 1_000);
if (USE_MILLISECOND_RESOLUTION) {
Expand All @@ -42,6 +55,12 @@ public FileInfo toFileInfo() {
if ((st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFDIR) {
info.setDirectory(true);
}
if (linkFile != null) {
info.setAttribute(EFS.ATTRIBUTE_SYMLINK, true);
if (!linkFile.isEmpty()) {
info.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, linkFile);
}
}
if ((st_flags & (UnixFileFlags.UF_IMMUTABLE | UnixFileFlags.SF_IMMUTABLE)) != 0) {
info.setAttribute(EFS.ATTRIBUTE_IMMUTABLE, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.provider.FileInfo;
import org.eclipse.core.internal.filesystem.*;
import org.eclipse.core.internal.filesystem.FileSystemAccess;
import org.eclipse.core.internal.filesystem.Messages;
import org.eclipse.core.internal.filesystem.Policy;
import org.eclipse.core.internal.filesystem.local.Convert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.osgi.util.NLS;
Expand All @@ -30,7 +32,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 int ENOENT = StructStat.ENOENT; // errno value for "No such file or directory"

private static final boolean usingNatives;
private static final int libattr;
Expand Down Expand Up @@ -80,23 +82,23 @@ public static FileInfo fetchFileInfo(String fileName) {
FileInfo info = null;
byte[] name = fileNameToBytes(fileName);
StructStat stat = new StructStat();
if (lstat(name, stat) == 0) {
if ((stat.st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFLNK) {
if (stat(name, stat) == 0) {
info = stat.toFileInfo();
} else {
if (lstat(name, stat) == 0) { // return information about the link itself if the file is a symbolic link
if ((stat.st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFLNK) { // it a link!
if (stat(name, stat) == 0) { // get the information about the file the link points to
info = stat.toFileInfo(); // store the target file stats in info
} else { // invalid link target!
info = new FileInfo();
if (getErrno() != ENOENT) {
info.setError(IFileInfo.IO_ERROR);
}
}
info.setAttribute(EFS.ATTRIBUTE_SYMLINK, true);
info.setAttribute(EFS.ATTRIBUTE_SYMLINK, true); // set symlink attribute
byte target[] = new byte[UnixFileFlags.PATH_MAX];
int length = readlink(name, target, target.length);
if (length > 0) {
if (length > 0) { // set target of the link
info.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, bytesToFileName(target, length));
}
} else {
} else { // regular file or directory
info = stat.toFileInfo();
}
} else {
Expand All @@ -106,7 +108,7 @@ public static FileInfo fetchFileInfo(String fileName) {
}
}

if (info.getName() == null) {
if (info.getName().isEmpty()) {
// If the file system is case insensitive, we don't know the real name of the file.
// Since obtaining the real name in such situation is pretty expensive, we use the name
// passed as a parameter, which may differ by case from the real name of the file
Expand Down
Loading