Browse Source

faux.base: Add faux_send...() functions

Serj Kalichev 3 years ago
parent
commit
d7e63f6cdb
2 changed files with 122 additions and 0 deletions
  1. 115 0
      faux/base/io.c
  2. 7 0
      faux/faux.h

+ 115 - 0
faux/base/io.c

@@ -7,6 +7,10 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
 
 /** @brief Writes data to file.
  *
@@ -141,3 +145,114 @@ size_t faux_read_block(int fd, void *buf, size_t n)
 
 	return total_readed;
 }
+
+
+/** @brief Sends data to socket.
+ *
+ * The system send() can be interrupted by signal. This function will retry to
+ * send in a case of interrupted call.
+ *
+ * @param [in] fd Socket.
+ * @param [in] buf Buffer to write.
+ * @param [in] n Number of bytes to write.
+ * @param [in] flags Flags.
+ * @return Number of bytes written or < 0 on error.
+ */
+ssize_t faux_send(int fd, const void *buf, size_t n, int flags)
+{
+	ssize_t bytes_written = 0;
+
+	assert(fd != -1);
+	assert(buf);
+	if ((-1 == fd) || !buf)
+		return -1;
+	if (0 == n)
+		return 0;
+
+	do {
+		bytes_written = send(fd, buf, n, flags);
+	} while ((bytes_written < 0) && (EINTR == errno));
+
+	return bytes_written;
+}
+
+
+/** @brief Sends data block to socket.
+ *
+ * The system send() can be interrupted by signal or can write less bytes
+ * than specified. This function will continue to send data until all data
+ * will be sent or error occured.
+ *
+ * @param [in] fd Socket.
+ * @param [in] buf Buffer to write.
+ * @param [in] n Number of bytes to write.
+ * @param [in] flags Flags.
+ * @return Number of bytes written.
+ * < n then insufficient space or error (but some data was already written).
+ * < 0 - error.
+ */
+ssize_t faux_send_block(int fd, const void *buf, size_t n, int flags)
+{
+	ssize_t bytes_written = 0;
+	size_t total_written = 0;
+	size_t left = n;
+	const void *data = buf;
+
+	do {
+		bytes_written = faux_send(fd, data, left, flags);
+		if (bytes_written < 0) { // Error
+			if (total_written != 0)
+				return total_written;
+			return -1;
+		}
+		if (0 == bytes_written) // Insufficient space
+			return total_written;
+		data += bytes_written;
+		left = left - bytes_written;
+		total_written += bytes_written;
+	} while (left > 0);
+
+	return total_written;
+}
+
+
+/** @brief Sends struct iovec data blocks to socket.
+ *
+ * This function is like a faux_send_block() function but uses scatter/gather.
+ *
+ * @see faux_send_block().
+ * @param [in] fd Socket.
+ * @param [in] buf Buffer to write.
+ * @param [in] n Number of bytes to write.
+ * @param [in] flags Flags.
+ * @return Number of bytes written.
+ * < n then insufficient space or error (but some data was already written).
+ * < 0 - error.
+ */
+ssize_t faux_sendv_block(int fd, const struct iovec *iov, int iovcnt, int flags)
+{
+	ssize_t bytes_written = 0;
+	size_t total_written = 0;
+	int i = 0;
+
+	if (!iov)
+		return -1;
+	if (iovcnt == 0)
+		return 0;
+
+	for (i = 0; i < iovcnt; i++) {
+		if (iov[i].iov_len == 0)
+			continue;
+		bytes_written = faux_send_block(fd, iov[i].iov_base, iov[i].iov_len, flags);
+		if (bytes_written < 0) { // Error
+			if (total_written != 0)
+				return total_written;
+			return -1;
+		}
+		if (0 == bytes_written) // Insufficient space
+			return total_written;
+		total_written += bytes_written;
+	}
+
+	return total_written;
+}

+ 7 - 0
faux/faux.h

@@ -6,6 +6,9 @@
 #define _faux_types_h
 
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
 
 /**
  * A standard boolean type. The possible values are
@@ -70,6 +73,10 @@ ssize_t faux_read(int fd, void *buf, size_t n);
 ssize_t faux_write_block(int fd, const void *buf, size_t n);
 size_t faux_read_block(int fd, void *buf, size_t n);
 
+ssize_t faux_send(int fd, const void *buf, size_t n, int flags);
+ssize_t faux_send_block(int fd, const void *buf, size_t n, int flags);
+ssize_t faux_sendv_block(int fd, const struct iovec *iov, int iovcnt, int flags);
+
 // Filesystem
 int faux_rm(const char *path);
 char *faux_expand_tilde(const char *path);