xref: /freebsd-src/contrib/xz/src/common/tuklib_exit.c (revision 3b35e7ee8de9b0260149a2b77e87a2b9c7a36244)
1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD
2*3b35e7eeSXin LI 
381ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
481ad8388SMartin Matuska //
581ad8388SMartin Matuska /// \file       tuklib_exit.c
681ad8388SMartin Matuska /// \brief      Close stdout and stderr, and exit
781ad8388SMartin Matuska //
881ad8388SMartin Matuska //  Author:     Lasse Collin
981ad8388SMartin Matuska //
1081ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
1181ad8388SMartin Matuska 
1281ad8388SMartin Matuska #include "tuklib_common.h"
1381ad8388SMartin Matuska 
1481ad8388SMartin Matuska #include <stdlib.h>
1581ad8388SMartin Matuska #include <stdio.h>
16a8675d92SXin LI #include <string.h>
1781ad8388SMartin Matuska 
1881ad8388SMartin Matuska #include "tuklib_gettext.h"
1981ad8388SMartin Matuska #include "tuklib_progname.h"
2081ad8388SMartin Matuska #include "tuklib_exit.h"
2181ad8388SMartin Matuska 
2281ad8388SMartin Matuska 
2381ad8388SMartin Matuska extern void
tuklib_exit(int status,int err_status,int show_error)2481ad8388SMartin Matuska tuklib_exit(int status, int err_status, int show_error)
2581ad8388SMartin Matuska {
2681ad8388SMartin Matuska 	if (status != err_status) {
2781ad8388SMartin Matuska 		// Close stdout. If something goes wrong,
2881ad8388SMartin Matuska 		// print an error message to stderr.
2981ad8388SMartin Matuska 		const int ferror_err = ferror(stdout);
3081ad8388SMartin Matuska 		const int fclose_err = fclose(stdout);
3181ad8388SMartin Matuska 		if (ferror_err || fclose_err) {
3281ad8388SMartin Matuska 			status = err_status;
3381ad8388SMartin Matuska 
3481ad8388SMartin Matuska 			// If it was fclose() that failed, we have the reason
3581ad8388SMartin Matuska 			// in errno. If only ferror() indicated an error,
3681ad8388SMartin Matuska 			// we have no idea what the reason was.
3781ad8388SMartin Matuska 			if (show_error)
3881ad8388SMartin Matuska 				fprintf(stderr, "%s: %s: %s\n", progname,
3981ad8388SMartin Matuska 						_("Writing to standard "
4081ad8388SMartin Matuska 							"output failed"),
4181ad8388SMartin Matuska 						fclose_err ? strerror(errno)
4281ad8388SMartin Matuska 							: _("Unknown error"));
4381ad8388SMartin Matuska 		}
4481ad8388SMartin Matuska 	}
4581ad8388SMartin Matuska 
4681ad8388SMartin Matuska 	if (status != err_status) {
4781ad8388SMartin Matuska 		// Close stderr. If something goes wrong, there's
4881ad8388SMartin Matuska 		// nothing where we could print an error message.
4981ad8388SMartin Matuska 		// Just set the exit status.
5081ad8388SMartin Matuska 		const int ferror_err = ferror(stderr);
5181ad8388SMartin Matuska 		const int fclose_err = fclose(stderr);
5281ad8388SMartin Matuska 		if (fclose_err || ferror_err)
5381ad8388SMartin Matuska 			status = err_status;
5481ad8388SMartin Matuska 	}
5581ad8388SMartin Matuska 
5681ad8388SMartin Matuska 	exit(status);
5781ad8388SMartin Matuska }
58