Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

error_prints.c 2.0KB

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