(root)/
strace-6.5/
src/
error_prints.c
       1  /*
       2   * Copyright (c) 1999-2022 The strace developers.
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   */
       7  
       8  #ifdef HAVE_CONFIG_H
       9  # include "config.h"
      10  #endif
      11  
      12  #include <errno.h>
      13  #include <stdarg.h>
      14  #include <string.h>
      15  #include <stdio.h>
      16  #include <stdlib.h>
      17  
      18  #include "error_prints.h"
      19  
      20  #ifndef HAVE_PROGRAM_INVOCATION_NAME
      21  extern char *program_invocation_name;
      22  #endif
      23  
      24  static void ATTRIBUTE_FORMAT((__printf__, 2, 0))
      25  verror_msg(int err_no, const char *fmt, va_list p)
      26  {
      27  	char *msg;
      28  
      29  	fflush(NULL);
      30  
      31  	/*
      32  	 * We want to print the entire message with a single fprintf to ensure
      33  	 * the message integrity if stderr is shared with other programs.
      34  	 * Thus we use vasprintf + single fprintf.
      35  	 */
      36  	msg = NULL;
      37  	if (vasprintf(&msg, fmt, p) >= 0) {
      38  		if (err_no)
      39  			fprintf(stderr, "%s: %s: %s\n",
      40  				program_invocation_name, msg, strerror(err_no));
      41  		else
      42  			fprintf(stderr, "%s: %s\n",
      43  				program_invocation_name, msg);
      44  		free(msg);
      45  	} else {
      46  		/* malloc in vasprintf failed, try it without malloc */
      47  		fprintf(stderr, "%s: ", program_invocation_name);
      48  		vfprintf(stderr, fmt, p);
      49  		if (err_no)
      50  			fprintf(stderr, ": %s\n", strerror(err_no));
      51  		else
      52  			putc('\n', stderr);
      53  	}
      54  	/*
      55  	 * We don't switch stderr to buffered, thus fprintf(stderr)
      56  	 * always flushes its output and this is not necessary:
      57  	 * fflush(stderr);
      58  	 */
      59  }
      60  
      61  void
      62  error_msg(const char *fmt, ...)
      63  {
      64  	va_list p;
      65  	va_start(p, fmt);
      66  	verror_msg(0, fmt, p);
      67  	va_end(p);
      68  }
      69  
      70  void
      71  error_msg_and_die(const char *fmt, ...)
      72  {
      73  	va_list p;
      74  	va_start(p, fmt);
      75  	verror_msg(0, fmt, p);
      76  	va_end(p);
      77  	die();
      78  }
      79  
      80  void
      81  error_msg_and_help(const char *fmt, ...)
      82  {
      83  	if (fmt != NULL) {
      84  		va_list p;
      85  		va_start(p, fmt);
      86  		verror_msg(0, fmt, p);
      87  		va_end(p);
      88  	}
      89  	fprintf(stderr, "Try '%s -h' for more information.\n",
      90  		program_invocation_name);
      91  	die();
      92  }
      93  
      94  void
      95  perror_msg(const char *fmt, ...)
      96  {
      97  	va_list p;
      98  	va_start(p, fmt);
      99  	verror_msg(errno, fmt, p);
     100  	va_end(p);
     101  }
     102  
     103  void
     104  perror_msg_and_die(const char *fmt, ...)
     105  {
     106  	va_list p;
     107  	va_start(p, fmt);
     108  	verror_msg(errno, fmt, p);
     109  	va_end(p);
     110  	die();
     111  }