rendered paste bodystatic 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);}