Skip to content

Instantly share code, notes, and snippets.

@truemedian
Created January 23, 2022 17:29
Show Gist options
  • Save truemedian/0f19ff91909e06f055faa7a0d89288c3 to your computer and use it in GitHub Desktop.
Save truemedian/0f19ff91909e06f055faa7a0d89288c3 to your computer and use it in GitHub Desktop.
local ffi = require 'ffi'
local fs = require 'fs'
local Process = {}
Process.__index = Process
if ffi.abi('win') then
local psapi = ffi.load('psapi')
ffi.cdef [[
void* OpenProcess(unsigned long access, int inherit, unsigned long pid);
unsigned long GetProcessImageFileNameA(void* process, char* image_file_name, unsigned long size);
int CloseHandle(void* handle);
]]
local PROCESS_QUERY_INFORMATION = 0x0400
function Process.new(pid)
local handle = ffi.C.OpenProcess(PROCESS_QUERY_INFORMATION, false, pid)
local self = setmetatable({}, Process)
self.inner = handle
ffi.gc(self.inner, Process.destroy)
return self
end
function Process:destroy()
ffi.C.CloseHandle(self.inner)
end
function Process:getName()
local name_buffer = ffi.new('char[?]', 260);
local len = psapi.GetProcessImageFileNameA(self.inner, name_buffer, 260)
local full_path = ffi.string(name_buffer, len);
local process_name = full_path:match('\\([^\\]+)$', 1) or full_path
return process_name
end
elseif ffi.os == 'Linux' then
function Process.new(pid)
local self = setmetatable({}, Process)
self.inner = pid
return self
end
function Process:destroy()
end
function Process:getName()
local cmdline = fs.readFileSync('/proc/' .. self.inner .. '/cmdline')
local first_sep = cmdline:find('\0', 1, true)
return cmdline:sub(1, first_sep - 1)
end
else
-- untested
ffi.cdef [[
int sysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen);
int sysctlnametomib(const char *name, int *mib, size_t *miblen);
]]
function Process.new(pid)
local self = setmetatable({}, Process)
self.inner = pid
-- ffi.gc(self.inner, Process.destroy)
return self
end
function Process:destroy()
end
function Process:getName()
local mib = ffi.new('int[?]', 4)
local miblen = ffi.new('size_t[1]', 4)
local name_buffer = ffi.new('char[?]', 256)
local name_buffer_len = ffi.new('size_t[1]', 256)
ffi.C.sysctlnametomib("kern.proc.args", mib, miblen)
mib[3] = self.inner
-- should we allocate the whole args buffer?
ffi.C.sysctl(mib, 4, name_buffer, name_buffer_len, nil, 0)
return ffi.string(name_buffer, name_buffer_len[0])
end
end
return Process
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment