add symlink capabilities to fd.c
This commit is contained in:
64
scripts/fd.c
64
scripts/fd.c
@@ -205,11 +205,6 @@ JSC_SCALL(fd_mkdir,
|
||||
ret = JS_ThrowInternalError(js, "could not make directory %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_unlink,
|
||||
if (unlink(str) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_mv,
|
||||
if (argc < 2)
|
||||
ret = JS_ThrowTypeError(js, "fd.mv requires 2 arguments: old path and new path");
|
||||
@@ -245,6 +240,29 @@ JSC_SCALL(fd_symlink,
|
||||
}
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_unlink,
|
||||
#ifdef _WIN32
|
||||
// On Windows, try to remove read-only attribute first
|
||||
DWORD attrs = GetFileAttributesA(str);
|
||||
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_READONLY)) {
|
||||
SetFileAttributesA(str, attrs & ~FILE_ATTRIBUTE_READONLY);
|
||||
}
|
||||
if (!DeleteFileA(str)) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_ACCESS_DENIED) {
|
||||
// Might be a directory, try RemoveDirectory
|
||||
if (!RemoveDirectoryA(str))
|
||||
ret = JS_ThrowInternalError(js, "could not remove %s: error %lu", str, GetLastError());
|
||||
} else {
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: error %lu", str, err);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (unlink(str) != 0)
|
||||
ret = JS_ThrowInternalError(js, "could not remove file %s: %s", str, strerror(errno));
|
||||
#endif
|
||||
)
|
||||
|
||||
// Helper function for recursive removal
|
||||
static int remove_recursive(const char *path) {
|
||||
struct stat st;
|
||||
@@ -570,6 +588,40 @@ JSC_SCALL(fd_enumerate,
|
||||
ret = results;
|
||||
)
|
||||
|
||||
JSC_CCALL(fd_realpath,
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) return JS_EXCEPTION;
|
||||
|
||||
#ifdef _WIN32
|
||||
char resolved[PATH_MAX];
|
||||
DWORD len = GetFullPathNameA(path, PATH_MAX, resolved, NULL);
|
||||
JS_FreeCString(js, path);
|
||||
if (len == 0 || len >= PATH_MAX) {
|
||||
return JS_ThrowInternalError(js, "realpath failed: %s", strerror(errno));
|
||||
}
|
||||
return JS_NewString(js, resolved);
|
||||
#else
|
||||
char *resolved = realpath(path, NULL);
|
||||
JS_FreeCString(js, path);
|
||||
if (!resolved) {
|
||||
return JS_ThrowInternalError(js, "realpath failed: %s", strerror(errno));
|
||||
}
|
||||
JSValue result = JS_NewString(js, resolved);
|
||||
free(resolved);
|
||||
return result;
|
||||
#endif
|
||||
)
|
||||
|
||||
JSC_CCALL(fd_is_link,
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) return JS_EXCEPTION;
|
||||
|
||||
struct stat st;
|
||||
if (lstat(path, &st) == 0 && S_ISLNK(st.st_mode))
|
||||
return JS_NewBool(js, 1);
|
||||
return JS_NewBool(js, 0);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_fd_funcs[] = {
|
||||
MIST_FUNC_DEF(fd, open, 2),
|
||||
MIST_FUNC_DEF(fd, write, 2),
|
||||
@@ -590,8 +642,10 @@ static const JSCFunctionListEntry js_fd_funcs[] = {
|
||||
MIST_FUNC_DEF(fd, readdir, 1),
|
||||
MIST_FUNC_DEF(fd, is_file, 1),
|
||||
MIST_FUNC_DEF(fd, is_dir, 1),
|
||||
MIST_FUNC_DEF(fd, is_link, 1),
|
||||
MIST_FUNC_DEF(fd, enumerate, 2),
|
||||
MIST_FUNC_DEF(fd, symlink, 2),
|
||||
MIST_FUNC_DEF(fd, realpath, 1),
|
||||
};
|
||||
|
||||
JSValue js_fd_use(JSContext *js) {
|
||||
|
||||
Reference in New Issue
Block a user