@@ -39,11 +39,46 @@ RPC = {
3939
4040if RPC .unix then
4141 local temp = os.getenv (' XDG_RUNTIME_DIR' )
42- or os.getenv (' TMPDIR' )
43- or os.getenv (' TMP' )
44- or os.getenv (' TEMP' )
45- or ' /tmp'
42+ or os.getenv (' TMPDIR' )
43+ or os.getenv (' TMP' )
44+ or os.getenv (' TEMP' )
45+ or ' /tmp'
4646 RPC .path = temp .. ' /discord-ipc-0'
47+ if type (jit ) == ' table' then
48+ msg .verbose (' using' , jit .version )
49+ ffi = require (' ffi' )
50+ ffi .cdef [[
51+ struct sockaddr {
52+ unsigned short int sa_family ;
53+ char sa_data [14 ];
54+ };
55+ struct sockaddr_un {
56+ unsigned short int sun_family ;
57+ char sun_path [108 ];
58+ };
59+ int socket (int domain , int type , int protocol );
60+ int connect (int fd , const struct sockaddr * addr , unsigned int len );
61+ int recv (int fd , void * buf , unsigned int len , int flags );
62+ int send (int fd , const void * buf , unsigned int n , int flags );
63+ int close (int fd );
64+ char *strerror (int errnum );
65+ ]]
66+ function _strerror ()
67+ return ffi .string (ffi .C .strerror (ffi .errno ()))
68+ end
69+ function _connect (fd , addr )
70+ local cast = ffi .cast (' const struct sockaddr *' , addr )
71+ return ffi .C .connect (fd , cast , ffi .sizeof (addr [0 ]))
72+ end
73+ function _recv (fd , len )
74+ local buff = ffi .new (' unsigned char[?]' , len )
75+ local status = ffi .C .recv (fd , buff , len , 0 ) ~= - 1
76+ return status , status and ffi .string (buff , len ) or _strerror ()
77+ end
78+ else
79+ local socket = assert (require ' socket' )
80+ msg .verbose (' using' , socket ._VERSION )
81+ end
4782else
4883 RPC .path = [[ \\?\pipe\discord-ipc-0]]
4984end
102137
103138function RPC :connect ()
104139 local status , data
105- if self .unix then
106- self .socket = assert (require ' socket.unix' ())
140+ if ffi then
141+ local addr = ffi .new (' struct sockaddr_un[1]' , {{
142+ sun_family = 1 , -- AF_UNIX
143+ sun_path = self .path
144+ }})
145+ self .socket = ffi .C .socket (1 , 1 , 0 ) -- AF_UNIX, SOCK_STREAM
146+ if self .socket ~= - 1 then
147+ status = _connect (self .socket , addr )
148+ if status ~= - 1 then return true end
149+ end
150+ data = _strerror ()
151+ elseif self .unix then
152+ self .socket = require ' socket.unix' ()
107153 status , data = pcall (function ()
108154 assert (self .socket :connect (self .path ))
109155 end )
@@ -125,7 +171,9 @@ function RPC:recv(len)
125171 assert (self :connect (), ' failed to connect' )
126172 end
127173 local status , data
128- if self .unix then
174+ if ffi then
175+ status , data = _recv (self .socket , len )
176+ elseif self .unix then
129177 status , data = pcall (function ()
130178 return assert (self .socket :receive (len ))
131179 end )
@@ -149,7 +197,10 @@ function RPC:send(op, body)
149197 end
150198 local data = self .pack (op , body )
151199 msg .debug (' sending' , data :tohex ())
152- if self .unix then
200+ if ffi then
201+ local status = ffi .C .send (self .socket , data , # data , 0 )
202+ assert (status ~= - 1 , _strerror ())
203+ elseif self .unix then
153204 assert (self .socket :send (data ))
154205 else
155206 assert (self .socket :write (data ))
203254function RPC :disconnect ()
204255 if self .socket then
205256 self :send (OP .CLOSE , ' ' )
206- self .socket :close ()
257+ if ffi then
258+ local status = ffi .C .close (self .socket )
259+ assert (status ~= - 1 , _strerror ())
260+ else
261+ self .socket :close ()
262+ end
207263 self .socket = nil
208264 end
209265end
0 commit comments