1/* Invoke fopen, but avoid some glitches.
2
3 Copyright (C) 2001, 2004-2006, 2009-2019 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 <https://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