From 4c650b92ab48b0f50b41f26fbc9e895f34a4fc53 Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Thu, 28 Nov 2013 21:06:40 +0100 Subject: fixes permission checks on Windows with VirtualStore redirection --- src/luarocks/fs/win32.lua | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index 0280b3f0..b6ea25e4 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua @@ -9,6 +9,15 @@ local cfg = require("luarocks.cfg") local dir = require("luarocks.dir") local util = require("luarocks.util") +-- Monkey patch io.popen and os.execute to make sure quoting +-- works as expected. +-- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html +local _prefix = "type NUL && " +local _popen, _execute = io.popen, os.execute +io.popen = function(cmd, ...) return _popen(_prefix..cmd, ...) end +os.execute = function(cmd, ...) return _execute(_prefix..cmd, ...) end + + --- Annotate command string for quiet execution. -- @param cmd string: A command-line string. -- @return string: The command-line, with silencing annotation. @@ -173,3 +182,36 @@ function replace_file(old_file, new_file) return os.rename(new_file, old_file) end +--- Test is file/dir is writable. +-- Warning: testing if a file/dir is writable does not guarantee +-- that it will remain writable and therefore it is no replacement +-- for checking the result of subsequent operations. +-- @param file string: filename to test +-- @return boolean: true if file exists, false otherwise. +function is_writable(file) + assert(file) + file = dir.normalize(file) + local result + local tmpname = 'tmpluarockstestwritable.deleteme' + if fs.is_dir(file) then + local file2 = dir.path(file, tmpname) + local fh = io.open(file2, 'wb') + result = fh ~= nil + if fh then fh:close() end + if result then + -- the above test might give a false positive when writing to + -- c:\program files\ because of VirtualStore redirection on Vista and up + -- So get a directory listing and check whether it's really there + local pipe = io.popen("dir "..fs.Q(file)) + local dir_list = pipe:read("*a") + pipe:close() + result = (nil ~= string.find(dir_list, tmpname, 1, true)) + end + os.remove(file2) + else + local fh = io.open(file, 'r+b') + result = fh ~= nil + if fh then fh:close() end + end + return result +end -- cgit v1.2.3-55-g6feb