diff --git a/docs/docs/standard-lib/path.md b/docs/docs/standard-lib/path.md index d17ccae90..29d6f9692 100644 --- a/docs/docs/standard-lib/path.md +++ b/docs/docs/standard-lib/path.md @@ -93,6 +93,16 @@ Checks whether a given path points to a directory or not. Path.isDir("/usr/bin/"); //true ``` +### Path.isSymbolicLink(String) -> Boolean + +Checks whether a given path is a symbolic link. + +**Note:** This is not available on windows systems. + +```cs +Path.isSymbolicLink("/usr/bin/"); //false +``` + ### Path.listDir(String) -> List Returns a list of strings containing the contents of the input path. diff --git a/src/optionals/path.c b/src/optionals/path.c index b7336f422..26735e1df 100644 --- a/src/optionals/path.c +++ b/src/optionals/path.c @@ -146,7 +146,10 @@ static Value isdirNative(DictuVM *vm, int argCount, Value *args) { char *path = AS_CSTRING(args[0]); struct stat path_stat; - stat(path, &path_stat); + int ret = stat(path, &path_stat); + + if (ret < 0) + return FALSE_VAL; if (S_ISDIR(path_stat.st_mode)) return TRUE_VAL; @@ -154,6 +157,32 @@ static Value isdirNative(DictuVM *vm, int argCount, Value *args) { return FALSE_VAL; } +#ifndef _WIN32 +static Value isSymlinkNative(DictuVM *vm, int argCount, Value *args) { + if (argCount != 1) { + runtimeError(vm, "isSymbolicLink() takes 1 argument (%d given)", argCount); + return EMPTY_VAL; + } + + if (!IS_STRING(args[0])) { + runtimeError(vm, "isSymbolicLink() argument must be a string"); + return EMPTY_VAL; + } + + char *path = AS_CSTRING(args[0]); + struct stat path_stat; + int ret = lstat(path, &path_stat); + + if(ret < 0) + return FALSE_VAL; + + if (S_ISLNK(path_stat.st_mode)) + return TRUE_VAL; + + return FALSE_VAL; + +} +#endif static Value listDirNative(DictuVM *vm, int argCount, Value *args) { if (argCount > 1) { @@ -330,6 +359,9 @@ Value createPathModule(DictuVM *vm) { defineNative(vm, &module->values, "dirname", dirnameNative); defineNative(vm, &module->values, "exists", existsNative); defineNative(vm, &module->values, "isDir", isdirNative); +#ifndef _WIN32 + defineNative(vm, &module->values, "isSymbolicLink", isSymlinkNative); +#endif defineNative(vm, &module->values, "listDir", listDirNative); defineNative(vm, &module->values, "join", joinNative); diff --git a/tests/path/import.du b/tests/path/import.du index d58d0bc89..ad647228d 100644 --- a/tests/path/import.du +++ b/tests/path/import.du @@ -11,5 +11,6 @@ import "isAbsolute.du"; import "realpath.du"; import "exists.du"; import "isDir.du"; +import "isSymbolicLink.du"; import "join.du"; import "listDir.du"; diff --git a/tests/path/isSymbolicLink.du b/tests/path/isSymbolicLink.du new file mode 100644 index 000000000..b2cd06b19 --- /dev/null +++ b/tests/path/isSymbolicLink.du @@ -0,0 +1,29 @@ +/** + * isSymbolic.du + * + * Testing Path.isSymbolicLink() + * + * Returns true if the given string is a symbolic Link, else false. (Linux only) + */ +from UnitTest import UnitTest; + +import Path; +import System; +import Process; + +class TestPathIsSL < UnitTest { + setUp() { + Process.run(["ln", "-s", "README.md", "README.md.sl"]); + } + tearDown() { + System.remove("README.md.sl"); + } + testIsSL() { + this.assertTruthy(Path.isSymbolicLink("README.md.sl")); + this.assertFalsey(Path.isSymbolicLink("README.md")); + } + +} + +if (System.platform != "windows") + TestPathIsSL().run();