Skip to content
Snippets Groups Projects
Commit a9769ad6 authored by juanf's avatar juanf Committed by vkovtun
Browse files

SSDM-13521: Providing same test coverage for new Posix class as for Unix class

parent 30bbb730
No related branches found
No related tags found
1 merge request!40SSDM-13578 : 2PT : Database and V3 Implementation - include the new AFS "free"...
...@@ -20,16 +20,18 @@ import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked; ...@@ -20,16 +20,18 @@ import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
import ch.systemsx.cisd.base.unix.FileLinkType; import ch.systemsx.cisd.base.unix.FileLinkType;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.attribute.GroupPrincipal; import java.nio.file.attribute.*;
import java.nio.file.attribute.PosixFilePermission; import java.time.Instant;
import java.nio.file.attribute.UserPrincipal; import java.time.temporal.ChronoUnit;
import java.nio.file.attribute.UserPrincipalLookupService; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
public final class Posix public final class Posix
...@@ -40,56 +42,149 @@ public final class Posix ...@@ -40,56 +42,149 @@ public final class Posix
} }
public static boolean isOperational() { public static boolean isOperational() {
return true; return File.separatorChar == '/'; //On Posix systems the value of this field is '/'
} }
// //
// User related methods // User related methods
// //
private static Integer gid = null;
public static int getGid() public static int getGid()
{ {
try if (gid == null)
{
Process process = Runtime.getRuntime().exec("id -g -r");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
return Integer.parseInt(output);
} catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); try
{
Process process = Runtime.getRuntime().exec("id -g -r");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
gid = Integer.parseInt(output);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
} }
return gid;
} }
private static Integer uid = null;
public static int getUid() throws IOExceptionUnchecked public static int getUid() throws IOExceptionUnchecked
{ {
try if (uid == null)
{ {
Process process = Runtime.getRuntime().exec("id -u -r"); try
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); {
String output = reader.readLine(); Process process = Runtime.getRuntime().exec("id -u -r");
reader.close(); BufferedReader reader =
return Integer.parseInt(output); new BufferedReader(new InputStreamReader(process.getInputStream()));
} catch (IOException e) String output = reader.readLine();
reader.close();
uid = Integer.parseInt(output);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
}
return uid;
}
private static Map<String, Integer> uidByUserName = new HashMap<>();
/**
* Returns the uid of the <var>userName</var>, or <code>-1</code>, if no user with this name exists.
*/
public static final int getUidForUserName(String userName)
{
if (userName == null)
{ {
throw new IOExceptionUnchecked(e); throw new NullPointerException("userName");
}
if (uidByUserName.get(userName) == null)
{
try
{
Process process = Runtime.getRuntime().exec("id -u " + userName);
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
int uid = Integer.parseInt(output);
uidByUserName.put(userName, uid);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
} }
return uidByUserName.get(userName);
} }
public static int getEuid() private static Map<String, Integer> gidByGroupName = new HashMap<>();
/**
* Returns the gid of the <var>groupName</var>, or <code>-1</code>, if no group with this name exists.
*/
public static final int getGidForGroupName(String groupName)
{ {
try if (groupName == null)
{ {
Process process = Runtime.getRuntime().exec("id -u"); throw new NullPointerException("groupName");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); }
String output = reader.readLine();
reader.close(); if (gidByGroupName.get(groupName) == null)
return Integer.parseInt(output);
} catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); try
{
Process process = Runtime.getRuntime().exec("id -g " + groupName);
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
int uid = Integer.parseInt(output);
gidByGroupName.put(groupName, uid);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
}
return gidByGroupName.get(groupName);
}
private static Integer euid = null;
public static int getEuid()
{
if (euid == null)
{
try
{
Process process = Runtime.getRuntime().exec("id -u");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
euid = Integer.parseInt(output);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
} }
return euid;
}
/**
* Returns the effective gid that determines the permissions of this process.
*/
public static final int getEgid()
{
return getGid();
} }
public static void setOwner(String path, int userId, int groupId) public static void setOwner(String path, int userId, int groupId)
...@@ -104,48 +199,165 @@ public final class Posix ...@@ -104,48 +199,165 @@ public final class Posix
} }
} }
public static int getUid(String path) public static int getUid(String path, boolean followLinks)
{ {
try try
{ {
return (int) Files.getAttribute(Path.of(path), "unix:uid"); if (followLinks)
{
return (int) Files.getAttribute(Path.of(path), "unix:uid");
} else {
return (int) Files.getAttribute(Path.of(path), "unix:uid", LinkOption.NOFOLLOW_LINKS);
}
} catch (IOException e) } catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); throw new IOExceptionUnchecked(e);
} }
} }
public static int getGid(String path) public static int getUid(String path)
{
return getUid(path, true);
}
public static int getGid(String path, boolean followLinks)
{ {
try try
{ {
return (int) Files.getAttribute(Path.of(path), "unix:gid"); if (followLinks)
{
return (int) Files.getAttribute(Path.of(path), "unix:gid");
} else {
return (int) Files.getAttribute(Path.of(path), "unix:gid", LinkOption.NOFOLLOW_LINKS);
}
} catch (IOException e) } catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); throw new IOExceptionUnchecked(e);
} }
} }
public static int getGid(String path)
{
return getGid(path, true);
}
private static Map<Integer, String> userNameByUid = new HashMap<>();
public static String tryGetUserNameForUid(int uid) public static String tryGetUserNameForUid(int uid)
{
if (userNameByUid.get(uid) == null)
{
try
{
Process process = Runtime.getRuntime().exec("id -un " + uid);
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
userNameByUid.put(uid, output);
uidByUserName.put(output, uid);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
}
return userNameByUid.get(uid);
}
private static Map<Integer, String> groupNameByGid = new HashMap<>();
public static String tryGetGroupNameForGid(int gid)
{
if (groupNameByGid.get(gid) == null)
{
try
{
Process process = Runtime.getRuntime().exec("id -gn " + gid);
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = reader.readLine();
reader.close();
groupNameByGid.put(gid, output);
gidByGroupName.put(output, gid);
} catch (IOException e)
{
throw new IOExceptionUnchecked(e);
}
}
return groupNameByGid.get(gid);
}
public static Time getSystemTime()
{
return Time.getInstance();
}
public static String tryReadSymbolicLink(String absolutePath)
{
Stat stat = tryGetLinkInfo(absolutePath);
return stat.isSymbolicLink() ? stat.tryGetSymbolicLink() : null;
}
/**
* Change link timestamps of a file, directory or link. Does not dereference a symbolic link.
*
* @param fileName The name of the file or link to change the timestamp of.
* @param accessTimeSecs The new access time in seconds since start of the epoch.
* @param accessTimeMicroSecs The micro-second part of the new access time.
* @param modificationTimeSecs The new modification time in seconds since start of the epoch.
* @param modificationTimeMicroSecs The micro-second part of the new modification time.
*/
public static void setLinkTimestamps(String fileName,
long accessTimeSecs,
long accessTimeMicroSecs,
long modificationTimeSecs,
long modificationTimeMicroSecs)
{ {
try try
{ {
UserPrincipalLookupService service = FileSystems.getDefault().getUserPrincipalLookupService(); Instant accessTimeInstant = Instant.ofEpochSecond(accessTimeSecs).plus(accessTimeMicroSecs, ChronoUnit.MICROS);
UserPrincipal user = service.lookupPrincipalByName(Integer.toString(uid)); FileTime accessTime = FileTime.from(accessTimeInstant);
return user.getName(); Instant modifiedTimeInstant = Instant.ofEpochSecond(modificationTimeSecs).plus(modificationTimeMicroSecs, ChronoUnit.MICROS);
FileTime modifiedTime = FileTime.from(modifiedTimeInstant);
Files.getFileAttributeView(Path.of(fileName), BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).setTimes(modifiedTime, accessTime, null);
Files.getFileAttributeView(Path.of(fileName), BasicFileAttributeView.class).setTimes(modifiedTime, accessTime, null);
} catch (IOException e) } catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); throw new IOExceptionUnchecked(e);
} }
} }
public static String tryGetGroupNameForGid(int gid) /**
* Change file timestamps of a file, directory or link to the current time. Does not dereference a symbolic link.
*
* @param fileName The name of the file or link to change the timestamp of.
*/
public static void setLinkTimestamps(String fileName) throws IOExceptionUnchecked
{
Time time = Time.getInstance();
setLinkTimestamps(fileName, time.getSecs(), time.getMicroSecPart(), time.getSecs(), time.getMicroSecPart());
}
/**
* Change file timestamps of a file, directory or link. Dereferences a symbolic link.
*
* @param fileName The name of the file or link to change the timestamp of.
* @param accessTimeSecs The new access time in seconds since start of the epoch.
* @param accessTimeMicroSecs The micro-second part of the new access time.
* @param modificationTimeSecs The new modification time in seconds since start of the epoch.
* @param modificationTimeMicroSecs The micro-second part of the new modification time.
*/
public static void setFileTimestamps(String fileName,
long accessTimeSecs, long accessTimeMicroSecs,
long modificationTimeSecs, long modificationTimeMicroSecs) throws IOExceptionUnchecked
{ {
try try
{ {
UserPrincipalLookupService service = FileSystems.getDefault().getUserPrincipalLookupService(); Instant accessTimeInstant = Instant.ofEpochSecond(accessTimeSecs).plus(accessTimeMicroSecs, ChronoUnit.MICROS);
GroupPrincipal group = service.lookupPrincipalByGroupName(Integer.toString(gid)); FileTime accessTime = FileTime.from(accessTimeInstant);
return group.getName(); Instant modifiedTimeInstant = Instant.ofEpochSecond(modificationTimeSecs).plus(modificationTimeMicroSecs, ChronoUnit.MICROS);
FileTime modifiedTime = FileTime.from(modifiedTimeInstant);
Files.getFileAttributeView(Path.of(fileName), BasicFileAttributeView.class).setTimes(modifiedTime, accessTime, null);
} catch (IOException e) } catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); throw new IOExceptionUnchecked(e);
...@@ -156,13 +368,128 @@ public final class Posix ...@@ -156,13 +368,128 @@ public final class Posix
// File related methods // File related methods
// //
/**
* A class to represent a Unix <code>struct timespec</code> that holds a system time in nano-second resolution.
*/
public static final class Time
{
private final long secs;
private final long nanos;
public static Time getInstance() {
Instant now = Instant.now();
return new Time(now);
}
private Time(Instant now) {
this(now.getEpochSecond(), now.getNano());
}
private Time(FileTime fileTime)
{
this(fileTime.toInstant().getEpochSecond(), fileTime.toInstant().getNano());
}
private Time(long secs, long nanos)
{
this.secs = secs;
this.nanos = nanos;
}
public long getSecs()
{
return secs;
}
public long getNanoSecPart()
{
return nanos;
}
public long getMicroSecPart()
{
if (nanos % 1000 >= 500)
{
return nanos / 1_000 + 1;
} else
{
return nanos / 1_000;
}
}
public long getMilliSecPart()
{
if (nanos % 1000000 >= 500000)
{
return nanos / 1_000_000 + 1;
} else
{
return nanos / 1_000_000;
}
}
public long getMillis()
{
return secs * 1_000 + getMilliSecPart();
}
@Override
public String toString()
{
return "Time [secs=" + secs + ", nanos=" + nanos + "]";
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + (int) (nanos ^ (nanos >>> 32));
result = prime * result + (int) (secs ^ (secs >>> 32));
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Posix.Time other = (Posix.Time) obj;
if (nanos != other.nanos)
{
return false;
}
if (secs != other.secs)
{
return false;
}
return true;
}
}
public static class Stat public static class Stat
{ {
private final Path path;
private final short permissions; private final short permissions;
private final FileLinkType linkType; private final FileLinkType linkType;
private final long lastModified; private final Time lastModified;
private final Time lastAccessed;
private final int uid; private final int uid;
...@@ -172,12 +499,14 @@ public final class Posix ...@@ -172,12 +499,14 @@ public final class Posix
private final long size; private final long size;
public Stat(short permissions, FileLinkType linkType, long lastModified, int uid, int gid, public Stat(Path path, short permissions, FileLinkType linkType, FileTime lastModified, FileTime lastAccessed, int uid, int gid,
String symbolicLinkOrNull, long size) String symbolicLinkOrNull, long size)
{ {
this.path = path;
this.permissions = permissions; this.permissions = permissions;
this.linkType = linkType; this.linkType = linkType;
this.lastModified = lastModified; this.lastModified = new Time(lastModified);
this.lastAccessed = new Time(lastAccessed);
this.uid = uid; this.uid = uid;
this.gid = gid; this.gid = gid;
this.symbolicLinkOrNull = symbolicLinkOrNull; this.symbolicLinkOrNull = symbolicLinkOrNull;
...@@ -194,7 +523,22 @@ public final class Posix ...@@ -194,7 +523,22 @@ public final class Posix
return linkType; return linkType;
} }
public long getLastAccess()
{
return lastAccessed.getSecs();
}
public Time getLastAccessTime()
{
return lastAccessed;
}
public long getLastModified() public long getLastModified()
{
return lastModified.getSecs();
}
public Time getLastModifiedTime()
{ {
return lastModified; return lastModified;
} }
...@@ -217,94 +561,220 @@ public final class Posix ...@@ -217,94 +561,220 @@ public final class Posix
public long getSize() { public long getSize() {
return size; return size;
} }
}
private static short getNumericAccessMode(Set<PosixFilePermission> permissions) { public boolean isSymbolicLink()
short mode = 0; {
if (permissions.contains(PosixFilePermission.OWNER_READ)) { return symbolicLinkOrNull != null;
mode |= 0400;
}
if (permissions.contains(PosixFilePermission.OWNER_WRITE)) {
mode |= 0200;
}
if (permissions.contains(PosixFilePermission.OWNER_EXECUTE)) {
mode |= 0100;
}
if (permissions.contains(PosixFilePermission.GROUP_READ)) {
mode |= 040;
}
if (permissions.contains(PosixFilePermission.GROUP_WRITE)) {
mode |= 020;
}
if (permissions.contains(PosixFilePermission.GROUP_EXECUTE)) {
mode |= 010;
}
if (permissions.contains(PosixFilePermission.OTHERS_READ)) {
mode |= 04;
} }
if (permissions.contains(PosixFilePermission.OTHERS_WRITE)) {
mode |= 02; public int getNumberOfHardLinks() throws IOException
{
Number count = (Number) Files.getAttribute(path, "unix:nlink", LinkOption.NOFOLLOW_LINKS);
return count.intValue();
} }
if (permissions.contains(PosixFilePermission.OTHERS_EXECUTE)) { }
mode |= 01;
private static short getNumericAccessMode(Set<PosixFilePermission> permissions) {
short posixPermissions = 0;
for (PosixFilePermission permission : permissions) {
switch (permission) {
case OWNER_READ:
posixPermissions |= 0400;
break;
case OWNER_WRITE:
posixPermissions |= 0200;
break;
case OWNER_EXECUTE:
posixPermissions |= 0100;
break;
case GROUP_READ:
posixPermissions |= 0040;
break;
case GROUP_WRITE:
posixPermissions |= 0020;
break;
case GROUP_EXECUTE:
posixPermissions |= 0010;
break;
case OTHERS_READ:
posixPermissions |= 0004;
break;
case OTHERS_WRITE:
posixPermissions |= 0002;
break;
case OTHERS_EXECUTE:
posixPermissions |= 0001;
break;
}
} }
return mode;
return posixPermissions;
} }
private static Set<PosixFilePermission> getFilePermissionsMode(short mode) { private static Set<PosixFilePermission> getFilePermissionsMode(short permissions) {
Set<PosixFilePermission> permissions = new HashSet<>(); Set<PosixFilePermission> posixPermissions = new HashSet<>();
if ((0400 & mode) == 0400) {
permissions.add(PosixFilePermission.OWNER_READ); if ((permissions & 0400) != 0) {
posixPermissions.add(PosixFilePermission.OWNER_READ);
} }
if ((0200 & mode) == 0200) { if ((permissions & 0200) != 0) {
permissions.add(PosixFilePermission.OWNER_WRITE); posixPermissions.add(PosixFilePermission.OWNER_WRITE);
} }
if ((0100 & mode) == 0100) { if ((permissions & 0100) != 0) {
permissions.add(PosixFilePermission.OWNER_EXECUTE); posixPermissions.add(PosixFilePermission.OWNER_EXECUTE);
} }
if ((040 & mode) == 040) { if ((permissions & 0040) != 0) {
permissions.add(PosixFilePermission.GROUP_READ); posixPermissions.add(PosixFilePermission.GROUP_READ);
} }
if ((020 & mode) == 020) { if ((permissions & 0020) != 0) {
permissions.add(PosixFilePermission.GROUP_WRITE); posixPermissions.add(PosixFilePermission.GROUP_WRITE);
} }
if ((010 & mode) == 010) { if ((permissions & 0010) != 0) {
permissions.add(PosixFilePermission.GROUP_EXECUTE); posixPermissions.add(PosixFilePermission.GROUP_EXECUTE);
} }
if ((04 & mode) == 04) { if ((permissions & 0004) != 0) {
permissions.add(PosixFilePermission.OTHERS_READ); posixPermissions.add(PosixFilePermission.OTHERS_READ);
} }
if ((02 & mode) == 02) { if ((permissions & 0002) != 0) {
permissions.add(PosixFilePermission.OWNER_WRITE); posixPermissions.add(PosixFilePermission.OTHERS_WRITE);
} }
if ((01 & mode) == 01) { if ((permissions & 0001) != 0) {
permissions.add(PosixFilePermission.OTHERS_EXECUTE); posixPermissions.add(PosixFilePermission.OTHERS_EXECUTE);
} }
return permissions;
return posixPermissions;
} }
public static Stat tryGetLinkInfo(String pathAsString) { /**
try * Returns the information about <var>linkName</var>.
*
* @throws IOExceptionUnchecked If the information could not be obtained, e.g. because the link does not exist.
*/
public static Stat getLinkInfo(String absolutePath)
{
return getLinkInfo(absolutePath, true);
}
public static Stat getLinkInfo(String pathAsString, boolean readSymbolicLinkTarget)
{
try {
if (pathAsString == null)
{
throw new NullPointerException("linkName");
}
Path path = Path.of(pathAsString);
if (Files.exists(path, LinkOption.NOFOLLOW_LINKS) == false)
{
return null;
}
BasicFileAttributes attrs = null;
FileLinkType linkType;
short permissions;
int uid;
int gid;
if(readSymbolicLinkTarget && Files.exists(path))
{
permissions = getNumericAccessMode(Files.getPosixFilePermissions(path));
attrs = Files.readAttributes(path, BasicFileAttributes.class);
if (Files.isSymbolicLink(path)) {
linkType = FileLinkType.SYMLINK;
} else if (Files.isDirectory(path)) {
linkType = FileLinkType.DIRECTORY;
} else if (Files.isRegularFile(path)) {
linkType = FileLinkType.REGULAR_FILE;
} else {
linkType = FileLinkType.OTHER;
}
uid = getUid(pathAsString);
gid = getGid(pathAsString);
} else {
permissions = getNumericAccessMode(Files.getPosixFilePermissions(path, LinkOption.NOFOLLOW_LINKS));
attrs = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
if (Files.isSymbolicLink(path)) {
linkType = FileLinkType.SYMLINK;
} else if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
linkType = FileLinkType.DIRECTORY;
} else if (Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) {
linkType = FileLinkType.REGULAR_FILE;
} else {
linkType = FileLinkType.OTHER;
}
uid = getUid(pathAsString, false);
gid = getGid(pathAsString, false);
}
FileTime lastModified = attrs.lastModifiedTime();
FileTime lastAccessed = attrs.lastAccessTime();
String symbolicLinkOrNull = null;
if (linkType == FileLinkType.SYMLINK && readSymbolicLinkTarget) {
symbolicLinkOrNull = Files.readSymbolicLink(path).toString();
}
long size = attrs.size();
return new Stat(path, permissions, linkType, lastModified, lastAccessed, uid, gid, symbolicLinkOrNull, size);
} catch (IOException e)
{ {
throw new IOExceptionUnchecked(e);
}
}
public static Stat tryGetLinkInfo(String pathAsString){
return getLinkInfo(pathAsString, true);
}
public static Stat tryGetFileInfo(String absolutePath)
{
return getFileInfo(absolutePath, true);
}
public static Stat getFileInfo(String pathAsString)
{
return getFileInfo(pathAsString, true);
}
public static Stat getFileInfo(String pathAsString, boolean readSymbolicLinkTarget)
throws IOExceptionUnchecked
{
try {
if (pathAsString == null)
{
throw new NullPointerException("linkName");
}
Path path = Path.of(pathAsString); Path path = Path.of(pathAsString);
if (Files.exists(path) == false)
{
return null;
}
short permissions = getNumericAccessMode(Files.getPosixFilePermissions(path)); short permissions = getNumericAccessMode(Files.getPosixFilePermissions(path));
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
FileLinkType linkType; FileLinkType linkType;
if (Files.isSymbolicLink(path)) { if (attrs.isSymbolicLink()) {
linkType = FileLinkType.SYMLINK; linkType = FileLinkType.SYMLINK;
} else if (Files.isDirectory(path)) { } else if (attrs.isDirectory()) {
linkType = FileLinkType.DIRECTORY; linkType = FileLinkType.DIRECTORY;
} else if (attrs.isRegularFile()) {
linkType = FileLinkType.REGULAR_FILE;
} else { } else {
linkType = FileLinkType.OTHER; linkType = FileLinkType.OTHER;
} }
long lastModified = Files.getLastModifiedTime(path).toMillis();
FileTime lastModified = attrs.lastModifiedTime();
FileTime lastAccessed = attrs.lastAccessTime();
int uid = getUid(pathAsString); int uid = getUid(pathAsString);
int gid = getGid(pathAsString); int gid = getGid(pathAsString);
String symbolicLinkOrNull = null; String symbolicLinkOrNull = null;
if (linkType == FileLinkType.SYMLINK) { if (linkType == FileLinkType.SYMLINK && readSymbolicLinkTarget) {
symbolicLinkOrNull = Files.readSymbolicLink(path).toString(); symbolicLinkOrNull = Files.readSymbolicLink(path).toString();
} }
long size = Files.size(path); long size = attrs.size();
return new Stat(permissions, linkType, lastModified, uid, gid, symbolicLinkOrNull, size); return new Stat(path, permissions, linkType, lastModified, lastAccessed, uid, gid, symbolicLinkOrNull, size);
} catch (IOException e) } catch (IOException e)
{ {
throw new IOExceptionUnchecked(e); throw new IOExceptionUnchecked(e);
...@@ -398,8 +868,7 @@ public final class Posix ...@@ -398,8 +868,7 @@ public final class Posix
try { try {
Path file = Path.of(fileName); Path file = Path.of(fileName);
Path link = Path.of(linkName); Path link = Path.of(linkName);
Files.createDirectories(link.getParent()); // Create any missing folder on the directory hierarchy leading to folder that will contain the link Files.createSymbolicLink(link, file);// Creates the link
Files.createSymbolicLink(link, file); // Creates the link
} catch (IOException exception) { } catch (IOException exception) {
throw new IOExceptionUnchecked(exception); throw new IOExceptionUnchecked(exception);
} }
...@@ -412,7 +881,6 @@ public final class Posix ...@@ -412,7 +881,6 @@ public final class Posix
try { try {
Path file = Path.of(fileName); Path file = Path.of(fileName);
Path link = Path.of(linkName); Path link = Path.of(linkName);
Files.createDirectories(link.getParent()); // Create any missing folder on the directory hierarchy leading to folder that will contain the link
Files.createLink(link, file); // Creates the link Files.createLink(link, file); // Creates the link
} catch (IOException exception) { } catch (IOException exception) {
throw new IOExceptionUnchecked(exception); throw new IOExceptionUnchecked(exception);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment