]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
logger: use iovec and sendmsg() to send message
authorKarel Zak <kzak@redhat.com>
Tue, 27 Oct 2015 12:19:16 +0000 (13:19 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 27 Oct 2015 12:19:16 +0000 (13:19 +0100)
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 <kzak@redhat.com>
misc-utils/logger.c

index 6a9655428680c32ae55be0b82d5e3af66bb4f294..9878c8229e23d3240db3c2de993a7587a64fe9e3 100644 (file)
@@ -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);