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