diff --git a/.vscode/settings.json b/.vscode/settings.json index 844e796..faf551b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,9 @@ "syscalls.h": "c", "registers.h": "c", "version_type.h": "c", - "library_version.h": "c" + "library_version.h": "c", + "scancodes.h": "c", + "ipc.h": "c" }, "cSpell.words": [ "syscalls", @@ -30,6 +32,7 @@ "luaL_checkudata", "luaL_optinteger", "luaL_pushfail", + "lua_pushlightuserdata", "lua_pushboolean", "lua_pushinteger", "lua_pushnumber", diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..63afc54 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,30 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build", + "type": "process", + "command": "make", + "args": [ + "syscalls.dll" + ], + "group": { + "isDefault": true, + "kind": "build" + }, + "problemMatcher": "$gcc" + }, + { + "label": "Clean", + "type": "process", + "command": "make", + "args": [ + "clean" + ], + "group": { + "isDefault": false, + "kind": "build" + } + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index f1868a4..cd14c8d 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ KOLIBRIOS_REPO = $(abspath ../kolibrios) SDK_DIR = $(KOLIBRIOS_REPO)/contrib/sdk NewLib_DIR = $(SDK_DIR)/sources/newlib -SYSCFLAGS = -fno-ident -fomit-frame-pointer -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -I$(NewLib_DIR)/libc/include -I$(TOOLCHAIN_PATH)/include/lua$(LUA_V) +SYSCFLAGS = -fno-ident -fomit-frame-pointer -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -I$(NewLib_DIR)/libc/include -I$(TOOLCHAIN_PATH)/include -I$(TOOLCHAIN_PATH)/include/lua$(LUA_V) SYSLIBS = -L $(SDK_DIR)/lib -lgcc -lc.dll -ldll MYCFLAGS = MYLDFLAGS = @@ -35,10 +35,11 @@ MYOBJS = Socket_O = src/sockets/socket.o src/sockets/socket_lua.o src/sockets/sockaddr.o +IPC_O = src/IPC/ipc.o src/IPC/IPC_msg.o src/IPC/IPC_buffer.o Debug_O = src/debug/debug.o src/debug/registers.o Version_O = src/version/coreversion.o src/version/version_type.o -ALL_O = src/syscalls.o src/ARP_entry.o src/systemColors.o src/graphic.o $(Socket_O) $(Debug_O) $(Version_O) src/background/background.o +ALL_O = src/syscalls.o src/ARP_entry.o src/systemColors.o src/graphic.o $(Socket_O) $(Debug_O) $(Version_O) $(IPC_O) src/background/background.o syscalls.dll: $(ALL_O) $(LD) -shared -T dll.lds --entry _DllStartup $(LDFLAGS) -o $@ $(ALL_O) $(LIBS) @@ -50,7 +51,9 @@ clean: ## Sources -src/syscalls.o: src/syscalls.c src/syscalls.h src/systemColors.h src/ARP_entry.h src/scancodes.h src/sockets/socket_lua.h src/graphic.h src/version/library_version.h +IPC_H = src/IPC/IPC_msg.h src/IPC/IPC_buffer.h src/IPC/ipc.h + +src/syscalls.o: src/syscalls.c src/syscalls.h src/systemColors.h src/ARP_entry.h src/scancodes.h src/sockets/socket_lua.h src/graphic.h src/version/library_version.h $(IPC_H) src/ARP_entry.o: src/ARP_entry.c src/ARP_entry.h src/debug.h src/systemColors.o: src/systemColors.c src/systemColors.h src/debug.h src/sockets/socket.o: src/sockets/socket.c src/sockets/socket.h @@ -58,10 +61,13 @@ src/sockets/socket_lua.o: src/sockets/socket_lua.c src/sockets/socket_lua.h src/sockets/sockaddr.o: src/sockets/sockaddr.c src/sockets/sockaddr.h src/graphic.o: src/graphic.c src/graphic.h src/debug/debug.o: src/debug/debug.c src/debug/debug.h src/debug/registers.h +src/IPC/ipc.o: src/IPC/ipc.c src/IPC/ipc.h src/IPC/IPC_msg.h +src/IPC/IPC_msg.o: src/IPC/IPC_msg.c src/IPC/IPC_msg.h +src/IPC/IPC_buffer.o: src/IPC/IPC_buffer.c src/IPC/IPC_buffer.h src/IPC/IPC_msg.h src/debug/registers.o: src/debug/registers.c src/debug/registers.h src/syscalls.h src/debug.h src/version/coreversion.o: src/version/coreversion.c src/version/coreversion.h src/version/version_type.o: src/version/version_type.c src/version/version_type.h src/debug.h -src/background/background.o: src/background/background.c src/background/background.h +src/background/background.o: src/background/background.c src/background/background.h ## headers @@ -70,6 +76,9 @@ src/sockets/socket_lua.h: src/syscalls.h src/sockets/socket.h src/sockets/sockaddr.h: src/sockets/socket.h src/syscalls.h src/debug/debug.h: src/syscalls.h src/debug/registers.h: src/syscalls.h +src/IPC/IPC_msg.h: src/syscalls.h +src/IPC/IPC_buffer.h: src/syscalls.h +src/IPC/ipc.h: src/syscalls.h src/version/coreversion.h: src/version/version_type.h src/version/version_type.h: src/syscalls.h -src/background/background.h: src/syscalls.h +src/background/background.h: src/syscalls.h diff --git a/doc/manual.md b/doc/manual.md index 008b973..84d88b1 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4,24 +4,24 @@ This is KolibriOS lua syscalls library. Usually you shouldn't use this library Better if you read before [KolibriOS syscalls wiki](http://wiki.kolibrios.org/wiki/) -include: +include this library: ```lua local syscalls = require("syscalls") ``` ## Events -### `SetEventMask(newMask)` +### SetEventMask(newMask) -### `CheckEvent()` +### CheckEvent() -check event +check [event](#events-list) -### `WaitEvent()` +### WaitEvent() -Endless wait event +Endless wait [event](#events-list) -### `WaitEventTimeout(timeout)` +### WaitEventTimeout(timeout) Wait timeout 1/100 sec @@ -44,37 +44,37 @@ syscalls.Event. ## Window -### `CreateWindow(x, y, width, height, workColor, style, borderColor, titleColor)` +### CreateWindow(x, y, width, height, workColor, [style](#window-style), borderColor, titleColor) Define window -`borderColor` and `borderColor` only for `FixSizes` and `CanChangeSizes` (without skin styles) style. +`borderColor` and borderColor` only for FixSizes` and CanChangeSizes` (without skin styles) style. -### `StartRedraw()` +### StartRedraw() -Start window redraw. Just call it before `CreateWindow` +Start window redraw. Just call it before CreateWindow` -### `EndRedraw()` +### EndRedraw() End window redraw. Just call it after you done redraw window. -### `ChangeWindow(newX, newY, newWidth, newHeight)` +### ChangeWindow(newX, newY, newWidth, newHeight) -### `FocusWindow(slot)` +### FocusWindow(slot) -### `UnfocusWindow(slot)` +### UnfocusWindow(slot) -### `SetWindowTitle(newTitle)` +### SetWindowTitle(newTitle) -### `GetSkinHeight()` +### GetSkinHeight() return skin height. -### `SetSkin(path)` +### SetSkin(path) return error code -### `GetSkinTitleArea()` +### GetSkinTitleArea() return table: ```lua @@ -86,7 +86,7 @@ return table: } ``` -### Style +### Window Style ```lua syscalls.windowStyle. @@ -134,34 +134,35 @@ syscalls.textSize. + `56x112` + `64x128` -### `DrawText(text, xPos, yPos, textColor, textScale, textLen, backgroundColor, encoding)` +### DrawText(text, xPos, yPos, textColor, [textScale](#text-sizes), textLen, backgroundColor, [encoding](#text-encoding)) -### `DrawTextFixSize(text, xPos, yPos, textColor, textSize, textLen, backgroundColor, encoding)` +### DrawTextFixSize(text, xPos, yPos, textColor, [textScale](#text-sizes), textLen, backgroundColor, [encoding](#text-encoding)) Draw text. textSize, textLen, backgroundColor, encoding are optional. -### `DrawLine(x1, y1, x2, y2)` +### DrawLine(x1, y1, x2, y2) -### `DrawRectangle(x, y, widht, height, color)` +### DrawRectangle(x, y, width, height, color) -### `ReadPoint(x, y)` +### ReadPoint(x, y) return color ## Buttons -### `DefineButton(x, y, widht, height, id, color)` +### DefineButton(x, y, width, height, id, color) -### `DeleteButton(id)` +### DeleteButton(id) -### `GetButton()` +### GetButton() return pressed button or `nil` -### `SetButtonStyle(style)` +### SetButtonStyle([style](#button-styles)) +Set buttons style ### buttons @@ -174,20 +175,23 @@ syscalls.buttons. + `close` + `minimization` -### ButtonStyles +### Button styles ```lua syscalls.buttonStyle. ``` ++ `Flat` ++ `Volume` + ## Keyboard -### `GetKey()` +### GetKey() return: -+ nil if buffer empty ++ `nil` if buffer empty + if hotkey return second number -+ if key pressed and key input mode is ascii return string(1 char), else return scancode ++ if key pressed and key input mode is ascii return string(1 char), else return [scancode](#scancodes) example: @@ -199,15 +203,15 @@ if key then end if hotkey then - print(hotkey pressed) + print("hotkey pressed") end ``` -### `SetKeyInputMode(mode)` +### SetKeyInputMode(mode) by default is `ASCII` -### `GetKeyInputMode()` +### GetKeyInputMode() return key input mode. @@ -310,17 +314,18 @@ syscalls.SystemColors.new( ) ``` -### `GetSystemColors()` +### GetSystemColors() -return SystemColors +return [SystemColors](#systemcolors-type) -### `SetSystemColors(SystemColors)` +### SetSystemColors([SystemColors](#systemcolors-type)) ## Threads -### `ThreadInfo(pid)` +### ThreadInfo(pid) return table: + ```lua { name: string, @@ -339,7 +344,7 @@ return table: } ``` -### `KillBySlot(slot)` +### KillBySlot(slot) ### Slot states @@ -357,7 +362,9 @@ syscalls.slotState. ## Sockets -### `OpenSocket(domain, type, protocol)` +### OpenSocket([domain](#socket-types), [type](#address-families), [protocol](#ip-protocols)) + +return socket ```lua local socket, err = syscalls.OpenSocket( @@ -373,9 +380,9 @@ else end ``` -### `CloseSocket(socket)` +### CloseSocket(socket) -### `PairSocket()` +### PairSocket() ```lua local first, second = PairSocket() @@ -387,19 +394,19 @@ else end ``` -### `Bind(socket, address)` +### Bind(socket, address) -### `Listen(socket, backlog)` +### Listen(socket, backlog) -### `Connect(socket, address)` +### Connect(socket, address) -### `Accept(socket, , flags)` +### Accept(socket, , flags) -### `Receive(socket, , flags)` +### Receive(socket, , flags) -### `SetSocketOption(socket, opt)` +### SetSocketOption(socket, [opt](#socket-options)) -### `GetSocketOption(socket, opt)` +### GetSocketOption(socket, [opt](#socket-options)) ### Socket types @@ -468,53 +475,116 @@ syscalls.SO. } ``` -### `DebugPutc(char)` +### DebugPutc(char) Put char to debug board -### `DebugPuts(text)` +### DebugPuts(text) Put string to debug board -### `GetRegisters(pid)` +### GetRegisters(pid) The process must be loaded for debugging (as stated in the general description). return registers table -### `SetRegisters(pid, registers)` +### SetRegisters(pid, [registers](#registers-type)) The process must be loaded for debugging (as stated in the general description). -### `Disconnect(pid)` +### Disconnect(pid) The process must be loaded for debugging (as stated in the general description). If the process was suspended, it resumes execution. -### `Stop(pid)` +### Stop(pid) The process must be loaded for debugging (as stated in the general description). -### `Continue(pid)` +### Continue(pid) The process must be loaded for debugging (as stated in the general description). -### `ReadFromMem(pid, bytes, pointer, buffer)` +### ReadFromMem(pid, bytes, pointer, buffer) The process must be loaded for debugging (as stated in the general description). return or `nil` -### `WriteToMem(pid, bytes, pointer, buffer)` +### WriteToMem(pid, bytes, pointer, buffer) The process must be loaded for debugging (as stated in the general description). return or `nil` -### `Done(pid)` +### Done(pid) -### `DefineBreakpoint(pid, index, condition, len)` +### DefineBreakpoint(pid, index, condition, len) -### `UndefBreakpoint(pid, index, condition, len)` +### UndefBreakpoint(pid, index, condition, len) +## IPC + +### DefineIPCBuffer(size) + +Define buffer for IPC receive + +Return [buffer](#ipc_buffer) type + +### SendIPCMessage(pid, [message](#ipc_msg)) + +Send message to process by pid + +return [Error code](#ipc-error-codes) + +### IPC Error codes + +```lua +syscalls.IPCError. +``` + ++ `Ok` ++ `BufferLocked` ++ `BufferNotDefined` ++ `BufferOverflow` ++ `PIDNotExist` + +### IPC_buffer + +```lua +{ + used: number, + lock: boolean, + Lock: (self: IPC_buffer) -> nil + Unlock: (self: IPC_buffer) -> nil + GetMessage: (self: IPC_buffer, i: number) -> IPC_msg + GetLastMessage: (self: IPC_buffer) -> IPC_msg +} +``` + +#### Lock(self) + +Lock buffer + +#### Unlock(self) + +Unlock buffer + +#### GetMessage(self, i) + +return [message](#ipc_msg) that were send by number i + +#### GetLastMessage(self) + +return last sended [message](#ipc_msg) + +### IPC_msg + +```lua +{ + pid: number, + size: number +} +``` \ No newline at end of file diff --git a/lua b/lua new file mode 160000 index 0000000..eae2ea0 --- /dev/null +++ b/lua @@ -0,0 +1 @@ +Subproject commit eae2ea0aaa2c4d0ad9e9c5c6594f9b2378971ced diff --git a/src/ARP_entry.c b/src/ARP_entry.c index f2443b0..258c437 100644 --- a/src/ARP_entry.c +++ b/src/ARP_entry.c @@ -33,7 +33,7 @@ int syscalls_indexARPEntry(lua_State* L) else if (strcmp(index, "MAC") == 0) { char str[7]; - memset(str, entry->MAC, 6); + memcpy(str, &entry->MAC, 6); str[6] = '\n'; lua_pushstring(L, str); } @@ -79,7 +79,7 @@ int syscalls_newindexARPEntry(lua_State* L) } else { - _ksys_debug_puts("err\n"); + luaL_error(L, "wrong index: %s", index); } return 0; diff --git a/src/ARP_entry.h b/src/ARP_entry.h index 090ccd9..97b6979 100644 --- a/src/ARP_entry.h +++ b/src/ARP_entry.h @@ -10,7 +10,7 @@ struct ARP_entry { uint32_t IP; - char MAC[6]; + uint8_t MAC[6]; uint16_t Status; uint16_t TTL; }; diff --git a/src/IPC/IPC_buffer.c b/src/IPC/IPC_buffer.c new file mode 100644 index 0000000..164ebff --- /dev/null +++ b/src/IPC/IPC_buffer.c @@ -0,0 +1,244 @@ +#include "IPC_buffer.h" +#include "IPC_msg.h" +#include +#include "../debug.h" +#include + + + +static int syscalls_indexIPC_buffer(lua_State* L) +{ + struct IPC_buffer* r = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + const char* index = luaL_checkstring(L, 2); + + if (strcmp(index, "used") == 0) + { + lua_pushinteger(L, r->used); + } + else if (strcmp(index, "lock") == 0) + { + lua_pushboolean(L, r->lock); + } + else if (strcmp(index, "size") == 0) + { + lua_pushinteger(L, r->size); + } + else + { + lua_pushnil(L); + } + + return 1; +} + +static int syscalls_newindexIPC_buffer(lua_State* L) +{ + struct IPC_buffer* r = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + const char* index = luaL_checkstring(L, 2); + int val = luaL_checkinteger(L, 3); + + if (strcmp(index, "used") == 0) + { + r->used = val; + } + else if (strcmp(index, "lock") == 0) + { + r->lock = val; + } + else + { + luaL_error(L, "wrong index: %s", index); + } + + return 0; +} + +static bool compare_ipc_buffer(ksys_ipc_buffer* a, ksys_ipc_buffer* b) +{ // блять че за высер... + if (a == b) + return true; + + if (a->used == b->used) + { + return memcmp( + a + (2 * sizeof(unsigned)), + b + (2 * sizeof(unsigned)), + a->used + ); + } + else // длина сообщений не совпадает, занчитт они зразу не могут быть равны + { + return false; + } +} + +static int syscalls_eqIPC_buffer(lua_State* L) +{ + lua_pushboolean( + L, + compare_ipc_buffer( + luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name), + luaL_checkudata(L, 2, syscalls_IPC_buffer_metatable_name) + ) + ); + + return 1; +} + +static int syscalls_IPC_buffer_lock(lua_State* L) +{ + struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + + buffer->lock = 1; + + return 0; +} + +static int syscalls_IPC_buffer_unlock(lua_State* L) +{ + struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + + buffer->lock = 0; + + return 0; +} + +/** + * @brief Получить сообщение под номером + * @param buffer + * @param i + * @return указатель на сообщение, если такого сообщения ещё нет, то возвращает 0 + */ +static ksys_ipc_msg* IPC_buffer_get_message(ksys_ipc_buffer* buffer, int i) +{ + ksys_ipc_msg* j = (ksys_ipc_msg*)(buffer + 8); + unsigned diff = 0; + + for (int k = 0; k < i; k++) + { + diff += j->datalen + 8; // прибавление длинны сообщения и заголовка + j += diff; + + if (diff >= buffer->used) + return 0; + } + + return j; +} + +static ksys_ipc_msg* IPC_buffer_get_last_message(ksys_ipc_buffer* buffer) +{ + ksys_ipc_msg* j = (ksys_ipc_msg*)(buffer + 8); + unsigned diff = 0; + + while (diff < buffer->used) + { + j += diff; + diff += j->datalen + 8; // прибавление длинны сообщения и заголовка + } + + return j; +} + +static int syscalls_IPC_buffer_get_message(lua_State* L) +{ + struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + unsigned i = luaL_checkinteger(L, 2); + + ksys_ipc_msg* msg = IPC_buffer_get_message(IPC_buffer_to_ksys_ipc_buffer(buffer), i); + + if (msg != 0) + { + lua_pushlightuserdata(L, msg); + luaL_setmetatable(L, syscalls_IPC_msg_metatable_name); + } + else + { + lua_pushnil(L); + } + + return 1; +} + +static int syscalls_IPC_buffer_get_last_message(lua_State* L) +{ + struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + + ksys_ipc_msg* msg = IPC_buffer_get_last_message(IPC_buffer_to_ksys_ipc_buffer(buffer)); + + if ((unsigned)msg != (unsigned)buffer) + { + lua_pushlightuserdata(L, msg); + luaL_setmetatable(L, syscalls_IPC_msg_metatable_name); + } + else + { + lua_pushnil(L); + } + + return 1; +} + +static int syscalls_IPC_buffer_reset(lua_State* L) +{ + struct IPC_buffer* buffer = luaL_checkudata(L, 1, syscalls_IPC_buffer_metatable_name); + + buffer->used = 0; + memset(&buffer->data, 0, buffer->size); + + return 0; +} + +static const luaL_Reg syscalls_IPC_buffer_m[] = { + {"__newindex", syscalls_newindexIPC_buffer}, + {"__eq", syscalls_eqIPC_buffer}, + {"__index", syscalls_indexIPC_buffer}, + {NULL, NULL} +}; + +struct IPC_buffer* syscalls_pushIPC_buffer(lua_State* L, size_t size) +{ + DEBUG_LINE("push " syscalls_IPC_buffer_name " entry"); + + struct IPC_buffer* buffer = lua_newuserdata(L, sizeof(struct IPC_buffer) + size); + + luaL_setmetatable(L, syscalls_IPC_buffer_metatable_name); + + buffer->used = 0; + buffer->size = size; + + return buffer; +} + +static int syscalls_newIPC_buffer(lua_State* L) +{ + size_t size = luaL_checkinteger(L, 1); + struct IPC_buffer* buffer = syscalls_pushIPC_buffer(L, size); + + return 1; +} + +static const luaL_Reg syscalls_IPC_buffer_lib[] = { + {"new", syscalls_newIPC_buffer}, + {"Lock", syscalls_IPC_buffer_lock}, + {"Unlock", syscalls_IPC_buffer_unlock}, + {"GetMessage", syscalls_IPC_buffer_get_message}, + {"GetLastMessage", syscalls_IPC_buffer_get_last_message}, + {"Reset", syscalls_IPC_buffer_reset}, + {NULL, NULL} +}; + +void syscalls_register_IPC_buffer(lua_State* L) +{ + DEBUG_LINE("register " syscalls_IPC_buffer_name " entry"); + + luaL_newlib(L, syscalls_IPC_buffer_lib); + + lua_setfield(L, -2, syscalls_IPC_buffer_name); + + + luaL_newmetatable(L, syscalls_IPC_buffer_metatable_name); + luaL_setfuncs(L, syscalls_IPC_buffer_m, 0); + + lua_pop(L, 1); +} diff --git a/src/IPC/IPC_buffer.h b/src/IPC/IPC_buffer.h new file mode 100644 index 0000000..6693603 --- /dev/null +++ b/src/IPC/IPC_buffer.h @@ -0,0 +1,27 @@ +#ifndef __IPC_BUFFER_H__ +#define __IPC_BUFFER_H__ + +#include "../syscalls.h" + +struct IPC_buffer +{ + size_t size; + ksys_ipc_buffer; +}; + +static inline ksys_ipc_buffer* IPC_buffer_to_ksys_ipc_buffer(struct IPC_buffer* buffer) +{ + return (ksys_ipc_buffer*)(buffer + (sizeof(struct IPC_buffer) - sizeof(ksys_ipc_buffer))); +} + +#define syscalls_IPC_buffer_metatable_name "syscalls IPC_buffer metatable" +#define syscalls_IPC_buffer_name "IPC_buffer" + +struct IPC_buffer* syscalls_pushIPC_buffer(lua_State* L, size_t dataLen); + +/** + * Register SystemColors lib + */ +void syscalls_register_IPC_buffer(lua_State* L); + +#endif // __IPC_BUFFER_H__ diff --git a/src/IPC/IPC_msg.c b/src/IPC/IPC_msg.c new file mode 100644 index 0000000..22e003f --- /dev/null +++ b/src/IPC/IPC_msg.c @@ -0,0 +1,225 @@ +#include "IPC_msg.h" +#include +#include "../debug.h" +#include +#include + + +static int syscalls_indexIPC_msg(lua_State* L) +{ + ksys_ipc_msg* r = luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name); + const char* index = luaL_checkstring(L, 2); + + if (strcmp(index, "size") == 0) + { + lua_pushinteger(L, r->datalen); + } + else if (strcmp(index, "pid") == 0) + { + lua_pushboolean(L, r->pid); + } + else + { + lua_pushnil(L); + } + + return 1; +} + +static int syscalls_newindexIPC_msg(lua_State* L) +{ + ksys_ipc_msg* r = luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name); + lua_Integer index_i = lua_isnumber(L, 2); + uint32_t val = luaL_checkinteger(L, 3); + + if (!index_i) + { + const char* index = luaL_checkstring(L, 2); + + if (strcmp(index, "size") == 0) + { + r->datalen = val; + } + else if (strcmp(index, "pid") == 0) + { + r->pid = val; + } + else + { + luaL_error(L, "wrong index: %s", index); + } + } + else + { + if (index_i < (unsigned)r->data) + { + ((lua_Integer*)r + (2 * sizeof(unsigned)))[index_i] = val; + } + else + { + luaL_error(L, "out of range. size: %d index: %d", r->datalen, index_i); + } + } + + return 0; +} + +static bool compare_ipc_msg(ksys_ipc_msg* a, ksys_ipc_msg* b) +{ + if (a->datalen == b->datalen) + { + return memcmp( + a + (2 * sizeof(unsigned)), + b + (2 * sizeof(unsigned)), + a->datalen + ); + } + else // длина сообщений не совпадает, занчитт они зразу не могут быть равны + { + return false; + } +} + +static int syscalls_eqIPC_msg(lua_State* L) +{ + lua_pushboolean( + L, + compare_ipc_msg( + luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name), + luaL_checkudata(L, 2, syscalls_IPC_msg_metatable_name) + ) + ); + + return 1; +} + +static int syscalls_IPC_msg_ReadByte(lua_State* L) +{ + lua_pushinteger( + L, + ((uint8_t*)luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name) + (2 * sizeof(unsigned)))[luaL_checkinteger(L, 2)] + ); + + return 1; +} + +static int syscalls_IPC_msg_ReadWord(lua_State* L) +{ + lua_pushinteger( + L, + ((uint16_t*)luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name) + (2 * sizeof(unsigned)))[luaL_checkinteger(L, 2)] + ); + + return 1; +} + +static int syscalls_IPC_msg_ReadDword(lua_State* L) +{ + lua_pushinteger( + L, + ((uint32_t*)luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name) + (2 * sizeof(unsigned)))[luaL_checkinteger(L, 2)] + ); + + return 1; +} + +static int syscalls_IPC_msg_ReadInteger(lua_State* L) +{ + lua_pushinteger( + L, + ((lua_Integer*)luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name) + (2 * sizeof(unsigned)))[luaL_checkinteger(L, 2)] + ); + + return 1; +} + +static int syscalls_IPC_msg_tostring(lua_State* L) +{ + ksys_ipc_msg* msg = luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name); + + char* buff = malloc(msg->datalen + 24 + 1); + + sprintf(buff, "pid: %d, len: %d, text: ", msg->pid, msg->datalen); + + memcpy(buff + 24, &msg->data, msg->datalen); + + buff[msg->datalen + 24] = '\0'; + + lua_pushstring(L, buff); + + free(buff); + + return 1; +} + +static const luaL_Reg syscalls_IPC_msg_m[] = { + {"__newindex", syscalls_newindexIPC_msg}, + {"__eq", syscalls_eqIPC_msg}, + {"__tostring", syscalls_IPC_msg_tostring}, + {"__index", syscalls_indexIPC_msg}, + {NULL, NULL} +}; + +ksys_ipc_msg* syscalls_pushIPC_msg(lua_State* L, size_t dataLen) +{ + DEBUG_LINE("push IPC_msg entry"); + + ksys_ipc_msg* msg = lua_newuserdata(L, sizeof(ksys_ipc_msg) + dataLen); + + luaL_setmetatable(L, syscalls_IPC_msg_metatable_name); + + msg->datalen = dataLen; + + return msg; +} + +static int syscalls_newIPC_msg(lua_State* L) +{ + size_t dataLen = luaL_checkinteger(L, 1); + unsigned pid = luaL_checkinteger(L, 2); + ksys_ipc_msg* msg = syscalls_pushIPC_msg(L, dataLen); + + msg->pid = pid; + + return 1; +} + +static int syscalls_fromStringIPC_msg(lua_State* L) +{ + const char* text = luaL_checkstring(L, 1); + unsigned pid = luaL_checkinteger(L, 2); + size_t len = strlen(text); + + ksys_ipc_msg* r = syscalls_pushIPC_msg(L, len); + r->pid = pid; + + memcpy(&r->data, text, len); + + return 1; +} + + +static const luaL_Reg syscalls_IPC_msg_lib[] = { + {"new", syscalls_newIPC_msg}, + {"fromString", syscalls_fromStringIPC_msg}, + {"ReadByte", syscalls_IPC_msg_ReadByte}, + {"ReadWord", syscalls_IPC_msg_ReadWord}, + {"ReadDword", syscalls_IPC_msg_ReadDword}, + {"ReadInteger", syscalls_IPC_msg_ReadInteger}, + {NULL, NULL} +}; + +void syscalls_register_IPC_msg(lua_State* L) +{ + DEBUG_LINE("register IPC_msg entry"); + + luaL_newlib(L, syscalls_IPC_msg_lib); + + lua_setfield(L, -2, syscalls_IPC_msg_name); + + + luaL_newmetatable(L, syscalls_IPC_msg_metatable_name); + luaL_setfuncs(L, syscalls_IPC_msg_m, 0); + + lua_pop(L, 1); +} diff --git a/src/IPC/IPC_msg.h b/src/IPC/IPC_msg.h new file mode 100644 index 0000000..baa5fc7 --- /dev/null +++ b/src/IPC/IPC_msg.h @@ -0,0 +1,17 @@ +#ifndef _SYSCALLS_IPC_MSG_H_ +#define _SYSCALLS_IPC_MSG_H_ + +#include "../syscalls.h" +#include + +#define syscalls_IPC_msg_metatable_name "syscalls IPC_msg metatable" +#define syscalls_IPC_msg_name "IPC_msg" + +ksys_ipc_msg* syscalls_pushIPC_msg(lua_State* L, size_t dataLen); + +/** + * Register SystemColors lib + */ +void syscalls_register_IPC_msg(lua_State* L); + +#endif // _SYSCALLS_IPC_MSG_H_ diff --git a/src/IPC/ipc.c b/src/IPC/ipc.c new file mode 100644 index 0000000..11c76fe --- /dev/null +++ b/src/IPC/ipc.c @@ -0,0 +1,51 @@ +#include "ipc.h" +#include "IPC_msg.h" +#include "IPC_buffer.h" +#include + +inline static void define_ipc(ksys_ipc_buffer* buffer, size_t bufLen) +{ + asm_inline( + "int $0x40" + ::"a"(60), "b"(1), "c"(buffer), "d"(bufLen) + ); +} + +inline static enum SendIPCErrors send_ipc(int pid, void* msg, size_t len) +{ + enum SendIPCErrors ret; + + asm_inline( + "int $0x40" + : "=a"(ret) + : "a"(60), "b"(2), "c"(pid), "d"(msg), "S"(len) + ); + + return ret; +} + +int syscalls_DefineIPCBuffer(lua_State* L) +{ + uint32_t len = luaL_checkinteger(L, 1); + struct IPC_buffer* buffer = syscalls_pushIPC_buffer(L, len); + + define_ipc(IPC_buffer_to_ksys_ipc_buffer(buffer), len); + + return 1; +} + +int syscalls_SendIPCMessage(lua_State* L) +{ + ksys_ipc_msg* msg = luaL_checkudata(L, 1, syscalls_IPC_msg_metatable_name); + + lua_pushinteger( + L, + send_ipc( + msg->pid, + msg + 8, + msg->datalen + ) + ); + + return 1; +} diff --git a/src/IPC/ipc.h b/src/IPC/ipc.h new file mode 100644 index 0000000..0f0aa42 --- /dev/null +++ b/src/IPC/ipc.h @@ -0,0 +1,32 @@ +#ifndef __IPC_H__ +#define __IPC_H__ + +#include "../syscalls.h" + +enum SendIPCErrors +{ + Ok = 0, + BufferNotDefined = 1, + BufferLocked = 2, + BufferOverflow = 3, + PIDNotExist = 4 +}; + +int syscalls_DefineIPCBuffer(lua_State* L); +int syscalls_SendIPCMessage(lua_State* L); + + +inline void syscalls_push_IPC_errors(lua_State* L) +{ + lua_createtable(L, 0, 5); + + LUA_PUSH_INTEGER_FIELD(L, Ok, "Ok"); + LUA_PUSH_INTEGER_FIELD(L, BufferLocked, "BufferLocked"); + LUA_PUSH_INTEGER_FIELD(L, BufferNotDefined, "BufferNotDefined"); + LUA_PUSH_INTEGER_FIELD(L, BufferOverflow, "BufferOverflow"); + LUA_PUSH_INTEGER_FIELD(L, PIDNotExist, "PIDNotExist"); + + lua_setfield(L, -2, "IPCError"); +} + +#endif // __IPC_H__ diff --git a/src/debug/registers.h b/src/debug/registers.h index e5dbd16..9bc5339 100644 --- a/src/debug/registers.h +++ b/src/debug/registers.h @@ -20,6 +20,6 @@ struct registers struct registers* syscalls_pushRegisters(lua_State* L); -inline void syscalls_register_registers(lua_State* L); +void syscalls_register_registers(lua_State* L); #endif // __REGISTERS_H__ diff --git a/src/syscalls.c b/src/syscalls.c index c8531ba..720261b 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -9,12 +9,15 @@ #include "syscalls.h" #include "scancodes.h" -#include "ARP_entry.h" +#include "ARP_entry.h" #include "systemColors.h" #include "sockets/socket_lua.h" #include "debug/debug.h" #include "graphic.h" +#include "IPC/ipc.h" +#include "IPC/IPC_msg.h" +#include "IPC/IPC_buffer.h" #include "version/coreversion.h" #include "version/library_version.h" #include "background/background.h" @@ -250,7 +253,7 @@ static int syscalls_threadInfo(lua_State* L) { ksys_thread_t t; - _ksys_thread_info(&t, luaL_checkinteger(L, 1)); + _ksys_thread_info(&t, luaL_optinteger(L, 1, -1)); lua_createtable(L, 0, 13); @@ -1136,7 +1139,7 @@ typedef enum SYSCALLS_PROTOCOLS ARP = 5 } SYSCALLS_PROTOCOLS; -inline int syscalls_ReadPacketSend(lua_State* L, SYSCALLS_PROTOCOLS protocol) +static inline int syscalls_ReadPacketSend(lua_State* L, SYSCALLS_PROTOCOLS protocol) { uint32_t eax; uint8_t device = luaL_checkinteger(L, 1); @@ -1151,7 +1154,7 @@ inline int syscalls_ReadPacketSend(lua_State* L, SYSCALLS_PROTOCOLS protocol) return 1; } -inline int syscalls_ReadPacketReceive(lua_State* L, SYSCALLS_PROTOCOLS protocol) +static inline int syscalls_ReadPacketReceive(lua_State* L, SYSCALLS_PROTOCOLS protocol) { uint32_t eax; uint8_t device = luaL_checkinteger(L, 1); @@ -1604,6 +1607,9 @@ static const luaL_Reg syscallsLib[] = { { "Done", syscalls_Done }, { "DefineBreakpoint", syscalls_DefineBreakpoint }, { "UndefBreakpoint", syscalls_UndefBreakpoint }, + /* IPC */ + { "DefineIPCBuffer", syscalls_DefineIPCBuffer }, + { "SendIPCMessage", syscalls_SendIPCMessage }, { NULL, NULL } }; @@ -1755,16 +1761,28 @@ LUALIB_API int luaopen_syscalls(lua_State* L) syscalls_push_events(L); syscalls_push_slotStates(L); + syscalls_register_scancodes(L); syscalls_push_hotkey_states(L); + syscalls_push_buttonsStyle(L); syscalls_push_windowStyles(L); + syscalls_push_buttons(L); + + // net syscalls_push_connectionStatus(L); + syscalls_register_ARPEntry(L); + syscalls_push_graphic(L); - syscalls_register_ARPEntry(L); + // Register IPC + syscalls_register_IPC_msg(L); + syscalls_register_IPC_buffer(L); + syscalls_push_IPC_errors(L); + syscalls_register_SystemColors(L); + syscalls_register_Version(L); _ksys_set_event_mask(7); // set default event mask diff --git a/tests/ipc_get.lua b/tests/ipc_get.lua new file mode 100644 index 0000000..ba3cb74 --- /dev/null +++ b/tests/ipc_get.lua @@ -0,0 +1,35 @@ +--[[ + Этот скрипт принимает данные от ipc_send и выводит в консоль +]] + +local syscalls = require("syscalls") + +-- Enable IPC event only +syscalls.SetEventMask(1 << (syscalls.Event.IPC - 1)) + +-- write pid to /tmp0/1/lua_test_ipc_pid + +local pid = syscalls.ThreadInfo().PID + +local f = io.open("/tmp0/1/lua_test_ipc_pid", "w") + +if f then + f:write(pid); + + f:close() +end + +------------ + +local buffer = syscalls.DefineIPCBuffer(4096) +syscalls.IPC_buffer.Unlock(buffer) + + +while true do + print("buffer:", buffer.used .. '/' .. buffer.size, "Locked:" .. tostring(buffer.lock)) + if syscalls.WaitEvent() == syscalls.Event.IPC then + syscalls.IPC_buffer.Lock(buffer) + print("message:", syscalls.IPC_buffer.GetLastMessage(buffer)) + syscalls.IPC_buffer.Unlock(buffer) + end +end diff --git a/tests/ipc_send.lua b/tests/ipc_send.lua new file mode 100644 index 0000000..2bd7187 --- /dev/null +++ b/tests/ipc_send.lua @@ -0,0 +1,21 @@ +--[[ + скрипт который отправляет данные по IPC +]] + +local syscalls = require("syscalls") + +local f = io.open("/tmp0/1/lua_test_ipc_pid", "r") + +local pid + +if f then + pid = tonumber(f:read("l")) + f:close() +end + +if pid then + while true do + local msg = syscalls.IPC_msg.fromString("Test aboba", pid) + print("Send:", msg, "State:", syscalls.SendIPCMessage(msg)) + end +end diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100644 index 0000000..21cd15d --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,11 @@ +#SHS + +# Graphic +../lua helloWorld.lua + +../lua SystemColors.lua + +# IPC tests +../lua ipc_get.lua +../lua ipc_send.lua +