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
|
local lgi = require("lgi")
local Gio = lgi.require("Gio")
local GLib = lgi.require("GLib")
-- Workaround for https://github.com/pavouk/lgi/issues/142
local function bus_get_async(type)
Gio.bus_get(type, nil, coroutine.running())
local a, b = coroutine.yield()
return Gio.bus_get_finish(b)
end
local function inhibit(bus, what, who, why, mode)
local name = "org.freedesktop.login1"
local object = "/org/freedesktop/login1"
local interface = "org.freedesktop.login1.Manager"
local message = Gio.DBusMessage.new_method_call(name, object, interface, "Inhibit")
message:set_body(GLib.Variant("(ssss)",
{ what, who, why, mode }))
local timeout = -1 -- Just use the default
local result, err = bus:async_send_message_with_reply(message, Gio.DBusSendMessageFlags.NONE,
timeout, nil)
if err then
print("error: " .. tostring(err))
return
end
if result:get_message_type() == "ERROR" then
local _, err = result:to_gerror()
print("error: " .. tostring(err))
return
end
local fd_list = result:get_unix_fd_list()
local fd, err = fd_list:get(0)
if err then
print("error: " .. tostring(err))
return
end
-- Now... somehow turn this fd into something we can close
return Gio.UnixInputStream.new(fd, true)
end
Gio.Async.call(function()
local bus = bus_get_async(Gio.BusType.SYSTEM)
local a = inhibit(bus, "shutdown:sleep", "hi, it's me!", "Just because", "delay")
print("got lock")
io.popen("sleep 10"):read("*a")
a:async_close()
-- Speed up deletion of the GDBusMessage that still references the FD
collectgarbage("collect")
collectgarbage("collect")
print("released lock")
io.popen("sleep 10"):read("*a")
end)()
|