xref: /freebsd/contrib/xz/src/common/tuklib_exit.c (revision 9398a495eb305d5bf240bc998ee2f6128d75f4ca)
1 // SPDX-License-Identifier: 0BSD
2 
3 ///////////////////////////////////////////////////////////////////////////////
4 //
5 /// \file       tuklib_exit.c
6 /// \brief      Close stdout and stderr, and exit
7 //
8 //  Author:     Lasse Collin
9 //
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #include "tuklib_common.h"
13 
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 
18 #include "tuklib_gettext.h"
19 #include "tuklib_progname.h"
20 #include "tuklib_exit.h"
21 
22 
23 extern void
24 tuklib_exit(int status, int err_status, int show_error)
25 {
26 	if (status != err_status) {
27 		// Close stdout. If something goes wrong,
28 		// print an error message to stderr.
29 		const int ferror_err = ferror(stdout);
30 		const int fclose_err = fclose(stdout);
31 		if (ferror_err || fclose_err) {
32 			status = err_status;
33 
34 			// If it was fclose() that failed, we have the reason
35 			// in errno. If only ferror() indicated an error,
36 			// we have no idea what the reason was.
37 			if (show_error)
38 				fprintf(stderr, "%s: %s: %s\n", progname,
39 						_("Writing to standard "
40 							"output failed"),
41 						fclose_err ? strerror(errno)
42 							: _("Unknown error"));
43 		}
44 	}
45 
46 	if (status != err_status) {
47 		// Close stderr. If something goes wrong, there's
48 		// nothing where we could print an error message.
49 		// Just set the exit status.
50 		const int ferror_err = ferror(stderr);
51 		const int fclose_err = fclose(stderr);
52 		if (fclose_err || ferror_err)
53 			status = err_status;
54 	}
55 
56 	exit(status);
57 }
58