]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/freopen64.c
posix/glob.c: update from gnulib
[thirdparty/glibc.git] / libio / freopen64.c
CommitLineData
581c785b 1/* Copyright (C) 1993-2022 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
dfd2257a 3
41bdb6e2
AJ
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
dfd2257a 8
41bdb6e2
AJ
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
dfd2257a 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
dfd2257a 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>.
dfd2257a 17
41bdb6e2
AJ
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
dfd2257a 26
0b727ed4 27#include <stdio.h>
94b7cc37 28#include <fcntl.h>
1a35b7fd 29#include <stdlib.h>
94b7cc37 30#include <unistd.h>
dfd2257a 31
0b727ed4 32#include <libioP.h>
c44a663d
UD
33#include <fd_to_filename.h>
34
dfd2257a 35FILE *
9d46370c 36freopen64 (const char *filename, const char *mode, FILE *fp)
dfd2257a 37{
0b727ed4 38 FILE *result = NULL;
fa185f0d 39 struct fd_to_filename fdfilename;
0b727ed4 40
dfd2257a 41 CHECK_FILE (fp, NULL);
0b727ed4 42
0261d33f 43 _IO_acquire_lock (fp);
0b727ed4
AZ
44 /* First flush the stream (failure should be ignored). */
45 _IO_SYNC (fp);
46
47 if (!(fp->_flags & _IO_IS_FILEBUF))
48 goto end;
49
94b7cc37 50 int fd = _IO_fileno (fp);
0b727ed4 51 const char *gfilename
fa185f0d 52 = filename != NULL ? filename : __fd_to_filename (fd, &fdfilename);
0b727ed4 53
94b7cc37 54 fp->_flags2 |= _IO_FLAGS2_NOCLOSE;
d18ea0c5 55 _IO_file_close_it (fp);
e69dcccb 56 _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
bbdef797 57 if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
15a686af 58 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
d18ea0c5 59 result = _IO_file_fopen (fp, gfilename, mode, 0);
94b7cc37 60 fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
81c64d40
UD
61 if (result != NULL)
62 result = __fopen_maybe_mmap (result);
3b1de3ba 63 if (result != NULL)
c44a663d 64 {
94b7cc37
UD
65 /* unbound stream orientation */
66 result->_mode = 0;
67
f1a67a2c 68 if (fd != -1 && _IO_fileno (result) != fd)
94b7cc37 69 {
f1a67a2c
AZ
70 /* At this point we have both file descriptors already allocated,
71 so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But
72 we still need to check for EINVAL and, due Linux internal
73 implementation, EBUSY. It is because on how it internally opens
74 the file by splitting the buffer allocation operation and VFS
75 opening (a dup operation may run when a file is still pending
76 'install' on VFS). */
77 if (__dup3 (_IO_fileno (result), fd,
78 (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0
79 ? O_CLOEXEC : 0) == -1)
80 {
81 _IO_file_close_it (result);
82 result = NULL;
83 goto end;
84 }
94b7cc37
UD
85 __close (_IO_fileno (result));
86 _IO_fileno (result) = fd;
87 }
c44a663d 88 }
94b7cc37
UD
89 else if (fd != -1)
90 __close (fd);
f1a67a2c
AZ
91
92end:
0261d33f 93 _IO_release_lock (fp);
dfd2257a 94 return result;
dfd2257a 95}