diff --git a/stio/lib/stio-prv.h b/stio/lib/stio-prv.h index f33cb38..1d48c7c 100644 --- a/stio/lib/stio-prv.h +++ b/stio/lib/stio-prv.h @@ -103,6 +103,8 @@ struct stio_t extern "C" { #endif +stio_errnum_t stio_syserrtoerrnum (int no); + stio_sckhnd_t stio_openasyncsck (int domain, int type); void stio_closeasyncsck (stio_sckhnd_t sck); int stio_makesckasync (stio_sckhnd_t sck); diff --git a/stio/lib/stio-tcp.c b/stio/lib/stio-tcp.c index 03e2390..895379e 100644 --- a/stio/lib/stio-tcp.c +++ b/stio/lib/stio-tcp.c @@ -55,8 +55,7 @@ static int tcp_make (stio_dev_t* dev, void* ctx) if (setsockopt (tcp->sck, SOL_SOCKET, SO_REUSEADDR, &iv, STIO_SIZEOF(iv)) == -1 || bind (tcp->sck, (struct sockaddr*)&arg->addr, len) == -1) { - // TODO: set errnum from errno ... - //dev->stio->errnum = STIO_EINVAL; + tcp->stio->errnum = stio_syserrtoerrnum(errno); goto oops; } @@ -124,6 +123,7 @@ static int tcp_recv (stio_dev_t* dev, void* buf, stio_len_t* len) { if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */ if (errno == EINTR) return 0; + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -146,6 +146,7 @@ static int tcp_send (stio_dev_t* dev, const void* data, stio_len_t* len) { if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */ if (errno == EINTR) return 0; + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -199,7 +200,7 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) x = bind (tcp->sck, sa, sl); if (x == -1) { - /* TODO: set dev->errnum from errno */ + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -264,7 +265,7 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) } } - /* TODO: set dev->errnum from errno */ + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -288,7 +289,7 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) x = listen (tcp->sck, lstn->backlogs); if (x == -1) { - /* TODO: set tcp->stio->errnum */ + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -340,9 +341,14 @@ printf ("TCP READY...%p\n", dev); stio_scklen_t len; len = STIO_SIZEOF(errcode); - if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == 0) + if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1) { - printf ("CANNOT CONNECT ERRORCODE - %s\n", strerror(errcode)); +printf ("CANNOT CONNECT ERRORCODE - %s\n", strerror(errcode)); + tcp->stio->errnum = stio_syserrtoerrnum(errno); + } + else + { + tcp->stio->errnum = stio_syserrtoerrnum(errcode); } return -1; @@ -354,11 +360,11 @@ printf ("TCP READY...%p\n", dev); STIO_ASSERT (!(tcp->state & STIO_DEV_TCP_CONNECTED)); - printf ("XXXXXXXXXXXXXXX CONNECTED...\n"); +printf ("XXXXXXXXXXXXXXX CONNECTED...\n"); len = STIO_SIZEOF(errcode); if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1) { - printf ("CANNOT GET SOCKET CONNECTION STATE....\n"); + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } else if (errcode == 0) @@ -368,7 +374,7 @@ printf ("TCP READY...%p\n", dev); if (stio_dev_event ((stio_dev_t*)tcp, STIO_DEV_EVENT_UPD, STIO_DEV_EVENT_IN) <= -1) { - printf ("CAANOT MANIPULTE EVENT ...\n"); +printf ("CAANOT MANIPULTE EVENT ...\n"); return -1; } @@ -390,7 +396,7 @@ printf ("TCP READY...%p\n", dev); } else { - printf ("failed to get SOCKET PROGRESS CODE...\n"); + tcp->stio->errnum = stio_syserrtoerrnum(errcode); return -1; } } @@ -413,7 +419,7 @@ printf ("TCP READY...%p\n", dev); if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */ - /* TODO: set tcp->stio->errnum from errno */ + tcp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -432,7 +438,6 @@ printf ("TCP READY...%p\n", dev); clitcp->parent = tcp; - /* inherit some event handlers from the parent. * you can still change them inside the on_connected handler */ clitcp->on_connected = tcp->on_connected; @@ -475,9 +480,9 @@ static stio_dev_evcb_t tcp_evcb = tcp_on_sent }; -stio_dev_tcp_t* stio_dev_tcp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_tcp_make_t* arg) +stio_dev_tcp_t* stio_dev_tcp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_tcp_make_t* data) { - return (stio_dev_tcp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_tcp_t) + xtnsize, &tcp_mth, &tcp_evcb, (void*)arg); + return (stio_dev_tcp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_tcp_t) + xtnsize, &tcp_mth, &tcp_evcb, (void*)data); } void stio_dev_tcp_kill (stio_dev_tcp_t* tcp) diff --git a/stio/lib/stio-udp.c b/stio/lib/stio-udp.c index 226b54c..096ebe3 100644 --- a/stio/lib/stio-udp.c +++ b/stio/lib/stio-udp.c @@ -36,36 +36,25 @@ static int udp_make (stio_dev_t* dev, void* ctx) { -/* NOTE: this can be extended to use ctx to tell between INET and INET6 or other types of sockets without creating a new dev method set. */ - stio_dev_udp_t* udp = (stio_dev_udp_t*)dev; - struct sockaddr* saddr = (struct sockaddr*)ctx; + stio_dev_udp_make_t* arg = (stio_dev_udp_make_t*)ctx; + stio_scklen_t len; + stio_sckfam_t family; - udp->sck = stio_openasyncsck (AF_INET, SOCK_DGRAM); + if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1; + + udp->sck = stio_openasyncsck (family, SOCK_DGRAM); if (udp->sck == STIO_SCKHND_INVALID) goto oops; - if (saddr) + /* some socket options? */ + if (bind (udp->sck, (struct sockaddr*)&arg->addr, len) == -1) { - stio_scklen_t len; - if (saddr->sa_family == AF_INET) - len = STIO_SIZEOF(struct sockaddr_in); - else if (saddr->sa_family == AF_INET6) - len = STIO_SIZEOF(struct sockaddr_in6); - else - { - dev->stio->errnum = STIO_EINVAL; - goto oops; - } - - - //setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...); - if (bind (udp->sck, saddr, len) == -1) - { - //dev->stio->errnum = STIO_EINVAL; TODO: - goto oops; - } + udp->stio->errnum = stio_syserrtoerrnum(errno); + goto oops; } + udp->on_sent = arg->on_sent; + udp->on_recv = arg->on_recv; return 0; oops: @@ -99,12 +88,15 @@ static int udp_recv (stio_dev_t* dev, void* buf, stio_len_t* len) stio_scklen_t addrlen; int x; +/* TODO: udp_recv need source address ... have to extend the send callback to accept the source address */ printf ("UDP RECVFROM...\n"); addrlen = STIO_SIZEOF(udp->peer); x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peer, &addrlen); if (x <= -1) { if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */ + if (errno == EINTR) return 0; + udp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -118,10 +110,13 @@ static int udp_send (stio_dev_t* dev, const void* data, stio_len_t* len) ssize_t x; #if 0 +/* TODO: udp_send need target address ... have to extend the send callback to accept the target address */ x = sendto (udp->sck, data, *len, skad, stio_getskadlen(skad)); if (x <= -1) { if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */ + if (errno == EINTR) return 0; + udp->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -157,6 +152,7 @@ static stio_dev_mth_t udp_mth = static int udp_ready (stio_dev_t* dev, int events) { +/* TODO: ... */ if (events & STIO_DEV_EVENT_ERR) printf ("UDP READY ERROR.....\n"); if (events & STIO_DEV_EVENT_HUP) printf ("UDP READY HANGUP.....\n"); if (events & STIO_DEV_EVENT_PRI) printf ("UDP READY PRI.....\n"); @@ -187,13 +183,9 @@ static stio_dev_evcb_t udp_evcb = }; -stio_dev_udp_t* stio_dev_udp_make (stio_t* stio, stio_size_t xtnsize, stio_sckadr_t* addr) +stio_dev_udp_t* stio_dev_udp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_udp_make_t* data) { - stio_dev_udp_t* udp; - - udp = (stio_dev_udp_t*)stio_makedev (stio, STIO_SIZEOF(*udp) + xtnsize, &udp_mth, &udp_evcb, addr); - - return udp; + return (stio_dev_udp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_udp_t) + xtnsize, &udp_mth, &udp_evcb, (void*)data); } diff --git a/stio/lib/stio-udp.h b/stio/lib/stio-udp.h index 50dcbc6..29fa00f 100644 --- a/stio/lib/stio-udp.h +++ b/stio/lib/stio-udp.h @@ -32,13 +32,27 @@ typedef struct stio_dev_udp_t stio_dev_udp_t; +typedef int (*stio_dev_udp_on_recv_t) (stio_dev_udp_t* dev, const void* data, stio_len_t len); +typedef int (*stio_dev_udp_on_sent_t) (stio_dev_udp_t* dev, void* sendctx); + +typedef struct stio_dev_udp_make_t stio_dev_udp_make_t; +struct stio_dev_udp_make_t +{ + /* TODO: options: REUSEADDR for binding?? */ + stio_sckadr_t addr; /* binding address. */ + stio_dev_udp_on_sent_t on_sent; + stio_dev_udp_on_recv_t on_recv; +}; + struct stio_dev_udp_t { STIO_DEV_HEADERS; stio_sckhnd_t sck; stio_sckadr_t peer; -}; + stio_dev_udp_on_sent_t on_sent; + stio_dev_udp_on_recv_t on_recv; +}; #ifdef __cplusplus extern "C" { @@ -46,9 +60,9 @@ extern "C" { STIO_EXPORT stio_dev_udp_t* stio_dev_udp_make ( - stio_t* stio, - stio_size_t xtnsize, - stio_sckadr_t* addr + stio_t* stio, + stio_size_t xtnsize, + const stio_dev_udp_make_t* data ); STIO_EXPORT void stio_dev_udp_kill ( diff --git a/stio/lib/stio.c b/stio/lib/stio.c index 3673a92..e77f4d9 100644 --- a/stio/lib/stio.c +++ b/stio/lib/stio.c @@ -32,9 +32,6 @@ #include #include - - - stio_t* stio_open (stio_mmgr_t* mmgr, stio_size_t xtnsize, stio_size_t tmrcapa, stio_errnum_t* errnum) { stio_t* stio; @@ -73,8 +70,7 @@ int stio_init (stio_t* stio, stio_mmgr_t* mmgr, stio_size_t tmrcapa) stio->mux = epoll_create (1000); if (stio->mux == -1) { -/* TODO: set error number */ - //if (stio->errnum) *errnum = XXXXX + stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -256,9 +252,8 @@ int stio_exec (stio_t* stio) if (nentries <= -1) { if (errno == EINTR) return 0; /* it's actually ok */ - /* other errors are critical - EBADF, EFAULT, EINVAL */ - /* TODO: set errnum */ + stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -508,7 +503,7 @@ int stio_dev_event (stio_dev_t* dev, stio_dev_event_cmd_t cmd, int flags) if (epoll_ctl (dev->stio->mux, epoll_op, dev->mth->getsyshnd(dev), &ev) == -1) { - /* TODO: set dev->stio->errnum from errno */ + dev->stio->errnum = stio_syserrtoerrnum(errno); return -1; } @@ -576,3 +571,30 @@ int stio_dev_send (stio_dev_t* dev, const void* data, stio_len_t len, void* send dev->evcb->on_sent (dev, sendctx); return 0; } + + +stio_errnum_t stio_syserrtoerrnum (int no) +{ + switch (no) + { + case ENOMEM: + return STIO_ENOMEM; + + case EINVAL: + return STIO_EINVAL; + + case ENOENT: + return STIO_ENOENT; + + case EMFILE: + return STIO_EMFILE; + + #if defined(ENFILE) + case ENFILE: + return STIO_ENFILE; + #endif + + default: + return STIO_ESYSERR; + } +} diff --git a/stio/lib/stio.h b/stio/lib/stio.h index aa1f4a3..a2496bc 100644 --- a/stio/lib/stio.h +++ b/stio/lib/stio.h @@ -94,8 +94,11 @@ enum stio_errnum_t STIO_EINVAL, STIO_ENOENT, STIO_ENOSUP, /* not supported */ + STIO_EMFILE, + STIO_ENFILE, - STIO_EDEVMAKE + STIO_EDEVMAKE, + STIO_ESYSERR }; typedef enum stio_errnum_t stio_errnum_t;