Skip to content

Commit

Permalink
[GR-15932] TruffleFile should allow setting the Owner and Group.
Browse files Browse the repository at this point in the history
PullRequest: graal/3638
  • Loading branch information
tzezula committed May 24, 2019
2 parents 6d6ff27 + 95ad758 commit 7bb1a83
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions truffle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This changelog summarizes major changes between Truffle versions relevant to lan
* `SlowPathException#fillInStackTrace` is now `final`.
* Added an ability to read a [path separator](https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/TruffleLanguage.Env.html#getPathSeparator--) used to separate filenames in a path list.
* `@TruffleBoundary` methods that throw but are not annotated with `@TruffleBoundary(transferToInterpreterOnException=false)` will now transfer to the interpreter only once per `CallTarget` (compilation root).
* Added [TruffleFile.setAttribute](https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/TruffleFile.html#setAttribute-com.oracle.truffle.api.TruffleFile.AttributeDescriptor-T-java.nio.file.LinkOption...-) to allow languages to set file attributes.

## Version 19.0.0
* Renamed version 1.0.0 to 19.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
import com.oracle.truffle.api.impl.Accessor;
import com.oracle.truffle.api.nodes.RootNode;
import java.nio.file.attribute.PosixFilePermission;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import org.graalvm.polyglot.PolyglotException;
import org.junit.Assume;

Expand All @@ -132,6 +134,7 @@ public class VirtualizedFileSystemTest {
private static final String FILE_NEW_SYMLINK = "new_symlink.txt";
private static final String FILE_NEW_COPY = "new_copy.txt";
private static final String FOLDER_NEW_COPY = "folder_copy";
private static final String FILE_CHANGE_ATTRS = "existing_attrs.txt";

private static Collection<Configuration> cfgs;
private static Consumer<Env> languageAction;
Expand Down Expand Up @@ -1373,6 +1376,50 @@ public void testGetAttribute() {
ctx.eval(LANGUAGE_ID, "");
}

@Test
public void testSetAttribute() {
Context ctx = cfg.getContext();
Path path = cfg.getPath();
boolean canRead = cfg.canRead();
boolean canWrite = cfg.canWrite();
languageAction = (Env env) -> {
TruffleFile root = env.getTruffleFile(path.toString());
try {
TruffleFile file = root.resolve(FILE_CHANGE_ATTRS);
FileTime time = FileTime.from(Instant.now().minusSeconds(1_000).truncatedTo(ChronoUnit.MINUTES));
file.setAttribute(TruffleFile.LAST_MODIFIED_TIME, time);
Assert.assertTrue(cfg.formatErrorMessage("Expected SecurityException"), canWrite);
Assert.assertEquals(time, file.getAttribute(TruffleFile.LAST_MODIFIED_TIME));
Assert.assertTrue(cfg.formatErrorMessage("Expected SecurityException"), canRead);
file.setAttribute(TruffleFile.LAST_ACCESS_TIME, time);
Assert.assertEquals(time, file.getAttribute(TruffleFile.LAST_ACCESS_TIME));
file.setAttribute(TruffleFile.CREATION_TIME, time);
Assert.assertEquals(time, file.getAttribute(TruffleFile.CREATION_TIME));
file.setAttribute(TruffleFile.UNIX_PERMISSIONS, EnumSet.of(PosixFilePermission.OWNER_READ));
Assert.assertEquals(EnumSet.of(PosixFilePermission.OWNER_READ), file.getAttribute(TruffleFile.UNIX_PERMISSIONS));
file.setAttribute(TruffleFile.UNIX_PERMISSIONS, EnumSet.of(PosixFilePermission.OWNER_READ));
Assert.assertEquals(EnumSet.of(PosixFilePermission.OWNER_READ), file.getAttribute(TruffleFile.UNIX_PERMISSIONS));
file.setAttribute(TruffleFile.UNIX_MODE, (file.getAttribute(TruffleFile.UNIX_MODE) & ~0700) | 0200);
Assert.assertEquals(0200, file.getAttribute(TruffleFile.UNIX_MODE) & 0777);
} catch (SecurityException se) {
Assert.assertFalse(cfg.formatErrorMessage("Unexpected SecurityException"), canWrite);
} catch (IOException ioe) {
throw new AssertionError(cfg.formatErrorMessage(ioe.getMessage()), ioe);
} catch (UnsupportedOperationException e) {
// Verify that file system does not support unix attributes
try {
cfg.fileSystem.readAttributes(path, "unix:*");
throw e;
} catch (UnsupportedOperationException unsupported) {
// Expected
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
};
ctx.eval(LANGUAGE_ID, "");
}

@Test
public void testGetAttributes() {
Context ctx = cfg.getContext();
Expand Down Expand Up @@ -1768,6 +1815,7 @@ private static Path createContent(
touch(folder.resolve(FILE_EXISTING_WRITE_MMAP), fs);
touch(folder.resolve(FILE_EXISTING_DELETE), fs);
touch(folder.resolve(FILE_EXISTING_RENAME), fs);
touch(folder.resolve(FILE_CHANGE_ATTRS), fs);
try {
ln(folder.resolve(FOLDER_EXISTING), folder.resolve(SYMLINK_EXISTING), fs);
} catch (UnsupportedOperationException unsupported) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,33 @@ public <T> T getAttribute(AttributeDescriptor<T> attribute, LinkOption... linkOp
}
}

/**
* Sets a single file's attribute.
*
* @param attribute the attribute to set
* @param value the attribute value
* @param linkOptions the options determining how the symbolic links should be handled
* @throws IOException in case of IO error
* @throws UnsupportedOperationException when the filesystem does not support given attribute
* @throws IllegalArgumentException when the attribute value has an inappropriate value
* @throws SecurityException if the {@link FileSystem} denied the operation
* @since 20.0.0 beta 1
*/
@TruffleBoundary
public <T> void setAttribute(AttributeDescriptor<T> attribute, T value, LinkOption... linkOptions) throws IOException {
try {
fileSystemContext.fileSystem.setAttribute(
normalizedPath,
createAttributeString(attribute.group, Collections.singleton(attribute.name)),
value,
linkOptions);
} catch (IOException | UnsupportedOperationException | SecurityException e) {
throw e;
} catch (Throwable t) {
throw wrapHostException(t);
}
}

/**
* Reads file's attributes as a bulk operation.
*
Expand Down

0 comments on commit 7bb1a83

Please sign in to comment.