Added binary and unicode file i/o support to msvcrt.
[reactos.git] / reactos / lib / msvcrt / stdio / fsopen.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/msvcrt/stdio/fsopen.c
5 * PURPOSE: Checks for keyboard hits
6 * PROGRAMER: Boudewijn Dekker
7 * UPDATE HISTORY:
8 * 28/12/98: Created
9 */
10 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
11
12 #include <msvcrt/sys/types.h>
13 #include <msvcrt/stdio.h>
14 #include <msvcrt/io.h>
15 #include <msvcrt/fcntl.h>
16 #include <msvcrt/share.h>
17 #include <msvcrt/internal/file.h>
18
19
20 FILE * __alloc_file(void);
21
22
23 FILE* _fsopen(const char *file, const char *mode, int shflag)
24 {
25 FILE *f;
26 int fd, rw, oflags = 0;
27 char tbchar;
28
29 int shf;
30
31 if (file == 0)
32 return 0;
33 if (mode == 0)
34 return 0;
35
36 f = __alloc_file();
37 if (f == NULL)
38 return NULL;
39
40 rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
41
42 switch (*mode)
43 {
44 case 'a':
45 oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
46 break;
47 case 'r':
48 oflags = rw ? O_RDWR : O_RDONLY;
49 break;
50 case 'w':
51 oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
52 break;
53 default:
54 return (NULL);
55 }
56 if (mode[1] == '+')
57 tbchar = mode[2];
58 else
59 tbchar = mode[1];
60 if (tbchar == 't')
61 oflags |= O_TEXT;
62 else if (tbchar == 'b')
63 oflags |= O_BINARY;
64 else
65 oflags |= (_fmode & (O_TEXT|O_BINARY));
66
67 if ( shflag == _SH_DENYNO )
68 shf = _S_IREAD | _S_IWRITE;
69 else if( shflag == _SH_DENYRD )
70 shf = _S_IWRITE;
71 else if( shflag == _SH_DENYRW )
72 shf = 0;
73 else if( shflag == _SH_DENYWR )
74 shf = _S_IREAD;
75 else
76 shf = _S_IREAD | _S_IWRITE;
77
78 fd = _open(file, oflags, shf);
79 if (fd < 0)
80 return NULL;
81
82 // msvcrt ensures that writes will end up at the end of file in append mode
83 // we just move the file pointer to the end of file initially
84 if (*mode == 'a')
85 lseek(fd, 0, SEEK_END);
86
87 f->_cnt = 0;
88 f->_file = fd;
89 f->_bufsiz = 0;
90 if (rw)
91 f->_flag = _IOREAD | _IOWRT;
92 else if (*mode == 'r')
93 f->_flag = _IOREAD;
94 else
95 f->_flag = _IOWRT;
96
97 f->_base = f->_ptr = NULL;
98 return f;
99 }
100
101 FILE* _wfsopen(const wchar_t *file, const wchar_t *mode, int shflag)
102 {
103 FILE *f;
104 int fd, rw, oflags = 0;
105 wchar_t tbchar;
106
107 int shf;
108
109 if (file == 0)
110 return 0;
111 if (mode == 0)
112 return 0;
113
114 f = __alloc_file();
115 if (f == NULL)
116 return NULL;
117
118 rw = (mode[1] == L'+') || (mode[1] && (mode[2] == L'+'));
119
120 switch (*mode)
121 {
122 case L'a':
123 oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
124 break;
125 case L'r':
126 oflags = rw ? O_RDWR : O_RDONLY;
127 break;
128 case L'w':
129 oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
130 break;
131 default:
132 return (NULL);
133 }
134 if (mode[1] == L'+')
135 tbchar = mode[2];
136 else
137 tbchar = mode[1];
138 if (tbchar == L't')
139 oflags |= O_TEXT;
140 else if (tbchar == L'b')
141 oflags |= O_BINARY;
142 else
143 oflags |= (_fmode & (O_TEXT|O_BINARY));
144
145 if ( shflag == _SH_DENYNO )
146 shf = _S_IREAD | _S_IWRITE;
147 else if( shflag == _SH_DENYRD )
148 shf = _S_IWRITE;
149 else if( shflag == _SH_DENYRW )
150 shf = 0;
151 else if( shflag == _SH_DENYWR )
152 shf = _S_IREAD;
153 else
154 shf = _S_IREAD | _S_IWRITE;
155
156 fd = _wopen(file, oflags, shf);
157 if (fd < 0)
158 return NULL;
159
160 // msvcrt ensures that writes will end up at the end of file in append mode
161 // we just move the file pointer to the end of file initially
162 if (*mode == L'a')
163 lseek(fd, 0, SEEK_END);
164
165 f->_cnt = 0;
166 f->_file = fd;
167 f->_bufsiz = 0;
168 if (rw)
169 f->_flag = _IOREAD | _IOWRT;
170 else if (*mode == L'r')
171 f->_flag = _IOREAD;
172 else
173 f->_flag = _IOWRT;
174
175 f->_base = f->_ptr = NULL;
176 return f;
177 }