# HG changeset patch # User jbe # Date 1428664114 -7200 # Node ID 118e320a7812cb2fe99b189b0c74f51527cbfd4f # Parent d8469c1039e64ed0fabc68b43182eec9e6d08cf9 Delete local socket in filesystem before and after listening diff -r d8469c1039e6 -r 118e320a7812 moonbridge_io.c --- a/moonbridge_io.c Fri Apr 10 02:40:43 2015 +0200 +++ b/moonbridge_io.c Fri Apr 10 13:08:34 2015 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ typedef struct { int fd; + sa_family_t addrfam; int nonblocking; } moonbr_io_listener_t; @@ -760,6 +762,7 @@ static int moonbr_io_locallisten(lua_State *L) { moonbr_io_listener_t *listener; const char *path; + struct stat sb; struct sockaddr_un sockaddr = { .sun_family = AF_LOCAL }; const int path_maxlen = sizeof(struct sockaddr_un) - ( (void *)sockaddr.sun_path - (void *)&sockaddr @@ -768,6 +771,9 @@ path = luaL_checkstring(L, 1); if (strlen(path) > path_maxlen) luaL_error(L, "Path too long; only %i characters allowed", path_maxlen); strcpy(sockaddr.sun_path, path); + if (stat(path, &sb) == 0) { + if (S_ISSOCK(sb.st_mode)) unlink(path); + } listener = lua_newuserdata(L, sizeof(moonbr_io_listener_t)); listener->fd = -1; luaL_setmetatable(L, MOONBR_IO_LISTENER_MT_REGKEY); @@ -797,6 +803,7 @@ return 2; } listener->fd = sock; + listener->addrfam = AF_LOCAL; listener->nonblocking = -1; return 1; } @@ -838,6 +845,7 @@ } addrinfo = res; moonbr_io_tcpconnect_found: + listener->addrfam = addrinfo->ai_family; sock = socket( addrinfo->ai_family, addrinfo->ai_socktype | SOCK_CLOEXEC, @@ -925,16 +933,31 @@ static int moonbr_io_unlisten(lua_State *L) { moonbr_io_listener_t *listener; + struct sockaddr_un addr; + socklen_t addrlen; + struct stat sb; listener = luaL_checkudata(L, 1, MOONBR_IO_LISTENER_MT_REGKEY); if (listener->fd < 0) luaL_error(L, "Attempt to close a closed listener"); + addrlen = sizeof(addr); + if (getsockname(listener->fd, (struct sockaddr *)&addr, &addrlen)) addrlen = 0; if (close(listener->fd)) { moonbr_io_errmsg(); listener->fd = -1; + if (addrlen && addrlen <= sizeof(addr)) { + if (stat(addr.sun_path, &sb) == 0) { + if (S_ISSOCK(sb.st_mode)) unlink(addr.sun_path); + } + } lua_pushnil(L); lua_pushstring(L, errmsg); return 2; } listener->fd = -1; + if (addrlen && addrlen <= sizeof(addr)) { + if (stat(addr.sun_path, &sb) == 0) { + if (S_ISSOCK(sb.st_mode)) unlink(addr.sun_path); + } + } lua_pushboolean(L, 1); return 1; } diff -r d8469c1039e6 -r 118e320a7812 reference.txt --- a/reference.txt Fri Apr 10 02:40:43 2015 +0200 +++ b/reference.txt Fri Apr 10 13:08:34 2015 +0200 @@ -264,11 +264,8 @@ ### moonbridge_io.locallisten(path) Attempts to create a local socket (also known as Unix Domain Socket) to accept -incoming connections. - -Note: The caller is responsible for unlinking the socket in the filesystem -before opening or after closing the listening socket. If a file (or socket) -already exists at the given path, this function returns with an I/O error. +incoming connections. If the file does already exist and is a socket, then it +is deleted automatically before being re-created. In case of an I/O error, nil (as first return value) plus an error message (as second return value) may be returned.On success, a listener object is returned