From ba3e73a32df8d9d37dcc44769ff71b19b8363578 Mon Sep 17 00:00:00 2001 From: Robert McLay Date: Fri, 1 Dec 2023 13:49:08 -0700 Subject: [PATCH] Issue #678: Make isFile() return nil if broken symlink; Change abspath to l_abspath; create realpath which uses posix.realpath when it exists --- README.new | 5 +++++ rt/symlink/err.txt | 18 +++++++++++++----- rt/symlink/foo/bar/mf/Core/bad_symlink/1.0.lua | 7 +++++++ rt/symlink/out.txt | 12 ++++++++++++ rt/symlink/symlink.tdesc | 6 ++++++ src/cmdfuncs.lua | 2 +- src/sandbox.lua | 3 ++- src/spider.in.lua | 2 +- src/utils.lua | 2 +- tools/fileOps.lua | 15 +++++++++++++-- 10 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 rt/symlink/foo/bar/mf/Core/bad_symlink/1.0.lua diff --git a/README.new b/README.new index 7433df296..9269700e9 100644 --- a/README.new +++ b/README.new @@ -117,3 +117,8 @@ Lmod 8.7+ (8.7.32) * Better handling of zsh shell functions in source_sh(). Must match "\n}\n" to find end of function. * Better name for extension title, remove trailing \n * Testing github actions +W.I.P: + (8.7.33) * Issue #678: Change isFile(fn) to return nil if fn is a broken symlink. + * Issue #678: Change abspath() to l_abspath() in tools/fileOps.lua + * Issue #678: Create realpath() to use posix.realpath() if it exists otherwise use l_abspath() + diff --git a/rt/symlink/err.txt b/rt/symlink/err.txt index cbbaaf365..d04898a19 100644 --- a/rt/symlink/err.txt +++ b/rt/symlink/err.txt @@ -2,17 +2,17 @@ step 1 lua ProjectDIR/src/lmod.in.lua shell --regression_testing --version =========================== -Modules based on Lua: Version 8.6.9 2022-02-02 11:25 -04:00 +Modules based on Lua: Version 8.7.32 2023-08-28 12:42 -05:00 by Robert McLay mclay@tacc.utexas.edu =========================== step 2 lua ProjectDIR/src/lmod.in.lua shell --regression_testing avail =========================== ProjectDIR/rt/symlink/mf/Core - a/1.1 boost/1.55.0 (D) intel/14.0.2 mv2/2.1 - a/1.2 (D) boost/1.56.0 mv2/2.0 mv2/2.2 - b/1.1 (D) intel/12.1.5 (D) mv2/2.1rc1 - b/1.2 intel/13.1 mv2/2.1rc2 (D) + a/1.1 bad_symlink/1.0 intel/13.1 mv2/2.1rc2 (D) + a/1.2 (D) boost/1.55.0 (D) intel/14.0.2 mv2/2.1 + b/1.1 (D) boost/1.56.0 mv2/2.0 mv2/2.2 + b/1.2 intel/12.1.5 (D) mv2/2.1rc1 Where: D: Default Module If the avail list is too long consider trying: @@ -27,6 +27,7 @@ lua ProjectDIR/src/lmod.in.lua shell --regression_testing -t -d avail ProjectDIR/rt/symlink/mf/Core: a/1.2 b/1.1 +bad_symlink/1.0 boost/1.55.0 intel/12.1.5 mv2/2.1rc2 @@ -40,3 +41,10 @@ lua ProjectDIR/src/lmod.in.lua shell --regression_testing list =========================== Currently Loaded Modules: 1) intel/12.1.5 2) a/1.2 3) b/1.1 4) boost/1.55.0 5) mv2/2.1rc2 +=========================== +step 6 +lua ProjectDIR/src/lmod.in.lua shell --regression_testing load bad_symlink +=========================== +good.text true +bad1.text nil +bad2.text nil diff --git a/rt/symlink/foo/bar/mf/Core/bad_symlink/1.0.lua b/rt/symlink/foo/bar/mf/Core/bad_symlink/1.0.lua new file mode 100644 index 000000000..480a34acc --- /dev/null +++ b/rt/symlink/foo/bar/mf/Core/bad_symlink/1.0.lua @@ -0,0 +1,7 @@ +local a = { "good.text", "bad1.text", "bad2.text"} + +for i = 1,#a do + local result = isFile(a[i]) + io.stderr:write(a[i].." "..tostring(result).."\n") +end + diff --git a/rt/symlink/out.txt b/rt/symlink/out.txt index d473d5de5..678462cd4 100644 --- a/rt/symlink/out.txt +++ b/rt/symlink/out.txt @@ -44,3 +44,15 @@ MODULEPATH=ProjectDIR/rt/symlink/mf/Core; export MODULEPATH; _ModuleTable_='_ModuleTable_={MTversion=3,depthT={},family={},mT={a={fn="ProjectDIR/rt/symlink/mf/Core/a/1.2.lua",fullName="a/1.2",loadOrder=2,propT={},stackDepth=0,status="active",userName="a",wV="^00000001.000000002.*zfinal",},b={fn="ProjectDIR/rt/symlink/mf/Core/b/1.1.lua",fullName="b/1.1",loadOrder=3,propT={},stackDepth=0,status="active",userName="b",wV="^00000001.000000001.*zfinal",},boost={fn="ProjectDIR/rt/symlink/mf/Core/boost/1.55.0.lua",fullName="boost/1.55.0",loadOrder=4,propT={},stackDepth=0,status="active",userName="boost",wV="^00000001.000000055.*zfinal",},intel={fn="ProjectDIR/rt/symlink/mf/Core/intel/12.1.5.lua",fullName="intel/12.1.5",loadOrder=1,propT={},stackDepth=0,status="active",userName="intel",wV="^00000012.000000001.000000005.*zfinal",},mv2={fn="ProjectDIR/rt/symlink/mf/Core/mv2/2.1rc2.lua",fullName="mv2/2.1rc2",loadOrder=5,propT={},stackDepth=0,status="active",userName="mv2",wV="^00000002.000000001.*c.000000002.*zfinal",},},mpathA={"ProjectDIR/rt/symlink/mf/Core",},systemBaseMPATH="ProjectDIR/rt/symlink/mf/Core",}'; export _ModuleTable_; +=========================== +step 6 +lua ProjectDIR/src/lmod.in.lua shell --regression_testing load bad_symlink +=========================== +LOADEDMODULES=intel/12.1.5:a/1.2:b/1.1:boost/1.55.0:mv2/2.1rc2:bad_symlink/1.0; +export LOADEDMODULES; +MODULEPATH=ProjectDIR/rt/symlink/mf/Core; +export MODULEPATH; +_LMFILES_=ProjectDIR/rt/symlink/mf/Core/intel/12.1.5.lua:ProjectDIR/rt/symlink/mf/Core/a/1.2.lua:ProjectDIR/rt/symlink/mf/Core/b/1.1.lua:ProjectDIR/rt/symlink/mf/Core/boost/1.55.0.lua:ProjectDIR/rt/symlink/mf/Core/mv2/2.1rc2.lua:ProjectDIR/rt/symlink/mf/Core/bad_symlink/1.0.lua; +export _LMFILES_; +_ModuleTable_='_ModuleTable_={MTversion=3,depthT={},family={},mT={a={fn="ProjectDIR/rt/symlink/mf/Core/a/1.2.lua",fullName="a/1.2",loadOrder=2,propT={},stackDepth=0,status="active",userName="a",wV="^00000001.000000002.*zfinal",},b={fn="ProjectDIR/rt/symlink/mf/Core/b/1.1.lua",fullName="b/1.1",loadOrder=3,propT={},stackDepth=0,status="active",userName="b",wV="^00000001.000000001.*zfinal",},bad_symlink={fn="ProjectDIR/rt/symlink/mf/Core/bad_symlink/1.0.lua",fullName="bad_symlink/1.0",loadOrder=6,propT={},stackDepth=0,status="active",userName="bad_symlink",wV="000000001.*zfinal",},boost={fn="ProjectDIR/rt/symlink/mf/Core/boost/1.55.0.lua",fullName="boost/1.55.0",loadOrder=4,propT={},stackDepth=0,status="active",userName="boost",wV="^00000001.000000055.*zfinal",},intel={fn="ProjectDIR/rt/symlink/mf/Core/intel/12.1.5.lua",fullName="intel/12.1.5",loadOrder=1,propT={},stackDepth=0,status="active",userName="intel",wV="^00000012.000000001.000000005.*zfinal",},mv2={fn="ProjectDIR/rt/symlink/mf/Core/mv2/2.1rc2.lua",fullName="mv2/2.1rc2",loadOrder=5,propT={},stackDepth=0,status="active",userName="mv2",wV="^00000002.000000001.*c.000000002.*zfinal",},},mpathA={"ProjectDIR/rt/symlink/mf/Core",},systemBaseMPATH="ProjectDIR/rt/symlink/mf/Core",}'; +export _ModuleTable_; diff --git a/rt/symlink/symlink.tdesc b/rt/symlink/symlink.tdesc index 9f3f08195..488feeede 100644 --- a/rt/symlink/symlink.tdesc +++ b/rt/symlink/symlink.tdesc @@ -23,12 +23,18 @@ testdescript = { MODULEPATH=$MODULEPATH_ROOT/Core; export MODULEPATH rm -fr _stderr.* _stdout.* err.* out.* .lmod.d .cache .config + rm -f good.text bad1.text bad2.text runLmod --version # 1 runLmod avail # 2 runLmod -t -d avail # 3 runLmod load intel a b boost mv2 # 4 runLmod list # 5 + touch good.text + ln -s bad bad1.text + ln -s bad1.text bad2.text + runLmod load bad_symlink # 6 + diff --git a/src/cmdfuncs.lua b/src/cmdfuncs.lua index 728c859c4..735b5ba45 100644 --- a/src/cmdfuncs.lua +++ b/src/cmdfuncs.lua @@ -1202,7 +1202,7 @@ function Use(...) if (v:sub(1,1) ~= '/') then local old = v -- If relative convert to try to convert to absolute path - v = abspath(v) + v = realpath(v) -- If it doesn't exist then build path with current directory and relative path. if (not v) then v = pathJoin(posix.getcwd(), old) diff --git a/src/sandbox.lua b/src/sandbox.lua index 2176bac1a..2e2b90b5f 100644 --- a/src/sandbox.lua +++ b/src/sandbox.lua @@ -218,7 +218,8 @@ local sandbox_env = { removeExt = removeExt, barefilename = barefilename, splitFileName = splitFileName, - abspath = abspath, + abspath = realpath, + realpath = realpath, path_regularize = path_regularize, ------------------------------------------------------------ diff --git a/src/spider.in.lua b/src/spider.in.lua index 2ddea3f90..031739622 100644 --- a/src/spider.in.lua +++ b/src/spider.in.lua @@ -211,7 +211,7 @@ local function l_add2map(entry, tbl, dirA, moduleFn, kind, rmapT) end dbg.print{"assigning rmapT for path: ",path,"\n"} rmapT[path] = t - local p2 = abspath(path) + local p2 = realpath(path) if (p2 and p2 ~= path) then dbg.print{"assigning rmapT for path: ",p2,"\n"} rmapT[p2] = deepcopy(t) diff --git a/src/utils.lua b/src/utils.lua index a91cd0b2d..97951ba55 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -1204,7 +1204,7 @@ function locatePkg(pkg) for path in package.path:split(";") do local s = path:gsub("?",pkg) if (isFile(s)) then - result = abspath(s) + result = realpath(s) break end end diff --git a/tools/fileOps.lua b/tools/fileOps.lua index 4138e598b..1483d7897 100644 --- a/tools/fileOps.lua +++ b/tools/fileOps.lua @@ -147,6 +147,9 @@ function isFile(fn) local t = posix.stat(fn,"type") local result = t and t ~= "directory" + if (t == "link") then + result = realpath(fn) + end return result end @@ -318,7 +321,7 @@ end -- when following symlinks -- @return A absolute path. -function abspath (path, localDir) +local function l_abspath (path, localDir) if (path == nil) then return nil end local cwd = lfs.currentdir() @@ -355,12 +358,20 @@ function abspath (path, localDir) lfs.chdir(cwd) return result end - result = abspath(rl, localDir) + result = l_abspath(rl, localDir) end lfs.chdir(cwd) return result end +function realpath(path, localDir) + if (localDir or not posix.realpath) then + return l_abspath(path, localDir) + end + return posix.realpath(path) +end + + -------------------------------------------------------------------------- -- Remove leading and trail spaces and extra slashes. -- @param value A path