From 3f4863096ca2a45657028a0ebea0fc4e1fc75609 Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Thu, 5 Dec 2024 09:27:25 -0500 Subject: [PATCH] Fixed removal of links on Unix-like OSes, updated tests against future regressions --- src/host/os_islink.c | 3 ++- src/host/os_linkdir.c | 28 ++++++++++++++++++++++++---- src/host/os_linkfile.c | 28 ++++++++++++++++++++++++---- src/host/os_rmdir.c | 11 ++++++++++- src/host/premake.c | 4 ++-- tests/base/test_os.lua | 7 ++++--- 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/host/os_islink.c b/src/host/os_islink.c index 80b7c5407b..8f4a49c862 100644 --- a/src/host/os_islink.c +++ b/src/host/os_islink.c @@ -31,7 +31,8 @@ int os_islink(lua_State* L) #else { struct stat buf; - if (lstat(path, &buf) == 0) { + if (lstat(path, &buf) == 0) + { lua_pushboolean(L, S_ISLNK(buf.st_mode)); return 1; } diff --git a/src/host/os_linkdir.c b/src/host/os_linkdir.c index 2d93718f59..58666f639d 100644 --- a/src/host/os_linkdir.c +++ b/src/host/os_linkdir.c @@ -34,8 +34,9 @@ int do_linkdir(lua_State* L, const char* src, const char* dst) GetCurrentDirectoryW(MAX_PATH, cwd); // Convert the source path to a relative path - wchar_t relSrcPath[MAX_PATH]; - swprintf(relSrcPath, MAX_PATH, L"%c:%s", cwd[0], wSrcPath); + wchar_t relSrcPath[MAX_PATH + 2]; + swprintf(relSrcPath, MAX_PATH + 2, L"%c:%s", cwd[0], wSrcPath); + relSrcPath[MAX_PATH + 1] = L'\0'; BOOLEAN res = CreateSymbolicLinkW(wDstPath, relSrcPath, SYMBOLIC_LINK_FLAG_DIRECTORY | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); return res != 0; @@ -46,8 +47,27 @@ int do_linkdir(lua_State* L, const char* src, const char* dst) return res != 0; } #else - int res = symlink(src, dst); - return res == 0; + (void)L; + if (!do_isabsolute(src)) + { + char cwd[PATH_MAX]; + if (!do_getcwd(cwd, PATH_MAX)) + { + return FALSE; + } + + char relSrcPath[2 * PATH_MAX + 1]; + snprintf(relSrcPath, 2 * PATH_MAX + 1, "%s/%s", cwd, src); + relSrcPath[2 * PATH_MAX] = '\0'; + + int res = symlink(relSrcPath, dst); + return res == 0; + } + else + { + int res = symlink(src, dst); + return res == 0; + } #endif } diff --git a/src/host/os_linkfile.c b/src/host/os_linkfile.c index 6f9e2954e8..4f1e86369d 100644 --- a/src/host/os_linkfile.c +++ b/src/host/os_linkfile.c @@ -33,8 +33,9 @@ int do_linkfile(lua_State* L, const char* src, const char* dst) GetCurrentDirectoryW(MAX_PATH, cwd); // Convert the source path to a relative path - wchar_t relSrcPath[MAX_PATH]; - swprintf(relSrcPath, MAX_PATH, L"%c:%s", cwd[0], wSrcPath); + wchar_t relSrcPath[MAX_PATH + 2]; + swprintf(relSrcPath, MAX_PATH + 2, L"%c:%s", cwd[0], wSrcPath); + relSrcPath[MAX_PATH + 1] = L'\0'; BOOLEAN res = CreateSymbolicLinkW(wDstPath, relSrcPath, SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); return res != 0; @@ -45,8 +46,27 @@ int do_linkfile(lua_State* L, const char* src, const char* dst) return res != 0; } #else - int res = symlink(src, dst); - return res == 0; + (void)L; + if (!do_isabsolute(src)) + { + char cwd[PATH_MAX]; + if (!do_getcwd(cwd, PATH_MAX)) + { + return FALSE; + } + + char relSrcPath[2 * PATH_MAX + 1]; + snprintf(relSrcPath, 2 * PATH_MAX + 1, "%s/%s", cwd, src); + relSrcPath[2 * PATH_MAX] = '\0'; + + int res = symlink(relSrcPath, dst); + return res == 0; + } + else + { + int res = symlink(src, dst); + return res == 0; + } #endif } diff --git a/src/host/os_rmdir.c b/src/host/os_rmdir.c index 47f8c1662b..49ae6e665d 100644 --- a/src/host/os_rmdir.c +++ b/src/host/os_rmdir.c @@ -4,6 +4,7 @@ * \author Copyright (c) 2002-2013 Jess Perkins and the Premake project */ +#include #include #include "premake.h" @@ -23,7 +24,15 @@ int os_rmdir(lua_State* L) z = RemoveDirectoryW(wide_path); #else - z = (0 == rmdir(path)); + struct stat buf; + if (lstat(path, &buf) == 0 && S_ISLNK(buf.st_mode)) + { + z = (0 == unlink(path)); + } + else + { + z = (0 == rmdir(path)); + } #endif if (!z) diff --git a/src/host/premake.c b/src/host/premake.c index 1da4830f7e..a5302f7020 100644 --- a/src/host/premake.c +++ b/src/host/premake.c @@ -87,8 +87,8 @@ static const luaL_Reg os_functions[] = { { "mkdir", os_mkdir }, #if PLATFORM_WINDOWS // utf8 functions for Windows (assuming posix already handle utf8) - {"remove", os_remove }, - {"rename", os_rename }, + { "remove", os_remove }, + { "rename", os_rename }, #endif { "pathsearch", os_pathsearch }, { "realpath", os_realpath }, diff --git a/tests/base/test_os.lua b/tests/base/test_os.lua index 1c0a50e844..90fd54c524 100644 --- a/tests/base/test_os.lua +++ b/tests/base/test_os.lua @@ -69,17 +69,18 @@ function suite.linkdir() test.istrue(os.linkdir("folder/subfolder", "folder/subfolder2")) test.istrue(os.islink("folder/subfolder2")) - os.rmdir("folder/subfolder2") + test.istrue(os.rmdir("folder/subfolder2")) + test.isfalse(os.islink("folder/subfolder2")) end function suite.linkfile() test.istrue(os.linkfile("folder/ok.lua", "folder/ok2.lua")) test.istrue(os.islink("folder/ok2.lua")) - os.remove("folder/ok2.lua") + test.istrue(os.remove("folder/ok2.lua")) + test.isfalse(os.islink("folder/ok2.lua")) end - -- -- os.matchdirs() tests --