Skip to content

Commit

Permalink
Changed: Make sure full path is included in FileUtilsErrnos
Browse files Browse the repository at this point in the history
Previously, `FileUtilsErrno` had some errors that didn't include the full path passed to the `FileUtils` functions and caller had to manually append the path to the error. This was done due to `termux-tasker` plugin config activity was using these errors in the executable and working directory text fields and we had to keep the error short as possible to reduce clutter. Now by default, the path will be included so that its not missing for other cases and the `FileUtils.getShortFileUtilsError()` function is provided to get a shorter version from the original error if its possible to do so if caller like `termux-tasker` requires it.
  • Loading branch information
agnostic-apollo committed Sep 5, 2021
1 parent 5c72c3c commit f00738f
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 49 deletions.
2 changes: 0 additions & 2 deletions app/src/main/java/com/termux/app/RunCommandService.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ public int onStartCommand(Intent intent, int flags, int startId) {
FileUtils.APP_EXECUTABLE_FILE_PERMISSIONS, true, true,
false);
if (error != null) {
error.appendMessage("\n" + this.getString(R.string.msg_executable_absolute_path, executionCommand.executable));
executionCommand.setStateFailed(error);
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
return stopService();
Expand All @@ -170,7 +169,6 @@ public int onStartCommand(Intent intent, int flags, int startId) {
true, true, true,
false, true);
if (error != null) {
error.appendMessage("\n" + this.getString(R.string.msg_working_directory_absolute_path, executionCommand.workingDirectory));
executionCommand.setStateFailed(error);
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
return stopService();
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@



<!-- Termux Execution Commands -->
<string name="msg_executable_absolute_path">Executable Absolute Path: \"%1$s\"</string>
<string name="msg_working_directory_absolute_path">Working Directory Absolute Path: \"%1$s\"</string>



<!-- Termux File Receiver -->
<string name="title_file_received">Save file in ~/downloads/</string>
<string name="action_file_received_edit">Edit</string>
Expand Down
88 changes: 63 additions & 25 deletions termux-shared/src/main/java/com/termux/shared/file/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.termux.shared.file.filesystem.FileTypes;
import com.termux.shared.data.DataUtils;
import com.termux.shared.logger.Logger;
import com.termux.shared.models.errors.Errno;
import com.termux.shared.models.errors.Error;
import com.termux.shared.models.errors.FileUtilsErrno;
import com.termux.shared.models.errors.FunctionErrno;
Expand All @@ -34,6 +35,7 @@
import java.nio.file.StandardCopyOption;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

public class FileUtils {
Expand Down Expand Up @@ -260,7 +262,7 @@ public static Error validateRegularFileExistenceAndPermissions(String label, fin

// If file exists but not a regular file
if (fileType != FileType.NO_EXIST && fileType != FileType.REGULAR) {
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file");
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file", filePath).setLabel(label + "file");
}

boolean isPathUnderParentDirPath = false;
Expand All @@ -283,7 +285,8 @@ public static Error validateRegularFileExistenceAndPermissions(String label, fin
// If path is not a regular file
// Regular files cannot be automatically created so we do not ignore if missing
if (fileType != FileType.REGULAR) {
return FileUtilsErrno.ERRNO_NO_REGULAR_FILE_FOUND.getError(label + "file");
label += "regular file";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label);
}

// If there is not parentDirPath restriction or path is not under parentDirPath or
Expand Down Expand Up @@ -341,7 +344,7 @@ public static Error validateDirectoryFileExistenceAndPermissions(String label, f

// If file exists but not a directory file
if (fileType != FileType.NO_EXIST && fileType != FileType.DIRECTORY) {
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory");
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory", filePath).setLabel(label + "directory");
}

boolean isPathInParentDirPath = false;
Expand Down Expand Up @@ -380,7 +383,8 @@ public static Error validateDirectoryFileExistenceAndPermissions(String label, f
// If path is not a directory
// Directories can be automatically created so we can ignore if missing with above check
if (fileType != FileType.DIRECTORY) {
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "directory", filePath);
label += "directory";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label);
}

if (permissionsToCheck != null) {
Expand Down Expand Up @@ -455,7 +459,7 @@ public static Error createRegularFile(String label, final String filePath,

// If file exists but not a regular file
if (fileType != FileType.NO_EXIST && fileType != FileType.REGULAR) {
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file");
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file", filePath).setLabel(label + "file");
}

// If regular file already exists
Expand Down Expand Up @@ -645,8 +649,10 @@ public static Error createSymlinkFile(String label, final String targetFilePath,
// If target file does not exist
if (targetFileType == FileType.NO_EXIST) {
// If dangling symlink should not be allowed, then return with error
if (!allowDangling)
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "symlink target file", targetFileAbsolutePath);
if (!allowDangling) {
label += "symlink target file";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, targetFileAbsolutePath).setLabel(label);
}
}

// If destination exists
Expand Down Expand Up @@ -920,8 +926,10 @@ public static Error copyOrMoveFile(String label, final String srcFilePath, final
if (ignoreNonExistentSrcFile)
return null;
// Else return with error
else
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "source file", srcFilePath);
else {
label += "source file";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, srcFilePath).setLabel(label);
}
}

// If the file type of the source file does not exist in the allowedFileTypeFlags, then return with error
Expand Down Expand Up @@ -1121,8 +1129,10 @@ public static Error deleteFile(String label, final String filePath, final boolea
if (ignoreNonExistentFile)
return null;
// Else return with error
else
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "file meant to be deleted", filePath);
else {
label += "file meant to be deleted";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label);
}
}

// If the file type of the file does not exist in the allowedFileTypeFlags
Expand Down Expand Up @@ -1224,7 +1234,7 @@ public static Error clearDirectory(String label, final String filePath) {

// If file exists but not a directory file
if (fileType != FileType.NO_EXIST && fileType != FileType.DIRECTORY) {
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory");
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory", filePath).setLabel(label + "directory");
}

// If directory exists, clear its contents
Expand Down Expand Up @@ -1288,7 +1298,7 @@ public static Error deleteFilesOlderThanXDays(String label, final String filePat

// If file exists but not a directory file
if (fileType != FileType.NO_EXIST && fileType != FileType.DIRECTORY) {
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory");
return FileUtilsErrno.ERRNO_NON_DIRECTORY_FILE_FOUND.getError(label + "directory", filePath).setLabel(label + "directory");
}

// If file does not exist
Expand All @@ -1297,8 +1307,10 @@ public static Error deleteFilesOlderThanXDays(String label, final String filePat
if (ignoreNonExistentFile)
return null;
// Else return with error
else
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "directory under which files had to be deleted", filePath);
else {
label += "directory under which files had to be deleted";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label);
}
}

// If directory exists, delete its contents
Expand Down Expand Up @@ -1349,7 +1361,7 @@ public static Error readStringFromFile(String label, final String filePath, Char

// If file exists but not a regular file
if (fileType != FileType.NO_EXIST && fileType != FileType.REGULAR) {
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file");
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file", filePath).setLabel(label + "file");
}

// If file does not exist
Expand All @@ -1358,8 +1370,10 @@ public static Error readStringFromFile(String label, final String filePath, Char
if (ignoreNonExistentFile)
return null;
// Else return with error
else
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "file meant to be read", filePath);
else {
label += "file meant to be read";
return FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label);
}
}

if (charset == null) charset = Charset.defaultCharset();
Expand Down Expand Up @@ -1428,7 +1442,7 @@ public static <T extends Serializable> ReadSerializableObjectResult readSerializ

// If file exists but not a regular file
if (fileType != FileType.NO_EXIST && fileType != FileType.REGULAR) {
return new ReadSerializableObjectResult(FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file"), null);
return new ReadSerializableObjectResult(FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file", filePath).setLabel(label + "file"), null);
}

// If file does not exist
Expand All @@ -1437,8 +1451,10 @@ public static <T extends Serializable> ReadSerializableObjectResult readSerializ
if (ignoreNonExistentFile)
return new ReadSerializableObjectResult(null, null);
// Else return with error
else
return new ReadSerializableObjectResult(FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label + "file meant to be read", filePath), null);
else {
label += "file meant to be read";
return new ReadSerializableObjectResult(FileUtilsErrno.ERRNO_FILE_NOT_FOUND_AT_PATH.getError(label, filePath).setLabel(label), null);
}
}

FileInputStream fileInputStream = null;
Expand Down Expand Up @@ -1556,7 +1572,7 @@ private static Error preWriteToFile(String label, String filePath) {

// If file exists but not a regular file
if (fileType != FileType.NO_EXIST && fileType != FileType.REGULAR) {
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file");
return FileUtilsErrno.ERRNO_NON_REGULAR_FILE_FOUND.getError(label + "file", filePath).setLabel(label + "file");
}

// Create the file parent directory
Expand Down Expand Up @@ -1764,17 +1780,17 @@ public static Error checkMissingFilePermissions(String label, final String fileP

// If file is not readable
if (permissionsToCheck.contains("r") && !file.canRead()) {
return FileUtilsErrno.ERRNO_FILE_NOT_READABLE.getError(label + "file");
return FileUtilsErrno.ERRNO_FILE_NOT_READABLE.getError(label + "file", filePath).setLabel(label + "file");
}

// If file is not writable
if (permissionsToCheck.contains("w") && !file.canWrite()) {
return FileUtilsErrno.ERRNO_FILE_NOT_WRITABLE.getError(label + "file");
return FileUtilsErrno.ERRNO_FILE_NOT_WRITABLE.getError(label + "file", filePath).setLabel(label + "file");
}
// If file is not executable
// This canExecute() will give "avc: granted { execute }" warnings for target sdk 29
else if (permissionsToCheck.contains("x") && !file.canExecute() && !ignoreIfNotExecutable) {
return FileUtilsErrno.ERRNO_FILE_NOT_EXECUTABLE.getError(label + "file");
return FileUtilsErrno.ERRNO_FILE_NOT_EXECUTABLE.getError(label + "file", filePath).setLabel(label + "file");
}

return null;
Expand All @@ -1794,4 +1810,26 @@ public static boolean isValidPermissionString(final String string) {
return Pattern.compile("^([r-])[w-][x-]$", 0).matcher(string).matches();
}



/**
* Get a {@link Error} that contains a shorter version of {@link Errno} message.
*
* @param error The original {@link Error} returned by one of the {@link FileUtils} functions.
* @return Returns the shorter {@link Error} if one exists, otherwise original {@code error}.
*/
public static Error getShortFileUtilsError(final Error error) {
String type = error.getType();
if (!FileUtilsErrno.TYPE.equals(type)) return error;

Errno shortErrno = FileUtilsErrno.ERRNO_SHORT_MAPPING.get(Errno.valueOf(type, error.getCode()));
if (shortErrno == null) return error;

List<Throwable> throwables = error.getThrowablesList();
if (throwables.isEmpty())
return shortErrno.getError(DataUtils.getDefaultIfNull(error.getLabel(), "file"));
else
return shortErrno.getError(throwables, error.getLabel(), "file");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/** The {@link Class} that defines error messages and codes. */
public class Errno {

private static final HashMap<String, Errno> map = new HashMap<>();

public static final String TYPE = "Error";


Expand All @@ -35,6 +38,7 @@ public Errno(final String type, final int code, final String message) {
this.type = type;
this.code = code;
this.message = message;
map.put(type + ":" + code, this);
}

@NonNull
Expand All @@ -56,6 +60,17 @@ public int getCode() {
return code;
}

/**
* Get the {@link Errno} of a specific type and code.
*
* @param type The unique type of the {@link Errno}.
* @param code The unique code of the {@link Errno}.
*/
public static Errno valueOf(String type, Integer code) {
if (type == null || type.isEmpty() || code == null) return null;
return map.get(type + ":" + code);
}



public Error getError() {
Expand All @@ -73,12 +88,18 @@ public Error getError(Object... args) {
}

public Error getError(Throwable throwable, Object... args) {
return getError(Collections.singletonList(throwable), args);
if (throwable == null)
return getError(args);
else
return getError(Collections.singletonList(throwable), args);
}

public Error getError(List<Throwable> throwablesList, Object... args) {
try {
return new Error(getType(), getCode(), String.format(getMessage(), args), throwablesList);
if (throwablesList == null)
return new Error(getType(), getCode(), String.format(getMessage(), args));
else
return new Error(getType(), getCode(), String.format(getMessage(), args), throwablesList);
} catch (Exception e) {
Logger.logWarn(LOG_TAG, "Exception raised while calling String.format() for error message of errno " + this + " with args" + Arrays.toString(args) + "\n" + e.getMessage());
// Return unformatted message as a backup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

public class Error implements Serializable {

/** The optional error label. */
private String label;
/** The error type. */
private String type;
/** The error code. */
Expand Down Expand Up @@ -76,7 +78,18 @@ private void InitError(String type, Integer code, String message, List<Throwable
this.code = Errno.ERRNO_SUCCESS.getCode();

this.message = message;
this.throwablesList = throwablesList;

if (throwablesList != null)
this.throwablesList = throwablesList;
}

public Error setLabel(String label) {
this.label = label;
return this;
}

public String getLabel() {
return label;
}


Expand Down
Loading

0 comments on commit f00738f

Please sign in to comment.