MINOR: sink/api: pass explicit maxlen parameter to sink_write()

sink_write() currently relies on sink->maxlen to know when to stop
writing a given payload.

But it could be useful to pass a smaller, explicit value to sink_write()
to stop before the ring maxlen, for instance if the ring is shared between
multiple feeders.

sink_write() now takes an optional maxlen parameter:
  if maxlen is > 0, then sink_write will stop writing at maxlen if maxlen
  is smaller than ring->maxlen, else only ring->maxlen will be considered.

[for haproxy <= 2.7, patch must be applied by hand: that is:
__sink_write() and sink_write() should be patched to take maxlen into
account and function calls to sink_write() should use 0 as second argument
to keep original behavior]

(cherry picked from commit b6e2d62fb3c3015f2da87e2c78cc562b3a0fc391)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 5bab37ef46d9db6653fc08fa03619c2cb35a66ae)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ce691552a45387dd96b3ae1d5a5d3b323c6d69c8)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d9aff564ef1a55cea2eeaefd96f23f84138984c3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/log.c b/src/log.c
index 51829c1..90c32aa 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1886,7 +1886,7 @@
 		if (msg.len > logsrv->maxlen)
 			msg.len = logsrv->maxlen;
 
-		sent = sink_write(logsrv->sink, &msg, 1, level, facility, metadata);
+		sent = sink_write(logsrv->sink, 0, &msg, 1, level, facility, metadata);
 	}
 	else if (logsrv->addr.ss_family == AF_CUST_EXISTING_FD) {
 		struct ist msg;
diff --git a/src/sample.c b/src/sample.c
index d9ae4c1..33628ae 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1528,7 +1528,7 @@
 
  done:
 	line = ist2(buf->area, buf->data);
-	sink_write(sink, &line, 1, 0, 0, NULL);
+	sink_write(sink, 0, &line, 1, 0, 0, NULL);
  end:
 	free_trash_chunk(buf);
 	return 1;
diff --git a/src/sink.c b/src/sink.c
index 421bac4..0489564 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -162,10 +162,13 @@
  * array <msg> to sink <sink>. Formatting according to the sink's preference is
  * done here. Lost messages are NOT accounted for. It is preferable to call
  * sink_write() instead which will also try to emit the number of dropped
- * messages when there are any. It returns >0 if it could write anything,
- * <=0 otherwise.
+ * messages when there are any. It will stop writing at <maxlen> instead of
+ * sink->maxlen if <maxlen> is positive and inferior to sink->maxlen.
+ *
+ * It returns >0 if it could write anything, <=0 otherwise.
  */
- ssize_t __sink_write(struct sink *sink, const struct ist msg[], size_t nmsg,
+ ssize_t __sink_write(struct sink *sink, size_t maxlen,
+	             const struct ist msg[], size_t nmsg,
 	             int level, int facility, struct ist *metadata)
  {
 	struct ist *pfx = NULL;
@@ -177,11 +180,13 @@
 	pfx = build_log_header(sink->fmt, level, facility, metadata, &npfx);
 
 send:
+	if (!maxlen)
+		maxlen = ~0;
 	if (sink->type == SINK_TYPE_FD) {
-		return fd_write_frag_line(sink->ctx.fd, sink->maxlen, pfx, npfx, msg, nmsg, 1);
+		return fd_write_frag_line(sink->ctx.fd, MIN(maxlen, sink->maxlen), pfx, npfx, msg, nmsg, 1);
 	}
 	else if (sink->type == SINK_TYPE_BUFFER) {
-		return ring_write(sink->ctx.ring, sink->maxlen, pfx, npfx, msg, nmsg);
+		return ring_write(sink->ctx.ring, MIN(maxlen, sink->maxlen), pfx, npfx, msg, nmsg);
 	}
 	return 0;
 }
@@ -223,7 +228,7 @@
 			metadata[LOG_META_PID] = ist2(pidstr, strlen(pidstr));
 		}
 
-		if (__sink_write(sink, msgvec, 1, LOG_NOTICE, facility, metadata) <= 0)
+		if (__sink_write(sink, 0, msgvec, 1, LOG_NOTICE, facility, metadata) <= 0)
 			return 0;
 		/* success! */
 		HA_ATOMIC_SUB(&sink->ctx.dropped, dropped);
diff --git a/src/trace.c b/src/trace.c
index ede3d0e..96d422a 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -240,7 +240,7 @@
 	}
 
 	if (src->sink)
-		sink_write(src->sink, line, words, 0, 0, NULL);
+		sink_write(src->sink, 0, line, words, 0, 0, NULL);
 
  end:
 	/* check if we need to stop the trace now */