xref: /netbsd-src/external/gpl2/texinfo/dist/lib/xexit.c (revision 29619d2afe564e54d657b83e5a3ae89584f83720)
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