moonbridge

changeset 118:118e320a7812

Delete local socket in filesystem before and after listening
author jbe
date Fri Apr 10 13:08:34 2015 +0200 (2015-04-10)
parents d8469c1039e6
children 84aa2b8dcf79
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Fri Apr 10 02:40:43 2015 +0200
     1.2 +++ b/moonbridge_io.c	Fri Apr 10 13:08:34 2015 +0200
     1.3 @@ -12,6 +12,7 @@
     1.4  #include <netinet/tcp.h>
     1.5  #include <arpa/inet.h>
     1.6  #include <sys/types.h>
     1.7 +#include <sys/stat.h>
     1.8  #include <netdb.h>
     1.9  #include <signal.h>
    1.10  #include <time.h>
    1.11 @@ -63,6 +64,7 @@
    1.12  
    1.13  typedef struct {
    1.14    int fd;
    1.15 +  sa_family_t addrfam;
    1.16    int nonblocking;
    1.17  } moonbr_io_listener_t;
    1.18  
    1.19 @@ -760,6 +762,7 @@
    1.20  static int moonbr_io_locallisten(lua_State *L) {
    1.21    moonbr_io_listener_t *listener;
    1.22    const char *path;
    1.23 +  struct stat sb;
    1.24    struct sockaddr_un sockaddr = { .sun_family = AF_LOCAL };
    1.25    const int path_maxlen = sizeof(struct sockaddr_un) - (
    1.26      (void *)sockaddr.sun_path - (void *)&sockaddr
    1.27 @@ -768,6 +771,9 @@
    1.28    path = luaL_checkstring(L, 1);
    1.29    if (strlen(path) > path_maxlen) luaL_error(L, "Path too long; only %i characters allowed", path_maxlen);
    1.30    strcpy(sockaddr.sun_path, path);
    1.31 +  if (stat(path, &sb) == 0) {
    1.32 +    if (S_ISSOCK(sb.st_mode)) unlink(path);
    1.33 +  }
    1.34    listener = lua_newuserdata(L, sizeof(moonbr_io_listener_t));
    1.35    listener->fd = -1;
    1.36    luaL_setmetatable(L, MOONBR_IO_LISTENER_MT_REGKEY);
    1.37 @@ -797,6 +803,7 @@
    1.38      return 2;
    1.39    }
    1.40    listener->fd = sock;
    1.41 +  listener->addrfam = AF_LOCAL;
    1.42    listener->nonblocking = -1;
    1.43    return 1;
    1.44  }
    1.45 @@ -838,6 +845,7 @@
    1.46    }
    1.47    addrinfo = res;
    1.48    moonbr_io_tcpconnect_found:
    1.49 +  listener->addrfam = addrinfo->ai_family;
    1.50    sock = socket(
    1.51      addrinfo->ai_family,
    1.52      addrinfo->ai_socktype | SOCK_CLOEXEC,
    1.53 @@ -925,16 +933,31 @@
    1.54  
    1.55  static int moonbr_io_unlisten(lua_State *L) {
    1.56    moonbr_io_listener_t *listener;
    1.57 +  struct sockaddr_un addr;
    1.58 +  socklen_t addrlen;
    1.59 +  struct stat sb;
    1.60    listener = luaL_checkudata(L, 1, MOONBR_IO_LISTENER_MT_REGKEY);
    1.61    if (listener->fd < 0) luaL_error(L, "Attempt to close a closed listener");
    1.62 +  addrlen = sizeof(addr);
    1.63 +  if (getsockname(listener->fd, (struct sockaddr *)&addr, &addrlen)) addrlen = 0;
    1.64    if (close(listener->fd)) {
    1.65      moonbr_io_errmsg();
    1.66      listener->fd = -1;
    1.67 +    if (addrlen && addrlen <= sizeof(addr)) {
    1.68 +      if (stat(addr.sun_path, &sb) == 0) {
    1.69 +        if (S_ISSOCK(sb.st_mode)) unlink(addr.sun_path);
    1.70 +      }
    1.71 +    }
    1.72      lua_pushnil(L);
    1.73      lua_pushstring(L, errmsg);
    1.74      return 2;
    1.75    }
    1.76    listener->fd = -1;
    1.77 +  if (addrlen && addrlen <= sizeof(addr)) {
    1.78 +    if (stat(addr.sun_path, &sb) == 0) {
    1.79 +      if (S_ISSOCK(sb.st_mode)) unlink(addr.sun_path);
    1.80 +    }
    1.81 +  }
    1.82    lua_pushboolean(L, 1);
    1.83    return 1;
    1.84  }
     2.1 --- a/reference.txt	Fri Apr 10 02:40:43 2015 +0200
     2.2 +++ b/reference.txt	Fri Apr 10 13:08:34 2015 +0200
     2.3 @@ -264,11 +264,8 @@
     2.4  ### moonbridge_io.locallisten(path)
     2.5  
     2.6  Attempts to create a local socket (also known as Unix Domain Socket) to accept
     2.7 -incoming connections.
     2.8 -
     2.9 -Note: The caller is responsible for unlinking the socket in the filesystem
    2.10 -before opening or after closing the listening socket. If a file (or socket)
    2.11 -already exists at the given path, this function returns with an I/O error.
    2.12 +incoming connections. If the file does already exist and is a socket, then it
    2.13 +is deleted automatically before being re-created.
    2.14  
    2.15  In case of an I/O error, nil (as first return value) plus an error message (as
    2.16  second return value) may be returned.On success, a listener object is returned

Impressum / About Us