Subject: [PATCH v3 02/26] pkt-line.c: add packet_write_timeout()

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Mon, 3 Feb 2014 11:28:50 +0700

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 cache.h    |  1 +
 pkt-line.c | 15 +++++++++++++++
 pkt-line.h |  1 +
 wrapper.c  | 26 ++++++++++++++++++++++++++
 4 files changed, 43 insertions(+)

diff --git a/cache.h b/cache.h
index dc040fb..718e32b 100644
--- a/cache.h
+++ b/cache.h
@@ -1231,6 +1231,7 @@ extern void fsync_or_die(int fd, const char *);
 
 extern ssize_t read_in_full(int fd, void *buf, size_t count);
 extern ssize_t write_in_full(int fd, const void *buf, size_t count);
+extern ssize_t write_in_full_timeout(int fd, const void *buf, size_t count, int timeout);
 static inline ssize_t write_str_in_full(int fd, const char *str)
 {
 	return write_in_full(fd, str, strlen(str));
diff --git a/pkt-line.c b/pkt-line.c
index eac45ad..cf681e9 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -94,6 +94,21 @@ void packet_write(int fd, const char *fmt, ...)
 	write_or_die(fd, write_buffer, n);
 }
 
+int packet_write_timeout(int fd, int timeout, const char *fmt, ...)
+{
+	static struct strbuf sb = STRBUF_INIT;
+	va_list args;
+	unsigned n;
+
+	if (fd == -1)
+		return -1;
+	va_start(args, fmt);
+	strbuf_reset(&sb);
+	n = format_packet(fmt, args);
+	va_end(args);
+	return write_in_full_timeout(fd, write_buffer, n, timeout);
+}
+
 void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
 {
 	va_list args;
diff --git a/pkt-line.h b/pkt-line.h
index 0a838d1..4b93a0c 100644
--- a/pkt-line.h
+++ b/pkt-line.h
@@ -21,6 +21,7 @@
  */
 void packet_flush(int fd);
 void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
+int packet_write_timeout(int fd, int timeout, const char *fmt, ...) __attribute__((format (printf, 3, 4)));
 void packet_buf_flush(struct strbuf *buf);
 void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 
diff --git a/wrapper.c b/wrapper.c
index 0cc5636..9a0e289 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -214,6 +214,32 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
 	return total;
 }
 
+ssize_t write_in_full_timeout(int fd, const void *buf,
+			      size_t count, int timeout)
+{
+	struct pollfd pfd;
+	const char *p = buf;
+	ssize_t total = 0;
+
+	pfd.fd = fd;
+	pfd.events = POLLOUT;
+	while (count > 0 && poll(&pfd, 1, timeout) > 0 &&
+	       (pfd.revents & POLLOUT)) {
+		ssize_t written = xwrite(fd, p, count);
+		if (written < 0)
+			return -1;
+		if (!written) {
+			errno = ENOSPC;
+			return -1;
+		}
+		count -= written;
+		p += written;
+		total += written;
+	}
+
+	return count ? -1 : total;
+}
+
 int xdup(int fd)
 {
 	int ret = dup(fd);
-- 
1.8.5.2.240.g8478abd