]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/iofdopen.c
Update.
[thirdparty/glibc.git] / libio / iofdopen.c
CommitLineData
0469311e 1/* Copyright (C) 1993,1994,1997-1999,2000,2002 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
96aa2d94 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.
96aa2d94 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
40a55d20 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
96aa2d94 13
41bdb6e2
AJ
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
96aa2d94 18
41bdb6e2
AJ
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
96aa2d94
RM
27
28#ifdef __STDC__
fd091d3f 29# include <stdlib.h>
96aa2d94
RM
30#endif
31#include "libioP.h"
32#include <fcntl.h>
33
fd091d3f
UD
34#ifdef _LIBC
35# include <shlib-compat.h>
36#endif
37
96aa2d94 38#ifndef _IO_fcntl
50304ef0
UD
39#ifdef _LIBC
40#define _IO_fcntl __fcntl
41#else
96aa2d94
RM
42#define _IO_fcntl fcntl
43#endif
50304ef0 44#endif
96aa2d94
RM
45
46_IO_FILE *
bd355af0 47_IO_new_fdopen (fd, mode)
96aa2d94
RM
48 int fd;
49 const char *mode;
50{
51 int read_write;
52 int posix_mode = 0;
edf5b2d7
UD
53 struct locked_FILE
54 {
bd355af0 55 struct _IO_FILE_plus fp;
499e7464 56#ifdef _IO_MTSAFE_IO
edf5b2d7 57 _IO_lock_t lock;
499e7464 58#endif
d64b6ad0 59 struct _IO_wide_data wd;
edf5b2d7 60 } *new_f;
96aa2d94
RM
61 int fd_flags;
62
63 switch (*mode++)
64 {
65 case 'r':
66 read_write = _IO_NO_WRITES;
67 break;
68 case 'w':
69 read_write = _IO_NO_READS;
70 break;
71 case 'a':
72 posix_mode = O_APPEND;
73 read_write = _IO_NO_READS|_IO_IS_APPENDING;
74 break;
75 default:
c4029823 76 MAYBE_SET_EINVAL;
96aa2d94
RM
77 return NULL;
78 }
79 if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
80 read_write &= _IO_IS_APPENDING;
81#ifdef F_GETFL
82 fd_flags = _IO_fcntl (fd, F_GETFL);
83#ifndef O_ACCMODE
84#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
85#endif
2e65ca2b 86 if (fd_flags == -1)
96aa2d94 87 return NULL;
fd091d3f 88
2e65ca2b
UD
89 if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
90 || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
91 {
92 MAYBE_SET_EINVAL;
93 return NULL;
94 }
96aa2d94
RM
95
96 /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
97 [System Application Program Interface (API) Amendment 1:
98 Realtime Extensions], Rationale B.8.3.3
99 Open a Stream on a File Descriptor says:
100
101 Although not explicitly required by POSIX.1, a good
102 implementation of append ("a") mode would cause the
103 O_APPEND flag to be set.
104
105 (Historical implementations [such as Solaris2] do a one-time
106 seek in fdopen.)
107
108 However, we do not turn O_APPEND off if the mode is "w" (even
109 though that would seem consistent) because that would be more
110 likely to break historical programs.
111 */
112 if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
113 {
114#ifdef F_SETFL
115 if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
116#endif
117 return NULL;
118 }
119#endif
120
edf5b2d7
UD
121 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
122 if (new_f == NULL)
96aa2d94 123 return NULL;
499e7464 124#ifdef _IO_MTSAFE_IO
bd355af0 125 new_f->fp.file._lock = &new_f->lock;
499e7464 126#endif
77fe0b9c
UD
127 _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &INTUSE(_IO_wfile_jumps));
128 _IO_JUMPS (&new_f->fp) = &INTUSE(_IO_file_jumps);
129 INTUSE(_IO_file_init) (&new_f->fp);
96aa2d94 130#if !_IO_UNIFIED_JUMPTABLES
edf5b2d7 131 new_f->fp.vtable = NULL;
96aa2d94 132#endif
77fe0b9c 133 if (INTUSE(_IO_file_attach) ((_IO_FILE *) &new_f->fp, fd) == NULL)
96aa2d94 134 {
77fe0b9c 135 INTUSE(_IO_un_link) (&new_f->fp);
edf5b2d7 136 free (new_f);
96aa2d94
RM
137 return NULL;
138 }
bd355af0 139 new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;
96aa2d94 140
bd355af0
UD
141 new_f->fp.file._IO_file_flags =
142 _IO_mask_flags (&new_f->fp.file, read_write,
96aa2d94
RM
143 _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
144
0469311e 145 return __fopen_maybe_mmap (&new_f->fp.file);
96aa2d94 146}
77fe0b9c 147INTDEF2(_IO_new_fdopen, _IO_fdopen)
96aa2d94 148
bd355af0 149strong_alias (_IO_new_fdopen, __new_fdopen)
fd091d3f
UD
150versioned_symbol (libc, _IO_new_fdopen, _IO_fdopen, GLIBC_2_1);
151versioned_symbol (libc, __new_fdopen, fdopen, GLIBC_2_1);