X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=dgram%2Fdgram.c;h=24c5446c0b1625528f98fbb5ce4dceb664845f28;hp=b2661a4fe82611792a359e02fb25a12ee3c713ff;hb=ceed4cf646a34245b3bc88089a2187ebf7a41f0f;hpb=ed7354bcb695fcf3ee3f5cea14be209fbb99f161 diff --git a/dgram/dgram.c b/dgram/dgram.c index b2661a4..24c5446 100644 --- a/dgram/dgram.c +++ b/dgram/dgram.c @@ -9,8 +9,7 @@ * if script not supplied, cancel */ -#include "tables.h" -#include "hbytes.h" +#include "dgram.h" typedef struct DgramSocket { int ix; /* first ! */ @@ -21,21 +20,19 @@ typedef struct DgramSocket { int addr_buflen, msg_buflen; } DgramSocket; -IdDataTable dgram_socks= { "dgramsock" }; - -int do_dgram_socket_create(ClientData cd, Tcl_Interp *ip, +int cht_do_dgramsocket_create(ClientData cd, Tcl_Interp *ip, SockAddr_Value local, void **sock_r) { int fd, al, r; DgramSocket *sock; const struct sockaddr *sa; - sa= sockaddr_addr(&local); - al= sockaddr_len(&local); + sa= cht_sockaddr_addr(&local); + al= cht_sockaddr_len(&local); fd= socket(sa->sa_family, SOCK_DGRAM, 0); - if (fd<0) return posixerr(ip,errno,"socket"); - r= bind(fd, sa, al); if (r) return newfdposixerr(ip,fd,"bind"); - r= setnonblock(fd, 1); if (r) return newfdposixerr(ip,fd,"setnonblock"); + if (fd<0) return cht_posixerr(ip,errno,"socket"); + r= bind(fd, sa, al); if (r) return cht_newfdposixerr(ip,fd,"bind"); + r= cht_setnonblock(fd, 1); if (r) return cht_newfdposixerr(ip,fd,"setnonblock"); sock= TALLOC(sizeof(DgramSocket)); sock->ix= -1; @@ -44,37 +41,37 @@ int do_dgram_socket_create(ClientData cd, Tcl_Interp *ip, sock->addr_buf= TALLOC(sock->addr_buflen); sock->msg_buflen= 0; sock->msg_buf= 0; - scriptinv_init(&sock->script); + cht_scriptinv_init(&sock->script); *sock_r= sock; return TCL_OK; } -int do_dgram_socket_transmit(ClientData cd, Tcl_Interp *ip, +int cht_do_dgramsocket_transmit(ClientData cd, Tcl_Interp *ip, void *sock_v, HBytes_Value data, SockAddr_Value remote) { DgramSocket *sock= sock_v; int l, r; r= sendto(sock->fd, - hbytes_data(&data), l=hbytes_len(&data), + cht_hb_data(&data), l=cht_hb_len(&data), 0, - sockaddr_addr(&remote), sockaddr_len(&remote)); - if (r==-1) return posixerr(ip,errno,"sendto"); - else if (r!=l) return staticerr(ip,"sendto gave wrong answer",0); + cht_sockaddr_addr(&remote), cht_sockaddr_len(&remote)); + if (r==-1) return cht_posixerr(ip,errno,"sendto"); + else if (r!=l) return cht_staticerr(ip,"sendto gave wrong answer",0); return TCL_OK; } static void cancel(DgramSocket *sock) { - if (sock->script.obj) { - scriptinv_cancel(&sock->script); + if (sock->script.script) { + cht_scriptinv_cancel(&sock->script); Tcl_DeleteFileHandler(sock->fd); } } static void recv_call(ClientData sock_cd, int mask) { DgramSocket *sock= (void*)sock_cd; - Tcl_Interp *ip= sock->script.ip; + Tcl_Interp *ip= sock->script.ipq; int sz, rc, peek; HBytes_Value message_val; SockAddr_Value peer_val; @@ -82,8 +79,8 @@ static void recv_call(ClientData sock_cd, int mask) { struct msghdr mh; struct iovec iov; - hbytes_empty(&message_val); - sockaddr_clear(&peer_val); + cht_hb_empty(&message_val); + cht_sockaddr_clear(&peer_val); mh.msg_iov= &iov; mh.msg_iovlen= 1; @@ -103,7 +100,7 @@ static void recv_call(ClientData sock_cd, int mask) { sz= recvmsg(sock->fd, &mh, peek); if (sz==-1) { if (errno == EAGAIN || errno == EWOULDBLOCK) rc=0; - else rc= posixerr(ip,errno,"recvmsg"); + else rc= cht_posixerr(ip,errno,"recvmsg"); goto x_rc; } @@ -116,18 +113,19 @@ static void recv_call(ClientData sock_cd, int mask) { } TFREE(sock->msg_buf); + assert(sock->msg_buflen < INT_MAX/4); sock->msg_buflen *= 2; sock->msg_buflen += 100; sock->msg_buf= TALLOC(sock->msg_buflen); } - hbytes_array(&message_val, iov.iov_base, sz); - sockaddr_create(&peer_val, mh.msg_name, mh.msg_namelen); + cht_hb_array(&message_val, iov.iov_base, sz); + cht_sockaddr_create(&peer_val, mh.msg_name, mh.msg_namelen); - args[0]= ret_hb(ip, message_val); hbytes_empty(&message_val); - args[1]= ret_sockaddr(ip, peer_val); sockaddr_clear(&peer_val); - args[2]= ret_iddata(ip, sock, &dgram_socks); - scriptinv_invoke(&sock->script,3,args); + args[0]= cht_ret_hb(ip, message_val); cht_hb_empty(&message_val); + args[1]= cht_ret_sockaddr(ip, peer_val); cht_sockaddr_clear(&peer_val); + args[2]= cht_ret_iddata(ip, sock, &cht_dgram_socks); + cht_scriptinv_invoke(&sock->script,3,args); rc= 0; @@ -136,7 +134,7 @@ x_rc: Tcl_BackgroundError(ip); } -int do_dgram_socket_on_receive(ClientData cd, Tcl_Interp *ip, +int cht_do_dgramsocket_on_receive(ClientData cd, Tcl_Interp *ip, void *sock_v, Tcl_Obj *newscript) { DgramSocket *sock= sock_v; int rc; @@ -144,7 +142,7 @@ int do_dgram_socket_on_receive(ClientData cd, Tcl_Interp *ip, cancel(sock); if (newscript) { - rc= scriptinv_set(&sock->script, ip, newscript); + rc= cht_scriptinv_set(&sock->script, ip, newscript, 0); if (rc) return rc; } @@ -152,15 +150,24 @@ int do_dgram_socket_on_receive(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -int do_dgram_socket_close(ClientData cd, Tcl_Interp *ip, void *sock_v) { - DgramSocket *sock= sock_v; - int sockix; +static void destroy(DgramSocket *sock) { cancel(sock); close(sock->fd); /* nothing useful to be done with errors */ - sockix= sock->ix; TFREE(sock->addr_buf); TFREE(sock->msg_buf); TFREE(sock); - dgram_socks.a[sockix]= 0; +} + +static void destroy_idtabcb(Tcl_Interp *ip, void *sock_v) { + destroy(sock_v); +} + +int cht_do_dgramsocket_close(ClientData cd, Tcl_Interp *ip, void *sock_v) { + cht_tabledataid_disposing(ip,sock_v,&cht_dgram_socks); + destroy(sock_v); return TCL_OK; } + +const IdDataSpec cht_dgram_socks= { + "dgramsock", "dgramsock-table", destroy_idtabcb +};