X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;ds=sidebyside;f=fd.c;h=9942eb925f33f86068d04729faf74bcd41a4566b;hb=b74c8941e36860a34483782cf91e449212401664;hp=8fc1abad19057bd724f26a25dca2ddb3ba5003ee;hpb=2ca70d00ec9b4486bca372873041c9e0233d36c4;p=paraslash.git diff --git a/fd.c b/fd.c index 8fc1abad..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. * @@ -285,9 +324,10 @@ int para_opendir(const char *dirname, DIR **dir, int *cwd) if (*dir) return 1; ret = -ERRNO_TO_PARA_ERROR(errno); -/* Ignore return value of fchdir() and close(). We're busted anyway. */ - if (cwd) - fchdir(*cwd); + /* Ignore return value of fchdir() and close(). We're busted anyway. */ + if (cwd) { + int __a_unused ret2 = fchdir(*cwd); /* STFU, gcc */ + } close_cwd: if (cwd) close(*cwd);