]> gitweb.fluxo.info Git - awesompd.git/commitdiff
Add asyncshell.lua to the repo
authorAlexander Yakushev <yakushev.alex@gmail.com>
Sat, 21 Jan 2012 10:22:46 +0000 (12:22 +0200)
committerAlexander Yakushev <yakushev.alex@gmail.com>
Sat, 21 Jan 2012 10:22:46 +0000 (12:22 +0200)
asyncshell.lua [new file with mode: 0644]

diff --git a/asyncshell.lua b/asyncshell.lua
new file mode 100644 (file)
index 0000000..63234c6
--- /dev/null
@@ -0,0 +1,63 @@
+-- Asynchronous io.popen for Awesome WM.
+-- How to use...
+-- ...asynchronously:
+-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
+-- ...synchronously
+-- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error"
+
+asyncshell = {}
+asyncshell.request_table = {}
+asyncshell.id_counter = 0
+asyncshell.file_template = '/tmp/asyncshellreq'
+
+os.execute('rm -f /tmp/myaw2.log')
+local nprint = function(t) os.execute("echo '" .. t .. "' >> /tmp/myaw2.log") end
+
+-- Returns next tag - unique identifier of the request
+local function next_id()
+   asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000
+   return asyncshell.id_counter
+end
+
+-- Sends an asynchronous request for an output of the shell command.
+-- @param command Command to be executed and taken output from
+-- @param callback Function of one argument to be called when the command finishes
+-- @return Request ID
+function asyncshell.request(command, callback)
+   local id = next_id()
+   local tmpfname = asyncshell.file_template .. id
+   asyncshell.request_table[id] = {callback = callback}
+   local req = 
+      string.format("bash -c '%s > %s; " ..
+                    'echo "asyncshell.deliver(%s)" | ' ..
+                    "awesome-client'", string.gsub(command, "'", "'\\''"), tmpfname, id, tmpfname)
+   awful.util.spawn(req)
+   return id
+end
+
+-- Calls the remembered callback function on the output of the shell
+-- command.
+-- @param id Request ID
+-- @param output The output file of the shell command to be delievered
+function asyncshell.deliver(id)
+   if asyncshell.request_table[id] then
+      local output = io.open(asyncshell.file_template .. id, 'r')
+      asyncshell.request_table[id].callback(output)
+   end
+end
+
+-- Sends a synchronous request for an output of the command. Waits for
+-- the output, but if the given timeout expires returns nil.
+-- @param command Command to be executed and taken output from
+-- @param timeout Maximum amount of time to wait for the result
+-- @return File handler on success, nil otherwise
+function asyncshell.demand(command, timeout)
+   local id = next_id()
+   local tmpfname = asyncshell.file_template .. id
+   local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & (sleep %s; echo asynchell_timeout)",
+                                    command, tmpfname, timeout))
+   local result = f:read("*line")
+   if result == "asyncshell_done" then
+      return io.open(tmpfname)
+   end
+end
\ No newline at end of file