(root)/
strace-6.5/
tests-mx32/
tprintf.c
       1  /*
       2   * Close stdin, move stdout to a non-standard descriptor, and print.
       3   *
       4   * Copyright (c) 2016-2021 Dmitry V. Levin <ldv@strace.io>
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  
      12  #include <assert.h>
      13  #include <errno.h>
      14  #include <stdarg.h>
      15  #include <stdio.h>
      16  #include <unistd.h>
      17  
      18  static ssize_t
      19  write_retry(int fd, const void *buf, size_t count)
      20  {
      21  	ssize_t rc;
      22  
      23  	do {
      24  		errno = 0;
      25  		rc = write(fd, buf, count);
      26  	} while (rc == -1 && EINTR == errno);
      27  
      28  	if (rc <= 0)
      29  		perror_msg_and_fail("write");
      30  
      31  	return rc;
      32  }
      33  
      34  static void
      35  write_loop(int fd, const char *buf, size_t count)
      36  {
      37  	ssize_t offset = 0;
      38  
      39  	while (count > 0) {
      40  		ssize_t block = write_retry(fd, &buf[offset], count);
      41  
      42  		offset += block;
      43  		count -= (size_t) block;
      44  	}
      45  }
      46  
      47  void
      48  tprintf(const char *fmt, ...)
      49  {
      50  	static int initialized;
      51  	if (!initialized) {
      52  		assert(dup2(1, 3) == 3);
      53  		assert(close(1) == 0);
      54  		(void) close(0);
      55  		initialized = 1;
      56  	}
      57  
      58  	va_list p;
      59  	va_start(p, fmt);
      60  
      61  	static char buf[65536];
      62  	int len = vsnprintf(buf, sizeof(buf), fmt, p);
      63  	if (len < 0)
      64  		perror_msg_and_fail("vsnprintf");
      65  	assert((unsigned) len < sizeof(buf));
      66  
      67  	write_loop(3, buf, len);
      68  
      69  	va_end(p);
      70  }