mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 18:55:31 +08:00
Create termux-shared library package for all termux constants and shared utils
The termux plugins should use this library instead of hardcoding "com.termux" values in their source code. The library can be included as a dependency by plugins and third party apps by including the following line in the build.gradle where x.xxx is the version number, once its published. `implementation 'com.termux:termux-shared:x.xxx'` The `TermuxConstants` class has been updated to `v0.17.0`, `TermuxPreferenceConstants` to `v0.9.0` and `TermuxPropertyConstants` to `v0.6.0`. Check their Changelog sections for info on changes. Some typos and redundant code has also been fixed.
This commit is contained in:
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
import android.os.Build;
|
||||
import android.system.StructStat;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Unix implementation of PosixFileAttributes.
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/sun/nio/fs/UnixFileAttributes.java
|
||||
*/
|
||||
|
||||
public class FileAttributes {
|
||||
private String filePath;
|
||||
private FileDescriptor fileDescriptor;
|
||||
|
||||
private int st_mode;
|
||||
private long st_ino;
|
||||
private long st_dev;
|
||||
private long st_rdev;
|
||||
private long st_nlink;
|
||||
private int st_uid;
|
||||
private int st_gid;
|
||||
private long st_size;
|
||||
private long st_blksize;
|
||||
private long st_blocks;
|
||||
private long st_atime_sec;
|
||||
private long st_atime_nsec;
|
||||
private long st_mtime_sec;
|
||||
private long st_mtime_nsec;
|
||||
private long st_ctime_sec;
|
||||
private long st_ctime_nsec;
|
||||
|
||||
// created lazily
|
||||
private volatile String owner;
|
||||
private volatile String group;
|
||||
private volatile FileKey key;
|
||||
|
||||
private FileAttributes(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
private FileAttributes(FileDescriptor fileDescriptor) {
|
||||
this.fileDescriptor = fileDescriptor;
|
||||
}
|
||||
|
||||
// get the FileAttributes for a given file
|
||||
public static FileAttributes get(String filePath, boolean followLinks) throws IOException {
|
||||
FileAttributes fileAttributes;
|
||||
|
||||
if (filePath == null || filePath.isEmpty())
|
||||
fileAttributes = new FileAttributes((String) null);
|
||||
else
|
||||
fileAttributes = new FileAttributes(new File(filePath).getAbsolutePath());
|
||||
|
||||
if (followLinks) {
|
||||
NativeDispatcher.stat(filePath, fileAttributes);
|
||||
} else {
|
||||
NativeDispatcher.lstat(filePath, fileAttributes);
|
||||
}
|
||||
|
||||
// Logger.logDebug(fileAttributes.toString());
|
||||
|
||||
return fileAttributes;
|
||||
}
|
||||
|
||||
// get the FileAttributes for an open file
|
||||
public static FileAttributes get(FileDescriptor fileDescriptor) throws IOException {
|
||||
FileAttributes fileAttributes = new FileAttributes(fileDescriptor);
|
||||
NativeDispatcher.fstat(fileDescriptor, fileAttributes);
|
||||
return fileAttributes;
|
||||
}
|
||||
|
||||
public String file() {
|
||||
if(filePath != null)
|
||||
return filePath;
|
||||
else if(fileDescriptor != null)
|
||||
return fileDescriptor.toString();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// package-private
|
||||
public boolean isSameFile(FileAttributes attrs) {
|
||||
return ((st_ino == attrs.st_ino) && (st_dev == attrs.st_dev));
|
||||
}
|
||||
|
||||
// package-private
|
||||
public int mode() {
|
||||
return st_mode;
|
||||
}
|
||||
|
||||
public long blksize() {
|
||||
return st_blksize;
|
||||
}
|
||||
|
||||
public long blocks() {
|
||||
return st_blocks;
|
||||
}
|
||||
|
||||
public long ino() {
|
||||
return st_ino;
|
||||
}
|
||||
|
||||
public long dev() {
|
||||
return st_dev;
|
||||
}
|
||||
|
||||
public long rdev() {
|
||||
return st_rdev;
|
||||
}
|
||||
|
||||
public long nlink() {
|
||||
return st_nlink;
|
||||
}
|
||||
|
||||
public int uid() {
|
||||
return st_uid;
|
||||
}
|
||||
|
||||
public int gid() {
|
||||
return st_gid;
|
||||
}
|
||||
|
||||
private static FileTime toFileTime(long sec, long nsec) {
|
||||
if (nsec == 0) {
|
||||
return FileTime.from(sec, TimeUnit.SECONDS);
|
||||
} else {
|
||||
// truncate to microseconds to avoid overflow with timestamps
|
||||
// way out into the future. We can re-visit this if FileTime
|
||||
// is updated to define a from(secs,nsecs) method.
|
||||
long micro = sec * 1000000L + nsec / 1000L;
|
||||
return FileTime.from(micro, TimeUnit.MICROSECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public FileTime lastAccessTime() {
|
||||
return toFileTime(st_atime_sec, st_atime_nsec);
|
||||
}
|
||||
|
||||
public FileTime lastModifiedTime() {
|
||||
return toFileTime(st_mtime_sec, st_mtime_nsec);
|
||||
}
|
||||
|
||||
public FileTime lastChangeTime() {
|
||||
return toFileTime(st_ctime_sec, st_ctime_nsec);
|
||||
}
|
||||
|
||||
public FileTime creationTime() {
|
||||
return lastModifiedTime();
|
||||
}
|
||||
|
||||
public boolean isRegularFile() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
|
||||
}
|
||||
|
||||
public boolean isSymbolicLink() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFLNK);
|
||||
}
|
||||
|
||||
public boolean isCharacter() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFCHR);
|
||||
}
|
||||
|
||||
public boolean isFifo() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFIFO);
|
||||
}
|
||||
|
||||
public boolean isBlock() {
|
||||
return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFBLK);
|
||||
}
|
||||
|
||||
public boolean isOther() {
|
||||
int type = st_mode & UnixConstants.S_IFMT;
|
||||
return (type != UnixConstants.S_IFREG &&
|
||||
type != UnixConstants.S_IFDIR &&
|
||||
type != UnixConstants.S_IFLNK);
|
||||
}
|
||||
|
||||
public boolean isDevice() {
|
||||
int type = st_mode & UnixConstants.S_IFMT;
|
||||
return (type == UnixConstants.S_IFCHR ||
|
||||
type == UnixConstants.S_IFBLK ||
|
||||
type == UnixConstants.S_IFIFO);
|
||||
}
|
||||
|
||||
public long size() {
|
||||
return st_size;
|
||||
}
|
||||
|
||||
public FileKey fileKey() {
|
||||
if (key == null) {
|
||||
synchronized (this) {
|
||||
if (key == null) {
|
||||
key = new FileKey(st_dev, st_ino);
|
||||
}
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public String owner() {
|
||||
if (owner == null) {
|
||||
synchronized (this) {
|
||||
if (owner == null) {
|
||||
owner = Integer.toString(st_uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return owner;
|
||||
}
|
||||
|
||||
public String group() {
|
||||
if (group == null) {
|
||||
synchronized (this) {
|
||||
if (group == null) {
|
||||
group = Integer.toString(st_gid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
public Set<FilePermission> permissions() {
|
||||
int bits = (st_mode & UnixConstants.S_IAMB);
|
||||
HashSet<FilePermission> perms = new HashSet<>();
|
||||
|
||||
if ((bits & UnixConstants.S_IRUSR) > 0)
|
||||
perms.add(FilePermission.OWNER_READ);
|
||||
if ((bits & UnixConstants.S_IWUSR) > 0)
|
||||
perms.add(FilePermission.OWNER_WRITE);
|
||||
if ((bits & UnixConstants.S_IXUSR) > 0)
|
||||
perms.add(FilePermission.OWNER_EXECUTE);
|
||||
|
||||
if ((bits & UnixConstants.S_IRGRP) > 0)
|
||||
perms.add(FilePermission.GROUP_READ);
|
||||
if ((bits & UnixConstants.S_IWGRP) > 0)
|
||||
perms.add(FilePermission.GROUP_WRITE);
|
||||
if ((bits & UnixConstants.S_IXGRP) > 0)
|
||||
perms.add(FilePermission.GROUP_EXECUTE);
|
||||
|
||||
if ((bits & UnixConstants.S_IROTH) > 0)
|
||||
perms.add(FilePermission.OTHERS_READ);
|
||||
if ((bits & UnixConstants.S_IWOTH) > 0)
|
||||
perms.add(FilePermission.OTHERS_WRITE);
|
||||
if ((bits & UnixConstants.S_IXOTH) > 0)
|
||||
perms.add(FilePermission.OTHERS_EXECUTE);
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
public void loadFromStructStat(StructStat structStat) {
|
||||
this.st_mode = structStat.st_mode;
|
||||
this.st_ino = structStat.st_ino;
|
||||
this.st_dev = structStat.st_dev;
|
||||
this.st_rdev = structStat.st_rdev;
|
||||
this.st_nlink = structStat.st_nlink;
|
||||
this.st_uid = structStat.st_uid;
|
||||
this.st_gid = structStat.st_gid;
|
||||
this.st_size = structStat.st_size;
|
||||
this.st_blksize = structStat.st_blksize;
|
||||
this.st_blocks = structStat.st_blocks;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
this.st_atime_sec = structStat.st_atim.tv_sec;
|
||||
this.st_atime_nsec = structStat.st_atim.tv_nsec;
|
||||
this.st_mtime_sec = structStat.st_mtim.tv_sec;
|
||||
this.st_mtime_nsec = structStat.st_mtim.tv_nsec;
|
||||
this.st_ctime_sec = structStat.st_ctim.tv_sec;
|
||||
this.st_ctime_nsec = structStat.st_ctim.tv_nsec;
|
||||
} else {
|
||||
this.st_atime_sec = structStat.st_atime;
|
||||
this.st_atime_nsec = 0;
|
||||
this.st_mtime_sec = structStat.st_mtime;
|
||||
this.st_mtime_nsec = 0;
|
||||
this.st_ctime_sec = structStat.st_ctime;
|
||||
this.st_ctime_nsec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String getFileString() {
|
||||
return "File: `" + file() + "`";
|
||||
}
|
||||
|
||||
public String getTypeString() {
|
||||
return "Type: `" + FileTypes.getFileType(this).getName() + "`";
|
||||
}
|
||||
|
||||
public String getSizeString() {
|
||||
return "Size: `" + size() + "`";
|
||||
}
|
||||
|
||||
public String getBlocksString() {
|
||||
return "Blocks: `" + blocks() + "`";
|
||||
}
|
||||
|
||||
public String getIOBlockString() {
|
||||
return "IO Block: `" + blksize() + "`";
|
||||
}
|
||||
|
||||
public String getDeviceString() {
|
||||
return "Device: `" + Long.toHexString(st_dev) + "`";
|
||||
}
|
||||
|
||||
public String getInodeString() {
|
||||
return "Inode: `" + st_ino + "`";
|
||||
}
|
||||
|
||||
public String getLinksString() {
|
||||
return "Links: `" + nlink() + "`";
|
||||
}
|
||||
|
||||
public String getDeviceTypeString() {
|
||||
return "Device Type: `" + rdev() + "`";
|
||||
}
|
||||
|
||||
public String getOwnerString() {
|
||||
return "Owner: `" + owner() + "`";
|
||||
}
|
||||
|
||||
public String getGroupString() {
|
||||
return "Group: `" + group() + "`";
|
||||
}
|
||||
|
||||
public String getPermissionString() {
|
||||
return "Permissions: `" + FilePermissions.toString(permissions()) + "`";
|
||||
}
|
||||
|
||||
public String getAccessTimeString() {
|
||||
return "Access Time: `" + lastAccessTime() + "`";
|
||||
}
|
||||
|
||||
public String getModifiedTimeString() {
|
||||
return "Modified Time: `" + lastModifiedTime() + "`";
|
||||
}
|
||||
|
||||
public String getChangeTimeString() {
|
||||
return "Change Time: `" + lastChangeTime() + "`";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getFileAttributesLogString(this);
|
||||
}
|
||||
|
||||
public static String getFileAttributesLogString(final FileAttributes fileAttributes) {
|
||||
if (fileAttributes == null) return "null";
|
||||
|
||||
StringBuilder logString = new StringBuilder();
|
||||
|
||||
logString.append(fileAttributes.getFileString());
|
||||
|
||||
logString.append("\n").append(fileAttributes.getTypeString());
|
||||
|
||||
logString.append("\n").append(fileAttributes.getSizeString());
|
||||
logString.append("\n").append(fileAttributes.getBlocksString());
|
||||
logString.append("\n").append(fileAttributes.getIOBlockString());
|
||||
|
||||
logString.append("\n").append(fileAttributes.getDeviceString());
|
||||
logString.append("\n").append(fileAttributes.getInodeString());
|
||||
logString.append("\n").append(fileAttributes.getLinksString());
|
||||
|
||||
if(fileAttributes.isBlock() || fileAttributes.isCharacter())
|
||||
logString.append("\n").append(fileAttributes.getDeviceTypeString());
|
||||
|
||||
logString.append("\n").append(fileAttributes.getOwnerString());
|
||||
logString.append("\n").append(fileAttributes.getGroupString());
|
||||
logString.append("\n").append(fileAttributes.getPermissionString());
|
||||
|
||||
logString.append("\n").append(fileAttributes.getAccessTimeString());
|
||||
logString.append("\n").append(fileAttributes.getModifiedTimeString());
|
||||
logString.append("\n").append(fileAttributes.getChangeTimeString());
|
||||
|
||||
return logString.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
/**
|
||||
* Container for device/inode to uniquely identify file.
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/sun/nio/fs/UnixFileKey.java
|
||||
*/
|
||||
|
||||
public class FileKey {
|
||||
private final long st_dev;
|
||||
private final long st_ino;
|
||||
|
||||
FileKey(long st_dev, long st_ino) {
|
||||
this.st_dev = st_dev;
|
||||
this.st_ino = st_ino;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int)(st_dev ^ (st_dev >>> 32)) +
|
||||
(int)(st_ino ^ (st_ino >>> 32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (!(obj instanceof FileKey))
|
||||
return false;
|
||||
FileKey other = (FileKey)obj;
|
||||
return (this.st_dev == other.st_dev) && (this.st_ino == other.st_ino);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(dev=")
|
||||
.append(Long.toHexString(st_dev))
|
||||
.append(",ino=")
|
||||
.append(st_ino)
|
||||
.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
/**
|
||||
* Defines the bits for use with the {@link FileAttributes#permissions()
|
||||
* permissions} attribute.
|
||||
*
|
||||
* <p> The {@link FileAttributes} class defines methods for manipulating
|
||||
* set of permissions.
|
||||
*
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/java/nio/file/attribute/PosixFilePermission.java
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public enum FilePermission {
|
||||
|
||||
/**
|
||||
* Read permission, owner.
|
||||
*/
|
||||
OWNER_READ,
|
||||
|
||||
/**
|
||||
* Write permission, owner.
|
||||
*/
|
||||
OWNER_WRITE,
|
||||
|
||||
/**
|
||||
* Execute/search permission, owner.
|
||||
*/
|
||||
OWNER_EXECUTE,
|
||||
|
||||
/**
|
||||
* Read permission, group.
|
||||
*/
|
||||
GROUP_READ,
|
||||
|
||||
/**
|
||||
* Write permission, group.
|
||||
*/
|
||||
GROUP_WRITE,
|
||||
|
||||
/**
|
||||
* Execute/search permission, group.
|
||||
*/
|
||||
GROUP_EXECUTE,
|
||||
|
||||
/**
|
||||
* Read permission, others.
|
||||
*/
|
||||
OTHERS_READ,
|
||||
|
||||
/**
|
||||
* Write permission, others.
|
||||
*/
|
||||
OTHERS_WRITE,
|
||||
|
||||
/**
|
||||
* Execute/search permission, others.
|
||||
*/
|
||||
OTHERS_EXECUTE
|
||||
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
import static com.termux.shared.file.filesystem.FilePermission.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods that operate on sets of
|
||||
* {@link FilePermission} objects.
|
||||
*
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/java/nio/file/attribute/PosixFilePermissions.java
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public final class FilePermissions {
|
||||
private FilePermissions() { }
|
||||
|
||||
// Write string representation of permission bits to {@code sb}.
|
||||
private static void writeBits(StringBuilder sb, boolean r, boolean w, boolean x) {
|
||||
if (r) {
|
||||
sb.append('r');
|
||||
} else {
|
||||
sb.append('-');
|
||||
}
|
||||
if (w) {
|
||||
sb.append('w');
|
||||
} else {
|
||||
sb.append('-');
|
||||
}
|
||||
if (x) {
|
||||
sb.append('x');
|
||||
} else {
|
||||
sb.append('-');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code String} representation of a set of permissions. It
|
||||
* is guaranteed that the returned {@code String} can be parsed by the
|
||||
* {@link #fromString} method.
|
||||
*
|
||||
* <p> If the set contains {@code null} or elements that are not of type
|
||||
* {@code FilePermission} then these elements are ignored.
|
||||
*
|
||||
* @param perms
|
||||
* the set of permissions
|
||||
*
|
||||
* @return the string representation of the permission set
|
||||
*/
|
||||
public static String toString(Set<FilePermission> perms) {
|
||||
StringBuilder sb = new StringBuilder(9);
|
||||
writeBits(sb, perms.contains(OWNER_READ), perms.contains(OWNER_WRITE),
|
||||
perms.contains(OWNER_EXECUTE));
|
||||
writeBits(sb, perms.contains(GROUP_READ), perms.contains(GROUP_WRITE),
|
||||
perms.contains(GROUP_EXECUTE));
|
||||
writeBits(sb, perms.contains(OTHERS_READ), perms.contains(OTHERS_WRITE),
|
||||
perms.contains(OTHERS_EXECUTE));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static boolean isSet(char c, char setValue) {
|
||||
if (c == setValue)
|
||||
return true;
|
||||
if (c == '-')
|
||||
return false;
|
||||
throw new IllegalArgumentException("Invalid mode");
|
||||
}
|
||||
private static boolean isR(char c) { return isSet(c, 'r'); }
|
||||
private static boolean isW(char c) { return isSet(c, 'w'); }
|
||||
private static boolean isX(char c) { return isSet(c, 'x'); }
|
||||
|
||||
/**
|
||||
* Returns the set of permissions corresponding to a given {@code String}
|
||||
* representation.
|
||||
*
|
||||
* <p> The {@code perms} parameter is a {@code String} representing the
|
||||
* permissions. It has 9 characters that are interpreted as three sets of
|
||||
* three. The first set refers to the owner's permissions; the next to the
|
||||
* group permissions and the last to others. Within each set, the first
|
||||
* character is {@code 'r'} to indicate permission to read, the second
|
||||
* character is {@code 'w'} to indicate permission to write, and the third
|
||||
* character is {@code 'x'} for execute permission. Where a permission is
|
||||
* not set then the corresponding character is set to {@code '-'}.
|
||||
*
|
||||
* <p> <b>Usage Example:</b>
|
||||
* Suppose we require the set of permissions that indicate the owner has read,
|
||||
* write, and execute permissions, the group has read and execute permissions
|
||||
* and others have none.
|
||||
* <pre>
|
||||
* Set<FilePermission> perms = FilePermissions.fromString("rwxr-x---");
|
||||
* </pre>
|
||||
*
|
||||
* @param perms
|
||||
* string representing a set of permissions
|
||||
*
|
||||
* @return the resulting set of permissions
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the string cannot be converted to a set of permissions
|
||||
*
|
||||
* @see #toString(Set)
|
||||
*/
|
||||
public static Set<FilePermission> fromString(String perms) {
|
||||
if (perms.length() != 9)
|
||||
throw new IllegalArgumentException("Invalid mode");
|
||||
Set<FilePermission> result = EnumSet.noneOf(FilePermission.class);
|
||||
if (isR(perms.charAt(0))) result.add(OWNER_READ);
|
||||
if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
|
||||
if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
|
||||
if (isR(perms.charAt(3))) result.add(GROUP_READ);
|
||||
if (isW(perms.charAt(4))) result.add(GROUP_WRITE);
|
||||
if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE);
|
||||
if (isR(perms.charAt(6))) result.add(OTHERS_READ);
|
||||
if (isW(perms.charAt(7))) result.add(OTHERS_WRITE);
|
||||
if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Represents the value of a file's time stamp attribute. For example, it may
|
||||
* represent the time that the file was last
|
||||
* {@link FileAttributes#lastModifiedTime() modified},
|
||||
* {@link FileAttributes#lastAccessTime() accessed},
|
||||
* or {@link FileAttributes#creationTime() created}.
|
||||
*
|
||||
* <p> Instances of this class are immutable.
|
||||
*
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/java/nio/file/attribute/FileTime.java
|
||||
*
|
||||
* @since 1.7
|
||||
* @see java.nio.file.Files#setLastModifiedTime
|
||||
* @see java.nio.file.Files#getLastModifiedTime
|
||||
*/
|
||||
|
||||
public final class FileTime {
|
||||
/**
|
||||
* The unit of granularity to interpret the value. Null if
|
||||
* this {@code FileTime} is converted from an {@code Instant},
|
||||
* the {@code value} and {@code unit} pair will not be used
|
||||
* in this scenario.
|
||||
*/
|
||||
private final TimeUnit unit;
|
||||
|
||||
/**
|
||||
* The value since the epoch; can be negative.
|
||||
*/
|
||||
private final long value;
|
||||
|
||||
|
||||
/**
|
||||
* The value return by toString (created lazily)
|
||||
*/
|
||||
private String valueAsString;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*/
|
||||
private FileTime(long value, TimeUnit unit) {
|
||||
this.value = value;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTime} representing a value at the given unit of
|
||||
* granularity.
|
||||
*
|
||||
* @param value
|
||||
* the value since the epoch (1970-01-01T00:00:00Z); can be
|
||||
* negative
|
||||
* @param unit
|
||||
* the unit of granularity to interpret the value
|
||||
*
|
||||
* @return a {@code FileTime} representing the given value
|
||||
*/
|
||||
public static FileTime from(long value, @NonNull TimeUnit unit) {
|
||||
Objects.requireNonNull(unit, "unit");
|
||||
return new FileTime(value, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTime} representing the given value in milliseconds.
|
||||
*
|
||||
* @param value
|
||||
* the value, in milliseconds, since the epoch
|
||||
* (1970-01-01T00:00:00Z); can be negative
|
||||
*
|
||||
* @return a {@code FileTime} representing the given value
|
||||
*/
|
||||
public static FileTime fromMillis(long value) {
|
||||
return new FileTime(value, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at the given unit of granularity.
|
||||
*
|
||||
* <p> Conversion from a coarser granularity that would numerically overflow
|
||||
* saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
|
||||
* if positive.
|
||||
*
|
||||
* @param unit
|
||||
* the unit of granularity for the return value
|
||||
*
|
||||
* @return value in the given unit of granularity, since the epoch
|
||||
* since the epoch (1970-01-01T00:00:00Z); can be negative
|
||||
*/
|
||||
public long to(TimeUnit unit) {
|
||||
Objects.requireNonNull(unit, "unit");
|
||||
return unit.convert(this.value, this.unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in milliseconds.
|
||||
*
|
||||
* <p> Conversion from a coarser granularity that would numerically overflow
|
||||
* saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
|
||||
* if positive.
|
||||
*
|
||||
* @return the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
|
||||
*/
|
||||
public long toMillis() {
|
||||
return unit.toMillis(value);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDate(toMillis(), "yyyy.MM.dd HH:mm:ss.SSS z");
|
||||
}
|
||||
|
||||
public static String getDate(long milliSeconds, String format) {
|
||||
try {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(milliSeconds);
|
||||
return new SimpleDateFormat(format).format(calendar.getTime());
|
||||
} catch(Exception e) {
|
||||
return Long.toString(milliSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
/** The {@link Enum} that defines file types. */
|
||||
public enum FileType {
|
||||
|
||||
NO_EXIST("no exist", 0), // 0000000
|
||||
REGULAR("regular", 1), // 0000001
|
||||
DIRECTORY("directory", 2), // 0000010
|
||||
SYMLINK("symlink", 4), // 0000100
|
||||
CHARACTER("character", 8), // 0001000
|
||||
FIFO("fifo", 16), // 0010000
|
||||
BLOCK("block", 32), // 0100000
|
||||
UNKNOWN("unknown", 64); // 1000000
|
||||
|
||||
private final String name;
|
||||
private final int value;
|
||||
|
||||
FileType(final String name, final int value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
import android.system.Os;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.termux.shared.logger.Logger;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FileTypes {
|
||||
|
||||
/** Flags to represent regular, directory and symlink file types defined by {@link FileType} */
|
||||
public static final int FILE_TYPE_NORMAL_FLAGS = FileType.REGULAR.getValue() | FileType.DIRECTORY.getValue() | FileType.SYMLINK.getValue();
|
||||
|
||||
/** Flags to represent any file type defined by {@link FileType} */
|
||||
public static final int FILE_TYPE_ANY_FLAGS = Integer.MAX_VALUE; // 1111111111111111111111111111111 (31 1's)
|
||||
|
||||
public static String convertFileTypeFlagsToNamesString(int fileTypeFlags) {
|
||||
StringBuilder fileTypeFlagsStringBuilder = new StringBuilder();
|
||||
|
||||
FileType[] fileTypes = {FileType.REGULAR, FileType.DIRECTORY, FileType.SYMLINK, FileType.CHARACTER, FileType.FIFO, FileType.BLOCK, FileType.UNKNOWN};
|
||||
for (FileType fileType : fileTypes) {
|
||||
if ((fileTypeFlags & fileType.getValue()) > 0)
|
||||
fileTypeFlagsStringBuilder.append(fileType.getName()).append(",");
|
||||
}
|
||||
|
||||
String fileTypeFlagsString = fileTypeFlagsStringBuilder.toString();
|
||||
|
||||
if (fileTypeFlagsString.endsWith(","))
|
||||
fileTypeFlagsString = fileTypeFlagsString.substring(0, fileTypeFlagsString.lastIndexOf(","));
|
||||
|
||||
return fileTypeFlagsString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the type of file that exists at {@code filePath}.
|
||||
*
|
||||
* Returns:
|
||||
* - {@link FileType#NO_EXIST} if {@code filePath} is {@code null}, empty, an exception is raised
|
||||
* or no file exists at {@code filePath}.
|
||||
* - {@link FileType#REGULAR} if file at {@code filePath} is a regular file.
|
||||
* - {@link FileType#DIRECTORY} if file at {@code filePath} is a directory file.
|
||||
* - {@link FileType#SYMLINK} if file at {@code filePath} is a symlink file and {@code followLinks} is {@code false}.
|
||||
* - {@link FileType#CHARACTER} if file at {@code filePath} is a character special file.
|
||||
* - {@link FileType#FIFO} if file at {@code filePath} is a fifo special file.
|
||||
* - {@link FileType#BLOCK} if file at {@code filePath} is a block special file.
|
||||
* - {@link FileType#UNKNOWN} if file at {@code filePath} is of unknown type.
|
||||
*
|
||||
* The {@link File#isFile()} and {@link File#isDirectory()} uses {@link Os#stat(String)} system
|
||||
* call (not {@link Os#lstat(String)}) to check file type and does follow symlinks.
|
||||
*
|
||||
* The {@link File#exists()} uses {@link Os#access(String, int)} system call to check if file is
|
||||
* accessible and does not follow symlinks. However, it returns {@code false} for dangling symlinks,
|
||||
* on android at least. Check https://stackoverflow.com/a/57747064/14686958
|
||||
*
|
||||
* Basically {@link File} API is not reliable to check for symlinks.
|
||||
*
|
||||
* So we get the file type directly with {@link Os#lstat(String)} if {@code followLinks} is
|
||||
* {@code false} and {@link Os#stat(String)} if {@code followLinks} is {@code true}. All exceptions
|
||||
* are assumed as non-existence.
|
||||
*
|
||||
* The {@link org.apache.commons.io.FileUtils#isSymlink(File)} can also be used for checking
|
||||
* symlinks but {@link FileAttributes} will provide access to more attributes if necessary,
|
||||
* including getting other special file types considering that {@link File#exists()} can't be
|
||||
* used to reliably check for non-existence and exclude the other 3 file types. commons.io is
|
||||
* also not compatible with android < 8 for many things.
|
||||
*
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/java/io/File.java;l=793
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/java/io/UnixFileSystem.java;l=248
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/native/UnixFileSystem_md.c;l=121
|
||||
* https://cs.android.com/android/_/android/platform/libcore/+/001ac51d61ad7443ba518bf2cf7e086efe698c6d
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/luni/src/main/java/libcore/io/Os.java;l=51
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/luni/src/main/java/libcore/io/Libcore.java;l=45
|
||||
* https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ActivityThread.java;l=7530
|
||||
*
|
||||
* @param filePath The {@code path} for file to check.
|
||||
* @param followLinks The {@code boolean} that decides if symlinks will be followed while
|
||||
* finding type. If set to {@code true}, then type of symlink target will
|
||||
* be returned if file at {@code filePath} is a symlink. If set to
|
||||
* {@code false}, then type of file at {@code filePath} itself will be
|
||||
* returned.
|
||||
* @return Returns the {@link FileType} of file.
|
||||
*/
|
||||
public static FileType getFileType(final String filePath, final boolean followLinks) {
|
||||
if (filePath == null || filePath.isEmpty()) return FileType.NO_EXIST;
|
||||
|
||||
try {
|
||||
FileAttributes fileAttributes = FileAttributes.get(filePath, followLinks);
|
||||
return getFileType(fileAttributes);
|
||||
} catch (Exception e) {
|
||||
// If not a ENOENT (No such file or directory) exception
|
||||
if (!e.getMessage().contains("ENOENT"))
|
||||
Logger.logError("Failed to get file type for file at path \"" + filePath + "\": " + e.getMessage());
|
||||
return FileType.NO_EXIST;
|
||||
}
|
||||
}
|
||||
|
||||
public static FileType getFileType(@NonNull final FileAttributes fileAttributes) {
|
||||
if (fileAttributes.isRegularFile())
|
||||
return FileType.REGULAR;
|
||||
else if (fileAttributes.isDirectory())
|
||||
return FileType.DIRECTORY;
|
||||
else if (fileAttributes.isSymbolicLink())
|
||||
return FileType.SYMLINK;
|
||||
else if (fileAttributes.isCharacter())
|
||||
return FileType.CHARACTER;
|
||||
else if (fileAttributes.isFifo())
|
||||
return FileType.FIFO;
|
||||
else if (fileAttributes.isBlock())
|
||||
return FileType.BLOCK;
|
||||
else
|
||||
return FileType.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
public class NativeDispatcher {
|
||||
|
||||
public static void stat(String filePath, FileAttributes fileAttributes) throws IOException {
|
||||
validateFileExistence(filePath);
|
||||
|
||||
try {
|
||||
fileAttributes.loadFromStructStat(Os.stat(filePath));
|
||||
} catch (ErrnoException e) {
|
||||
throw new IOException("Failed to run Os.stat() on file at path \"" + filePath + "\": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void lstat(String filePath, FileAttributes fileAttributes) throws IOException {
|
||||
validateFileExistence(filePath);
|
||||
|
||||
try {
|
||||
fileAttributes.loadFromStructStat(Os.lstat(filePath));
|
||||
} catch (ErrnoException e) {
|
||||
throw new IOException("Failed to run Os.lstat() on file at path \"" + filePath + "\": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void fstat(FileDescriptor fileDescriptor, FileAttributes fileAttributes) throws IOException {
|
||||
validateFileDescriptor(fileDescriptor);
|
||||
|
||||
try {
|
||||
fileAttributes.loadFromStructStat(Os.fstat(fileDescriptor));
|
||||
} catch (ErrnoException e) {
|
||||
throw new IOException("Failed to run Os.fstat() on file descriptor \"" + fileDescriptor.toString() + "\": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateFileExistence(String filePath) throws IOException {
|
||||
if (filePath == null || filePath.isEmpty()) throw new IOException("The path is null or empty");
|
||||
|
||||
File file = new File(filePath);
|
||||
|
||||
//if (!file.exists())
|
||||
// throw new IOException("No such file or directory: \"" + filePath + "\"");
|
||||
}
|
||||
|
||||
public static void validateFileDescriptor(FileDescriptor fileDescriptor) throws IOException {
|
||||
if (fileDescriptor == null) throw new IOException("The file descriptor is null");
|
||||
|
||||
if (!fileDescriptor.valid())
|
||||
throw new IOException("No such file descriptor: \"" + fileDescriptor.toString() + "\"");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,149 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
// AUTOMATICALLY GENERATED FILE - DO NOT EDIT
|
||||
package com.termux.shared.file.filesystem;
|
||||
|
||||
// BEGIN Android-changed: Use constants from android.system.OsConstants. http://b/32203242
|
||||
// Those constants are initialized by native code to ensure correctness on different architectures.
|
||||
// AT_SYMLINK_NOFOLLOW (used by fstatat) and AT_REMOVEDIR (used by unlinkat) as of July 2018 do not
|
||||
// have equivalents in android.system.OsConstants so left unchanged.
|
||||
import android.system.OsConstants;
|
||||
|
||||
/**
|
||||
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:libcore/ojluni/src/main/java/sun/nio/fs/UnixConstants.java
|
||||
*/
|
||||
public class UnixConstants {
|
||||
private UnixConstants() { }
|
||||
|
||||
static final int O_RDONLY = OsConstants.O_RDONLY;
|
||||
|
||||
static final int O_WRONLY = OsConstants.O_WRONLY;
|
||||
|
||||
static final int O_RDWR = OsConstants.O_RDWR;
|
||||
|
||||
static final int O_APPEND = OsConstants.O_APPEND;
|
||||
|
||||
static final int O_CREAT = OsConstants.O_CREAT;
|
||||
|
||||
static final int O_EXCL = OsConstants.O_EXCL;
|
||||
|
||||
static final int O_TRUNC = OsConstants.O_TRUNC;
|
||||
|
||||
static final int O_SYNC = OsConstants.O_SYNC;
|
||||
|
||||
static final int O_DSYNC = OsConstants.O_DSYNC;
|
||||
|
||||
static final int O_NOFOLLOW = OsConstants.O_NOFOLLOW;
|
||||
|
||||
static final int S_IAMB = get_S_IAMB();
|
||||
|
||||
static final int S_IRUSR = OsConstants.S_IRUSR;
|
||||
|
||||
static final int S_IWUSR = OsConstants.S_IWUSR;
|
||||
|
||||
static final int S_IXUSR = OsConstants.S_IXUSR;
|
||||
|
||||
static final int S_IRGRP = OsConstants.S_IRGRP;
|
||||
|
||||
static final int S_IWGRP = OsConstants.S_IWGRP;
|
||||
|
||||
static final int S_IXGRP = OsConstants.S_IXGRP;
|
||||
|
||||
static final int S_IROTH = OsConstants.S_IROTH;
|
||||
|
||||
static final int S_IWOTH = OsConstants.S_IWOTH;
|
||||
|
||||
static final int S_IXOTH = OsConstants.S_IXOTH;
|
||||
|
||||
static final int S_IFMT = OsConstants.S_IFMT;
|
||||
|
||||
static final int S_IFREG = OsConstants.S_IFREG;
|
||||
|
||||
static final int S_IFDIR = OsConstants.S_IFDIR;
|
||||
|
||||
static final int S_IFLNK = OsConstants.S_IFLNK;
|
||||
|
||||
static final int S_IFCHR = OsConstants.S_IFCHR;
|
||||
|
||||
static final int S_IFBLK = OsConstants.S_IFBLK;
|
||||
|
||||
static final int S_IFIFO = OsConstants.S_IFIFO;
|
||||
|
||||
static final int R_OK = OsConstants.R_OK;
|
||||
|
||||
static final int W_OK = OsConstants.W_OK;
|
||||
|
||||
static final int X_OK = OsConstants.X_OK;
|
||||
|
||||
static final int F_OK = OsConstants.F_OK;
|
||||
|
||||
static final int ENOENT = OsConstants.ENOENT;
|
||||
|
||||
static final int EACCES = OsConstants.EACCES;
|
||||
|
||||
static final int EEXIST = OsConstants.EEXIST;
|
||||
|
||||
static final int ENOTDIR = OsConstants.ENOTDIR;
|
||||
|
||||
static final int EINVAL = OsConstants.EINVAL;
|
||||
|
||||
static final int EXDEV = OsConstants.EXDEV;
|
||||
|
||||
static final int EISDIR = OsConstants.EISDIR;
|
||||
|
||||
static final int ENOTEMPTY = OsConstants.ENOTEMPTY;
|
||||
|
||||
static final int ENOSPC = OsConstants.ENOSPC;
|
||||
|
||||
static final int EAGAIN = OsConstants.EAGAIN;
|
||||
|
||||
static final int ENOSYS = OsConstants.ENOSYS;
|
||||
|
||||
static final int ELOOP = OsConstants.ELOOP;
|
||||
|
||||
static final int EROFS = OsConstants.EROFS;
|
||||
|
||||
static final int ENODATA = OsConstants.ENODATA;
|
||||
|
||||
static final int ERANGE = OsConstants.ERANGE;
|
||||
|
||||
static final int EMFILE = OsConstants.EMFILE;
|
||||
|
||||
// S_IAMB are access mode bits, therefore, calculated by taking OR of all the read, write and
|
||||
// execute permissions bits for owner, group and other.
|
||||
private static int get_S_IAMB() {
|
||||
return (OsConstants.S_IRUSR | OsConstants.S_IWUSR | OsConstants.S_IXUSR |
|
||||
OsConstants.S_IRGRP | OsConstants.S_IWGRP | OsConstants.S_IXGRP |
|
||||
OsConstants.S_IROTH | OsConstants.S_IWOTH | OsConstants.S_IXOTH);
|
||||
}
|
||||
// END Android-changed: Use constants from android.system.OsConstants. http://b/32203242
|
||||
|
||||
|
||||
static final int AT_SYMLINK_NOFOLLOW = 0x100;
|
||||
static final int AT_REMOVEDIR = 0x200;
|
||||
}
|
Reference in New Issue
Block a user