Created
January 23, 2022 17:29
-
-
Save truemedian/0f19ff91909e06f055faa7a0d89288c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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