From 94a28496aa3fcec48dc58917342ec6bcc23f0c31 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 27 Oct 2015 13:19:16 +0100 Subject: [PATCH] logger: use iovec and sendmsg() to send message The iovec based solutions allow to send multiple strings by one syscall (for example additional \n messages separator). We can also use it to send additional socket header metadata (e.g. SCM_CREDENTIALS) later. Signed-off-by: Karel Zak --- misc-utils/logger.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/misc-utils/logger.c b/misc-utils/logger.c index 6a96554286..9878c8229e 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -416,18 +416,26 @@ static void write_output(const struct logger_ctl *ctl, const char *const msg) xasprintf(&buf, "%s%s", ctl->hdr, msg); if (!ctl->noact) { - if (write_all(ctl->fd, buf, len) < 0) - warn(_("write failed")); - else if ((ctl->socket_type == TYPE_TCP) && !ctl->octet_count) { - /* using an additional write seems like the best compromise: - * - writev() is not yet supported by framework - * - adding the \n to the buffer in formatters violates layers - * - adding \n after the fact requires memory copy - * - logger is not a high-performance app - */ - if (write_all(ctl->fd, "\n", 1) < 0) - warn(_("write failed")); + struct msghdr msg = { 0 }; + struct iovec iov[2]; + size_t iovlen = 0; + + iov[0].iov_base = buf; + iov[0].iov_len = len; + iovlen++; + + /* add extra \n to make sure message is terminated */ + if ((ctl->socket_type == TYPE_TCP) && !ctl->octet_count) { + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + iovlen++; } + + msg.msg_iov = iov; + msg.msg_iovlen = iovlen; + + if (sendmsg(ctl->fd, &msg, 0) < 0) + warn(_("send message failed")); } if (ctl->stderr_printout) fprintf(stderr, "%s\n", buf); -- 2.47.2