X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=dgram%2Fdgram.c;h=81487921b7cbca3900d7d66f6734bb9ed671b71d;hp=e541a3a2ed5891c687696d7bae982f4d18668d76;hb=b6017ccf067a7fefa893c8bf19288a1909f17263;hpb=7419270cc04e1d026b31838c527cf051550a2add diff --git a/dgram/dgram.c b/dgram/dgram.c index e541a3a..8148792 100644 --- a/dgram/dgram.c +++ b/dgram/dgram.c @@ -13,49 +13,33 @@ #include "hbytes.h" typedef struct DgramSocket { - int ix, fd, script_llength; + int ix; /* first ! */ + int fd, script_llength; Tcl_Interp *ip; Tcl_Obj *script; void *addr_buf, *msg_buf; int addr_buflen, msg_buflen; } DgramSocket; -static int n_socks; -static DgramSocket **socks; - -static int sockfail(Tcl_Interp *ip, int fd, const char *m) { - int e; - e= errno; - close(fd); - return posixerr(ip,e,m); -} +IdDataTable dgram_socks= { "dgramsock" }; int do_dgram_socket_create(ClientData cd, Tcl_Interp *ip, - SockAddr_Value local, DgramSockID *sock_r) { - int fd, al, r, sockix; + SockAddr_Value local, void **sock_r) { + int fd, al, r; DgramSocket *sock; const struct sockaddr *sa; - for (sockix=0; sockix=n_socks) { - n_socks += 2; - n_socks *= 2; - socks= (void*)Tcl_Realloc((void*)socks, n_socks*sizeof(*socks)); - while (sockixsa_family, SOCK_DGRAM, 0); if (fd<0) return posixerr(ip,errno,"socket"); - r= bind(fd, sa, al); if (r) return sockfail(ip,fd,"bind"); - r= setnonblock(fd, 1); if (r) return sockfail(ip,fd,"setnonblock"); + r= bind(fd, sa, al); if (r) return newfdposixerr(ip,fd,"bind"); + r= setnonblock(fd, 1); if (r) return newfdposixerr(ip,fd,"setnonblock"); - socks[sockix]= sock= TALLOC(sizeof(DgramSocket)); + sock= TALLOC(sizeof(DgramSocket)); + sock->ix= -1; sock->fd= fd; - sock->ix= sockix; sock->script= 0; sock->addr_buflen= al+1; sock->addr_buf= TALLOC(sock->addr_buflen); @@ -67,8 +51,9 @@ int do_dgram_socket_create(ClientData cd, Tcl_Interp *ip, } int do_dgram_socket_transmit(ClientData cd, Tcl_Interp *ip, - DgramSocket *sock, HBytes_Value data, + void *sock_v, HBytes_Value data, SockAddr_Value remote) { + DgramSocket *sock= sock_v; int l, r; r= sendto(sock->fd, @@ -139,7 +124,7 @@ static void recv_call(ClientData sock_cd, int mask) { 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_sockid(ip, sock); + args[2]= ret_iddata(ip, sock, &dgram_socks); for (i=0; i<3; i++) Tcl_IncrRefCount(args[i]); invoke= Tcl_DuplicateObj(sock->script); @@ -159,7 +144,8 @@ x_rc: } int do_dgram_socket_on_receive(ClientData cd, Tcl_Interp *ip, - DgramSocket *sock, Tcl_Obj *script) { + void *sock_v, Tcl_Obj *script) { + DgramSocket *sock= sock_v; int rc; if (script) { @@ -177,7 +163,8 @@ int do_dgram_socket_on_receive(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -int do_dgram_socket_close(ClientData cd, Tcl_Interp *ip, DgramSocket *sock) { +int do_dgram_socket_close(ClientData cd, Tcl_Interp *ip, void *sock_v) { + DgramSocket *sock= sock_v; int sockix; cancel(sock); close(sock->fd); /* nothing useful to be done with errors */ @@ -185,73 +172,6 @@ int do_dgram_socket_close(ClientData cd, Tcl_Interp *ip, DgramSocket *sock) { TFREE(sock->addr_buf); TFREE(sock->msg_buf); TFREE(sock); - socks[sockix]= 0; - return TCL_OK; -} - -/* Arg parsing */ - -int pat_sockid(Tcl_Interp *ip, Tcl_Obj *o, DgramSocket **val) { - int rc, sockix; - DgramSocket *sock; - - rc= Tcl_ConvertToType(ip,o,&dgramsockid_type); - if (rc) return rc; - - sockix= o->internalRep.longValue; - if (sockix >= n_socks || !(sock= socks[sockix])) - return staticerr(ip,"dgram socket not open",0); - - assert(socks[sockix]->ix == sockix); - - *val= sock; - return TCL_OK; -} - -Tcl_Obj *ret_sockid(Tcl_Interp *ip, DgramSocket *val) { - Tcl_Obj *o; - - o= Tcl_NewObj(); - Tcl_InvalidateStringRep(o); - o->internalRep.longValue= val->ix; - o->typePtr= &dgramsockid_type; - return o; -} - -static void sockid_t_free(Tcl_Obj *o) { } - -static void sockid_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { - dup->internalRep= src->internalRep; - dup->typePtr= &dgramsockid_type; -} - -static void sockid_t_ustr(Tcl_Obj *o) { - char buf[75]; - - snprintf(buf,sizeof(buf), "%d", (int)o->internalRep.longValue); - obj_updatestr_vstringls(o, - "dgramsock",9, - buf, strlen(buf), - (char*)0); -} - -static int sockid_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { - unsigned long ul; - char *ep, *str; - - str= Tcl_GetStringFromObj(o,0); - if (memcmp(str,"dgramsock",9)) return staticerr(ip,"bad dgram socket id",0); - errno=0; ul=strtoul(str+9,&ep,10); - if (errno || *ep) return staticerr(ip,"bad dgram socket id number",0); - if (ul > INT_MAX) return staticerr(ip,"out of range dgram socket id",0); - - objfreeir(o); - o->internalRep.longValue= ul; - o->typePtr= &dgramsockid_type; + dgram_socks.a[sockix]= 0; return TCL_OK; } - -Tcl_ObjType dgramsockid_type = { - "dgramsockid", - sockid_t_free, sockid_t_dup, sockid_t_ustr, sockid_t_sfa -};