Compare commits

...

5 Commits

Author SHA1 Message Date
Azamat H. Hackimov
c50b9c0af2
Merge aae30a8a7e7bb0bafcc65d7e05173e39bf975365 into e3ca4a767a68d127df548d82669aba3689bd84f4 2024-05-24 13:28:58 +03:00
Kim Alvefur
e3ca4a767a
fix(unix): Pass correct path length for abstract sockets (#430) 2024-05-24 13:28:51 +03:00
Caleb Maclennan
aae30a8a7e
Merge branch 'master' into public-api 2023-11-10 22:54:02 +03:00
Azamat H. Hackimov
815d6d7f3d Fix CFLAGS and LDFLAGS options
Remove CFLAGS optimization overrides, add -Wl,-soname option to LDFLAGS
for external linking.
2022-03-22 09:51:05 +01:00
Jonas Wielicki
26fd89be84 Make the API more accessible by publishing constants 2022-03-22 09:51:04 +01:00
12 changed files with 136 additions and 108 deletions

View File

@ -18,6 +18,7 @@
#include "luasocket.h"
#include "io.h"
#include "timeout.h"
#include "common.h"
/* buffer size in bytes */
#define BUF_SIZE 8192
@ -37,13 +38,13 @@ typedef t_buffer *p_buffer;
#pragma GCC visibility push(hidden)
#endif
int buffer_open(lua_State *L);
void buffer_init(p_buffer buf, p_io io, p_timeout tm);
int buffer_meth_getstats(lua_State *L, p_buffer buf);
int buffer_meth_setstats(lua_State *L, p_buffer buf);
int buffer_meth_send(lua_State *L, p_buffer buf);
int buffer_meth_receive(lua_State *L, p_buffer buf);
int buffer_isempty(p_buffer buf);
LUASOCKET_API int buffer_open(lua_State *L);
LUASOCKET_API void buffer_init(p_buffer buf, p_io io, p_timeout tm);
LUASOCKET_API int buffer_meth_getstats(lua_State *L, p_buffer buf);
LUASOCKET_API int buffer_meth_setstats(lua_State *L, p_buffer buf);
LUASOCKET_API int buffer_meth_send(lua_State *L, p_buffer buf);
LUASOCKET_API int buffer_meth_receive(lua_State *L, p_buffer buf);
LUASOCKET_API int buffer_isempty(p_buffer buf);
#ifndef _WIN32
#pragma GCC visibility pop

16
src/common.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef LUASOCKET_COMMON_H
#define LUASOCKET_COMMON_H
#ifndef LUASOCKET_API
#define LUASOCKET_API extern
#endif
#ifndef UNIX_API
#define UNIX_API extern
#endif
#ifndef MIME_API
#define MIME_API extern
#endif
#endif

View File

@ -14,13 +14,14 @@
\*=========================================================================*/
#include "luasocket.h"
#include "timeout.h"
#include "common.h"
/* IO error codes */
enum {
IO_DONE = 0, /* operation completed successfully */
IO_TIMEOUT = -1, /* operation timed out */
IO_CLOSED = -2, /* the connection has been closed */
IO_UNKNOWN = -3
IO_UNKNOWN = -3
};
/* interface to error message function */
@ -60,8 +61,8 @@ typedef t_io *p_io;
#pragma GCC visibility push(hidden)
#endif
void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
const char *io_strerror(int err);
LUASOCKET_API void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
LUASOCKET_API const char *io_strerror(int err);
#ifndef _WIN32
#pragma GCC visibility pop

View File

@ -162,7 +162,7 @@ SO_macosx=so
O_macosx=o
CC_macosx=gcc
DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN
CFLAGS_macosx=$(LUAINC:%=-I%) $(DEF) -Wall -O2 -fno-common
CFLAGS_macosx=$(LUAINC:%=-I%) $(DEF) -Wall -fno-common
LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o
LD_macosx=gcc
SOCKET_macosx=usocket.o
@ -174,8 +174,7 @@ SO_linux=so
O_linux=o
CC_linux=gcc
DEF_linux=-DLUASOCKET_$(DEBUG)
CFLAGS_linux=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic
CFLAGS_linux=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra -Wimplicit -fpic
LDFLAGS_linux=-O -shared -fpic -o
LD_linux=gcc
SOCKET_linux=usocket.o
@ -187,9 +186,7 @@ SO_freebsd=so
O_freebsd=o
CC_freebsd=gcc
DEF_freebsd=-DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN
CFLAGS_freebsd=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic
LDFLAGS_freebsd=-O -shared -fpic -o
CFLAGS_freebsd=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra -Wimplicit -fpic
LD_freebsd=gcc
SOCKET_freebsd=usocket.o
@ -200,8 +197,7 @@ SO_solaris=so
O_solaris=o
CC_solaris=gcc
DEF_solaris=-DLUASOCKET_$(DEBUG)
CFLAGS_solaris=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic
CFLAGS_solaris=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra -Wimplicit -fpic
LDFLAGS_solaris=-lnsl -lsocket -lresolv -O -shared -fpic -o
LD_solaris=gcc
SOCKET_solaris=usocket.o
@ -214,7 +210,7 @@ O_mingw=o
CC_mingw=gcc
DEF_mingw= -DLUASOCKET_$(DEBUG) \
-DWINVER=0x0501
CFLAGS_mingw=$(LUAINC:%=-I%) $(DEF) -Wall -O2 -fno-common
CFLAGS_mingw=$(LUAINC:%=-I%) $(DEF) -Wall -fno-common
LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
LD_mingw=gcc
SOCKET_mingw=wsocket.o
@ -396,18 +392,18 @@ none:
all: $(SOCKET_SO) $(MIME_SO)
$(SOCKET_SO): $(SOCKET_OBJS)
$(LD) $(SOCKET_OBJS) $(LDFLAGS)$@
$(LD) $(SOCKET_OBJS) -Wl,-soname,socket/core.so $(LDFLAGS)$@
$(MIME_SO): $(MIME_OBJS)
$(LD) $(MIME_OBJS) $(LDFLAGS)$@
$(LD) $(MIME_OBJS) -Wl,-soname,mime/core.so $(LDFLAGS)$@
all-unix: all $(UNIX_SO) $(SERIAL_SO)
$(UNIX_SO): $(UNIX_OBJS)
$(LD) $(UNIX_OBJS) $(LDFLAGS)$@
$(LD) $(UNIX_OBJS) -Wl,-soname,socket/unix.so $(LDFLAGS)$@
$(SERIAL_SO): $(SERIAL_OBJS)
$(LD) $(SERIAL_OBJS) $(LDFLAGS)$@
$(LD) $(SERIAL_OBJS) -Wl,-soname,socket/serial.so $(LDFLAGS)$@
install:
$(INSTALL_DIR) $(INSTALL_TOP_LDIR)

View File

@ -10,6 +10,7 @@
* creates a interface compatible with the io.h module.
\*=========================================================================*/
#include "io.h"
#include "common.h"
/*=========================================================================*\
* Platform specific compatibilization
@ -42,31 +43,31 @@ typedef struct sockaddr SA;
#pragma GCC visibility push(hidden)
#endif
int socket_waitfd(p_socket ps, int sw, p_timeout tm);
int socket_open(void);
int socket_close(void);
void socket_destroy(p_socket ps);
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm);
int socket_create(p_socket ps, int domain, int type, int protocol);
int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);
int socket_listen(p_socket ps, int backlog);
void socket_shutdown(p_socket ps, int how);
int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);
int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *addr_len, p_timeout tm);
int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm);
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm);
int socket_write(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
void socket_setblocking(p_socket ps);
void socket_setnonblocking(p_socket ps);
int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp);
int socket_gethostbyname(const char *addr, struct hostent **hp);
const char *socket_hoststrerror(int err);
const char *socket_strerror(int err);
const char *socket_ioerror(p_socket ps, int err);
const char *socket_gaistrerror(int err);
LUASOCKET_API int socket_waitfd(p_socket ps, int sw, p_timeout tm);
LUASOCKET_API int socket_open(void);
LUASOCKET_API int socket_close(void);
LUASOCKET_API void socket_destroy(p_socket ps);
LUASOCKET_API int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm);
LUASOCKET_API int socket_create(p_socket ps, int domain, int type, int protocol);
LUASOCKET_API int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);
LUASOCKET_API int socket_listen(p_socket ps, int backlog);
LUASOCKET_API void socket_shutdown(p_socket ps, int how);
LUASOCKET_API int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);
LUASOCKET_API int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *addr_len, p_timeout tm);
LUASOCKET_API int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
LUASOCKET_API int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm);
LUASOCKET_API int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
LUASOCKET_API int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm);
LUASOCKET_API int socket_write(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
LUASOCKET_API int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
LUASOCKET_API void socket_setblocking(p_socket ps);
LUASOCKET_API void socket_setnonblocking(p_socket ps);
LUASOCKET_API int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp);
LUASOCKET_API int socket_gethostbyname(const char *addr, struct hostent **hp);
LUASOCKET_API const char *socket_hoststrerror(int err);
LUASOCKET_API const char *socket_strerror(int err);
LUASOCKET_API const char *socket_ioerror(p_socket ps, int err);
LUASOCKET_API const char *socket_gaistrerror(int err);
#ifndef _WIN32
#pragma GCC visibility pop

View File

@ -5,6 +5,7 @@
* LuaSocket toolkit
\*=========================================================================*/
#include "luasocket.h"
#include "common.h"
/* timeout control structure */
typedef struct t_timeout_ {
@ -18,18 +19,18 @@ typedef t_timeout *p_timeout;
#pragma GCC visibility push(hidden)
#endif
void timeout_init(p_timeout tm, double block, double total);
double timeout_get(p_timeout tm);
double timeout_getstart(p_timeout tm);
double timeout_getretry(p_timeout tm);
p_timeout timeout_markstart(p_timeout tm);
LUASOCKET_API void timeout_init(p_timeout tm, double block, double total);
LUASOCKET_API double timeout_get(p_timeout tm);
LUASOCKET_API double timeout_getstart(p_timeout tm);
LUASOCKET_API double timeout_getretry(p_timeout tm);
LUASOCKET_API p_timeout timeout_markstart(p_timeout tm);
double timeout_gettime(void);
LUASOCKET_API double timeout_gettime(void);
int timeout_open(lua_State *L);
LUASOCKET_API int timeout_open(lua_State *L);
int timeout_meth_settimeout(lua_State *L, p_timeout tm);
int timeout_meth_gettimeout(lua_State *L, p_timeout tm);
LUASOCKET_API int timeout_meth_settimeout(lua_State *L, p_timeout tm);
LUASOCKET_API int timeout_meth_gettimeout(lua_State *L, p_timeout tm);
#ifndef _WIN32
#pragma GCC visibility pop

View File

@ -16,13 +16,6 @@
#define UNIXDGRAM_DATAGRAMSIZE 8192
/* provide a SUN_LEN macro if sys/un.h doesn't (e.g. Android) */
#ifndef SUN_LEN
#define SUN_LEN(ptr) \
((size_t) (((struct sockaddr_un *) 0)->sun_path) \
+ strlen ((ptr)->sun_path))
#endif
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
@ -42,8 +35,8 @@ static int meth_receivefrom(lua_State *L);
static int meth_sendto(lua_State *L);
static int meth_getsockname(lua_State *L);
static const char *unixdgram_tryconnect(p_unix un, const char *path);
static const char *unixdgram_trybind(p_unix un, const char *path);
static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len);
static const char *unixdgram_trybind(p_unix un, const char *path, size_t len);
/* unixdgram object methods */
static luaL_Reg unixdgram_methods[] = {
@ -133,13 +126,12 @@ static int meth_send(lua_State *L)
static int meth_sendto(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1);
size_t count, sent = 0;
size_t count, sent, len = 0;
const char *data = luaL_checklstring(L, 2, &count);
const char *path = luaL_checkstring(L, 3);
const char *path = luaL_checklstring(L, 3, &len);
p_timeout tm = &un->tm;
int err;
struct sockaddr_un remote;
size_t len = strlen(path);
if (len >= sizeof(remote.sun_path)) {
lua_pushnil(L);
@ -148,7 +140,7 @@ static int meth_sendto(lua_State *L)
}
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
memcpy(remote.sun_path, path, len);
remote.sun_family = AF_UNIX;
timeout_markstart(tm);
#ifdef UNIX_HAS_SUN_LEN
@ -264,18 +256,22 @@ static int meth_dirty(lua_State *L) {
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
static const char *unixdgram_trybind(p_unix un, const char *path) {
static const char *unixdgram_trybind(p_unix un, const char *path, size_t len) {
struct sockaddr_un local;
size_t len = strlen(path);
int err;
if (len >= sizeof(local.sun_path)) return "path too long";
memset(&local, 0, sizeof(local));
strcpy(local.sun_path, path);
memcpy(local.sun_path, path, len);
local.sun_family = AF_UNIX;
size_t addrlen = SUN_LEN(&local);
#ifdef UNIX_HAS_SUN_LEN
local.sun_len = addrlen + 1;
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
+ len + 1;
err = socket_bind(&un->sock, (SA *) &local, local.sun_len);
#else
err = socket_bind(&un->sock, (SA *) &local,
sizeof(local.sun_family) + len);
#endif
int err = socket_bind(&un->sock, (SA *) &local, addrlen);
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}
@ -283,8 +279,9 @@ static const char *unixdgram_trybind(p_unix un, const char *path) {
static int meth_bind(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixdgram_trybind(un, path);
size_t len;
const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixdgram_trybind(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
@ -313,20 +310,23 @@ static int meth_getsockname(lua_State *L)
/*-------------------------------------------------------------------------*\
* Turns a master unixdgram object into a client object.
\*-------------------------------------------------------------------------*/
static const char *unixdgram_tryconnect(p_unix un, const char *path)
static const char *unixdgram_tryconnect(p_unix un, const char *path, size_t len)
{
struct sockaddr_un remote;
size_t len = strlen(path);
int err;
if (len >= sizeof(remote.sun_path)) return "path too long";
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
memcpy(remote.sun_path, path, len);
remote.sun_family = AF_UNIX;
timeout_markstart(&un->tm);
size_t addrlen = SUN_LEN(&remote);
#ifdef UNIX_HAS_SUN_LEN
remote.sun_len = addrlen + 1;
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
+ len + 1;
err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
#else
err = socket_connect(&un->sock, (SA *) &remote,
sizeof(remote.sun_family) + len, &un->tm);
#endif
int err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm);
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}
@ -334,8 +334,9 @@ static const char *unixdgram_tryconnect(p_unix un, const char *path)
static int meth_connect(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixdgram_tryconnect(un, path);
size_t len;
const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixdgram_tryconnect(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);

View File

@ -33,8 +33,8 @@ static int meth_getstats(lua_State *L);
static int meth_setstats(lua_State *L);
static int meth_getsockname(lua_State *L);
static const char *unixstream_tryconnect(p_unix un, const char *path);
static const char *unixstream_trybind(p_unix un, const char *path);
static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len);
static const char *unixstream_trybind(p_unix un, const char *path, size_t len);
/* unixstream object methods */
static luaL_Reg unixstream_methods[] = {
@ -181,13 +181,12 @@ static int meth_accept(lua_State *L) {
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
static const char *unixstream_trybind(p_unix un, const char *path) {
static const char *unixstream_trybind(p_unix un, const char *path, size_t len) {
struct sockaddr_un local;
size_t len = strlen(path);
int err;
if (len >= sizeof(local.sun_path)) return "path too long";
memset(&local, 0, sizeof(local));
strcpy(local.sun_path, path);
memcpy(local.sun_path, path, len);
local.sun_family = AF_UNIX;
#ifdef UNIX_HAS_SUN_LEN
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
@ -204,8 +203,9 @@ static const char *unixstream_trybind(p_unix un, const char *path) {
static int meth_bind(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixstream_trybind(un, path);
size_t len;
const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixstream_trybind(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
@ -234,14 +234,13 @@ static int meth_getsockname(lua_State *L)
/*-------------------------------------------------------------------------*\
* Turns a master unixstream object into a client object.
\*-------------------------------------------------------------------------*/
static const char *unixstream_tryconnect(p_unix un, const char *path)
static const char *unixstream_tryconnect(p_unix un, const char *path, size_t len)
{
struct sockaddr_un remote;
int err;
size_t len = strlen(path);
if (len >= sizeof(remote.sun_path)) return "path too long";
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
memcpy(remote.sun_path, path, len);
remote.sun_family = AF_UNIX;
timeout_markstart(&un->tm);
#ifdef UNIX_HAS_SUN_LEN
@ -259,8 +258,9 @@ static const char *unixstream_tryconnect(p_unix un, const char *path)
static int meth_connect(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixstream_tryconnect(un, path);
size_t len;
const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixstream_tryconnect(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);

View File

@ -20,9 +20,6 @@
#ifndef SOCKET_SELECT
#include <sys/poll.h>
#define WAITFD_R POLLIN
#define WAITFD_W POLLOUT
#define WAITFD_C (POLLIN|POLLOUT)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;
struct pollfd pfd;
@ -41,9 +38,6 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
}
#else
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_C (WAITFD_R|WAITFD_W)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;

View File

@ -56,4 +56,20 @@ typedef struct sockaddr_storage t_sockaddr_storage;
#define SOCKET_INVALID (-1)
#ifndef SOCKET_SELECT
#include <sys/poll.h>
#define WAITFD_R POLLIN
#define WAITFD_W POLLOUT
#define WAITFD_C (POLLIN|POLLOUT)
#else
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_C (WAITFD_R|WAITFD_W)
#endif
#endif /* USOCKET_H */

View File

@ -42,10 +42,6 @@ int socket_close(void) {
/*-------------------------------------------------------------------------*\
* Wait for readable/writable/connected socket with timeout
\*-------------------------------------------------------------------------*/
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_E 4
#define WAITFD_C (WAITFD_E|WAITFD_W)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;

View File

@ -30,4 +30,9 @@ typedef t_socket *p_socket;
#define AI_NUMERICSERV (0)
#endif
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_E 4
#define WAITFD_C (WAITFD_E|WAITFD_W)
#endif /* WSOCKET_H */