1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
local P = {}
-- Shell-safe quoting: wraps in single quotes, escapes inner quotes
local function shell_quote(str)
return "'" .. tostring(str):gsub("'", "'\"'\"'") .. "'"
end
-- Build a safe shell command from argv
local function build_cmd(argv)
local quoted = {}
for i, arg in ipairs(argv) do
quoted[i] = shell_quote(arg)
end
return table.concat(quoted, " ")
end
--- Check if a process matching the given pattern is running.
--- Uses `pgrep -f -- <pattern>`
--- @param pattern string
function P.is_running(pattern)
local cmd = build_cmd({ "pgrep", "-f", "--", pattern })
local h = io.popen(cmd)
if not h then
return false
end
local r = h:read("*l")
h:close()
return r ~= nil
end
--- @class waywall
--- @field exec fun(cmd: string): nil
--- wrapper around waywall.exec
--- @param ww waywall
--- @param argv table array-like table of args
--- @return nil
function P.ww_exec_argv(ww, argv)
-- No quoting needed; execvp-style expects raw argv
assert(type(argv) == "table", "argv must be an array-like table of strings")
for i, v in ipairs(argv) do
assert(type(v) == "string", "argv element must be a string")
end
local cmd = table.concat(argv, " ")
return ww.exec(cmd)
end
--- Return a function that starts an application when called.
--- @param ww waywall waywall dependency
--- @param app_path string path to the application executable
--- @param args? string[] optional additional arguments to pass to the application
--- @return fun(): nil
function P.start_application(ww, app_path, args)
return function()
local argv = { app_path }
if args then
for _, a in ipairs(args) do
argv[#argv + 1] = a
end
end
P.ww_exec_argv(ww, argv)(ww, argv)
end
end
--- Ensure an application is running, start it if not.
--- @param ww waywall waywall dependency
--- @param app_path string path to the application executable
--- @param args? string[] optional additional arguments to pass to the application
--- @return fun(pattern: string): fun(): nil
function P.ensure_application(ww, app_path, args)
return function(pattern)
return function()
if not P.is_running(pattern) then
local argv = { app_path }
if args then
for _, a in ipairs(args) do
argv[#argv + 1] = a
end
end
P.ww_exec_argv(ww, argv)
end
end
end
end
--- Ensure a Java JAR is running, start it if not.
--- @param ww waywall
--- @param java_path string path to java executable
--- @param jar_path string path to the JAR file
--- @param args? string[] optional additional arguments to pass to java
--- @return fun(pattern: string): fun(): nil
function P.ensure_java_jar(ww, java_path, jar_path, args)
return function(pattern)
return function()
if not P.is_running(pattern) then
local argv = { java_path }
if args then
for _, a in ipairs(args) do
argv[#argv + 1] = a
end
end
argv[#argv + 1] = "-jar"
argv[#argv + 1] = jar_path
P.ww_exec_argv(ww, argv)
end
end
end
end
return P
|