closeout.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* Close standard output and standard error, exiting with a diagnostic on error.
  2. Copyright (C) 1998-2002, 2004, 2006, 2008-2013 Free Software Foundation,
  3. Inc.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #include <config.h>
  15. #include "closeout.h"
  16. #include <errno.h>
  17. #include <stdbool.h>
  18. #include <stdio.h>
  19. #include <unistd.h>
  20. #include "gettext.h"
  21. #define _(msgid) gettext (msgid)
  22. #include "close-stream.h"
  23. #include "error.h"
  24. #include "exitfail.h"
  25. #include "quotearg.h"
  26. static const char *file_name;
  27. /* Set the file name to be reported in the event an error is detected
  28. by close_stdout. */
  29. void
  30. close_stdout_set_file_name (const char *file)
  31. {
  32. file_name = file;
  33. }
  34. static bool ignore_EPIPE /* = false */;
  35. /* Specify the reaction to an EPIPE error during the closing of stdout:
  36. - If ignore = true, it shall be ignored.
  37. - If ignore = false, it shall evoke a diagnostic, along with a nonzero
  38. exit status.
  39. The default is ignore = false.
  40. This setting matters only if the SIGPIPE signal is ignored (i.e. its
  41. handler set to SIG_IGN) or blocked. Only particular programs need to
  42. temporarily ignore SIGPIPE. If SIGPIPE is ignored or blocked because
  43. it was ignored or blocked in the parent process when it created the
  44. child process, it usually is a bug in the parent process: It is bad
  45. practice to have SIGPIPE ignored or blocked while creating a child
  46. process.
  47. EPIPE occurs when writing to a pipe or socket that has no readers now,
  48. when SIGPIPE is ignored or blocked.
  49. The ignore = false setting is suitable for a scenario where it is normally
  50. guaranteed that the pipe writer terminates before the pipe reader. In
  51. this case, an EPIPE is an indication of a premature termination of the
  52. pipe reader and should lead to a diagnostic and a nonzero exit status.
  53. The ignore = true setting is suitable for a scenario where you don't know
  54. ahead of time whether the pipe writer or the pipe reader will terminate
  55. first. In this case, an EPIPE is an indication that the pipe writer can
  56. stop doing useless write() calls; this is what close_stdout does anyway.
  57. EPIPE is part of the normal pipe/socket shutdown protocol in this case,
  58. and should not lead to a diagnostic message. */
  59. void
  60. close_stdout_set_ignore_EPIPE (bool ignore)
  61. {
  62. ignore_EPIPE = ignore;
  63. }
  64. /* Close standard output. On error, issue a diagnostic and _exit
  65. with status 'exit_failure'.
  66. Also close standard error. On error, _exit with status 'exit_failure'.
  67. Since close_stdout is commonly registered via 'atexit', POSIX
  68. and the C standard both say that it should not call 'exit',
  69. because the behavior is undefined if 'exit' is called more than
  70. once. So it calls '_exit' instead of 'exit'. If close_stdout
  71. is registered via atexit before other functions are registered,
  72. the other functions can act before this _exit is invoked.
  73. Applications that use close_stdout should flush any streams
  74. other than stdout and stderr before exiting, since the call to
  75. _exit will bypass other buffer flushing. Applications should
  76. be flushing and closing other streams anyway, to check for I/O
  77. errors. Also, applications should not use tmpfile, since _exit
  78. can bypass the removal of these files.
  79. It's important to detect such failures and exit nonzero because many
  80. tools (most notably 'make' and other build-management systems) depend
  81. on being able to detect failure in other tools via their exit status. */
  82. void
  83. close_stdout (void)
  84. {
  85. if (close_stream (stdout) != 0
  86. && !(ignore_EPIPE && errno == EPIPE))
  87. {
  88. char const *write_error = _("write error");
  89. if (file_name)
  90. error (0, errno, "%s: %s", quotearg_colon (file_name),
  91. write_error);
  92. else
  93. error (0, errno, "%s", write_error);
  94. _exit (exit_failure);
  95. }
  96. if (close_stream (stderr) != 0)
  97. _exit (exit_failure);
  98. }