|
@@ -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;
|
|
|
+}
|