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