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, "%s\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;ibufnum;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);
}