chiark / gitweb /
do not crash on disposal of sock and tuntap
[chiark-tcl.git] / tuntap / tuntap.c
index ee8e99e7aa4e99011b044afe49833fd423970759..60a8cdcdeae0f8261da14e0e509063cd0d8101ff 100644 (file)
@@ -1,18 +1,17 @@
 /*
  */
 /*
- * tuntap-socket-rawlinux create [<ifname>] => <sockid>
- * tuntap-socket-rawlinux ifname <sockid> => <ifname>
- * tuntap-socket-rawlinux close <sockid>
- * tuntap-socket-rawlinux receive <sockid> <data>
- * tuntap-socket-rawlinux on-transmit <sockid> <mtu> [<script>]
+ * tuntap-socket-raw create [<ifname>] => <sockid>
+ * tuntap-socket-raw ifname <sockid> => <ifname>
+ * tuntap-socket-raw close <sockid>
+ * tuntap-socket-raw receive <sockid> <data>
+ * tuntap-socket-raw on-transmit <sockid> <mtu> [<script>]
  *    calls, effectively,  eval <script> [list <data> <socket>]
  *    if script not supplied, cancel
  */
 
 #include "tables.h"
 #include "hbytes.h"
-#include "hbytes.h"
 
 #include <sys/ioctl.h>
 #include <linux/if.h>
@@ -27,10 +26,8 @@ typedef struct TunSocket {
   char *ifname;
 } TuntapSocket;
 
-IdDataTable tuntap_socks= { "tuntap" };
-
-int do_tuntap_socket_create(ClientData cd, Tcl_Interp *ip,
-                           const char *ifname, void **sock_r) {
+int do_tuntap_socket_raw_create(ClientData cd, Tcl_Interp *ip,
+                               const char *ifname, void **sock_r) {
   int fd, r;
   struct ifreq ifr;
   TuntapSocket *sock;
@@ -66,8 +63,8 @@ int do_tuntap_socket_create(ClientData cd, Tcl_Interp *ip,
   return TCL_OK;
 }
 
-int do_tuntap_socket_receive(ClientData cd, Tcl_Interp *ip,
-                            void *sock_v, HBytes_Value data) {
+int do_tuntap_socket_raw_receive(ClientData cd, Tcl_Interp *ip,
+                                void *sock_v, HBytes_Value data) {
   TuntapSocket *sock= sock_v;
   int l, r;
 
@@ -78,8 +75,8 @@ int do_tuntap_socket_receive(ClientData cd, Tcl_Interp *ip,
   return TCL_OK;
 }
 
-int do_tuntap_socket_ifname(ClientData cd, Tcl_Interp *ip,
-                           void *sock_v, const char **result) {
+int do_tuntap_socket_raw_ifname(ClientData cd, Tcl_Interp *ip,
+                               void *sock_v, const char **result) {
   TuntapSocket *sock= sock_v;
   *result= sock->ifname;
   return TCL_OK;
@@ -121,8 +118,9 @@ x_rc:
   if (rc) Tcl_BackgroundError(ip);
 }
 
-int do_tuntap_socket_on_transmit(ClientData cd, Tcl_Interp *ip, void *sock_v,
-                                long mtu, Tcl_Obj *newscript) {
+int do_tuntap_socket_raw_on_transmit(ClientData cd, Tcl_Interp *ip,
+                                    void *sock_v,
+                                    long mtu, Tcl_Obj *newscript) {
   TuntapSocket *sock= sock_v;
   int rc;
 
@@ -132,7 +130,7 @@ int do_tuntap_socket_on_transmit(ClientData cd, Tcl_Interp *ip, void *sock_v,
   cancel(sock);
   
   if (newscript) {
-    rc= scriptinv_set(&sock->script,ip,newscript);
+    rc= scriptinv_set(&sock->script,ip,newscript,0);
     if (rc) return rc;
     
     sock->mtu= mtu;
@@ -142,15 +140,24 @@ int do_tuntap_socket_on_transmit(ClientData cd, Tcl_Interp *ip, void *sock_v,
   return TCL_OK;
 }
 
-int do_tuntap_socket_close(ClientData cd, Tcl_Interp *ip, void *sock_v) {
+static void destroy(void *sock_v) {
   TuntapSocket *sock= sock_v;
-  
-  int sockix;
   cancel(sock);
   close(sock->fd); /* nothing useful to be done with errors */
-  sockix= sock->ix;
   TFREE(sock->msg_buf);
   TFREE(sock);
-  tuntap_socks.a[sockix]= 0;
+}
+
+static void destroy_idtabcb(Tcl_Interp *ip, void *sock_v) {
+  destroy(sock_v);
+}
+
+int do_tuntap_socket_raw_close(ClientData cd, Tcl_Interp *ip, void *sock) {
+  tabledataid_disposing(ip,sock,&tuntap_socks);
+  destroy(sock);
   return TCL_OK;
 }
+
+const IdDataSpec tuntap_socks= {
+  "tuntap", "tuntap-table", destroy_idtabcb
+};