]> jfr.im git - irc/quakenet/newserv.git/blobdiff - lua/luasocket.c
merge
[irc/quakenet/newserv.git] / lua / luasocket.c
index 4e1ae02722d7fb3f063e0d915a495e2525011606..3aa6f6e5c3a87ab05bb179b1ad4c92e705e7360e 100644 (file)
@@ -14,7 +14,7 @@
 #include "lua.h"
 #include "luabot.h"
 
-#define lua_vnpcall(F2, N2, S2, ...) _lua_vpcall(F2->l->l, (void *)F2->handler, LUA_POINTERMODE, "ls" S2 , F2->identifier, N2 , ##__VA_ARGS__)
+#define lua_vnpcall(F2, N2, S2, ...) _lua_vpcall(F2->l->l, (void *)F2->handler, LUA_POINTERMODE, "lsR" S2 , F2->identifier, N2, F2->tag , ##__VA_ARGS__)
 
 /*
  * instead of these identifiers I could just use the file descriptor...
@@ -34,17 +34,20 @@ static int lua_socket_unix_connect(lua_State *l) {
   if(!ll)
     return 0;
 
+  if(!lua_isfunction(l, 2))
+    return 0;
+
   path = (char *)lua_tostring(l, 1);
   if(!path)
     return 0;
 
-  ls = (lua_socket *)malloc(sizeof(lua_socket));
+  ls = (lua_socket *)luamalloc(sizeof(lua_socket));
   if(!ls)
     return 0;
 
   ls->fd = socket(AF_UNIX, SOCK_STREAM, 0);
   if(ls->fd <= -1) {
-    free(ls);
+    luafree(ls);
     return 0;
   }
 
@@ -58,14 +61,14 @@ static int lua_socket_unix_connect(lua_State *l) {
   /* WTB exceptions */
   ret = fcntl(ls->fd, F_GETFL, 0);
   if(ret < 0) {
-    free(ls);
+    luafree(ls);
     close(ls->fd);
     return 0;
   }
 
   ret = fcntl(ls->fd, F_SETFL, ret | O_NONBLOCK);
   if(ret < 0) {
-    free(ls);
+    luafree(ls);
     close(ls->fd);
     return 0;
   }
@@ -76,14 +79,16 @@ static int lua_socket_unix_connect(lua_State *l) {
   } else if(ret == -1 && (errno == EINPROGRESS)) {
     ls->state = SOCKET_CONNECTING;
   } else {
-    free(ls);
+    luafree(ls);
     close(ls->fd);
     return 0;
   }
 
   /* this whole identifier thing should probably use userdata stuff */
   ls->identifier = nextidentifier++;
+  ls->tag = luaL_ref(l, LUA_REGISTRYINDEX);
   ls->handler = luaL_ref(l, LUA_REGISTRYINDEX);
+
   ls->l = ll;
 
   ls->next = ll->sockets;
@@ -91,8 +96,9 @@ static int lua_socket_unix_connect(lua_State *l) {
 
   registerhandler(ls->fd, (ls->state==SOCKET_CONNECTED?POLLIN:POLLOUT) | POLLERR | POLLHUP, lua_socket_poll_event);
 
+  lua_pushboolean(l, ls->state==SOCKET_CONNECTED?1:0);
   lua_pushlong(l, ls->identifier);
-  return 1;
+  return 2;
 }
 
 static lua_socket *socketbyfd(int fd) {
@@ -138,9 +144,10 @@ static void lua_socket_call_close(lua_socket *ls) {
         p->next = ls->next;
       }
 
+      luaL_unref(ls->l->l, LUA_REGISTRYINDEX, ls->tag);
       luaL_unref(ls->l->l, LUA_REGISTRYINDEX, ls->handler);
 
-      free(ls);
+      luafree(ls);
       return;
     }
   }
@@ -171,12 +178,19 @@ static int lua_socket_write(lua_State *l) {
   if(ret == -1 && (errno == EAGAIN)) {
     deregisterhandler(ls->fd, 0);
     registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event);
-    return 0;
+
+    lua_pushint(l, 0);
+    return 1;
   }
 
   if(ret == -1)
     lua_socket_call_close(ls);
 
+  if(ret < len) {
+    deregisterhandler(ls->fd, 0);
+    registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event);
+  }
+
   lua_pushint(l, ret);
   return 1;
 }
@@ -236,7 +250,7 @@ static void lua_socket_poll_event(int fd, short events) {
          return;
         }
 
-        lua_vnpcall(ls, "read", "L", buf, bytesread);
+        lua_vnpcall(ls, "read", "L", buf, (long)bytesread);
       }
       break;
   }