diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2019-07-25 14:56:28 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2019-07-25 18:47:00 -0300 |
| commit | 869a628bec218b94b4b312fadcedf13262fa5b03 (patch) | |
| tree | fd3e548f4e69cfae6b822bf54ba3e06df39ed8da | |
| parent | c79d3a85820d5b69b3a8f309d456a9feb4eeb013 (diff) | |
| download | luarocks-869a628bec218b94b4b312fadcedf13262fa5b03.tar.gz luarocks-869a628bec218b94b4b312fadcedf13262fa5b03.tar.bz2 luarocks-869a628bec218b94b4b312fadcedf13262fa5b03.zip | |
fs: use Unix fork-free versions of is_file/is_dir in Linux and macOS only
The Unix fork-free version relies on non-standard behaviors. It works
on Linux, but it took a while for it to work properly in macOS, and it
turns out that you can't really properly detect a directory in FreeBSD
using io.open() because it can actually open a directory. To avoid filling
in platform-specific tricks in luarocks/fs/unix.lua, which was never the
goal, it's better to move the fork-free operations to Linux and macOS
specific backends, and keep other Unices using the 'test' command.
| -rw-r--r-- | src/luarocks/core/cfg.lua | 1 | ||||
| -rw-r--r-- | src/luarocks/fs/linux.lua | 50 | ||||
| -rw-r--r-- | src/luarocks/fs/macosx.lua | 50 | ||||
| -rw-r--r-- | src/luarocks/fs/unix.lua | 43 | ||||
| -rw-r--r-- | src/luarocks/fs/unix/tools.lua | 24 |
5 files changed, 125 insertions, 43 deletions
diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua index 8c11d408..0505b11d 100644 --- a/src/luarocks/core/cfg.lua +++ b/src/luarocks/core/cfg.lua | |||
| @@ -370,6 +370,7 @@ local function make_defaults(lua_version, target_cpu, platforms, home) | |||
| 370 | defaults.variables.LD = "gcc" | 370 | defaults.variables.LD = "gcc" |
| 371 | defaults.gcc_rpath = true | 371 | defaults.gcc_rpath = true |
| 372 | defaults.variables.LIBFLAG = "-shared" | 372 | defaults.variables.LIBFLAG = "-shared" |
| 373 | defaults.variables.TEST = "test" | ||
| 373 | 374 | ||
| 374 | defaults.external_deps_patterns = { | 375 | defaults.external_deps_patterns = { |
| 375 | bin = { "?" }, | 376 | bin = { "?" }, |
diff --git a/src/luarocks/fs/linux.lua b/src/luarocks/fs/linux.lua new file mode 100644 index 00000000..c1b057c2 --- /dev/null +++ b/src/luarocks/fs/linux.lua | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | --- Linux-specific implementation of filesystem and platform abstractions. | ||
| 2 | local linux = {} | ||
| 3 | |||
| 4 | local fs = require("luarocks.fs") | ||
| 5 | local dir = require("luarocks.dir") | ||
| 6 | |||
| 7 | function linux.is_dir(file) | ||
| 8 | file = fs.absolute_name(file) | ||
| 9 | file = dir.normalize(file) .. "/." | ||
| 10 | local fd, _, code = io.open(file, "r") | ||
| 11 | if code == 2 then -- "No such file or directory" | ||
| 12 | return false | ||
| 13 | end | ||
| 14 | if code == 20 then -- "Not a directory", regardless of permissions | ||
| 15 | return false | ||
| 16 | end | ||
| 17 | if code == 13 then -- "Permission denied", but is a directory | ||
| 18 | return true | ||
| 19 | end | ||
| 20 | if fd then | ||
| 21 | local _, _, ecode = fd:read(1) | ||
| 22 | fd:close() | ||
| 23 | if ecode == 21 then -- "Is a directory" | ||
| 24 | return true | ||
| 25 | end | ||
| 26 | end | ||
| 27 | return false | ||
| 28 | end | ||
| 29 | |||
| 30 | function linux.is_file(file) | ||
| 31 | file = fs.absolute_name(file) | ||
| 32 | if fs.is_dir(file) then | ||
| 33 | return false | ||
| 34 | end | ||
| 35 | file = dir.normalize(file) | ||
| 36 | local fd, _, code = io.open(file, "r") | ||
| 37 | if code == 2 then -- "No such file or directory" | ||
| 38 | return false | ||
| 39 | end | ||
| 40 | if code == 13 then -- "Permission denied", but it exists | ||
| 41 | return true | ||
| 42 | end | ||
| 43 | if fd then | ||
| 44 | fd:close() | ||
| 45 | return true | ||
| 46 | end | ||
| 47 | return false | ||
| 48 | end | ||
| 49 | |||
| 50 | return linux | ||
diff --git a/src/luarocks/fs/macosx.lua b/src/luarocks/fs/macosx.lua new file mode 100644 index 00000000..b71e7f12 --- /dev/null +++ b/src/luarocks/fs/macosx.lua | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | --- macOS-specific implementation of filesystem and platform abstractions. | ||
| 2 | local macosx = {} | ||
| 3 | |||
| 4 | local fs = require("luarocks.fs") | ||
| 5 | local dir = require("luarocks.dir") | ||
| 6 | |||
| 7 | function macosx.is_dir(file) | ||
| 8 | file = fs.absolute_name(file) | ||
| 9 | file = dir.normalize(file) .. "/." | ||
| 10 | local fd, _, code = io.open(file, "r") | ||
| 11 | if code == 2 then -- "No such file or directory" | ||
| 12 | return false | ||
| 13 | end | ||
| 14 | if code == 20 then -- "Not a directory", regardless of permissions | ||
| 15 | return false | ||
| 16 | end | ||
| 17 | if code == 13 then -- "Permission denied", but is a directory | ||
| 18 | return true | ||
| 19 | end | ||
| 20 | if fd then | ||
| 21 | local _, _, ecode = fd:read(1) | ||
| 22 | fd:close() | ||
| 23 | if ecode == 21 then -- "Is a directory" | ||
| 24 | return true | ||
| 25 | end | ||
| 26 | end | ||
| 27 | return false | ||
| 28 | end | ||
| 29 | |||
| 30 | function macosx.is_file(file) | ||
| 31 | file = fs.absolute_name(file) | ||
| 32 | if fs.is_dir(file) then | ||
| 33 | return false | ||
| 34 | end | ||
| 35 | file = dir.normalize(file) | ||
| 36 | local fd, _, code = io.open(file, "r") | ||
| 37 | if code == 2 then -- "No such file or directory" | ||
| 38 | return false | ||
| 39 | end | ||
| 40 | if code == 13 then -- "Permission denied", but it exists | ||
| 41 | return true | ||
| 42 | end | ||
| 43 | if fd then | ||
| 44 | fd:close() | ||
| 45 | return true | ||
| 46 | end | ||
| 47 | return false | ||
| 48 | end | ||
| 49 | |||
| 50 | return macosx | ||
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua index 3e05fbf3..92a2dd91 100644 --- a/src/luarocks/fs/unix.lua +++ b/src/luarocks/fs/unix.lua | |||
| @@ -206,49 +206,6 @@ function unix._unix_moderate_permissions(perms) | |||
| 206 | return moderated_perms | 206 | return moderated_perms |
| 207 | end | 207 | end |
| 208 | 208 | ||
| 209 | function unix.is_dir(file) | ||
| 210 | file = fs.absolute_name(file) | ||
| 211 | file = dir.normalize(file) .. "/." | ||
| 212 | local fd, _, code = io.open(file, "r") | ||
| 213 | if code == 2 then -- "No such file or directory" | ||
| 214 | return false | ||
| 215 | end | ||
| 216 | if code == 20 then -- "Not a directory", regardless of permissions | ||
| 217 | return false | ||
| 218 | end | ||
| 219 | if code == 13 then -- "Permission denied", but is a directory | ||
| 220 | return true | ||
| 221 | end | ||
| 222 | if fd then | ||
| 223 | local _, _, ecode = fd:read(1) | ||
| 224 | fd:close() | ||
| 225 | if ecode == 21 then -- "Is a directory" | ||
| 226 | return true | ||
| 227 | end | ||
| 228 | end | ||
| 229 | return false | ||
| 230 | end | ||
| 231 | |||
| 232 | function unix.is_file(file) | ||
| 233 | file = fs.absolute_name(file) | ||
| 234 | if fs.is_dir(file) then | ||
| 235 | return false | ||
| 236 | end | ||
| 237 | file = dir.normalize(file) | ||
| 238 | local fd, _, code = io.open(file, "r") | ||
| 239 | if code == 2 then -- "No such file or directory" | ||
| 240 | return false | ||
| 241 | end | ||
| 242 | if code == 13 then -- "Permission denied", but it exists | ||
| 243 | return true | ||
| 244 | end | ||
| 245 | if fd then | ||
| 246 | fd:close() | ||
| 247 | return true | ||
| 248 | end | ||
| 249 | return false | ||
| 250 | end | ||
| 251 | |||
| 252 | function unix.system_cache_dir() | 209 | function unix.system_cache_dir() |
| 253 | if fs.is_dir("/var/cache") then | 210 | if fs.is_dir("/var/cache") then |
| 254 | return "/var/cache" | 211 | return "/var/cache" |
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index 65b5681c..2e46c19b 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua | |||
| @@ -273,4 +273,28 @@ function tools.make_temp_dir(name_pattern) | |||
| 273 | return nil, "Failed to create temporary directory "..tostring(dirname) | 273 | return nil, "Failed to create temporary directory "..tostring(dirname) |
| 274 | end | 274 | end |
| 275 | 275 | ||
| 276 | --- Test is file/directory exists | ||
| 277 | -- @param file string: filename to test | ||
| 278 | -- @return boolean: true if file exists, false otherwise. | ||
| 279 | function tools.exists(file) | ||
| 280 | assert(file) | ||
| 281 | return fs.execute(vars.TEST, "-e", file) | ||
| 282 | end | ||
| 283 | |||
| 284 | --- Test is pathname is a directory. | ||
| 285 | -- @param file string: pathname to test | ||
| 286 | -- @return boolean: true if it is a directory, false otherwise. | ||
| 287 | function tools.is_dir(file) | ||
| 288 | assert(file) | ||
| 289 | return fs.execute(vars.TEST, "-d", file) | ||
| 290 | end | ||
| 291 | |||
| 292 | --- Test is pathname is a regular file. | ||
| 293 | -- @param file string: pathname to test | ||
| 294 | -- @return boolean: true if it is a regular file, false otherwise. | ||
| 295 | function tools.is_file(file) | ||
| 296 | assert(file) | ||
| 297 | return fs.execute(vars.TEST, "-f", file) | ||
| 298 | end | ||
| 299 | |||
| 276 | return tools | 300 | return tools |
