commit ffb747b8b5c7a877d3f0846833942f0f1340a4e0
parent c532d46cafe0f7e2f873289b35bb1c38d8c794f8
Author: aabacchus <ben@bvnf.space>
Date: Wed, 14 Jun 2023 03:50:41 +0100
make dirs and add pkg_clean traps
to implement the EXIT handler, a finalizer (__gc) is used. This adds the
requirements of 1) keeping a reference to atexit throughout the program,
2) always calling os.exit with the second argument as true (so that the Lua
state is properly closed and finalizers run). To achieve (2), monkey-patch
os.exit.
Diffstat:
4 files changed, 85 insertions(+), 24 deletions(-)
diff --git a/bliss/list.lua b/bliss/list.lua
@@ -4,7 +4,7 @@ local dirent = require 'posix.dirent'
local function list(env, arg)
if #arg == 0 then
- for file in dirent.files(env.pkg_db) do
+ for file in dirent.files(env.sys_db) do
if string.sub(file, 1, 1) ~= '.' then
table.insert(arg, file)
end
@@ -12,7 +12,7 @@ local function list(env, arg)
table.sort(arg)
end
for _,a in ipairs(arg) do
- local ver = pkg.find_version(a, {env.pkg_db})
+ local ver = pkg.find_version(a, {env.sys_db})
io.write(string.format("%s %s-%s\n", a, ver[1], ver[2]))
end
end
diff --git a/bliss/search.lua b/bliss/search.lua
@@ -4,9 +4,9 @@ local sys_stat = require 'posix.sys.stat'
local function search(env, arg)
- -- append pkg_db to search path
+ -- append sys_db to search path
local path = utils.shallowcopy(env.PATH)
- table.insert(path, env.pkg_db)
+ table.insert(path, env.sys_db)
for _, a in ipairs(arg) do
local res = {}
diff --git a/bliss/utils.lua b/bliss/utils.lua
@@ -1,39 +1,65 @@
-- Copyright 2023 phoebos
local sys_stat = require 'posix.sys.stat'
local unistd = require 'posix.unistd'
+local signal = require 'posix.signal'
local colors = {"", "", ""}
-local setup, setup_colors, check_execute, get_available, split, mkdirp, log, warn, die, run, capture, shallowcopy
+local setup, setup_colors, check_execute, get_available, trap_on, trap_off, split, mkdirp, rm_rf, log, warn, die, run, capture, shallowcopy
function setup()
colors = setup_colors()
check_execute()
local env = {
+ _LVL = 1 + (os.getenv("_KISS_LVL") or 0),
CHK = os.getenv("KISS_CHK")
or get_available("openssl", "sha256sum", "sha256", "shasum", "digest")
or warn("No sha256 utility found"),
COMPRESS= os.getenv("KISS_COMPRESS") or "gz",
- DEBUG = os.getenv("KISS_DEBUG"),
- FORCE = os.getenv("KISS_FORCE"),
+ DEBUG = os.getenv("KISS_DEBUG") or 0,
+ FORCE = os.getenv("KISS_FORCE") or 0,
GET = os.getenv("KISS_GET")
or get_available("aria2c", "axel", "curl", "wget", "wget2")
or warn("No download utility found (aria2c, axel, curl, wget, wget2"),
HOOK = split(os.getenv("KISS_HOOK"), ':'),
- KEEPLOG = os.getenv("KISS_KEEPLOG"),
+ KEEPLOG = os.getenv("KISS_KEEPLOG") or 0,
PATH = split(os.getenv("KISS_PATH"), ':'),
PID = os.getenv("KISS_PID") or unistd.getpid(),
- PROMPT = os.getenv("KISS_PROMPT"),
+ PROMPT = os.getenv("KISS_PROMPT") or 1,
ROOT = os.getenv("KISS_ROOT") or "",
SU = os.getenv("KISS_SU") or get_available("ssu", "sudo", "doas", "su"),
TMPDIR = os.getenv("KISS_TMPDIR"),
time = os.date("%Y-%m-%d-%H:%M"),
}
- -- pkg_db depends on ROOT so must be set after env is constructed
- env.pkg_db = env.ROOT .. "/var/db/kiss/installed"
+ -- sys_db depends on ROOT so must be set after env is constructed
+ env.pkg_db = "var/db/kiss/installed"
+ env.cho_db = "var/db/kiss/choices"
+ env.sys_db = env.ROOT .. "/" .. env.pkg_db
+ env.sys_ch = env.ROOT .. "/" .. env.cho_db
+
+ env.cac_dir = (os.getenv("XDG_CACHE_HOME") or (os.getenv("HOME") .. "/.cache")) .. "/kiss"
+ env.src_dir = env.cac_dir .. "/sources"
+ env.log_dir = env.cac_dir .. "/logs/" .. string.sub(env.time, 1, 10)
+ env.bin_dir = env.cac_dir .. "/bin"
+
+ env.TMPDIR = env.TMPDIR or (env.cac_dir .. "/proc")
+ env.proc = env.TMPDIR .. '/' .. env.PID
+
+ env.mak_dir = env.proc .. "/build"
+ env.pkg_dir = env.proc .. "/pkg"
+ env.tar_dir = env.proc .. "/extract"
+ env.tmp_dir = env.proc .. "/tmp"
mkdirp(env.ROOT .. '/')
- return env
+ mkdirp(env.src_dir, env.log_dir, env.bin_dir,
+ env.mak_dir, env.pkg_dir, env.tar_dir, env.tmp_dir)
+
+ -- make sure os.exit always closes the Lua state
+ local o = os.exit
+ os.exit = function(code, close) o(code, not close) end
+
+ local atexit = trap_on(env)
+ return env, atexit
end
function setup_colors()
@@ -60,6 +86,31 @@ function get_available(...)
return nil
end
+function trap_on(env)
+ signal.signal(signal.SIGINT, function () os.exit(false) end)
+ -- use a finalizer to get pkg_clean to run on EXIT. A reference to atexit must
+ -- be kept for the whole duration of the program (should it be a global?)
+ local atexit = setmetatable({}, {__gc = get_pkg_clean(env)})
+ return atexit
+end
+
+function trap_off(atexit)
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+ setmetatable(atexit, {})
+end
+
+-- returns a function with cached env so that it can be called without args or globals.
+function get_pkg_clean(env)
+ return function ()
+ if env.DEBUG ~= 0 then return end
+ if env._LVL == 1 then
+ rm_rf(env.proc)
+ else
+ rm_rf(env.tar_dir)
+ end
+ end
+end
+
function split(s, sep)
local c = {}
for a in string.gmatch(s, "[^%s"..sep.."]+") do
@@ -68,21 +119,28 @@ function split(s, sep)
return c
end
-function mkdirp(path)
- assert(string.sub(path, 1, 1) == '/')
- local t = split(path, '/')
- local p = ''
- for _, v in ipairs(t) do
- p = p .. '/' .. v
-
- local sb = sys_stat.stat(p)
- if not sb then
- local c, msg = sys_stat.mkdir(p)
- if not c then die("mkdir " .. msg) end
+function mkdirp(...)
+ for i = 1, select('#', ...) do
+ local path = select(i, ...)
+ assert(string.sub(path, 1, 1) == '/')
+ local t = split(path, '/')
+ local p = ''
+ for _, v in ipairs(t) do
+ p = p .. '/' .. v
+
+ local sb = sys_stat.stat(p)
+ if not sb then
+ local c, msg = sys_stat.mkdir(p)
+ if not c then die("mkdir " .. msg) end
+ end
end
end
end
+function rm_rf(path)
+ os.execute("rm -rf \"" .. path .. "\"")
+end
+
function log(name, msg, category)
-- This is a direct translation of kiss's log(). Quite hacky.
io.stderr:write(string.format("%s%s %s%s%s %s\n",
@@ -128,8 +186,11 @@ end
local M = {
setup = setup,
+ trap_on = trap_on,
+ trap_off = trap_off,
split = split,
mkdirp = mkdirp,
+ rm_rf = rm_rf,
log = log,
warn = warn,
die = die,
diff --git a/main.lua b/main.lua
@@ -55,5 +55,5 @@ local function args(arg)
end
end
-env = bliss.setup()
+env, atexit = bliss.setup()
args(arg)