X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fd.c;h=9942eb925f33f86068d04729faf74bcd41a4566b;hp=c675aaffd4b99083d3ab0e26445574c2b87ad51b;hb=e59019f183e080486fda280868cf4669955148c2;hpb=40de1dd2fdbb054444d585aa70e2d50166a66e07 diff --git a/fd.c b/fd.c index c675aaff..9942eb92 100644 --- a/fd.c +++ b/fd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Andre Noll + * Copyright (C) 2006-2009 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -40,6 +40,45 @@ int write_all(int fd, const char *buf, size_t *len) return 1; } +/** + * Write a buffer to a non-blocking file descriptor. + * + * \param fd The file descriptor. + * \param buf the buffer to write. + * \param len the number of bytes of \a buf. + * \param max_bytes_per_write Do not write more than that many bytes at once. + * + * If \a max_bytes_per_write is non-zero, do not send more than that many bytes + * per write(). + * + * EAGAIN is not considered an error condition. For example 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. + * + * \return Negative on errors, number of bytes written else. + */ +int write_nonblock(int fd, const char *buf, size_t len, + size_t max_bytes_per_write) +{ + size_t written = 0; + int ret = 0; + + while (written < len) { + size_t num = len - written; + + if (max_bytes_per_write && max_bytes_per_write < num) + num = max_bytes_per_write; + ret = write(fd, buf + written, num); + if (ret < 0 && errno == EAGAIN) + return written; + if (ret < 0) + return -ERRNO_TO_PARA_ERROR(errno); + written += ret; + } + return written; +} + /** * Check whether a file exists. *