From 536a0353ddf11a6edc78c10102c046bc58221ff0 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 20 Jan 2016 02:06:59 +0000 Subject: [PATCH] tests: add tprintf function to libtests * tests/tests.h (tprintf): New prototype. * tests/tprintf.c: New file. * tests/Makefile.am (libtests_a_SOURCES): Add it. * tests/mmsg.c: Use tprintf. --- tests/Makefile.am | 1 + tests/mmsg.c | 29 +++++---------- tests/tests.h | 4 +++ tests/tprintf.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 tests/tprintf.c diff --git a/tests/Makefile.am b/tests/Makefile.am index ff3175db..0b79ed6b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -45,6 +45,7 @@ libtests_a_SOURCES = \ error_msg.c \ tail_alloc.c \ tests.h \ + tprintf.c \ # end of libtests_a_SOURCES libtests_a_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64 check_LIBRARIES = libtests.a diff --git a/tests/mmsg.c b/tests/mmsg.c index fa1ee8b9..ba6cfe41 100644 --- a/tests/mmsg.c +++ b/tests/mmsg.c @@ -47,8 +47,6 @@ struct mmsghdr { # define LENGTH_OF(arg) ((unsigned int) sizeof(arg) - 1) -static FILE *logfp; - static int send_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags) { @@ -58,8 +56,7 @@ send_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags) (unsigned long) flags); if (rc >= 0 || ENOSYS != errno) return rc; - fprintf(logfp, - "sendmmsg(%d, %p, %u, MSG_DONTROUTE|MSG_NOSIGNAL)" + tprintf("sendmmsg(%d, %p, %u, MSG_DONTROUTE|MSG_NOSIGNAL)" " = -1 ENOSYS (%m)\n", fd, vec, vlen); #endif #ifdef HAVE_SENDMMSG @@ -78,8 +75,7 @@ recv_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags, (unsigned long) flags, timeout); if (rc >= 0 || ENOSYS != errno) return rc; - fprintf(logfp, - "recvmmsg(%d, %p, %u, MSG_DONTWAIT, NULL)" + tprintf("recvmmsg(%d, %p, %u, MSG_DONTWAIT, NULL)" " = -1 ENOSYS (%m)\n", fd, vec, vlen); #endif #ifdef HAVE_RECVMMSG @@ -91,15 +87,10 @@ recv_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags, int main(void) { + tprintf("%s", ""); + const int R = 0, W = 1; int sv[2]; - - int logfd = dup(1); - assert(logfd > 2); - assert((logfp = fdopen(logfd, "w"))); - - (void) close(0); - (void) close(1); if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv)) perror_msg_and_skip("socketpair"); assert(R == sv[0]); @@ -151,8 +142,7 @@ main(void) perror_msg_and_skip("sendmmsg"); assert(r == (int) n_mmh); assert(close(W) == 0); - fprintf(logfp, - "sendmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" + tprintf("sendmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" ", {\"%s\", %u}], msg_controllen=0, msg_flags=0}, %u}" ", {{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}]" ", msg_controllen=0, msg_flags=0}, %u}}, %u" @@ -166,7 +156,7 @@ main(void) " * %u bytes in buffer 0\n" " | 00000 %-48s %-16s |\n", W, 2, one, LENGTH_OF(one), two, LENGTH_OF(two), - LENGTH_OF(one) + LENGTH_OF(two), + LENGTH_OF(one) + LENGTH_OF(two), 1, three, LENGTH_OF(three), LENGTH_OF(three), n_mmh, r, 2, LENGTH_OF(one), ascii_one, one, @@ -175,8 +165,7 @@ main(void) assert(recv_mmsg(R, copy_mmh, n_mmh, MSG_DONTWAIT, NULL) == (int) n_mmh); assert(close(R) == 0); - fprintf(logfp, - "recvmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" + tprintf("recvmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" ", {\"%s\", %u}], msg_controllen=0, msg_flags=0}, %u}" ", {{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}]" ", msg_controllen=0, msg_flags=0}, %u}}, %u" @@ -190,14 +179,14 @@ main(void) " * %u bytes in buffer 0\n" " | 00000 %-48s %-16s |\n", R, 2, one, LENGTH_OF(one), two, LENGTH_OF(two), - LENGTH_OF(one) + LENGTH_OF(two), + LENGTH_OF(one) + LENGTH_OF(two), 1, three, LENGTH_OF(three), LENGTH_OF(three), n_mmh, r, 2, LENGTH_OF(one), ascii_one, one, LENGTH_OF(two), ascii_two, two, 1, LENGTH_OF(three), ascii_three, three); - fprintf(logfp, "+++ exited with 0 +++\n"); + tprintf("+++ exited with 0 +++\n"); return 0; } diff --git a/tests/tests.h b/tests/tests.h index 36ddea31..e69e4d1a 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -59,6 +59,10 @@ void *tail_alloc(const size_t) void *tail_memdup(const void *, const size_t) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((2)); +/* Close stdin, move stdout to a non-standard descriptor, and print. */ +void tprintf(const char *, ...) + ATTRIBUTE_FORMAT((printf, 1, 2)); + # define SKIP_MAIN_UNDEFINED(arg) \ int main(void) { error_msg_and_skip("undefined: %s", arg); } diff --git a/tests/tprintf.c b/tests/tprintf.c new file mode 100644 index 00000000..a759d8af --- /dev/null +++ b/tests/tprintf.c @@ -0,0 +1,90 @@ +/* + * Close stdin, move stdout to a non-standard descriptor, and print. + * + * Copyright (c) 2016 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" + +#include +#include +#include +#include +#include + +static ssize_t +write_retry(int fd, const void *buf, size_t count) +{ + ssize_t rc; + + do { + errno = 0; + rc = write(fd, buf, count); + } while (rc == -1 && EINTR == errno); + + if (rc <= 0) + perror_msg_and_fail("write"); + + return rc; +} + +static void +write_loop(int fd, const char *buf, size_t count) +{ + ssize_t offset = 0; + + while (count > 0) { + ssize_t block = write_retry(fd, &buf[offset], count); + + offset += block; + count -= (size_t) block; + } +} + +void +tprintf(const char *fmt, ...) +{ + static int initialized; + if (!initialized) { + assert(dup2(1, 3) == 3); + assert(close(1) == 0); + (void) close(0); + initialized = 1; + } + + va_list p; + va_start(p, fmt); + + static char buf[65536]; + int len = vsnprintf(buf, sizeof(buf), fmt, p); + if (len < 0) + perror_msg_and_fail("vsnprintf"); + assert((unsigned) len < sizeof(buf)); + + write_loop(3, buf, len); + + va_end(p); +} -- 2.40.0