1*29619d2aSchristos /* $NetBSD: xexit.c,v 1.1.1.1 2016/01/14 00:11:29 christos Exp $ */
2*29619d2aSchristos
3*29619d2aSchristos /* xexit.c -- exit with attention to return values and closing stdout.
4*29619d2aSchristos Id: xexit.c,v 1.5 2004/04/11 17:56:46 karl Exp
5*29619d2aSchristos
6*29619d2aSchristos Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
7*29619d2aSchristos
8*29619d2aSchristos This program is free software; you can redistribute it and/or modify
9*29619d2aSchristos it under the terms of the GNU General Public License as published by
10*29619d2aSchristos the Free Software Foundation; either version 2, or (at your option)
11*29619d2aSchristos any later version.
12*29619d2aSchristos
13*29619d2aSchristos This program is distributed in the hope that it will be useful,
14*29619d2aSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
15*29619d2aSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*29619d2aSchristos GNU General Public License for more details.
17*29619d2aSchristos
18*29619d2aSchristos You should have received a copy of the GNU General Public License along
19*29619d2aSchristos with this program; if not, write to the Free Software Foundation, Inc.,
20*29619d2aSchristos 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21*29619d2aSchristos
22*29619d2aSchristos #include "system.h"
23*29619d2aSchristos
24*29619d2aSchristos /* SunOS 4.1.1 gets STDC_HEADERS defined, but it doesn't provide
25*29619d2aSchristos EXIT_FAILURE. So far no system has defined one of EXIT_FAILURE and
26*29619d2aSchristos EXIT_SUCCESS without the other. */
27*29619d2aSchristos #ifdef EXIT_SUCCESS
28*29619d2aSchristos /* The following test is to work around the gross typo in
29*29619d2aSchristos systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE
30*29619d2aSchristos is defined to 0, not 1. */
31*29619d2aSchristos # if !EXIT_FAILURE
32*29619d2aSchristos # undef EXIT_FAILURE
33*29619d2aSchristos # define EXIT_FAILURE 1
34*29619d2aSchristos # endif
35*29619d2aSchristos #else /* not EXIT_SUCCESS */
36*29619d2aSchristos # ifdef VMS /* these values suppress some messages; from gnuplot */
37*29619d2aSchristos # define EXIT_SUCCESS 1
38*29619d2aSchristos # define EXIT_FAILURE 0x10000002
39*29619d2aSchristos # else /* not VMS */
40*29619d2aSchristos # define EXIT_SUCCESS 0
41*29619d2aSchristos # define EXIT_FAILURE 1
42*29619d2aSchristos # endif /* not VMS */
43*29619d2aSchristos #endif /* not EXIT_SUCCESS */
44*29619d2aSchristos
45*29619d2aSchristos
46*29619d2aSchristos /* Flush stdout first, exit if failure (therefore, xexit should be
47*29619d2aSchristos called to exit every program, not just `return' from main).
48*29619d2aSchristos Otherwise, if EXIT_STATUS is zero, exit successfully, else
49*29619d2aSchristos unsuccessfully. */
50*29619d2aSchristos
51*29619d2aSchristos void
xexit(int exit_status)52*29619d2aSchristos xexit (int exit_status)
53*29619d2aSchristos {
54*29619d2aSchristos if (ferror (stdout))
55*29619d2aSchristos {
56*29619d2aSchristos fputs (_("ferror on stdout\n"), stderr);
57*29619d2aSchristos exit_status = 1;
58*29619d2aSchristos }
59*29619d2aSchristos else if (fflush (stdout) != 0)
60*29619d2aSchristos {
61*29619d2aSchristos fputs (_("fflush error on stdout\n"), stderr);
62*29619d2aSchristos exit_status = 1;
63*29619d2aSchristos }
64*29619d2aSchristos
65*29619d2aSchristos exit_status = exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
66*29619d2aSchristos
67*29619d2aSchristos exit (exit_status);
68*29619d2aSchristos }
69*29619d2aSchristos
70*29619d2aSchristos
71*29619d2aSchristos /* Why do we care about stdout you may ask? Here's why, from Jim
72*29619d2aSchristos Meyering in the lib/closeout.c file. */
73*29619d2aSchristos
74*29619d2aSchristos /* If a program writes *anything* to stdout, that program should close
75*29619d2aSchristos stdout and make sure that the close succeeds. Otherwise, suppose that
76*29619d2aSchristos you go to the extreme of checking the return status of every function
77*29619d2aSchristos that does an explicit write to stdout. The last printf can succeed in
78*29619d2aSchristos writing to the internal stream buffer, and yet the fclose(stdout) could
79*29619d2aSchristos still fail (due e.g., to a disk full error) when it tries to write
80*29619d2aSchristos out that buffered data. Thus, you would be left with an incomplete
81*29619d2aSchristos output file and the offending program would exit successfully.
82*29619d2aSchristos
83*29619d2aSchristos Besides, it's wasteful to check the return value from every call
84*29619d2aSchristos that writes to stdout -- just let the internal stream state record
85*29619d2aSchristos the failure. That's what the ferror test is checking below.
86*29619d2aSchristos
87*29619d2aSchristos It's important to detect such failures and exit nonzero because many
88*29619d2aSchristos tools (most notably `make' and other build-management systems) depend
89*29619d2aSchristos on being able to detect failure in other tools via their exit status. */
90