1*5af32e75SAxel Dörfler /* Copyright (C) 1993,1994,1997-1999,2000,2002 Free Software Foundation, Inc.
2*5af32e75SAxel Dörfler This file is part of the GNU C Library.
3*5af32e75SAxel Dörfler
4*5af32e75SAxel Dörfler The GNU C Library is free software; you can redistribute it and/or
5*5af32e75SAxel Dörfler modify it under the terms of the GNU Lesser General Public
6*5af32e75SAxel Dörfler License as published by the Free Software Foundation; either
7*5af32e75SAxel Dörfler version 2.1 of the License, or (at your option) any later version.
8*5af32e75SAxel Dörfler
9*5af32e75SAxel Dörfler The GNU C Library is distributed in the hope that it will be useful,
10*5af32e75SAxel Dörfler but WITHOUT ANY WARRANTY; without even the implied warranty of
11*5af32e75SAxel Dörfler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12*5af32e75SAxel Dörfler Lesser General Public License for more details.
13*5af32e75SAxel Dörfler
14*5af32e75SAxel Dörfler You should have received a copy of the GNU Lesser General Public
15*5af32e75SAxel Dörfler License along with the GNU C Library; if not, write to the Free
16*5af32e75SAxel Dörfler Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17*5af32e75SAxel Dörfler 02111-1307 USA.
18*5af32e75SAxel Dörfler
19*5af32e75SAxel Dörfler As a special exception, if you link the code in this file with
20*5af32e75SAxel Dörfler files compiled with a GNU compiler to produce an executable,
21*5af32e75SAxel Dörfler that does not cause the resulting executable to be covered by
22*5af32e75SAxel Dörfler the GNU Lesser General Public License. This exception does not
23*5af32e75SAxel Dörfler however invalidate any other reasons why the executable file
24*5af32e75SAxel Dörfler might be covered by the GNU Lesser General Public License.
25*5af32e75SAxel Dörfler This exception applies to code released by its copyright holders
26*5af32e75SAxel Dörfler in files containing the exception.
27*5af32e75SAxel Dörfler */
28*5af32e75SAxel Dörfler
29*5af32e75SAxel Dörfler
30*5af32e75SAxel Dörfler #include "libioP.h"
31*5af32e75SAxel Dörfler #include <stdlib.h>
32*5af32e75SAxel Dörfler #include <fcntl.h>
33*5af32e75SAxel Dörfler
34*5af32e75SAxel Dörfler #ifdef _LIBC
35*5af32e75SAxel Dörfler # include <shlib-compat.h>
36*5af32e75SAxel Dörfler #endif
37*5af32e75SAxel Dörfler
38*5af32e75SAxel Dörfler
39*5af32e75SAxel Dörfler _IO_FILE *
_IO_new_fdopen(int fd,const char * mode)40*5af32e75SAxel Dörfler _IO_new_fdopen (int fd, const char *mode)
41*5af32e75SAxel Dörfler {
42*5af32e75SAxel Dörfler int read_write;
43*5af32e75SAxel Dörfler int posix_mode = 0;
44*5af32e75SAxel Dörfler struct locked_FILE
45*5af32e75SAxel Dörfler {
46*5af32e75SAxel Dörfler struct _IO_FILE_plus fp;
47*5af32e75SAxel Dörfler #ifdef _IO_MTSAFE_IO
48*5af32e75SAxel Dörfler _IO_lock_t lock;
49*5af32e75SAxel Dörfler #endif
50*5af32e75SAxel Dörfler struct _IO_wide_data wd;
51*5af32e75SAxel Dörfler } *new_f;
52*5af32e75SAxel Dörfler int fd_flags;
53*5af32e75SAxel Dörfler int i;
54*5af32e75SAxel Dörfler int use_mmap = 0;
55*5af32e75SAxel Dörfler
56*5af32e75SAxel Dörfler switch (*mode)
57*5af32e75SAxel Dörfler {
58*5af32e75SAxel Dörfler case 'r':
59*5af32e75SAxel Dörfler read_write = _IO_NO_WRITES;
60*5af32e75SAxel Dörfler break;
61*5af32e75SAxel Dörfler case 'w':
62*5af32e75SAxel Dörfler read_write = _IO_NO_READS;
63*5af32e75SAxel Dörfler break;
64*5af32e75SAxel Dörfler case 'a':
65*5af32e75SAxel Dörfler posix_mode = O_APPEND;
66*5af32e75SAxel Dörfler read_write = _IO_NO_READS|_IO_IS_APPENDING;
67*5af32e75SAxel Dörfler break;
68*5af32e75SAxel Dörfler default:
69*5af32e75SAxel Dörfler MAYBE_SET_EINVAL;
70*5af32e75SAxel Dörfler return NULL;
71*5af32e75SAxel Dörfler }
72*5af32e75SAxel Dörfler for (i = 1; i < 5; ++i)
73*5af32e75SAxel Dörfler {
74*5af32e75SAxel Dörfler switch (*++mode)
75*5af32e75SAxel Dörfler {
76*5af32e75SAxel Dörfler case '\0':
77*5af32e75SAxel Dörfler break;
78*5af32e75SAxel Dörfler case '+':
79*5af32e75SAxel Dörfler read_write &= _IO_IS_APPENDING;
80*5af32e75SAxel Dörfler break;
81*5af32e75SAxel Dörfler case 'm':
82*5af32e75SAxel Dörfler use_mmap = 1;
83*5af32e75SAxel Dörfler continue;
84*5af32e75SAxel Dörfler case 'x':
85*5af32e75SAxel Dörfler case 'b':
86*5af32e75SAxel Dörfler default:
87*5af32e75SAxel Dörfler /* Ignore */
88*5af32e75SAxel Dörfler continue;
89*5af32e75SAxel Dörfler }
90*5af32e75SAxel Dörfler break;
91*5af32e75SAxel Dörfler }
92*5af32e75SAxel Dörfler #ifdef F_GETFL
93*5af32e75SAxel Dörfler fd_flags = fcntl(fd, F_GETFL);
94*5af32e75SAxel Dörfler #ifndef O_ACCMODE
95*5af32e75SAxel Dörfler #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
96*5af32e75SAxel Dörfler #endif
97*5af32e75SAxel Dörfler if (fd_flags == -1)
98*5af32e75SAxel Dörfler return NULL;
99*5af32e75SAxel Dörfler
100*5af32e75SAxel Dörfler if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
101*5af32e75SAxel Dörfler || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
102*5af32e75SAxel Dörfler {
103*5af32e75SAxel Dörfler MAYBE_SET_EINVAL;
104*5af32e75SAxel Dörfler return NULL;
105*5af32e75SAxel Dörfler }
106*5af32e75SAxel Dörfler
107*5af32e75SAxel Dörfler /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
108*5af32e75SAxel Dörfler [System Application Program Interface (API) Amendment 1:
109*5af32e75SAxel Dörfler Realtime Extensions], Rationale B.8.3.3
110*5af32e75SAxel Dörfler Open a Stream on a File Descriptor says:
111*5af32e75SAxel Dörfler
112*5af32e75SAxel Dörfler Although not explicitly required by POSIX.1, a good
113*5af32e75SAxel Dörfler implementation of append ("a") mode would cause the
114*5af32e75SAxel Dörfler O_APPEND flag to be set.
115*5af32e75SAxel Dörfler
116*5af32e75SAxel Dörfler (Historical implementations [such as Solaris2] do a one-time
117*5af32e75SAxel Dörfler seek in fdopen.)
118*5af32e75SAxel Dörfler
119*5af32e75SAxel Dörfler However, we do not turn O_APPEND off if the mode is "w" (even
120*5af32e75SAxel Dörfler though that would seem consistent) because that would be more
121*5af32e75SAxel Dörfler likely to break historical programs.
122*5af32e75SAxel Dörfler */
123*5af32e75SAxel Dörfler if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
124*5af32e75SAxel Dörfler {
125*5af32e75SAxel Dörfler #ifdef F_SETFL
126*5af32e75SAxel Dörfler if (fcntl(fd, F_SETFL, fd_flags | O_APPEND) == -1)
127*5af32e75SAxel Dörfler #endif
128*5af32e75SAxel Dörfler return NULL;
129*5af32e75SAxel Dörfler }
130*5af32e75SAxel Dörfler #endif
131*5af32e75SAxel Dörfler
132*5af32e75SAxel Dörfler new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
133*5af32e75SAxel Dörfler if (new_f == NULL)
134*5af32e75SAxel Dörfler return NULL;
135*5af32e75SAxel Dörfler #ifdef _IO_MTSAFE_IO
136*5af32e75SAxel Dörfler new_f->fp.file._lock = &new_f->lock;
137*5af32e75SAxel Dörfler #endif
138*5af32e75SAxel Dörfler /* Set up initially to use the `maybe_mmap' jump tables rather than using
139*5af32e75SAxel Dörfler __fopen_maybe_mmap to do it, because we need them in place before we
140*5af32e75SAxel Dörfler call _IO_file_attach or else it will allocate a buffer immediately. */
141*5af32e75SAxel Dörfler _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
142*5af32e75SAxel Dörfler #ifdef _G_HAVE_MMAP
143*5af32e75SAxel Dörfler (use_mmap && (read_write & _IO_NO_WRITES))
144*5af32e75SAxel Dörfler ? &_IO_wfile_jumps_maybe_mmap :
145*5af32e75SAxel Dörfler #endif
146*5af32e75SAxel Dörfler &INTUSE(_IO_wfile_jumps));
147*5af32e75SAxel Dörfler _IO_JUMPS (&new_f->fp) =
148*5af32e75SAxel Dörfler #ifdef _G_HAVE_MMAP
149*5af32e75SAxel Dörfler (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap :
150*5af32e75SAxel Dörfler #endif
151*5af32e75SAxel Dörfler &INTUSE(_IO_file_jumps);
152*5af32e75SAxel Dörfler INTUSE(_IO_file_init) (&new_f->fp);
153*5af32e75SAxel Dörfler #if !_IO_UNIFIED_JUMPTABLES
154*5af32e75SAxel Dörfler new_f->fp.vtable = NULL;
155*5af32e75SAxel Dörfler #endif
156*5af32e75SAxel Dörfler if (INTUSE(_IO_file_attach) ((_IO_FILE *) &new_f->fp, fd) == NULL)
157*5af32e75SAxel Dörfler {
158*5af32e75SAxel Dörfler INTUSE(_IO_setb) (&new_f->fp.file, NULL, NULL, 0);
159*5af32e75SAxel Dörfler INTUSE(_IO_un_link) (&new_f->fp);
160*5af32e75SAxel Dörfler free (new_f);
161*5af32e75SAxel Dörfler return NULL;
162*5af32e75SAxel Dörfler }
163*5af32e75SAxel Dörfler new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;
164*5af32e75SAxel Dörfler
165*5af32e75SAxel Dörfler new_f->fp.file._IO_file_flags =
166*5af32e75SAxel Dörfler _IO_mask_flags (&new_f->fp.file, read_write,
167*5af32e75SAxel Dörfler _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
168*5af32e75SAxel Dörfler
169*5af32e75SAxel Dörfler return &new_f->fp.file;
170*5af32e75SAxel Dörfler }
171*5af32e75SAxel Dörfler INTDEF2(_IO_new_fdopen, _IO_fdopen)
172*5af32e75SAxel Dörfler
173*5af32e75SAxel Dörfler strong_alias (_IO_new_fdopen, __new_fdopen)
174*5af32e75SAxel Dörfler versioned_symbol (libc, _IO_new_fdopen, _IO_fdopen, GLIBC_2_1);
175*5af32e75SAxel Dörfler versioned_symbol (libc, __new_fdopen, fdopen, GLIBC_2_1);
176