diff --git a/Channel.cpp b/Channel.cpp index a729860..db4a599 100644 --- a/Channel.cpp +++ b/Channel.cpp @@ -1,4 +1,5 @@ #include "include.h" +#include #include #include #include diff --git a/Event.cpp b/Event.cpp index 9cfe3b2..ee3f345 100644 --- a/Event.cpp +++ b/Event.cpp @@ -1,4 +1,5 @@ #include "include.h" +#include /* Event diff --git a/Linux.cpp b/Linux.cpp index f26c33e..3be6052 100644 --- a/Linux.cpp +++ b/Linux.cpp @@ -4,11 +4,18 @@ using namespace std; #ifndef _WIN32 -int lua_errno(lua_State* L, const char* hint) +void put_linuxerror(lua_State* L, int errcode, const char* hint) { - char buff[1024] = { 0 }; - strerror_r(errno, buff, 1024); - return luaL_error(L, "%s: %s", hint, buff); + char buff[4096] = { 0 }; + strerror_r(errcode, buff, 4096); + if(hint) + { + lua_pushfstring(L, "%s: %s", hint, buff); + } + else + { + lua_pushstring(L, buff); + } } void PlatInit() diff --git a/Renderer.cpp b/Renderer.cpp index 0ecd4a0..b72d3ed 100644 --- a/Renderer.cpp +++ b/Renderer.cpp @@ -1,5 +1,6 @@ #include "include.h" #include +#include /* class Renderer @@ -169,7 +170,7 @@ int render_copyto(lua_State* L) { h = luaL_checkinteger(L, 6); } - + SDL_Rect r; r.w = w; r.h = h; diff --git a/TCPWin.cpp b/TCP.cpp similarity index 82% rename from TCPWin.cpp rename to TCP.cpp index a987a46..8d41026 100644 --- a/TCPWin.cpp +++ b/TCP.cpp @@ -1,12 +1,63 @@ #include "TCP.h" +#include #ifdef _WIN32 #define _WIN32_WINNT 0x0A00 // Win10 #include #include +static int SetSocketBlocking(lua_State* L, int fd, bool blocking) +{ + u_long arg = blocking ? 0 : 1; + int ret = ioctlsocket(fd, FIONBIO, &arg); + if (ret) + { + int errcode = WSAGetLastError(); + put_winerror(L, errcode, "ioctlsocket"); + return lua_error(L); + } + return 0; +} + +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int SetSocketBlocking(lua_State* L, int fd, bool blocking) +{ + const int flags = fcntl(fd, F_GETFL, 0); + if( ((flags & O_NONBLOCK) && !blocking) || (!(flags & O_NONBLOCK) && blocking)) + { + return 0; + } + int ret = fcntl(fd, F_SETFL, blocking ? flags & ~O_NONBLOCK : flags | O_NONBLOCK); + if (ret) + { + put_linuxerror(L, errno, "fcntl"); + return lua_error(L); + } + return 0; +} + +#define closesocket close +#define WSAGetLastError() errno +#define WSAEWOULDBLOCK EWOULDBLOCK +#define put_winerror put_linuxerror + +#endif + using namespace std; + int tcp_socket_dtor(lua_State* L) { auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); @@ -133,7 +184,7 @@ int tcp_socket_listen(lua_State* L) backlog = luaL_checkinteger(L, 3); } } - + sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -180,28 +231,8 @@ int tcp_socket_setblocking(lua_State* L) { return 0; } - if (blocking) // set to blocking - { - u_long arg = 0; - int ret = ioctlsocket(s->fd, FIONBIO, &arg); - if (ret) - { - int errcode = WSAGetLastError(); - put_winerror(L, errcode, "ioctlsocket"); - return lua_error(L); - } - } - else // set to nonblocking - { - u_long arg = 1; - int ret = ioctlsocket(s->fd, FIONBIO, &arg); - if (ret) - { - int errcode = WSAGetLastError(); - put_winerror(L, errcode, "ioctlsocket"); - return lua_error(L); - } - } + + SetSocketBlocking(L, s->fd, blocking); return 0; } @@ -234,7 +265,7 @@ int tcp_socket_accept(lua_State* L) { auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); sockaddr_in addr; - int addrsz = sizeof(addr); + socklen_t addrsz = sizeof(addr); int ret = accept(s->fd, (sockaddr*)&addr, &addrsz); if (ret < 0) { @@ -279,15 +310,7 @@ int tcp_socket_new(lua_State* L) } if (nonblocking) { - u_long arg = 1; - int ret = ioctlsocket(fd, FIONBIO, &arg); - if (ret) - { - int errcode = WSAGetLastError(); - closesocket(fd); - put_winerror(L, errcode, "ioctlsocket"); - return lua_error(L); - } + SetSocketBlocking(L, fd, false); } put_tcp_socket(L, fd, nonblocking); return 1; @@ -301,5 +324,3 @@ void InitTCPSocket(lua_State* L) lua_setfield(L, -2, "TCPSocket"); lua_pop(L, 2); } - -#endif diff --git a/TCPLinux.cpp b/TCPLinux.cpp deleted file mode 100644 index 32c4b56..0000000 --- a/TCPLinux.cpp +++ /dev/null @@ -1,265 +0,0 @@ -#include "TCP.h" - -#ifndef _WIN32 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int tcp_socket_dtor(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - if (s->fd > 0) - { - close(s->fd); - s->fd = -1; - } - s->~TCPSocket(); - return 0; -} - -int tcp_socket_close(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - if (s->fd > 0) - { - close(s->fd); - s->fd = -1; - } - return 0; -} - -int tcp_socket_send(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - size_t sz; - const char* str = luaL_checklstring(L, 2, &sz); - size_t done = 0; - while (done < sz) - { - int ret = send(s->fd, str + done, sz - done, 0); - if (ret < 0) - { - if (s->nonblocking && errno == EWOULDBLOCK) - { - lua_pushinteger(L, done); - lua_pushboolean(L, true); - return 2; - } - return lua_errno(L, "send"); - } - done += ret; - } - lua_pushinteger(L, done); - return 1; -} - -int tcp_socket_recv(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - int ret = recv(s->fd, s->data.data(), s->buffsz, 0); - if (ret < 0) - { - if (s->nonblocking && errno == EWOULDBLOCK) - { - lua_pushstring(L, ""); - lua_pushboolean(L, true); - return 2; - } - return lua_errno(L, "recv"); - } - lua_pushlstring(L, s->data.data(), ret); - return 1; -} - -int tcp_socket_connect(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - const char* ip = luaL_checkstring(L, 2); - int port = luaL_checkinteger(L, 3); - - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(ip); - addr.sin_port = htons(port); - - int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr)); - if (ret < 0) - { - if (s->nonblocking && errno == EWOULDBLOCK) - { - lua_pushboolean(L, true); - return 1; - } - return lua_errno(L, "connect"); - } - - return 0; -} - -int tcp_socket_listen(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - const char* ip = NULL; - int port; - int backlog = 10; - if (lua_isstring(L, 2)) - { - ip = luaL_checkstring(L, 2); - port = luaL_checkinteger(L, 3); - if (!lua_isnone(L, 4)) - { - backlog = luaL_checkinteger(L, 4); - } - } - else - { - port = luaL_checkinteger(L, 2); - if (!lua_isnone(L, 3)) - { - backlog = luaL_checkinteger(L, 3); - } - } - - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - if (ip && strcmp(ip, "0.0.0.0")) - { - addr.sin_addr.s_addr = inet_addr(ip); - } - else - { - addr.sin_addr.s_addr = INADDR_ANY; - } - addr.sin_port = htons(port); - - int ret = bind(s->fd, (const sockaddr*)&addr, sizeof(addr)); - if (ret < 0) - { - return lua_errno(L, "bind"); - } - ret = listen(s->fd, backlog); - if (ret < 0) - { - return lua_errno(L, "listen"); - } - return 0; -} - -int tcp_socket_setblocking(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - luaL_checkany(L, 2); - bool blocking = lua_toboolean(L, 2); - if (blocking != s->nonblocking) - { - return 0; - } - if (blocking) // set to blocking - { - int flag = fcntl(s->fd, F_GETFL, 0); - if (flag < 0) return lua_errno(L, "fnctl"); - flag &= ~O_NONBLOCK; - if (fcntl(s->fd, F_GETFL, flag) < 0) return lua_errno(L, "fnctl"); - } - else // set to nonblocking - { - int flag = fcntl(s->fd, F_GETFL, 0); - if (flag < 0) return lua_errno(L, "fnctl"); - flag |= O_NONBLOCK; - if (fcntl(s->fd, F_GETFL, flag) < 0) return lua_errno(L, "fnctl"); - } - - return 0; -} - -int tcp_socket_accept(lua_State* L); - -void put_tcp_socket(lua_State* L, int fd, bool nonblocking) -{ - auto s = new (lua_newblock(L)) TCPSocket; - if (luaL_newmetatable(L, "LuaEngineTCPSocket")) - { - lua_setfield_function(L, "__gc", tcp_socket_dtor); - lua_newtable(L); - lua_setfield_function(L, "close", tcp_socket_close); - lua_setfield_function(L, "send", tcp_socket_send); - lua_setfield_function(L, "recv", tcp_socket_recv); - lua_setfield_function(L, "listen", tcp_socket_listen); - lua_setfield_function(L, "connect", tcp_socket_connect); - lua_setfield_function(L, "accept", tcp_socket_accept); - lua_setfield_function(L, "setblocking", tcp_socket_setblocking); - lua_setfield(L, -2, "__index"); - } - lua_setmetatable(L, -2); - s->fd = fd; - s->nonblocking = nonblocking; - s->buffsz = 4096; - s->data.resize(s->buffsz); -} - -int tcp_socket_accept(lua_State* L) -{ - auto s = lua_checkblock(L, 1, "LuaEngineTCPSocket"); - sockaddr_in addr; - socklen_t addrsz = sizeof(addr); - int ret = accept(s->fd, (sockaddr*)&addr, &addrsz); - if (ret < 0) - { - if (s->nonblocking && errno == EWOULDBLOCK) - { - return 0; - } - return lua_errno(L, "accept"); - } - put_tcp_socket(L, ret, false); - lua_pushstring(L, inet_ntoa(addr.sin_addr)); - lua_pushinteger(L, ntohs(addr.sin_port)); - return 3; -} - -int tcp_socket_new(lua_State* L) -{ - bool nonblocking = false; - if (!lua_isnone(L, 1)) - { - if (lua_toboolean(L, 1)) - { - nonblocking = true; - } - } - int fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - { - return lua_errno(L, "socket"); - } - if (nonblocking) - { - int flag = fcntl(fd, F_GETFL, 0); - if (flag < 0) return lua_errno(L, "fnctl"); - flag |= O_NONBLOCK; - if (fcntl(fd, F_GETFL, flag) < 0) return lua_errno(L, "fnctl"); - } - put_tcp_socket(L, fd, nonblocking); - return 1; -} - -void InitTCPSocket(lua_State* L) -{ - lua_getglobal(L, "package"); - lua_getfield(L, -1, "loaded"); - lua_pushcfunction(L, tcp_socket_new); - lua_setfield(L, -2, "TCPSocket"); - lua_pop(L, 2); -} - -#endif // end of ifndef _WIN32 diff --git a/Windows.cpp b/Windows.cpp index 5884bc4..8cfdf50 100644 --- a/Windows.cpp +++ b/Windows.cpp @@ -25,13 +25,6 @@ void put_winerror(lua_State* L, int errcode, const char* hint) } } -int lua_errno(lua_State* L, const char* hint) -{ - char buff[1024] = { 0 }; - strerror_s(buff, errno); - return luaL_error(L, "%s: %s", hint, buff); -} - void PlatInit() { WORD wd = MAKEWORD(2, 2); diff --git a/include.h b/include.h index 7af4f2f..5b2d235 100644 --- a/include.h +++ b/include.h @@ -138,6 +138,9 @@ void PlatInit(); #ifdef _WIN32 void put_winerror(lua_State* L, int errcode, const char* hint); +#else +void put_linuxerror(lua_State* L, int errcode, const char* hint); + #endif // ifdef _WIN32 int lua_errno(lua_State* L, const char* hint); diff --git a/main.cpp b/main.cpp index 9571a0c..13e94af 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,15 @@ #include "LuaEngine.h" +#include #include #include -#include + +#ifdef _WIN32 +#include // _chdir +#define ChangeDir _chdir +#else +#include +#define ChangeDir chdir +#endif using namespace std; string LoadFile(const string& filename) @@ -28,7 +36,7 @@ int main() { InitEngine(); lua_State* L = CreateLuaEngine(); - _chdir("game"); + ChangeDir("game"); string code = LoadFile("app.lua"); if (luaL_loadbufferx(L, code.c_str(), code.size(), "ProgramMain", "t")) {