All pastes #954916 Raw Edit

Wolong

public c v1 · immutable
#954916 ·published 2008-03-24 05:29 UTC
rendered paste body
static struct kevent *ke_vec = NULL;static unsigned ke_vec_alloc = 0;static unsigned ke_vec_used = 0;static unsigned ke_vec_ghost = 0;typedef void (action) (register struct kevent const *const kep);typedef struct {    action              *do_read;    action              *do_write;    struct sockaddr_in  sin;    socklen_t           sinsiz;    XML_Parser          parser;    char                **bufs;    int                 *bufsiz;    int                 bufnum;    int                 ident;    int                 on_error;} ecb;int main(...){//создание слушающего сокетаlisten_ecb.do_read = do_accept;listen_ecb.do_write = NULL;listen_ecb.bufs = NULL;int kq = kqueue();ke_change (sock, EVFILT_READ, EV_ADD | EV_ENABLE, &listen_ecb);}static void ke_change (int const ident,int const filter, int const flags, void *const udata){    enum { initial_alloc = 1024 };    struct kevent *kep;    if (!ke_vec_alloc){        ke_vec_alloc=initial_alloc;        ke_vec=(struct kevent*)malloc(ke_vec_alloc*sizeof (struct kevent));    }else if (ke_vec_used == ke_vec_alloc){        ke_vec_alloc<<=1;        ke_vec=(struct kevent*)realloc(ke_vec, ke_vec_alloc*sizeof(struct kevent));    }    kep = &ke_vec[ke_vec_used++];    kep->ident = ident;    kep->filter = filter;    kep->flags = flags;    log_printf(\"ke_change socket=%d filter=%s flags=0x%04x (%s%s%s%s%s%s%s%s), \", kep->ident, (kep->filter==EVFILT_READ?\"EVFILT_READ\":\"EVFILT_WRITE\"), flags,            (flags & EV_EOF) ? \"EV_EOF\" : \"\",            (flags & EV_ERROR)  ? ((flags & (~(EV_ERROR - 1) & ~EV_ERROR)) ? \" | EV_ERROR\" : \"EV_ERROR\") : \"\",            (flags & EV_ADD)    ? ((flags & (EV_SYSFLAGS | (EV_ADD - 1))) ? \" | EV_ADD\" : \"EV_ADD\") : \"\",            (flags & EV_DELETE)   ? ((flags & (EV_SYSFLAGS | (EV_DELETE - 1))) ? \" | EV_DELETE\" : \"EV_DELETE\") : \"\",            (flags & EV_ENABLE)   ? ((flags & (EV_SYSFLAGS | (EV_ENABLE - 1))) ? \" | EV_ENABLE\" : \"EV_ENABLE\") : \"\",            (flags & EV_DISABLE)  ? ((flags & (EV_SYSFLAGS | (EV_DISABLE - 1))) ? \" | EV_DISABLE\" : \"EV_DISABLE\") : \"\",            (flags & EV_ONESHOT)  ? ((flags & (EV_SYSFLAGS | (EV_ONESHOT - 1))) ? \" | EV_ONESHOT\" : \"EV_ONESHOT\") : \"\",            (flags & EV_CLEAR)  ? ((flags & (EV_SYSFLAGS | (EV_CLEAR - 1))) ? \" | EV_CLEAR\" : \"EV_CLEAR\") : \"\" );    kep->fflags = 0;    kep->data = 0;    kep->udata = udata;}void unistall_connect(ecb *ecbp){    ke_change(ecbp->ident, EVFILT_READ, EV_DELETE, NULL);    ke_change(ecbp->ident, EVFILT_WRITE, EV_DELETE, NULL);//    ke_change(ecbp->ident, EVFILT_WRITE, EV_CLEAR, (void*)1);//    ke_change(ecbp->ident, EVFILT_READ, EV_CLEAR, (void*)1);    close(ecbp->ident);    free_msgs(ecbp);    free(ecbp->bufs);    free(ecbp->bufsiz);    XML_ParserFree(ecbp->parser);    free(ecbp);}static void event_loop (int const kq){  while(1){        int n;        struct kevent const *kep;        ke_vec_ghost = ke_vec_used;        log_printf(\"kevent() ke_vec_used = %d\",ke_vec_used);        n = kevent (kq, ke_vec, ke_vec_used, ke_vec, ke_vec_alloc, NULL);        log_printf(\"%d events recieved :)\",n);        ke_vec_used = 0;        if (n == -1)            log_printf(\"Error in kevent(): %s\", strerror (errno));        if (n == 0)            log_printf(\"No events received!\");        for (kep = ke_vec; kep < &ke_vec[n]; kep++){            if(!kep->udata) continue; //костылик            log_printf(\"event socket %d: %s\",kep->ident,(kep->filter==EVFILT_READ?\"EVFILT_READ\":\"!EVFILT_READ\"));            ecb const *const ecbp = (ecb *) kep->udata;            if (kep->filter == EVFILT_READ)                (*ecbp->do_read) (kep);            else                (*ecbp->do_write) (kep);        }    }}static void do_read (register struct kevent const *const kep){    enum { bufsize = 1024 };    char buf[bufsize];    int n;    ecb *ecbp = (ecb *) kep->udata;    if ((n = read (kep->ident, buf, bufsize)) == -1){        log_printf(\"Error reading socket: %s\", strerror (errno));        unistall_connect(ecbp);        return;    }else if(n == 0){        log_printf(\"disconnect %s\",inet_ntoa(ecbp->sin.sin_addr));        unistall_connect(ecbp);        return;    }    if (XML_Parse(ecbp->parser, buf, n, 0) == XML_STATUS_ERROR) {        char *errormsg = calloc(1024, sizeof(char));        sprintf(errormsg, \"<error type=\\\"protocol\\\" line=\\\"%lu\\\">%s</error>\\n\", XML_GetCurrentLineNumber(ecbp->parser),XML_ErrorString(XML_GetErrorCode(ecbp->parser)));        add_msg(ecbp,errormsg);        ecbp->on_error=1;        log_printf(\"disconnect %s on protocol error\",inet_ntoa(ecbp->sin.sin_addr));    }}static void do_write(register struct kevent const *const kep){    int n,i;    ecb *ecbp = (ecb*) kep->udata;    for(i=0;i<ecbp->bufnum;i++){        n = write(kep->ident, ecbp->bufs[i], ecbp->bufsiz[i]);        if (n == -1){            log_printf(\"Error writing socket: %s\", strerror (errno));            unistall_connect(ecbp);            return;        }    }    if(ecbp->on_error){        unistall_connect(ecbp);        return;    }    free_msgs(ecbp);    ke_change(ecbp->ident, EVFILT_WRITE, EV_DISABLE, ecbp);}