1/* Invoke fopen, but avoid some glitches. 2 Copyright (C) 2001, 2004 Free Software Foundation, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18/* Written by Paul Eggert. */ 19 20#if HAVE_CONFIG_H 21# include <config.h> 22#endif 23 24#if HAVE_UNISTD_H 25# include <unistd.h> 26#endif 27#include <unistd-safer.h> 28 29#ifndef STDERR_FILENO 30# define STDERR_FILENO 2 31#endif 32 33#include <errno.h> 34#include <stdio.h> 35#include <stdio-safer.h> 36 37/* Like fopen, but do not return stdin, stdout, or stderr. */ 38 39FILE * 40fopen_safer (char const *file, char const *mode) 41{ 42 FILE *fp = fopen (file, mode); 43 44 if (fp) 45 { 46 int fd = fileno (fp); 47 48 if (0 <= fd && fd <= STDERR_FILENO) 49 { 50 int f = dup_safer (fd); 51 52 if (f < 0) 53 { 54 int e = errno; 55 fclose (fp); 56 errno = e; 57 return NULL; 58 } 59 60 if (fclose (fp) != 0 61 || ! (fp = fdopen (f, mode))) 62 { 63 int e = errno; 64 close (f); 65 errno = e; 66 return NULL; 67 } 68 } 69 } 70 71 return fp; 72} 73