From cfcb979f9c41c79cc2355c2049d02e5fc22fb40c Mon Sep 17 00:00:00 2001 From: Alexander Turenko Date: Thu, 23 Aug 2018 20:55:41 +0300 Subject: [PATCH] WIP: socket: fix dgram_length and recv* for OS X Part of #3619. --- src/lua/socket.c | 11 +++++++++++ src/lua/socket.lua | 47 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/lua/socket.c b/src/lua/socket.c index c1f971c32d1c..78f8029641c6 100644 --- a/src/lua/socket.c +++ b/src/lua/socket.c @@ -268,6 +268,9 @@ static const struct lbox_sockopt_reg so_opts[] = { #ifdef SO_PROTOCOL {"SO_PROTOCOL", SO_PROTOCOL, 1, 0, }, #endif +#ifdef SO_NREAD /* available on Darwin */ + {"SO_NREAD", SO_NREAD, 1, 0, }, +#endif {"SO_TYPE", SO_TYPE, 1, 0, }, @@ -950,7 +953,11 @@ lbox_socket_recvfrom(struct lua_State *L) int fh = lua_tointeger(L, 1); int size = lua_tointeger(L, 2); int flags = lua_tointeger(L, 3); +#ifdef TARGET_OS_DARWIN + int dgram_length = lua_tointeger(L, 4); +#else flags |= MSG_TRUNC; +#endif struct sockaddr_storage fa; socklen_t len = sizeof(fa); @@ -969,7 +976,11 @@ lbox_socket_recvfrom(struct lua_State *L) free(buf); lua_pushnil(L); return 1; +#ifdef TARGET_OS_DARWIN + } else if (dgram_length > size) { +#else } else if (res > size) { +#endif free(buf); lua_pushnil(L); lbox_socket_push_addr(L, (struct sockaddr *)&fa, len); diff --git a/src/lua/socket.lua b/src/lua/socket.lua index 64bdeffdf59c..aeb778b2891d 100644 --- a/src/lua/socket.lua +++ b/src/lua/socket.lua @@ -785,17 +785,23 @@ local function socket_dgram_length(self) error("socket:dgram_length() supports only a UDP socket") end - local iflags = get_iflags(internal.SEND_FLAGS, {'MSG_TRUNC', 'MSG_PEEK'}) - assert(iflags ~= nil) + local len + if jit.os == 'OSX' then + self._errno = nil + len = self:getsockopt('SOL_SOCKET', 'SO_NREAD') + else + local iflags = get_iflags(internal.SEND_FLAGS, {'MSG_TRUNC', 'MSG_PEEK'}) + assert(iflags ~= nil) + self._errno = nil + len = tonumber(ffi.C.recv(fd, nil, 0, iflags)) + end - self._errno = nil - local len = ffi.C.recv(fd, nil, 0, iflags) if len == -1 or len == 0 then self._errno = boxerrno() return nil end - return tonumber(len) + return len end local function socket_recv(self, size, flags) @@ -806,12 +812,21 @@ local function socket_recv(self, size, flags) return nil end + local dgram_length if self:is_udp() then - size = size or self:dgram_length() + if jit.os == 'OSX' then + dgram_length = self:dgram_length() + if dgram_length == nil then + return nil + end + end + size = size or dgram_length or self:dgram_length() if size == nil then return nil end - iflags = bit.bor(iflags, internal.SEND_FLAGS['MSG_TRUNC']) + if jit.os ~= 'OSX' then + iflags = bit.bor(iflags, internal.SEND_FLAGS['MSG_TRUNC']) + end else size = size or 512 end @@ -824,7 +839,7 @@ local function socket_recv(self, size, flags) if res == -1 then self._errno = boxerrno() return nil - elseif res > size then + elseif (dgram_length or res) > size then self._errno = boxerrno.EMSGSIZE return nil end @@ -839,8 +854,15 @@ local function socket_recvfrom(self, size, flags) return nil end + local dgram_length if self:is_udp() then - size = size or self:dgram_length() + if jit.os == 'OSX' then + dgram_length = self:dgram_length() + if dgram_length == nil then + return nil + end + end + size = size or dgram_length or self:dgram_length() if size == nil then return nil end @@ -849,7 +871,12 @@ local function socket_recvfrom(self, size, flags) end self._errno = nil - local res, from = internal.recvfrom(fd, size, iflags) + local res, from + if jit.os == 'OSX' then + res, from = internal.recvfrom(fd, size, iflags, dgram_length) + else + res, from = internal.recvfrom(fd, size, iflags) + end if res == nil then self._errno = boxerrno() return nil, from