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