aboutsummaryrefslogtreecommitdiffstats
path: root/libcoopgamma_flush.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-02-10 17:50:58 +0100
committerMattias Andrée <m@maandree.se>2025-02-10 17:52:46 +0100
commitec1bcdcd0dd6e196303e8d9a30b3b2740e32c502 (patch)
treedcc759aaf897c915827659e00644f12503cf1268 /libcoopgamma_flush.c
parentImprove makefile (diff)
downloadlibcoopgamma-ec1bcdcd0dd6e196303e8d9a30b3b2740e32c502.tar.gz
libcoopgamma-ec1bcdcd0dd6e196303e8d9a30b3b2740e32c502.tar.bz2
libcoopgamma-ec1bcdcd0dd6e196303e8d9a30b3b2740e32c502.tar.xz
Minor code improvements and split into multiple c files
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libcoopgamma_flush.c')
-rw-r--r--libcoopgamma_flush.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/libcoopgamma_flush.c b/libcoopgamma_flush.c
new file mode 100644
index 0000000..a1f23d1
--- /dev/null
+++ b/libcoopgamma_flush.c
@@ -0,0 +1,49 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * Send all pending outbound data
+ *
+ * If this function or another function that sends a request
+ * to the server fails with EINTR, call this function to
+ * complete the transfer. The `async` parameter will always
+ * be in a properly configured state if a function fails
+ * with EINTR.
+ *
+ * @param ctx The state of the library, must be connected
+ * @return Zero on success, -1 on error
+ */
+int
+libcoopgamma_flush(libcoopgamma_context_t *restrict ctx)
+{
+ ssize_t sent;
+ size_t chunksize = ctx->outbound_head - ctx->outbound_tail;
+ size_t sendsize;
+
+ while (ctx->outbound_tail < ctx->outbound_head) {
+ sendsize = ctx->outbound_head - ctx->outbound_tail;
+ sendsize = sendsize < chunksize ? sendsize : chunksize;
+ sent = send(ctx->fd, &ctx->outbound[ctx->outbound_tail], sendsize, MSG_NOSIGNAL);
+ if (sent < 0) {
+ if (errno == EPIPE)
+ errno = ECONNRESET;
+ if (errno != EMSGSIZE)
+ return -1;
+ if (!(chunksize >>= 1))
+ return -1;
+ continue;
+ }
+
+#ifdef DEBUG_MODE
+ fprintf(stderr, "\033[31m");
+ fwrite(&ctx->outbound[ctx->outbound_tail], (size_t)sent, 1U, stderr);
+ fprintf(stderr, "\033[m");
+ fflush(stderr);
+#endif
+
+ ctx->outbound_tail += (size_t)sent;
+ }
+
+ return 0;
+}