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
24extern void
25tuklib_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