summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2019-11-04 22:20:02 +0800
committerGitHub <[email protected]>2019-11-04 22:20:02 +0800
commitb1eee1ec65dd0f9d3a26af52596d86c331160587 (patch)
tree6811a354f07c146ba4417e649d3a31d0c9aabd45 /core/src
parent20b40c57bbe9d28f822d5feac304a5b892b02790 (diff)
parentf00316a42943a9a75303658f8d646d35f9e8d1b9 (diff)
Merge pull request #593 from xmake-io/socket
Add io.socket support
Diffstat (limited to 'core/src')
-rw-r--r--core/src/demo/xmake.lua6
-rw-r--r--core/src/xmake/io/file_close.c4
-rw-r--r--core/src/xmake/io/file_flush.c4
-rw-r--r--core/src/xmake/io/file_isatty.c2
-rw-r--r--core/src/xmake/io/file_open.c8
-rw-r--r--core/src/xmake/io/file_rawfd.c4
-rw-r--r--core/src/xmake/io/file_read.c36
-rw-r--r--core/src/xmake/io/file_seek.c8
-rw-r--r--core/src/xmake/io/file_size.c4
-rw-r--r--core/src/xmake/io/file_write.c2
-rw-r--r--core/src/xmake/io/prefix.h4
-rw-r--r--core/src/xmake/io/socket_accept.c57
-rw-r--r--core/src/xmake/io/socket_bind.c73
-rw-r--r--core/src/xmake/io/socket_close.c57
-rw-r--r--core/src/xmake/io/socket_connect.c73
-rw-r--r--core/src/xmake/io/socket_listen.c58
-rw-r--r--core/src/xmake/io/socket_open.c70
-rw-r--r--core/src/xmake/io/socket_rawfd.c62
-rw-r--r--core/src/xmake/io/socket_recv.c77
-rw-r--r--core/src/xmake/io/socket_recvfrom.c101
-rw-r--r--core/src/xmake/io/socket_send.c109
-rw-r--r--core/src/xmake/io/socket_sendfile.c117
-rw-r--r--core/src/xmake/io/socket_sendto.c106
-rw-r--r--core/src/xmake/io/socket_wait.c61
-rw-r--r--core/src/xmake/io/stdfile.c2
-rw-r--r--core/src/xmake/machine.c28
-rw-r--r--core/src/xmake/makefile13
27 files changed, 1102 insertions, 44 deletions
diff --git a/core/src/demo/xmake.lua b/core/src/demo/xmake.lua
index edd6adfdd..d0ac78909 100644
--- a/core/src/demo/xmake.lua
+++ b/core/src/demo/xmake.lua
@@ -7,9 +7,6 @@ target("demo")
-- make as a binary
set_kind("binary")
- -- set basename of target file
- set_basename("xmake")
-
-- add defines
add_defines("__tb_prefix__=\"xmake\"")
@@ -30,6 +27,7 @@ target("demo")
-- add links
if is_plat("windows") then
add_links("ws2_32", "advapi32", "shell32")
+ add_ldflags("/export:malloc", "/export:free")
elseif is_plat("android") then
add_links("m", "c")
elseif is_plat("macosx") then
@@ -49,6 +47,6 @@ target("demo")
-- copy target to the build directory
after_build(function (target)
- os.cp(target:targetfile(), "$(buildir)")
+ os.cp(target:targetfile(), "$(buildir)/xmake" .. (is_plat("windows") and ".exe" or ""))
end)
diff --git a/core/src/xmake/io/file_close.c b/core/src/xmake/io/file_close.c
index 6b3efdd98..1e3ebd131 100644
--- a/core/src/xmake/io/file_close.c
+++ b/core/src/xmake/io/file_close.c
@@ -42,7 +42,7 @@ tb_int_t xm_io_file_close(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "close(invalid file)!");
+ xm_io_return_error(lua, "close(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -88,6 +88,6 @@ tb_int_t xm_io_file_close(lua_State* lua)
lua_pushboolean(lua, tb_true);
return 1;
}
- else xm_io_file_return_error(lua, "cannot close this file!");
+ else xm_io_return_error(lua, "cannot close this file!");
}
diff --git a/core/src/xmake/io/file_flush.c b/core/src/xmake/io/file_flush.c
index 72969b09d..a4bf0f672 100644
--- a/core/src/xmake/io/file_flush.c
+++ b/core/src/xmake/io/file_flush.c
@@ -69,7 +69,7 @@ tb_int_t xm_io_file_flush(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "flush(invalid file)!");
+ xm_io_return_error(lua, "flush(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -82,5 +82,5 @@ tb_int_t xm_io_file_flush(lua_State* lua)
lua_pushboolean(lua, tb_true);
return 1;
}
- else xm_io_file_return_error(lua, "failed to flush file");
+ else xm_io_return_error(lua, "failed to flush file");
}
diff --git a/core/src/xmake/io/file_isatty.c b/core/src/xmake/io/file_isatty.c
index d8c5183d8..06eea4b29 100644
--- a/core/src/xmake/io/file_isatty.c
+++ b/core/src/xmake/io/file_isatty.c
@@ -42,7 +42,7 @@ tb_int_t xm_io_file_isatty(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "isatty(invalid file)!");
+ xm_io_return_error(lua, "isatty(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
diff --git a/core/src/xmake/io/file_open.c b/core/src/xmake/io/file_open.c
index 46e63cd62..9db81a82c 100644
--- a/core/src/xmake/io/file_open.c
+++ b/core/src/xmake/io/file_open.c
@@ -217,10 +217,10 @@ tb_int_t xm_io_file_open(lua_State* lua)
else
{
if (stream) tb_stream_exit(stream);
- xm_io_file_return_error(lua, "file not found!");
+ xm_io_return_error(lua, "file not found!");
}
}
- else xm_io_file_return_error(lua, "invalid open mode!");
+ else xm_io_return_error(lua, "invalid open mode!");
tb_assert_and_check_return_val(encoding != XM_IO_FILE_ENCODING_UNKNOWN, 0);
// open file
@@ -271,9 +271,7 @@ tb_int_t xm_io_file_open(lua_State* lua)
fstream = tb_null;
// return errors
- lua_pushnil(lua);
- lua_pushliteral(lua, "failed to open file.");
- return 2;
+ xm_io_return_error(lua, "failed to open file!");
}
// make file
diff --git a/core/src/xmake/io/file_rawfd.c b/core/src/xmake/io/file_rawfd.c
index dcc69eceb..a298c29c2 100644
--- a/core/src/xmake/io/file_rawfd.c
+++ b/core/src/xmake/io/file_rawfd.c
@@ -58,7 +58,7 @@ tb_int_t xm_io_file_rawfd(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "get rawfd for invalid file!");
+ xm_io_return_error(lua, "get rawfd for invalid file!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -76,5 +76,5 @@ tb_int_t xm_io_file_rawfd(lua_State* lua)
}
// get rawfd failed
- xm_io_file_return_error(lua, "get rawfd for invalid file!");
+ xm_io_return_error(lua, "get rawfd for invalid file!");
}
diff --git a/core/src/xmake/io/file_read.c b/core/src/xmake/io/file_read.c
index 438dc022d..d5748ffe3 100644
--- a/core/src/xmake/io/file_read.c
+++ b/core/src/xmake/io/file_read.c
@@ -182,7 +182,7 @@ static tb_int_t xm_io_file_read_all_directly(lua_State* lua, xm_io_file_t* file)
// init buffer
tb_buffer_t buf;
if (!tb_buffer_init(&buf))
- xm_io_file_return_error(lua, "init buffer failed!");
+ xm_io_return_error(lua, "init buffer failed!");
// read all
tb_byte_t data[TB_STREAM_BLOCK_MAXN];
@@ -219,7 +219,7 @@ static tb_int_t xm_io_file_read_all(lua_State* lua, xm_io_file_t* file, tb_char_
// init buffer
tb_buffer_t buf;
if (!tb_buffer_init(&buf))
- xm_io_file_return_error(lua, "init buffer failed!");
+ xm_io_return_error(lua, "init buffer failed!");
// read all
tb_bool_t has_content = tb_false;
@@ -239,7 +239,7 @@ static tb_int_t xm_io_file_read_all(lua_State* lua, xm_io_file_t* file, tb_char_
case PL_FAIL:
default:
tb_buffer_exit(&buf);
- xm_io_file_return_error(lua, "failed to read all");
+ xm_io_return_error(lua, "failed to read all");
break;
}
}
@@ -253,7 +253,7 @@ static tb_int_t xm_io_file_read_line(lua_State* lua, xm_io_file_t* file, tb_char
// init buffer
tb_buffer_t buf;
if (!tb_buffer_init(&buf))
- xm_io_file_return_error(lua, "init buffer failed!");
+ xm_io_return_error(lua, "init buffer failed!");
// read line
tb_bool_t has_content = tb_false;
@@ -276,7 +276,7 @@ static tb_int_t xm_io_file_read_line(lua_State* lua, xm_io_file_t* file, tb_char
case PL_FAIL:
default:
tb_buffer_exit(&buf);
- xm_io_file_return_error(lua, "failed to readline");
+ xm_io_return_error(lua, "failed to readline");
break;
}
}
@@ -289,11 +289,11 @@ static tb_int_t xm_io_file_read_n(lua_State* lua, xm_io_file_t* file, tb_char_t
// check continuation
if (*continuation != '\0')
- xm_io_file_return_error(lua, "continuation is not supported for read number of bytes");
+ xm_io_return_error(lua, "continuation is not supported for read number of bytes");
// check encoding
if (file->encoding != XM_IO_FILE_ENCODING_BINARY)
- xm_io_file_return_error(lua, "read number of bytes only allows binary file, reopen with 'rb' and try again");
+ xm_io_return_error(lua, "read number of bytes only allows binary file, reopen with 'rb' and try again");
tb_bool_t ok = tb_false;
if (n == 0)
@@ -381,7 +381,7 @@ static tb_int_t xm_io_file_std_read_line(lua_State* lua, xm_io_file_t* file, tb_
// init buffer
tb_buffer_t buf;
if (!tb_buffer_init(&buf))
- xm_io_file_return_error(lua, "init buffer failed!");
+ xm_io_return_error(lua, "init buffer failed!");
// read line
tb_bool_t has_content = tb_false;
@@ -404,7 +404,7 @@ static tb_int_t xm_io_file_std_read_line(lua_State* lua, xm_io_file_t* file, tb_
case PL_FAIL:
default:
tb_buffer_exit(&buf);
- xm_io_file_return_error(lua, "failed to readline");
+ xm_io_return_error(lua, "failed to readline");
break;
}
}
@@ -418,7 +418,7 @@ static tb_int_t xm_io_file_std_read_all(lua_State* lua, xm_io_file_t* file, tb_c
// init buffer
tb_buffer_t buf;
if (!tb_buffer_init(&buf))
- xm_io_file_return_error(lua, "init buffer failed!");
+ xm_io_return_error(lua, "init buffer failed!");
// read all
tb_bool_t has_content = tb_false;
@@ -438,7 +438,7 @@ static tb_int_t xm_io_file_std_read_all(lua_State* lua, xm_io_file_t* file, tb_c
case PL_FAIL:
default:
tb_buffer_exit(&buf);
- xm_io_file_return_error(lua, "failed to readline");
+ xm_io_return_error(lua, "failed to readline");
break;
}
}
@@ -451,7 +451,7 @@ static tb_int_t xm_io_file_std_read_n(lua_State* lua, xm_io_file_t* file, tb_cha
// check continuation
if (*continuation != '\0')
- xm_io_file_return_error(lua, "continuation is not supported for std streams");
+ xm_io_return_error(lua, "continuation is not supported for std streams");
// io.read(0)
if (n == 0)
@@ -482,7 +482,7 @@ static tb_int_t xm_io_file_std_read_num(lua_State* lua, xm_io_file_t* file, tb_c
// check continuation
if (*continuation != '\0')
- xm_io_file_return_error(lua, "continuation is not supported for std streams");
+ xm_io_return_error(lua, "continuation is not supported for std streams");
// read number
tb_char_t strbuf[512];
@@ -506,7 +506,7 @@ tb_int_t xm_io_file_read(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "read(invalid file)!");
+ xm_io_return_error(lua, "read(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -521,7 +521,7 @@ tb_int_t xm_io_file_read(lua_State* lua)
if (lua_isnumber(lua, 2))
{
count = (tb_long_t)lua_tointeger(lua, 2);
- if (count < 0) xm_io_file_return_error(lua, "invalid read size, must be positive nubmber or 0");
+ if (count < 0) xm_io_return_error(lua, "invalid read size, must be positive nubmber or 0");
}
else if (*mode == '*')
mode++;
@@ -533,10 +533,10 @@ tb_int_t xm_io_file_read(lua_State* lua)
{
case 'a': return xm_io_file_read_all(lua, file, continuation);
case 'L': return xm_io_file_read_line(lua, file, continuation, tb_true);
- case 'n': xm_io_file_return_error(lua, "read number is not implemented");
+ case 'n': xm_io_return_error(lua, "read number is not implemented");
case 'l': return xm_io_file_read_line(lua, file, continuation, tb_false);
default:
- xm_io_file_return_error(lua, "unknonwn read mode");
+ xm_io_return_error(lua, "unknonwn read mode");
return 0;
}
}
@@ -550,7 +550,7 @@ tb_int_t xm_io_file_read(lua_State* lua)
case 'n': return xm_io_file_std_read_num(lua, file, continuation);
case 'l': return xm_io_file_std_read_line(lua, file, continuation, tb_false);
default:
- xm_io_file_return_error(lua, "unknonwn read mode");
+ xm_io_return_error(lua, "unknonwn read mode");
return 0;
}
}
diff --git a/core/src/xmake/io/file_seek.c b/core/src/xmake/io/file_seek.c
index a4e14bffa..67cfe061c 100644
--- a/core/src/xmake/io/file_seek.c
+++ b/core/src/xmake/io/file_seek.c
@@ -42,7 +42,7 @@ tb_int_t xm_io_file_seek(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "seek(invalid file)!");
+ xm_io_return_error(lua, "seek(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -66,7 +66,7 @@ tb_int_t xm_io_file_seek(lua_State* lua)
tb_hong_t size = tb_stream_size(file->file_ref);
if (size > 0 && size + offset <= size)
offset = size + offset;
- else xm_io_file_return_error(lua, "seek failed, invalid offset!");
+ else xm_io_return_error(lua, "seek failed, invalid offset!");
}
break;
default: // "cur"
@@ -79,7 +79,7 @@ tb_int_t xm_io_file_seek(lua_State* lua)
lua_pushnumber(lua, (lua_Number)offset);
return 1;
}
- else xm_io_file_return_error(lua, "seek failed!");
+ else xm_io_return_error(lua, "seek failed!");
}
- else xm_io_file_return_error(lua, "seek is not supported on this file");
+ else xm_io_return_error(lua, "seek is not supported on this file");
}
diff --git a/core/src/xmake/io/file_size.c b/core/src/xmake/io/file_size.c
index 4e502bbfb..637268ced 100644
--- a/core/src/xmake/io/file_size.c
+++ b/core/src/xmake/io/file_size.c
@@ -42,7 +42,7 @@ tb_int_t xm_io_file_size(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "get size for invalid file!");
+ xm_io_return_error(lua, "get size for invalid file!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
@@ -56,5 +56,5 @@ tb_int_t xm_io_file_size(lua_State* lua)
lua_pushnumber(lua, (lua_Number)tb_stream_size(file->stream));
return 1;
}
- else xm_io_file_return_error(lua, "get size for invalid file!");
+ else xm_io_return_error(lua, "get size for invalid file!");
}
diff --git a/core/src/xmake/io/file_write.c b/core/src/xmake/io/file_write.c
index 43aaf606e..b276a0e10 100644
--- a/core/src/xmake/io/file_write.c
+++ b/core/src/xmake/io/file_write.c
@@ -116,7 +116,7 @@ tb_int_t xm_io_file_write(lua_State* lua)
// is user data?
if (!lua_isuserdata(lua, 1))
- xm_io_file_return_error(lua, "write(invalid file)!");
+ xm_io_return_error(lua, "write(invalid file)!");
// get file
xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 1);
diff --git a/core/src/xmake/io/prefix.h b/core/src/xmake/io/prefix.h
index ba567f6fb..c96570396 100644
--- a/core/src/xmake/io/prefix.h
+++ b/core/src/xmake/io/prefix.h
@@ -33,8 +33,8 @@
#define xm_io_file_is_std(file) ((file)->type != XM_IO_FILE_TYPE_FILE)
#define xm_io_file_is_tty(file) (!!((file)->type & XM_IO_FILE_FLAG_TTY))
-// return file error
-#define xm_io_file_return_error(lua, error) \
+// return io error
+#define xm_io_return_error(lua, error) \
do \
{ \
lua_pushnil(lua); \
diff --git a/core/src/xmake/io/socket_accept.c b/core/src/xmake/io/socket_accept.c
new file mode 100644
index 000000000..efd667c5a
--- /dev/null
+++ b/core/src/xmake/io/socket_accept.c
@@ -0,0 +1,57 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_accept.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_accept"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// local sock = io.socket_accept(sock)
+tb_int_t xm_io_socket_accept(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // is user data?
+ if (!lua_isuserdata(lua, 1))
+ return 0;
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // accept socket
+ tb_socket_ref_t client = tb_socket_accept(sock, tb_null);
+ if (client) lua_pushlightuserdata(lua, (tb_pointer_t)client);
+ else lua_pushnil(lua);
+ return 1;
+}
+
diff --git a/core/src/xmake/io/socket_bind.c b/core/src/xmake/io/socket_bind.c
new file mode 100644
index 000000000..f4c1c06b9
--- /dev/null
+++ b/core/src/xmake/io/socket_bind.c
@@ -0,0 +1,73 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_bind.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_bind"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// io.socket_bind(sock, addr, port, family)
+tb_int_t xm_io_socket_bind(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushboolean(lua, tb_false);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get address
+ tb_char_t const* address = lua_tostring(lua, 2);
+ tb_assert_and_check_return_val(address, 0);
+
+ // get port
+ tb_uint16_t port = (tb_uint16_t)luaL_checknumber(lua, 3);
+
+ // get family
+ tb_uint8_t family = (tb_uint8_t)luaL_checknumber(lua, 4);
+
+ // init address
+ tb_ipaddr_t addr;
+ tb_ipaddr_set(&addr, address, port, family);
+
+ // bind socket
+ lua_pushboolean(lua, tb_socket_bind(sock, &addr));
+ return 1;
+}
+
diff --git a/core/src/xmake/io/socket_close.c b/core/src/xmake/io/socket_close.c
new file mode 100644
index 000000000..fe0d24f32
--- /dev/null
+++ b/core/src/xmake/io/socket_close.c
@@ -0,0 +1,57 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_close.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_close"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// io.socket_close(sock)
+tb_int_t xm_io_socket_close(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // is user data?
+ if (!lua_isuserdata(lua, 1))
+ return 0;
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // exit socket
+ lua_pushboolean(lua, tb_socket_exit(sock));
+
+ // ok
+ return 1;
+}
+
diff --git a/core/src/xmake/io/socket_connect.c b/core/src/xmake/io/socket_connect.c
new file mode 100644
index 000000000..d758a9734
--- /dev/null
+++ b/core/src/xmake/io/socket_connect.c
@@ -0,0 +1,73 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_connect.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_connect"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// io.socket_connect(sock, addr, port, family)
+tb_int_t xm_io_socket_connect(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get address
+ tb_char_t const* address = lua_tostring(lua, 2);
+ tb_assert_and_check_return_val(address, 0);
+
+ // get port
+ tb_uint16_t port = (tb_uint16_t)luaL_checknumber(lua, 3);
+
+ // get family
+ tb_uint8_t family = (tb_uint8_t)luaL_checknumber(lua, 4);
+
+ // init address
+ tb_ipaddr_t addr;
+ tb_ipaddr_set(&addr, address, port, family);
+
+ // connect socket
+ lua_pushnumber(lua, (tb_int_t)tb_socket_connect(sock, &addr));
+ return 1;
+}
+
diff --git a/core/src/xmake/io/socket_listen.c b/core/src/xmake/io/socket_listen.c
new file mode 100644
index 000000000..c075bcb67
--- /dev/null
+++ b/core/src/xmake/io/socket_listen.c
@@ -0,0 +1,58 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_listen.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_listen"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// io.socket_listen(sock, backlog)
+tb_int_t xm_io_socket_listen(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // is user data?
+ if (!lua_isuserdata(lua, 1))
+ return 0;
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get backlog
+ tb_size_t backlog = (tb_size_t)luaL_checknumber(lua, 2);
+
+ // listen socket
+ lua_pushnumber(lua, (tb_int_t)tb_socket_listen(sock, backlog));
+ return 1;
+}
+
diff --git a/core/src/xmake/io/socket_open.c b/core/src/xmake/io/socket_open.c
new file mode 100644
index 000000000..fbfd7a3c7
--- /dev/null
+++ b/core/src/xmake/io/socket_open.c
@@ -0,0 +1,70 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_open.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_open"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/*
+ * io.socket_open(socktype, family)
+ */
+tb_int_t xm_io_socket_open(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get socket type
+ tb_size_t socktype = (tb_size_t)luaL_checknumber(lua, 1);
+
+ // get address family
+ tb_size_t family = (tb_size_t)luaL_checknumber(lua, 2);
+
+ // map socket type
+ switch (socktype)
+ {
+ case 2:
+ socktype = TB_SOCKET_TYPE_UDP;
+ break;
+ case 3:
+ socktype = TB_SOCKET_TYPE_ICMP;
+ break;
+ default:
+ socktype = TB_SOCKET_TYPE_TCP;
+ break;
+ }
+
+ // init socket
+ tb_socket_ref_t sock = tb_socket_init(socktype, family);
+ if (sock) lua_pushlightuserdata(lua, (tb_pointer_t)sock);
+ else lua_pushnil(lua);
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_rawfd.c b/core/src/xmake/io/socket_rawfd.c
new file mode 100644
index 000000000..8682e99fc
--- /dev/null
+++ b/core/src/xmake/io/socket_rawfd.c
@@ -0,0 +1,62 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this sock except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @sock socket_rawfd.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_rawfd"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * macros
+ */
+
+// socket to fd
+#define xm_io_sock2fd(sock) (lua_Number)tb_sock2fd(sock)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* io.socket_rawfd(sock)
+ */
+tb_int_t xm_io_socket_rawfd(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // is user data?
+ if (!lua_isuserdata(lua, 1))
+ xm_io_return_error(lua, "get rawfd for invalid sock!");
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // return result
+ lua_pushnumber(lua, xm_io_sock2fd(sock));
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_recv.c b/core/src/xmake/io/socket_recv.c
new file mode 100644
index 000000000..4ed41e080
--- /dev/null
+++ b/core/src/xmake/io/socket_recv.c
@@ -0,0 +1,77 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_recv.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_recv"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// real, data_or_errors = io.socket_recv(sock, size)
+tb_int_t xm_io_socket_recv(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get data and size
+ tb_byte_t data[8192];
+ tb_long_t size = 0;
+ if (lua_isnumber(lua, 2)) size = (tb_long_t)lua_tonumber(lua, 2);
+ if (size < 0)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid size(%ld)!", size);
+ return 2;
+ }
+ if (size > sizeof(data))
+ size = sizeof(data);
+
+ // recv data
+ tb_long_t real = tb_socket_recv(sock, data, size);
+ lua_pushnumber(lua, (tb_int_t)real);
+ if (real > 0)
+ {
+ lua_pushlstring(lua, (tb_char_t const*)data, real);
+ return 2;
+ }
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_recvfrom.c b/core/src/xmake/io/socket_recvfrom.c
new file mode 100644
index 000000000..2933a44f0
--- /dev/null
+++ b/core/src/xmake/io/socket_recvfrom.c
@@ -0,0 +1,101 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_recvfrom.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_recvfrom"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// real, data_or_errors, addr, port = io.socket_recvfrom(sock, size)
+tb_int_t xm_io_socket_recvfrom(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get data and size
+ tb_byte_t buffer[8192];
+ tb_byte_t* data = buffer;
+ tb_long_t size = 0;
+ if (lua_isnumber(lua, 2)) size = (tb_long_t)lua_tonumber(lua, 2);
+ if (size < 0)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid size(%ld)!", size);
+ return 2;
+ }
+ if (!size) size = sizeof(data);
+ else if (size > sizeof(data))
+ {
+ data = tb_malloc_bytes(size);
+ if (!data)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "malloc(%ld) failed!", size);
+ return 2;
+ }
+ }
+
+ // recv data
+ tb_ipaddr_t ipaddr;
+ tb_ipaddr_clear(&ipaddr);
+ tb_int_t retn = 1;
+ tb_long_t real = tb_socket_urecv(sock, &ipaddr, data, size);
+ lua_pushnumber(lua, (tb_int_t)real);
+ if (real > 0)
+ {
+ retn = 2;
+ lua_pushlstring(lua, (tb_char_t const*)data, real);
+ if (!tb_ipaddr_is_empty(&ipaddr))
+ {
+ tb_char_t const* ipstr = tb_ipaddr_ip_cstr(&ipaddr, (tb_char_t*)buffer, sizeof(buffer));
+ if (ipstr)
+ {
+ lua_pushstring(lua, ipstr);
+ lua_pushnumber(lua, (tb_int_t)tb_ipaddr_port(&ipaddr));
+ retn = 4;
+ }
+ }
+ }
+ if (data != buffer) tb_free(data);
+ return retn;
+}
diff --git a/core/src/xmake/io/socket_send.c b/core/src/xmake/io/socket_send.c
new file mode 100644
index 000000000..8cce64f29
--- /dev/null
+++ b/core/src/xmake/io/socket_send.c
@@ -0,0 +1,109 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_send.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_send"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// io.socket_send(sock, data, start, last)
+tb_int_t xm_io_socket_send(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get data
+ tb_size_t size = 0;
+ tb_byte_t const* data = tb_null;
+ if (lua_istable(lua, 2))
+ {
+ // get data address
+ lua_pushstring(lua, "data");
+ lua_gettable(lua, 2);
+ data = (tb_byte_t const*)(tb_size_t)(tb_long_t)lua_tonumber(lua, -1);
+ lua_pop(lua, 1);
+
+ // get data size
+ lua_pushstring(lua, "size");
+ lua_gettable(lua, 2);
+ size = (tb_size_t)lua_tonumber(lua, -1);
+ lua_pop(lua, 1);
+ }
+ else
+ {
+ size_t datasize = 0;
+ data = (tb_byte_t const*)luaL_checklstring(lua, 2, &datasize);
+ size = (tb_size_t)datasize;
+ }
+ if (!data || !size)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid data(%p) and size(%zu)!", data, size);
+ return 2;
+ }
+
+ // get start
+ tb_long_t start = 1;
+ if (lua_isnumber(lua, 3)) start = (tb_long_t)lua_tonumber(lua, 3);
+ if (start < 1 || start > size)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid start position(%ld)!", start);
+ return 2;
+ }
+
+ // get last
+ tb_long_t last = (tb_long_t)size;
+ if (lua_isnumber(lua, 4)) last = (tb_long_t)lua_tonumber(lua, 4);
+ if (last < start - 1 || last > size + start - 1)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid last position(%ld)!", last);
+ return 2;
+ }
+
+ // send data
+ tb_long_t real = tb_socket_send(sock, data + start - 1, last - start + 1);
+ lua_pushnumber(lua, (tb_int_t)real);
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_sendfile.c b/core/src/xmake/io/socket_sendfile.c
new file mode 100644
index 000000000..df29afd32
--- /dev/null
+++ b/core/src/xmake/io/socket_sendfile.c
@@ -0,0 +1,117 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_sendfile.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_sendfile"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// io.socket_sendfile(sock, file, start, last)
+tb_int_t xm_io_socket_sendfile(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // check file
+ if (!lua_isuserdata(lua, 2))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid file!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get file
+ xm_io_file_t* file = (xm_io_file_t*)lua_touserdata(lua, 2);
+ tb_check_return_val(file, 0);
+
+ // does not support stdfile
+ if (!xm_io_file_is_file(file) || !file->stream)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid file type!");
+ return 2;
+ }
+
+ // get file reference
+ tb_file_ref_t rawfile = tb_null;
+ if (!tb_stream_ctrl(file->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) || !rawfile)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "cannot get file reference!");
+ return 2;
+ }
+
+ // get file size
+ tb_hize_t filesize = tb_file_size(rawfile);
+ if (!filesize)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "cannot send empty file!");
+ return 2;
+ }
+
+ // get start
+ tb_long_t start = 1;
+ if (lua_isnumber(lua, 3)) start = (tb_long_t)lua_tonumber(lua, 3);
+ if (start < 1 || start > filesize)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid start position(%ld)!", start);
+ return 2;
+ }
+
+ // get last
+ tb_long_t last = (tb_long_t)filesize;
+ if (lua_isnumber(lua, 4)) last = (tb_long_t)lua_tonumber(lua, 4);
+ if (last < start - 1 || last > filesize + start - 1)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid last position(%ld)!", last);
+ return 2;
+ }
+
+ // send file data
+ tb_long_t real = (tb_long_t)tb_socket_sendf(sock, rawfile, start - 1, last - start + 1);
+ lua_pushnumber(lua, (tb_int_t)real);
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_sendto.c b/core/src/xmake/io/socket_sendto.c
new file mode 100644
index 000000000..6b1f8fa49
--- /dev/null
+++ b/core/src/xmake/io/socket_sendto.c
@@ -0,0 +1,106 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_sendto.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_sendto"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// io.socket_sendto(sock, data, addr, port)
+tb_int_t xm_io_socket_sendto(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // check socket
+ if (!lua_isuserdata(lua, 1))
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid socket!");
+ return 2;
+ }
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get data
+ tb_size_t size = 0;
+ tb_byte_t const* data = tb_null;
+ if (lua_istable(lua, 2))
+ {
+ // get data address
+ lua_pushstring(lua, "data");
+ lua_gettable(lua, 2);
+ data = (tb_byte_t const*)(tb_size_t)(tb_long_t)lua_tonumber(lua, -1);
+ lua_pop(lua, 1);
+
+ // get data size
+ lua_pushstring(lua, "size");
+ lua_gettable(lua, 2);
+ size = (tb_size_t)lua_tonumber(lua, -1);
+ lua_pop(lua, 1);
+ }
+ else
+ {
+ size_t datasize = 0;
+ data = (tb_byte_t const*)luaL_checklstring(lua, 2, &datasize);
+ size = (tb_size_t)datasize;
+ }
+ if (!data || !size)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushfstring(lua, "invalid data(%p) and size(%zu)!", data, size);
+ return 2;
+ }
+
+ // get address
+ tb_char_t const* addr = lua_tostring(lua, 3);
+ tb_uint16_t port = (tb_uint16_t)luaL_checknumber(lua, 4);
+ if (!addr || !port)
+ {
+ lua_pushnumber(lua, -1);
+ lua_pushliteral(lua, "invalid address!");
+ return 2;
+ }
+
+ // get address family
+ tb_size_t family = (tb_size_t)luaL_checknumber(lua, 5);
+
+ // init ip address
+ tb_ipaddr_t ipaddr;
+ tb_ipaddr_set(&ipaddr, addr, port, (tb_uint8_t)family);
+
+ // send data
+ tb_long_t real = tb_socket_usend(sock, &ipaddr, data, size);
+ lua_pushnumber(lua, (tb_int_t)real);
+ return 1;
+}
diff --git a/core/src/xmake/io/socket_wait.c b/core/src/xmake/io/socket_wait.c
new file mode 100644
index 000000000..d9b845785
--- /dev/null
+++ b/core/src/xmake/io/socket_wait.c
@@ -0,0 +1,61 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file socket_wait.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "socket_wait"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+// io.socket_wait(sock, events, timeout)
+tb_int_t xm_io_socket_wait(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // is user data?
+ if (!lua_isuserdata(lua, 1))
+ return 0;
+
+ // get socket
+ tb_socket_ref_t sock = (tb_socket_ref_t)lua_touserdata(lua, 1);
+ tb_check_return_val(sock, 0);
+
+ // get events
+ tb_size_t events = (tb_size_t)luaL_checknumber(lua, 2);
+
+ // get timeout
+ tb_long_t timeout = (tb_long_t)luaL_checknumber(lua, 3);
+
+ // wait socket
+ lua_pushnumber(lua, (tb_int_t)tb_socket_wait(sock, events, timeout));
+ return 1;
+}
+
diff --git a/core/src/xmake/io/stdfile.c b/core/src/xmake/io/stdfile.c
index c5adae143..8f466fa7a 100644
--- a/core/src/xmake/io/stdfile.c
+++ b/core/src/xmake/io/stdfile.c
@@ -167,6 +167,6 @@ tb_int_t xm_io_stdfile(lua_State* lua)
lua_pushlightuserdata(lua, (tb_pointer_t)file);
return 1;
}
- else xm_io_file_return_error(lua, "invalid stdfile type!");
+ else xm_io_return_error(lua, "invalid stdfile type!");
}
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index b98e60236..835e10b73 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -109,6 +109,21 @@ tb_int_t xm_io_filelock_unlock(lua_State* lua);
tb_int_t xm_io_filelock_trylock(lua_State* lua);
tb_int_t xm_io_filelock_close(lua_State* lua);
+// the io/socket functions
+tb_int_t xm_io_socket_open(lua_State* lua);
+tb_int_t xm_io_socket_rawfd(lua_State* lua);
+tb_int_t xm_io_socket_wait(lua_State* lua);
+tb_int_t xm_io_socket_bind(lua_State* lua);
+tb_int_t xm_io_socket_listen(lua_State* lua);
+tb_int_t xm_io_socket_accept(lua_State* lua);
+tb_int_t xm_io_socket_connect(lua_State* lua);
+tb_int_t xm_io_socket_send(lua_State* lua);
+tb_int_t xm_io_socket_sendto(lua_State* lua);
+tb_int_t xm_io_socket_sendfile(lua_State* lua);
+tb_int_t xm_io_socket_recv(lua_State* lua);
+tb_int_t xm_io_socket_recvfrom(lua_State* lua);
+tb_int_t xm_io_socket_close(lua_State* lua);
+
// the path functions
tb_int_t xm_path_relative(lua_State* lua);
tb_int_t xm_path_absolute(lua_State* lua);
@@ -241,6 +256,19 @@ static luaL_Reg const g_io_functions[] =
, { "filelock_trylock", xm_io_filelock_trylock }
, { "filelock_unlock", xm_io_filelock_unlock }
, { "filelock_close", xm_io_filelock_close }
+, { "socket_open", xm_io_socket_open }
+, { "socket_rawfd", xm_io_socket_rawfd }
+, { "socket_wait", xm_io_socket_wait }
+, { "socket_bind", xm_io_socket_bind }
+, { "socket_listen", xm_io_socket_listen }
+, { "socket_accept", xm_io_socket_accept }
+, { "socket_connect", xm_io_socket_connect }
+, { "socket_send", xm_io_socket_send }
+, { "socket_sendto", xm_io_socket_sendto }
+, { "socket_sendfile", xm_io_socket_sendfile }
+, { "socket_recv", xm_io_socket_recv }
+, { "socket_recvfrom", xm_io_socket_recvfrom }
+, { "socket_close", xm_io_socket_close }
, { tb_null, tb_null }
};
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 996123191..e2660128a 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -60,6 +60,19 @@ xmake_C_FILES += \
io/filelock_unlock \
io/filelock_trylock \
io/filelock_close \
+ io/socket_open \
+ io/socket_rawfd \
+ io/socket_wait \
+ io/socket_bind \
+ io/socket_listen \
+ io/socket_accept \
+ io/socket_connect \
+ io/socket_send \
+ io/socket_sendto \
+ io/socket_sendfile \
+ io/socket_recv \
+ io/socket_recvfrom \
+ io/socket_close \
path/relative \
path/absolute \
path/translate \