1 | /* |
---|
2 | FUNCTION |
---|
3 | <<fdopen64>>---turn open large file into a stream |
---|
4 | |
---|
5 | INDEX |
---|
6 | fdopen64 |
---|
7 | INDEX |
---|
8 | _fdopen64_r |
---|
9 | |
---|
10 | SYNOPSIS |
---|
11 | #include <stdio.h> |
---|
12 | FILE *fdopen64(int <[fd]>, const char *<[mode]>); |
---|
13 | FILE *_fdopen64_r(void *<[reent]>, |
---|
14 | int <[fd]>, const char *<[mode]>); |
---|
15 | |
---|
16 | DESCRIPTION |
---|
17 | <<fdopen64>> produces a file descriptor of type <<FILE *>>, from a |
---|
18 | descriptor for an already-open file (returned, for example, by the |
---|
19 | system subroutine <<open>> rather than by <<fopen>>). |
---|
20 | The <[mode]> argument has the same meanings as in <<fopen>>. |
---|
21 | |
---|
22 | RETURNS |
---|
23 | File pointer or <<NULL>>, as for <<fopen>>. |
---|
24 | */ |
---|
25 | |
---|
26 | #include <sys/types.h> |
---|
27 | #include <sys/fcntl.h> |
---|
28 | |
---|
29 | #include <stdio.h> |
---|
30 | #include <errno.h> |
---|
31 | #include "local.h" |
---|
32 | #include <_syslist.h> |
---|
33 | #include <sys/lock.h> |
---|
34 | |
---|
35 | extern int __sflags (); |
---|
36 | |
---|
37 | FILE * |
---|
38 | _fdopen64_r (struct _reent *ptr, |
---|
39 | int fd, |
---|
40 | const char *mode) |
---|
41 | { |
---|
42 | register FILE *fp; |
---|
43 | int flags, oflags; |
---|
44 | #ifdef HAVE_FCNTL |
---|
45 | int fdflags, fdmode; |
---|
46 | #endif |
---|
47 | |
---|
48 | if ((flags = __sflags (ptr, mode, &oflags)) == 0) |
---|
49 | return 0; |
---|
50 | |
---|
51 | /* make sure the mode the user wants is a subset of the actual mode */ |
---|
52 | #ifdef HAVE_FCNTL |
---|
53 | if ((fdflags = _fcntl_r (ptr, fd, F_GETFL, 0)) < 0) |
---|
54 | return 0; |
---|
55 | fdmode = fdflags & O_ACCMODE; |
---|
56 | if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE))) |
---|
57 | { |
---|
58 | ptr->_errno = EBADF; |
---|
59 | return 0; |
---|
60 | } |
---|
61 | #endif |
---|
62 | |
---|
63 | if ((fp = __sfp (ptr)) == 0) |
---|
64 | return 0; |
---|
65 | |
---|
66 | _newlib_flockfile_start(fp); |
---|
67 | |
---|
68 | fp->_flags = flags; |
---|
69 | /* POSIX recommends setting the O_APPEND bit on fd to match append |
---|
70 | streams. Someone may later clear O_APPEND on fileno(fp), but the |
---|
71 | stream must still remain in append mode. Rely on __sflags |
---|
72 | setting __SAPP properly. */ |
---|
73 | #ifdef HAVE_FCNTL |
---|
74 | if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) |
---|
75 | _fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND); |
---|
76 | #endif |
---|
77 | fp->_file = fd; |
---|
78 | fp->_cookie = (void *) fp; |
---|
79 | |
---|
80 | #undef _read |
---|
81 | #undef _write |
---|
82 | #undef _seek |
---|
83 | #undef _close |
---|
84 | |
---|
85 | fp->_read = __sread; |
---|
86 | fp->_write = __swrite64; |
---|
87 | fp->_seek = __sseek; |
---|
88 | fp->_seek64 = __sseek64; |
---|
89 | fp->_close = __sclose; |
---|
90 | |
---|
91 | #ifdef __SCLE |
---|
92 | /* Explicit given mode results in explicit setting mode on fd */ |
---|
93 | if (oflags & O_BINARY) |
---|
94 | setmode(fp->_file, O_BINARY); |
---|
95 | else if (oflags & O_TEXT) |
---|
96 | setmode(fp->_file, O_TEXT); |
---|
97 | if (__stextmode(fp->_file)) |
---|
98 | fp->_flags |= __SCLE; |
---|
99 | #endif |
---|
100 | |
---|
101 | fp->_flags |= __SL64; |
---|
102 | |
---|
103 | _newlib_flockfile_end(fp); |
---|
104 | return fp; |
---|
105 | } |
---|
106 | |
---|
107 | #ifndef _REENT_ONLY |
---|
108 | |
---|
109 | FILE * |
---|
110 | fdopen64 (int fd, |
---|
111 | const char *mode) |
---|
112 | { |
---|
113 | return _fdopen64_r (_REENT, fd, mode); |
---|
114 | } |
---|
115 | |
---|
116 | #endif |
---|