Made env variables local (i.e. os.getenv/setenv will operate per process now), to avoid programs running in parallel (via piping) to interfere.

Copying env vars from last process to shell's env to avoid breaking compat. (cd.lua will still work that way, e.g.)
Closes #634.
This commit is contained in:
Florian Nücke 2015-04-22 11:22:14 +02:00
parent 6377a5824f
commit 76172d0dfb
3 changed files with 21 additions and 12 deletions

View File

@ -266,6 +266,7 @@ local function execute(env, command, ...)
local program, args, input, output, mode = table.unpack(commands[i])
local reason
threads[i], reason = process.load(program, env, function()
os.setenv("_", program)
if input then
local file, reason = io.open(shell.resolve(input))
if not file then
@ -304,9 +305,6 @@ local function execute(env, command, ...)
return false, reason
end
-- TODO needs moving of env vars into process lib/info
-- os.setenv("_", program)
if i < #commands then
pipes[i] = require("buffer").new("rw", memoryStream.new())
pipes[i]:setvbuf("no")
@ -351,6 +349,15 @@ local function execute(env, command, ...)
end
end
-- copy env vars from last process; mostly to ensure stuff like cd.lua works
local lastVars = rawget(process.info(threads[#threads]).data, "vars")
if lastVars then
local localVars = process.info().data.vars
for k,v in pairs(lastVars) do
localVars[k] = v
end
end
for _, input in ipairs(inputs) do
input:close()
end

View File

@ -8,8 +8,6 @@ local function env()
-- copy parent env when first requested; easiest way to keep things
-- like number of env vars trivial (#vars).
local data = require("process").info().data
--[[ TODO breaking change; will require set to be a shell built-in and
may break other programs relying on setenv being global.
if not rawget(data, "vars") then
local vars = {}
for k, v in pairs(data.vars or {}) do
@ -17,7 +15,6 @@ local function env()
end
data.vars = vars
end
--]]
data.vars = data.vars or {}
return data.vars
end

View File

@ -83,13 +83,18 @@ function process.running(level) -- kept for backwards compat, prefer process.inf
end
end
function process.info(level)
level = level or 1
local process = findProcess()
function process.info(levelOrThread)
local process
if type(levelOrThread) == "thread" then
process = findProcess(levelOrThread)
else
local level = levelOrThread or 1
process = findProcess()
while level > 1 and process do
process = process.parent
level = level - 1
end
end
if process then
return {path=process.path, env=process.env, command=process.command, data=process.data}
end