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