X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=dccp_send.c;h=bdc7681e1de02469daaa0bc10698514eac563583;hp=6cd7fa4b8ca9d28d3c0b69c4966788a27a0d71a3;hb=8dffec19598a4a0ed77fa082abaf52c8fe66d889;hpb=471684761a2039bbc89aa1e3c33c62de6bef86cf diff --git a/dccp_send.c b/dccp_send.c index 6cd7fa4b..bdc7681e 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -79,7 +79,7 @@ static int dccp_open(void) return ret; listen_fd = ret; - bzero(&servaddr, sizeof(servaddr)); + memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(conf.dccp_port_arg); @@ -108,31 +108,26 @@ static void dccp_shutdown_client(struct dccp_client *dc) free(dc); } -/** give up if write would block that many times */ -#define DCCP_WRITE_RETRIES 100 - static int dccp_write(int fd, const char *buf, size_t len) { - size_t size, written = 0; - int ret, retries = 0; -again: - size = PARA_MIN(1024, len - written); - ret = write(fd, buf + written, size); - if (ret < 0) { - if (errno != EAGAIN || retries++ > DCCP_WRITE_RETRIES) - goto err_out; - PARA_DEBUG_LOG("EAGAIN #%d@%zd/%zd\n", retries, written, len); - goto again; + size_t written = 0; + int ret = 0; + + while (written < len) { + ret = write(fd, buf + written, PARA_MIN(1024, len - written)); + /* + * Error handling: CCID3 has a sending wait queue which fills up and is + * emptied asynchronously. The EAGAIN case means that there is currently + * no space in the wait queue, but this can change at any moment and is + * thus not an error condition. Keep polling until an entry becomes free. + */ + if (ret < 0 && errno == EAGAIN) + continue; + if (ret < 0) + return -E_DCCP_WRITE; + written += ret; } - retries = 0; - written += ret; - if (written >= len) - return written; - ret = write_ok(fd); - if (ret > 0) - goto again; -err_out: - return -E_DCCP_WRITE; + return written; } static void dccp_send(long unsigned current_chunk,