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 program, args, input, output, mode = table.unpack(commands[i])
local reason local reason
threads[i], reason = process.load(program, env, function() threads[i], reason = process.load(program, env, function()
os.setenv("_", program)
if input then if input then
local file, reason = io.open(shell.resolve(input)) local file, reason = io.open(shell.resolve(input))
if not file then if not file then
@ -304,9 +305,6 @@ local function execute(env, command, ...)
return false, reason return false, reason
end end
-- TODO needs moving of env vars into process lib/info
-- os.setenv("_", program)
if i < #commands then if i < #commands then
pipes[i] = require("buffer").new("rw", memoryStream.new()) pipes[i] = require("buffer").new("rw", memoryStream.new())
pipes[i]:setvbuf("no") pipes[i]:setvbuf("no")
@ -351,6 +349,15 @@ local function execute(env, command, ...)
end end
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 for _, input in ipairs(inputs) do
input:close() input:close()
end end

View File

@ -8,8 +8,6 @@ local function env()
-- copy parent env when first requested; easiest way to keep things -- copy parent env when first requested; easiest way to keep things
-- like number of env vars trivial (#vars). -- like number of env vars trivial (#vars).
local data = require("process").info().data 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 if not rawget(data, "vars") then
local vars = {} local vars = {}
for k, v in pairs(data.vars or {}) do for k, v in pairs(data.vars or {}) do
@ -17,7 +15,6 @@ local function env()
end end
data.vars = vars data.vars = vars
end end
--]]
data.vars = data.vars or {} data.vars = data.vars or {}
return data.vars return data.vars
end end

View File

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