X-Git-Url: http://git.pk910.de/?p=TransparentIRC.git;a=blobdiff_plain;f=src%2FIOHandler.c;h=375bcea86e3a20e8196114a33cbf6f3bbdd47df2;hp=b276272ec11a44480468f95e87bc8bae00855598;hb=4fdc419424dd18df5807ed4218a84fa38e1dd6f6;hpb=1f2baa2e7b90ea83c5a0c93598e22e5063fc6d95 diff --git a/src/IOHandler.c b/src/IOHandler.c index b276272..375bcea 100644 --- a/src/IOHandler.c +++ b/src/IOHandler.c @@ -71,7 +71,7 @@ struct IODescriptor *iohandler_add(int sockfd, enum IOType type, iohandler_callb return descriptor; } -static void iohandler_remove(struct IODescriptor *descriptor) { +static void iohandler_remove(struct IODescriptor *descriptor, int engine_remove) { //remove IODescriptor from the list if(descriptor->prev) descriptor->prev->next = descriptor->next; @@ -79,7 +79,8 @@ static void iohandler_remove(struct IODescriptor *descriptor) { first_descriptor = descriptor->next; if(descriptor->next) descriptor->next->prev = descriptor->prev; - engine->remove(descriptor); + if(engine_remove) + engine->remove(descriptor); if(descriptor->readbuf.buffer) free(descriptor->readbuf.buffer); if(descriptor->writebuf.buffer) @@ -296,7 +297,7 @@ void iohandler_write(struct IODescriptor *iofd, const char *line) { } void iohandler_send(struct IODescriptor *iofd, const char *data, size_t datalen) { - if(iofd->type == IOTYPE_TIMER) return; //can not write to timer? :D + if(iofd->type == IOTYPE_TIMER || iofd->state == IO_CLOSED) return; //can not write to timer? :D if(iofd->writebuf.buflen < iofd->writebuf.bufpos + datalen) { iohandler_increase_iobuf(&iofd->writebuf, iofd->writebuf.bufpos + datalen); if(iofd->writebuf.buflen < iofd->writebuf.bufpos + datalen) @@ -335,10 +336,24 @@ void iohandler_try_write(struct IODescriptor *iofd) { } void iohandler_close(struct IODescriptor *iofd) { + int engine_remove = 1; + if(iofd->writebuf.bufpos) { + //try to send everything before closing +#if defined(F_GETFL) + flags = fcntl(sockfd, F_GETFL); + fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); + flags = fcntl(sockfd, F_GETFD); + fcntl(sockfd, F_SETFD, flags|FD_CLOEXEC); +#else + engine_remove = 0; + engine->remove(iofd); +#endif + iohandler_try_write(iofd); + } //close IODescriptor if(iofd->type == IOTYPE_SERVER || iofd->type == IOTYPE_CLIENT || iofd->type == IOTYPE_STDIN) close(iofd->fd); - iohandler_remove(iofd); + iohandler_remove(iofd, engine_remove); } void iohandler_update(struct IODescriptor *iofd) { @@ -360,11 +375,13 @@ void iohandler_events(struct IODescriptor *iofd, int readable, int writeable) { callback_event.type = IOEVENT_TIMEOUT; break; case IO_LISTENING: - callback_event.data.accept_fd = accept(iofd->fd, NULL, 0); - if(callback_event.data.accept_fd < 0) { - //error: could not accept - } else - callback_event.type = IOEVENT_ACCEPT; + if(readable) { + callback_event.data.accept_fd = accept(iofd->fd, NULL, 0); + if(callback_event.data.accept_fd < 0) { + //error: could not accept + } else + callback_event.type = IOEVENT_ACCEPT; + } break; case IO_CONNECTING: if(readable) { //could not connect @@ -386,6 +403,7 @@ void iohandler_events(struct IODescriptor *iofd, int readable, int writeable) { int bytes = recv(iofd->fd, iofd->readbuf.buffer + iofd->readbuf.bufpos, iofd->readbuf.buflen - iofd->readbuf.bufpos, 0); if(bytes <= 0) { if (errno != EAGAIN) { + iofd->state = IO_CLOSED; callback_event.type = IOEVENT_CLOSED; callback_event.data.errid = errno; } @@ -429,6 +447,8 @@ void iohandler_events(struct IODescriptor *iofd, int readable, int writeable) { } break; } + if(callback_event.type == IOEVENT_IGNORE && !readable && !writeable) + callback_event.type = IOEVENT_TIMEOUT; if(callback_event.type != IOEVENT_IGNORE) iohandler_trigger_event(&callback_event); }