1131554Stjr/* closeout.c - close standard output 2131554Stjr Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 3131554Stjr 4131554Stjr This program is free software; you can redistribute it and/or modify 5131554Stjr it under the terms of the GNU General Public License as published by 6131554Stjr the Free Software Foundation; either version 2, or (at your option) 7131554Stjr any later version. 8131554Stjr 9131554Stjr This program is distributed in the hope that it will be useful, 10131554Stjr but WITHOUT ANY WARRANTY; without even the implied warranty of 11131554Stjr MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12131554Stjr GNU General Public License for more details. 13131554Stjr 14131554Stjr You should have received a copy of the GNU General Public License 15131554Stjr along with this program; if not, write to the Free Software Foundation, 16131554Stjr Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17131554Stjr 18131554Stjr#if HAVE_CONFIG_H 19131554Stjr# include <config.h> 20131554Stjr#endif 21131554Stjr 22131554Stjr#if ENABLE_NLS 23131554Stjr# include <libintl.h> 24131554Stjr# define _(Text) gettext (Text) 25131554Stjr#else 26131554Stjr# define _(Text) Text 27131554Stjr#endif 28131554Stjr 29131554Stjr#if HAVE_STDLIB_H 30131554Stjr# include <stdlib.h> 31131554Stjr#endif 32131554Stjr#ifndef EXIT_FAILURE 33131554Stjr# define EXIT_FAILURE 1 34131554Stjr#endif 35131554Stjr 36131554Stjr#include <stdio.h> 37131554Stjr 38131554Stjr#include <errno.h> 39131554Stjr#ifndef errno 40131554Stjrextern int errno; 41131554Stjr#endif 42131554Stjr 43131554Stjr#include "closeout.h" 44131554Stjr#include "error.h" 45131554Stjr#include "quotearg.h" 46131554Stjr#if 0 47131554Stjr#include "__fpending.h" 48131554Stjr#endif 49131554Stjr 50131554Stjrstatic int default_exit_status = EXIT_FAILURE; 51131554Stjrstatic const char *file_name; 52131554Stjr 53131554Stjr/* Set the value to be used for the exit status when close_stdout is called. 54131554Stjr This is useful when it is not convenient to call close_stdout_status, 55131554Stjr e.g., when close_stdout is called via atexit. */ 56131554Stjrvoid 57131554Stjrclose_stdout_set_status (int status) 58131554Stjr{ 59131554Stjr default_exit_status = status; 60131554Stjr} 61131554Stjr 62131554Stjr/* Set the file name to be reported in the event an error is detected 63131554Stjr by close_stdout_status. */ 64131554Stjrvoid 65131554Stjrclose_stdout_set_file_name (const char *file) 66131554Stjr{ 67131554Stjr file_name = file; 68131554Stjr} 69131554Stjr 70131554Stjr/* Close standard output, exiting with status STATUS on failure. 71131554Stjr If a program writes *anything* to stdout, that program should `fflush' 72131554Stjr stdout and make sure that it succeeds before exiting. Otherwise, 73131554Stjr suppose that you go to the extreme of checking the return status 74131554Stjr of every function that does an explicit write to stdout. The last 75131554Stjr printf can succeed in writing to the internal stream buffer, and yet 76131554Stjr the fclose(stdout) could still fail (due e.g., to a disk full error) 77131554Stjr when it tries to write out that buffered data. Thus, you would be 78131554Stjr left with an incomplete output file and the offending program would 79131554Stjr exit successfully. 80131554Stjr 81131554Stjr FIXME: note the fflush suggested above is implicit in the fclose 82131554Stjr we actually do below. Consider doing only the fflush and/or using 83131554Stjr setvbuf to inhibit buffering. 84131554Stjr 85131554Stjr Besides, it's wasteful to check the return value from every call 86131554Stjr that writes to stdout -- just let the internal stream state record 87131554Stjr the failure. That's what the ferror test is checking below. 88131554Stjr 89131554Stjr It's important to detect such failures and exit nonzero because many 90131554Stjr tools (most notably `make' and other build-management systems) depend 91131554Stjr on being able to detect failure in other tools via their exit status. */ 92131554Stjr 93131554Stjrvoid 94131554Stjrclose_stdout_status (int status) 95131554Stjr{ 96131554Stjr int e = ferror (stdout) ? 0 : -1; 97131554Stjr 98131554Stjr#if 0 99131554Stjr if (__fpending (stdout) == 0) 100131554Stjr return; 101131554Stjr#endif 102131554Stjr 103131554Stjr if (fclose (stdout) != 0) 104131554Stjr e = errno; 105131554Stjr 106131554Stjr if (0 < e) 107131554Stjr { 108131554Stjr char const *write_error = _("write error"); 109131554Stjr if (file_name) 110131554Stjr error (status, e, "%s: %s", quotearg_colon (file_name), write_error); 111131554Stjr else 112131554Stjr error (status, e, "%s", write_error); 113131554Stjr } 114131554Stjr} 115131554Stjr 116131554Stjr/* Close standard output, exiting with status EXIT_FAILURE on failure. */ 117131554Stjrvoid 118131554Stjrclose_stdout (void) 119131554Stjr{ 120131554Stjr close_stdout_status (default_exit_status); 121131554Stjr} 122