[MSVCRT_WINETEST] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / rostests / winetests / msvcrt / file.c
1 /*
2 * Unit test suite for file functions
3 *
4 * Copyright 2002 Bill Currie
5 * Copyright 2005 Paul Rupe
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "wine/test.h"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <share.h>
28 #include <sys/stat.h>
29 #include <io.h>
30 #include <direct.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winnls.h>
34 #include <process.h>
35 #include <errno.h>
36 #include <locale.h>
37
38 #define MSVCRT_FD_BLOCK_SIZE 32
39 typedef struct {
40 HANDLE handle;
41 unsigned char wxflag;
42 char lookahead[3];
43 int exflag;
44 CRITICAL_SECTION crit;
45 } ioinfo;
46 static ioinfo **__pioinfo;
47
48 static HANDLE proc_handles[2];
49
50 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
51 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
52 static errno_t (__cdecl *p__get_fmode)(int*);
53 static errno_t (__cdecl *p__set_fmode)(int);
54
55 static const char* get_base_name(const char *path)
56 {
57 const char *ret = path+strlen(path)-1;
58
59 while(ret >= path) {
60 if(*ret=='\\' || *ret=='/')
61 break;
62 ret--;
63 }
64 return ret+1;
65 }
66
67 static void init(void)
68 {
69 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
70
71 setlocale(LC_CTYPE, "C");
72
73 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
74 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
75 __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo");
76 p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode");
77 p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode");
78 }
79
80 static void test_filbuf( void )
81 {
82 FILE *fp;
83 int c;
84 fpos_t pos;
85
86 fp = fopen("filbuf.tst", "wb");
87 fwrite("\n\n\n\n", 1, 4, fp);
88 fclose(fp);
89
90 fp = fopen("filbuf.tst", "rt");
91 c = _filbuf(fp);
92 ok(c == '\n', "read wrong byte\n");
93 /* See bug 16970 for why we care about _filbuf.
94 * ftell returns screwy values on files with lots
95 * of bare LFs in ascii mode because it assumes
96 * that ascii files contain only CRLFs, removes
97 * the CR's early in _filbuf, and adjusts the return
98 * value of ftell to compensate.
99 * native _filbuf will read the whole file, then consume and return
100 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
101 * pointing to a buffer of three bare LFs, so
102 * ftell will return 4 - 3 - 3 = -2.
103 */
104 ok(ftell(fp) == -2, "ascii crlf removal does not match native\n");
105 ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n");
106 ok(pos == -2, "ftell does not match fgetpos\n");
107 fclose(fp);
108 unlink("filbuf.tst");
109 }
110
111 static void test_fdopen( void )
112 {
113 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
114 char ibuf[10];
115 int fd;
116 FILE *file;
117
118 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
119 write (fd, buffer, sizeof (buffer));
120 close (fd);
121
122 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
123 lseek (fd, 5, SEEK_SET);
124 file = fdopen (fd, "rb");
125 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
126 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
127 fclose (file);
128 unlink ("fdopen.tst");
129 }
130
131 static void test_fileops( void )
132 {
133 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
134 char buffer[256];
135 WCHAR wbuffer[256];
136 int fd;
137 FILE *file;
138 fpos_t pos;
139 int i, c, bufmode;
140 static const int bufmodes[] = {_IOFBF,_IONBF};
141
142 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
143 write (fd, outbuffer, sizeof (outbuffer));
144 close (fd);
145
146 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
147 {
148 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
149 file = fdopen (fd, "rb");
150 setvbuf(file,NULL,bufmodes[bufmode],2048);
151 if(bufmodes[bufmode] == _IOFBF)
152 ok(file->_bufsiz == 2048, "file->_bufsiz = %d\n", file->_bufsiz);
153 ok(file->_base != NULL, "file->_base = NULL\n");
154 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
155 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
156 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
157 ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
158 rewind(file);
159 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
160 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]);
161 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
162 ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]);
163 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]);
164
165 rewind(file);
166 for (i = 0; i < sizeof(outbuffer); i++)
167 {
168 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
169 }
170 ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
171 ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
172 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
173 ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
174 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
175 c = outbuffer[sizeof(outbuffer) - 1];
176 ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]);
177 ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
178 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
179 ok(c == outbuffer[sizeof(outbuffer) - 1],
180 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]);
181 ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]);
182 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
183 ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
184
185 rewind(file);
186 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
187 ok(pos == 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
188 pos = sizeof (outbuffer);
189 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
190 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
191 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
192
193 fclose (file);
194 }
195 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
196 file = fdopen (fd, "rt"); /* open in TEXT mode */
197 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
198 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
199 ok(feof(file) !=0,"feof doesn't signal EOF\n");
200 rewind(file);
201 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
202 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
203 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
204 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
205 fclose (file);
206
207 file = fopen("fdopen.tst", "rb");
208 ok( file != NULL, "fopen failed\n");
209 /* sizeof(buffer) > content of file */
210 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
211 /* feof should be set now */
212 ok(feof(file), "feof after fread failed\n");
213 fclose (file);
214
215 unlink ("fdopen.tst");
216 }
217
218 #define IOMODE (ao?"ascii mode":"binary mode")
219 static void test_readmode( BOOL ascii_mode )
220 {
221 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9\r\n\r\nA,B,C,D,E\r\nX,Y,Z";
222 static const char padbuffer[] = "ghjghjghjghj";
223 static const char nlbuffer[] = "\r\n";
224 char buffer[2*BUFSIZ+256];
225 const char *optr;
226 int fd;
227 FILE *file;
228 const int *ip;
229 int i, j, m, ao, pl;
230 unsigned int fp;
231 LONG l;
232
233 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
234 /* an internal buffer of BUFSIZ is maintained, so make a file big
235 * enough to test operations that cross the buffer boundary
236 */
237 j = (2*BUFSIZ-4)/strlen(padbuffer);
238 for (i=0; i<j; i++)
239 write (fd, padbuffer, strlen(padbuffer));
240 j = (2*BUFSIZ-4)%strlen(padbuffer);
241 for (i=0; i<j; i++)
242 write (fd, &padbuffer[i], 1);
243 write (fd, nlbuffer, strlen(nlbuffer));
244 write (fd, outbuffer, sizeof (outbuffer));
245 close (fd);
246
247 if (ascii_mode) {
248 /* Open file in ascii mode */
249 fd = open ("fdopen.tst", O_RDONLY);
250 file = fdopen (fd, "r");
251 ao = -1; /* on offset to account for carriage returns */
252 }
253 else {
254 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
255 file = fdopen (fd, "rb");
256 ao = 0;
257 }
258
259 /* first is a test of fgets, ftell, fseek */
260 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
261 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
262 l = ftell(file);
263 pl = 2*BUFSIZ-2;
264 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
265 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
266 lstrlenA(buffer), pl+ao, IOMODE);
267 for (fp=0; fp<strlen(outbuffer); fp++)
268 if (outbuffer[fp] == '\n') break;
269 fp++;
270 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
271 l = ftell(file);
272 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
273 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
274 lstrlenA(buffer), fp+ao, IOMODE);
275 /* test a seek back across the buffer boundary */
276 l = pl;
277 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
278 l = ftell(file);
279 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
280 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
281 l = ftell(file);
282 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
283 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
284 lstrlenA(buffer), fp+ao, IOMODE);
285 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
286 fp += 2;
287 l = ftell(file);
288 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
289 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
290 lstrlenA(buffer), 2+ao, IOMODE);
291
292 /* test fread across buffer boundary */
293 rewind(file);
294 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
295 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
296 j=strlen(outbuffer);
297 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
298 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
299 l = ftell(file);
300 ok(l == pl+j-(ao*4)-5,"ftell after fread got %d should be %d in %s\n", l, pl+j-(ao*4)-5, IOMODE);
301 for (m=0; m<3; m++)
302 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
303 m+=BUFSIZ+2+ao;
304 optr = outbuffer;
305 for (; m<i; m++) {
306 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
307 optr++;
308 if (ao && (*optr == '\r'))
309 optr++;
310 }
311 /* fread should return the requested number of bytes if available */
312 rewind(file);
313 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
314 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
315 j = fp+10;
316 i=fread(buffer,1,j,file);
317 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
318 /* test fread eof */
319 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
320 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
321 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
322 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
323 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
324 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
325 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
326 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
327 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
328 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
329
330 /* test some additional functions */
331 rewind(file);
332 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
333 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
334 i = _getw(file);
335 ip = (const int *)outbuffer;
336 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
337 for (fp=0; fp<strlen(outbuffer); fp++)
338 if (outbuffer[fp] == '\n') break;
339 fp++;
340 /* this will cause the next _getw to cross carriage return characters */
341 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
342 for (i=0, j=0; i<6; i++) {
343 if (ao==0 || outbuffer[fp-3+i] != '\r')
344 buffer[j++] = outbuffer[fp-3+i];
345 }
346 i = _getw(file);
347 ip = (int *)buffer;
348 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
349
350 fclose (file);
351 unlink ("fdopen.tst");
352 }
353
354 static void test_asciimode(void)
355 {
356 FILE *fp;
357 char buf[64];
358 int c, i, j;
359
360 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
361 fp = fopen("ascii.tst", "wb");
362 fputs("\r\r\n", fp);
363 fclose(fp);
364 fp = fopen("ascii.tst", "rt");
365 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
366 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
367 rewind(fp);
368 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
369 fclose(fp);
370 unlink("ascii.tst");
371
372 /* Simple test of foo ^Z [more than one block] bar handling */
373 fp = fopen("ascii.tst", "wb");
374 fputs("foo\032", fp); /* foo, logical EOF, ... */
375 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
376 fputs("bar", fp); /* ... bar */
377 fclose(fp);
378 fp = fopen("ascii.tst", "rt");
379 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
380 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
381 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
382 rewind(fp);
383 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
384 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
385 fclose(fp);
386
387 /* Show ASCII mode handling*/
388 fp= fopen("ascii.tst","wb");
389 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
390 fclose(fp);
391
392 fp = fopen("ascii.tst", "r");
393 c= fgetc(fp);
394 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
395 c= fgetc(fp);
396 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
397 fseek(fp,0,SEEK_CUR);
398 for(i=1; i<10; i++) {
399 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
400 fseek(fp,0,SEEK_CUR);
401 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
402 c= fgetc(fp);
403 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
404 }
405 /* Show that fseek doesn't skip \\r !*/
406 rewind(fp);
407 c= fgetc(fp);
408 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
409 fseek(fp, 2 ,SEEK_CUR);
410 for(i=1; i<10; i++) {
411 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
412 fseek(fp, 2 ,SEEK_CUR);
413 }
414 fseek(fp, 9*3 ,SEEK_SET);
415 c = fgetc(fp);
416 ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c);
417 fseek(fp, -4 ,SEEK_CUR);
418 for(i= 8; i>=0; i--) {
419 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
420 fseek(fp, -4 ,SEEK_CUR);
421 }
422 /* Show what happens if fseek positions filepointer on \\r */
423 fclose(fp);
424 fp = fopen("ascii.tst", "r");
425 fseek(fp, 3 ,SEEK_SET);
426 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
427 fclose(fp);
428
429 unlink("ascii.tst");
430 }
431
432 static void test_asciimode2(void)
433 {
434 /* Error sequence from one app was getchar followed by small fread
435 * with one \r removed had last byte of buffer filled with
436 * next byte of *unbuffered* data rather than next byte from buffer
437 * Test case is a short string of one byte followed by a newline
438 * followed by filler to fill out the sector, then a sector of
439 * some different byte.
440 */
441
442 FILE *fp;
443 char ibuf[4];
444 int i;
445 static const char obuf[] =
446 "00\n"
447 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
448 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
449 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
450 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
451 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
452 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
453 "000000000000000000\n"
454 "1111111111111111111";
455
456 fp = fopen("ascii2.tst", "wt");
457 fwrite(obuf, 1, sizeof(obuf), fp);
458 fclose(fp);
459
460 fp = fopen("ascii2.tst", "rt");
461 ok(getc(fp) == '0', "first char not 0\n");
462 memset(ibuf, 0, sizeof(ibuf));
463 i = fread(ibuf, 1, sizeof(ibuf), fp);
464 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
465 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
466 fclose(fp);
467 unlink("ascii2.tst");
468 }
469
470 static void test_filemodeT(void)
471 {
472 char DATA [] = {26, 't', 'e', 's' ,'t'};
473 char DATA2 [100];
474 char temppath[MAX_PATH];
475 char tempfile[MAX_PATH];
476 FILE* f;
477 size_t bytesWritten;
478 size_t bytesRead;
479 WIN32_FIND_DATAA findData;
480 HANDLE h;
481
482 GetTempPathA(MAX_PATH, temppath);
483 GetTempFileNameA(temppath, "", 0, tempfile);
484
485 f = fopen(tempfile, "w+bDT");
486 bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
487 rewind(f);
488 bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
489 fclose(f);
490
491 ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
492 "fopen file mode 'T' wrongly interpreted as 't'\n" );
493
494 h = FindFirstFileA(tempfile, &findData);
495
496 ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
497
498 if (h != INVALID_HANDLE_VALUE) FindClose(h);
499 }
500
501 static WCHAR* AtoW( const char* p )
502 {
503 WCHAR* buffer;
504 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
505 buffer = malloc( len * sizeof(WCHAR) );
506 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
507 return buffer;
508 }
509
510 /* Test reading in text mode when the 512'th character read is \r*/
511 static void test_readboundary(void)
512 {
513 FILE *fp;
514 char buf[513], rbuf[513];
515 int i, j;
516 for (i = 0; i < 511; i++)
517 {
518 j = (i%('~' - ' ')+ ' ');
519 buf[i] = j;
520 }
521 buf[511] = '\n';
522 buf[512] =0;
523 fp = fopen("boundary.tst", "wt");
524 fwrite(buf, 512,1,fp);
525 fclose(fp);
526 fp = fopen("boundary.tst", "rt");
527 for(i=0; i<512; i++)
528 {
529 fseek(fp,0 , SEEK_CUR);
530 rbuf[i] = fgetc(fp);
531 }
532 rbuf[512] =0;
533 fclose(fp);
534 unlink("boundary.tst");
535
536 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
537 }
538
539 static void test_fgetc( void )
540 {
541 char* tempf;
542 FILE *tempfh;
543 int ich=0xe0, ret;
544
545 tempf=_tempnam(".","wne");
546 tempfh = fopen(tempf,"w+");
547 fputc(ich, tempfh);
548 fputc(ich, tempfh);
549 rewind(tempfh);
550 ret = fgetc(tempfh);
551 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
552 ret = fgetc(tempfh);
553 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
554 fclose(tempfh);
555 tempfh = fopen(tempf,"wt");
556 fputc('\n', tempfh);
557 fclose(tempfh);
558 tempfh = fopen(tempf,"wt");
559 setbuf(tempfh, NULL);
560 ret = fgetc(tempfh);
561 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
562 fclose(tempfh);
563 unlink(tempf);
564 free(tempf);
565 }
566
567 static void test_fputc( void )
568 {
569 char* tempf;
570 FILE *tempfh;
571 int ret;
572
573 tempf=_tempnam(".","wne");
574 tempfh = fopen(tempf,"wb");
575 ret = fputc(0,tempfh);
576 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
577 ret = fputc(0xff,tempfh);
578 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
579 ret = fputc(0xffffffff,tempfh);
580 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
581 fclose(tempfh);
582
583 tempfh = fopen(tempf,"rb");
584 ret = fputc(0,tempfh);
585 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
586 fclose(tempfh);
587
588 unlink(tempf);
589 free(tempf);
590 }
591
592 static void test_flsbuf( void )
593 {
594 char* tempf;
595 FILE *tempfh;
596 int c;
597 int ret;
598 int bufmode;
599 static const int bufmodes[] = {_IOFBF,_IONBF};
600
601 tempf=_tempnam(".","wne");
602 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
603 {
604 tempfh = fopen(tempf,"wb");
605 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
606 ret = _flsbuf(0,tempfh);
607 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
608 bufmodes[bufmode], 0, ret);
609 ret = _flsbuf(0xff,tempfh);
610 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
611 bufmodes[bufmode], 0xff, ret);
612 ret = _flsbuf(0xffffffff,tempfh);
613 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
614 bufmodes[bufmode], 0xff, ret);
615 if(tempfh->_base) {
616 fputc('x', tempfh);
617 tempfh->_cnt = -1;
618 tempfh->_base[1] = 'a';
619 ret = _flsbuf(0xab,tempfh);
620 ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
621 bufmodes[bufmode], ret);
622 ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
623 tempfh->_base[1]);
624 }
625
626 fclose(tempfh);
627 }
628
629 tempfh = fopen(tempf,"rb");
630 ret = _flsbuf(0,tempfh);
631 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
632 fclose(tempfh);
633
634 /* See bug 17123, exposed by WinAVR's make */
635 tempfh = fopen(tempf,"w");
636 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
637 setbuf(tempfh, NULL);
638 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
639 ok(tempfh->_bufsiz == 2, "_bufsiz = %d\n", tempfh->_bufsiz);
640 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
641 tempfh->_cnt = 1234;
642 ret = _flsbuf('Q',tempfh);
643 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
644 /* ... and reset it to zero */
645 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
646 fclose(tempfh);
647 /* And just for grins, make sure the file is correct */
648 tempfh = fopen(tempf,"r");
649 c = fgetc(tempfh);
650 ok(c == 'Q', "first byte should be 'Q'\n");
651 c = fgetc(tempfh);
652 ok(c == EOF, "there should only be one byte\n");
653 fclose(tempfh);
654
655 unlink(tempf);
656 free(tempf);
657 }
658
659 static void test_fflush( void )
660 {
661 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
662 char buf1[16], buf2[24];
663 char *tempf;
664 FILE *tempfh;
665 int ret;
666
667 tempf=_tempnam(".","wne");
668
669 /* Prepare the file. */
670 tempfh = fopen(tempf,"wb");
671 ok(tempfh != NULL, "Can't open test file.\n");
672 fwrite(obuf, 1, sizeof(obuf), tempfh);
673 fclose(tempfh);
674
675 /* Open the file for input. */
676 tempfh = fopen(tempf,"rb");
677 ok(tempfh != NULL, "Can't open test file.\n");
678 fread(buf1, 1, sizeof(buf1), tempfh);
679
680 /* Using fflush() on input stream is undefined in ANSI.
681 * But MSDN says that it clears input buffer. */
682 _lseek(_fileno(tempfh), 0, SEEK_SET);
683 ret = fflush(tempfh);
684 ok(ret == 0, "expected 0, got %d\n", ret);
685 memset(buf2, '?', sizeof(buf2));
686 fread(buf2, 1, sizeof(buf2), tempfh);
687 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
688
689 /* fflush(NULL) doesn't clear input buffer. */
690 _lseek(_fileno(tempfh), 0, SEEK_SET);
691 ret = fflush(NULL);
692 ok(ret == 0, "expected 0, got %d\n", ret);
693 memset(buf2, '?', sizeof(buf2));
694 fread(buf2, 1, sizeof(buf2), tempfh);
695 ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]);
696
697 /* _flushall() clears input buffer. */
698 _lseek(_fileno(tempfh), 0, SEEK_SET);
699 ret = _flushall();
700 ok(ret >= 0, "unexpected ret %d\n", ret);
701 memset(buf2, '?', sizeof(buf2));
702 fread(buf2, 1, sizeof(buf2), tempfh);
703 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
704
705 fclose(tempfh);
706
707 unlink(tempf);
708 free(tempf);
709 }
710
711 static void test_fgetwc( void )
712 {
713 #define LLEN 512
714
715 char* tempf;
716 FILE *tempfh;
717 static const char mytext[]= "This is test_fgetwc\r\n";
718 WCHAR wtextW[BUFSIZ+LLEN+1];
719 WCHAR *mytextW = NULL, *aptr, *wptr;
720 BOOL diff_found = FALSE;
721 int j;
722 unsigned int i;
723 LONG l;
724
725 tempf=_tempnam(".","wne");
726 tempfh = fopen(tempf,"wb");
727 j = 'a';
728 /* pad to almost the length of the internal buffer */
729 for (i=0; i<BUFSIZ-4; i++)
730 fputc(j,tempfh);
731 j = '\r';
732 fputc(j,tempfh);
733 j = '\n';
734 fputc(j,tempfh);
735 fputs(mytext,tempfh);
736 fclose(tempfh);
737 /* in text mode, getws/c expects multibyte characters */
738 /*currently Wine only supports plain ascii, and that is all that is tested here */
739 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
740 fgetws(wtextW,LLEN,tempfh);
741 l=ftell(tempfh);
742 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
743 fgetws(wtextW,LLEN,tempfh);
744 l=ftell(tempfh);
745 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlenA(mytext), l);
746 mytextW = AtoW (mytext);
747 aptr = mytextW;
748 wptr = wtextW;
749 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
750 {
751 diff_found |= (*aptr != *wptr);
752 }
753 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
754 ok(*wptr == '\n', "Carriage return was not skipped\n");
755 fclose(tempfh);
756 unlink(tempf);
757
758 tempfh = fopen(tempf,"wb");
759 j = 'a';
760 /* pad to almost the length of the internal buffer. Use an odd number of bytes
761 to test that we can read wchars that are split across the internal buffer
762 boundary */
763 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
764 fputc(j,tempfh);
765 j = '\r';
766 fputwc(j,tempfh);
767 j = '\n';
768 fputwc(j,tempfh);
769 fputws(wtextW,tempfh);
770 fputws(wtextW,tempfh);
771 fclose(tempfh);
772 /* in binary mode, getws/c expects wide characters */
773 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
774 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
775 fgetws(wtextW,j,tempfh);
776 l=ftell(tempfh);
777 j=(j-1)*sizeof(WCHAR);
778 ok(l==j, "ftell expected %d got %d\n", j, l);
779 i=fgetc(tempfh);
780 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
781 l=ftell(tempfh);
782 j++;
783 ok(l==j, "ftell expected %d got %d\n", j, l);
784 fgetws(wtextW,3,tempfh);
785 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
786 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
787 l=ftell(tempfh);
788 j += 4;
789 ok(l==j, "ftell expected %d got %d\n", j, l);
790 for(i=0; i<strlen(mytext); i++)
791 wtextW[i] = 0;
792 /* the first time we get the string, it should be entirely within the local buffer */
793 fgetws(wtextW,LLEN,tempfh);
794 l=ftell(tempfh);
795 j += (strlen(mytext)-1)*sizeof(WCHAR);
796 ok(l==j, "ftell expected %d got %d\n", j, l);
797 diff_found = FALSE;
798 aptr = mytextW;
799 wptr = wtextW;
800 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
801 {
802 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
803 diff_found |= (*aptr != *wptr);
804 }
805 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
806 ok(*wptr == '\n', "Should get newline\n");
807 for(i=0; i<strlen(mytext); i++)
808 wtextW[i] = 0;
809 /* the second time we get the string, it should cross the local buffer boundary.
810 One of the wchars should be split across the boundary */
811 fgetws(wtextW,LLEN,tempfh);
812 diff_found = FALSE;
813 aptr = mytextW;
814 wptr = wtextW;
815 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
816 {
817 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
818 diff_found |= (*aptr != *wptr);
819 }
820 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
821 ok(*wptr == '\n', "Should get newline\n");
822
823 free(mytextW);
824 fclose(tempfh);
825 unlink(tempf);
826 free(tempf);
827 }
828
829 static void test_fgetwc_locale(const char* text, const char* locale, int codepage)
830 {
831 char temppath[MAX_PATH], tempfile[MAX_PATH];
832 FILE *tempfh;
833 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
834 WCHAR wtextW[BUFSIZ];
835 int ret = 0, i;
836 wint_t ch;
837
838 if (!setlocale(LC_CTYPE, locale))
839 {
840 win_skip("%s locale not available\n", locale);
841 return;
842 }
843
844 GetTempPathA(MAX_PATH, temppath);
845 GetTempFileNameA(temppath, "", 0, tempfile);
846
847 tempfh = fopen(tempfile, "wb");
848 ok(tempfh != NULL, "can't open tempfile\n");
849 fwrite(text, 1, strlen(text), tempfh);
850 fclose(tempfh);
851
852 if (codepage != 0)
853 {
854 /* mbstowcs rejects invalid multibyte sequence,
855 so we use MultiByteToWideChar here. */
856 ret = MultiByteToWideChar(codepage, 0, text, -1,
857 wtextW, sizeof(wtextW)/sizeof(wtextW[0]));
858 ok(ret > 0, "MultiByteToWideChar failed\n");
859 }
860 else
861 {
862 /* C locale */
863 const char *p;
864 for (p = text; *p != '\0'; p++)
865 wtextW[ret++] = (unsigned char)*p;
866 wtextW[ret++] = 0;
867 }
868
869 tempfh = fopen(tempfile, "rt");
870 ok(tempfh != NULL, "can't open tempfile\n");
871
872 for (i = 0; i < ret-1; i++)
873 {
874 ch = fgetwc(tempfh);
875 ok(ch == wtextW[i], "got %04hx, expected %04hx (cp%d[%d])\n", ch, wtextW[i], codepage, i);
876 }
877 ch = fgetwc(tempfh);
878 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
879 fclose(tempfh);
880
881 tempfh = fopen(tempfile, "wb");
882 ok(tempfh != NULL, "can't open tempfile\n");
883 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
884 fclose(tempfh);
885
886 tempfh = fopen(tempfile, "rb");
887 ok(tempfh != NULL, "can't open tempfile\n");
888 for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
889 {
890 ch = fgetwc(tempfh);
891 ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
892 }
893 ch = fgetwc(tempfh);
894 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
895 fclose(tempfh);
896 unlink(tempfile);
897 }
898
899 static void test_fgetwc_unicode(void)
900 {
901 char temppath[MAX_PATH], tempfile[MAX_PATH];
902 FILE *tempfh;
903 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
904 char utf8_text[BUFSIZ];
905 int ret, i;
906 wint_t ch;
907
908 GetTempPathA(MAX_PATH, temppath);
909 GetTempFileNameA(temppath, "", 0, tempfile);
910
911 if (!p_fopen_s)
912 {
913 win_skip("fopen_s not available\n");
914 return;
915 }
916
917 tempfh = fopen(tempfile, "wb");
918 ok(tempfh != NULL, "can't open tempfile\n");
919 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
920 fclose(tempfh);
921
922 tempfh = fopen(tempfile, "rt,ccs=unicode");
923 ok(tempfh != NULL, "can't open tempfile\n");
924 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
925 {
926 ch = fgetwc(tempfh);
927 ok(ch == wchar_text[i],
928 "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1);
929 }
930 ch = fgetwc(tempfh);
931 ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch);
932 fclose(tempfh);
933
934 tempfh = fopen(tempfile, "wb");
935 ok(tempfh != NULL, "can't open tempfile\n");
936 ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]),
937 utf8_text, sizeof(utf8_text), NULL, NULL);
938 ok(ret > 0, "utf-8 conversion failed\n");
939 fwrite(utf8_text, sizeof(char), ret, tempfh);
940 fclose(tempfh);
941
942 tempfh = fopen(tempfile, "rt, ccs=UTF-8");
943 ok(tempfh != NULL, "can't open tempfile\n");
944 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
945 {
946 ch = fgetwc(tempfh);
947 ok(ch == wchar_text[i],
948 "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1);
949 }
950 ch = fgetwc(tempfh);
951 ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch);
952 fclose(tempfh);
953 unlink(temppath);
954 }
955
956 static void test_fputwc(void)
957 {
958 char temppath[MAX_PATH];
959 char tempfile[MAX_PATH];
960 FILE *f;
961 char buf[1024];
962 int ret;
963
964 GetTempPathA(MAX_PATH, temppath);
965 GetTempFileNameA(temppath, "", 0, tempfile);
966
967 f = fopen(tempfile, "w");
968 ret = fputwc('a', f);
969 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
970 ret = fputwc('\n', f);
971 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
972 fclose(f);
973
974 f = fopen(tempfile, "rb");
975 ret = fread(buf, 1, sizeof(buf), f);
976 ok(ret == 3, "fread returned %d, expected 3\n", ret);
977 ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
978 fclose(f);
979
980 if(p_fopen_s) {
981 f = fopen(tempfile, "w,ccs=unicode");
982 ret = fputwc('a', f);
983 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
984 ret = fputwc('\n', f);
985 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
986 fclose(f);
987
988 f = fopen(tempfile, "rb");
989 ret = fread(buf, 1, sizeof(buf), f);
990 ok(ret == 8, "fread returned %d, expected 8\n", ret);
991 ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
992 fclose(f);
993
994 f = fopen(tempfile, "w,ccs=utf-8");
995 ret = fputwc('a', f);
996 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
997 ret = fputwc('\n', f);
998 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
999 fclose(f);
1000
1001 f = fopen(tempfile, "rb");
1002 ret = fread(buf, 1, sizeof(buf), f);
1003 ok(ret == 6, "fread returned %d, expected 6\n", ret);
1004 ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
1005 fclose(f);
1006 }else {
1007 win_skip("fputwc tests on unicode files\n");
1008 }
1009
1010 _unlink(tempfile);
1011 }
1012
1013 static void test_ctrlz( void )
1014 {
1015 char* tempf;
1016 FILE *tempfh;
1017 static const char mytext[]= "This is test_ctrlz";
1018 char buffer[256];
1019 int i, j;
1020 LONG l;
1021
1022 tempf=_tempnam(".","wne");
1023 tempfh = fopen(tempf,"wb");
1024 fputs(mytext,tempfh);
1025 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
1026 fputc(j,tempfh);
1027 j = '\r';
1028 fputc(j,tempfh);
1029 j = '\n';
1030 fputc(j,tempfh);
1031 j = 'a';
1032 fputc(j,tempfh);
1033 fclose(tempfh);
1034 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1035 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1036 i=strlen(buffer);
1037 j=strlen(mytext);
1038 ok(i==j, "returned string length expected %d got %d\n", j, i);
1039 j+=4; /* ftell should indicate the true end of file */
1040 l=ftell(tempfh);
1041 ok(l==j, "ftell expected %d got %d\n", j, l);
1042 ok(feof(tempfh), "did not get EOF\n");
1043 fclose(tempfh);
1044
1045 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
1046 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1047 i=strlen(buffer);
1048 j=strlen(mytext)+3; /* should get through newline */
1049 ok(i==j, "returned string length expected %d got %d\n", j, i);
1050 l=ftell(tempfh);
1051 ok(l==j, "ftell expected %d got %d\n", j, l);
1052 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1053 i=strlen(buffer);
1054 ok(i==1, "returned string length expected %d got %d\n", 1, i);
1055 ok(feof(tempfh), "did not get EOF\n");
1056 fclose(tempfh);
1057 unlink(tempf);
1058 free(tempf);
1059 }
1060
1061 static void test_file_put_get( void )
1062 {
1063 char* tempf;
1064 FILE *tempfh;
1065 static const char mytext[]= "This is a test_file_put_get\n";
1066 static const char dostext[]= "This is a test_file_put_get\r\n";
1067 char btext[LLEN];
1068 WCHAR wtextW[LLEN+1];
1069 WCHAR *mytextW = NULL, *aptr, *wptr;
1070 BOOL diff_found = FALSE;
1071 unsigned int i;
1072
1073 tempf=_tempnam(".","wne");
1074 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
1075 fputs(mytext,tempfh);
1076 fclose(tempfh);
1077 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1078 fgets(btext,LLEN,tempfh);
1079 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
1080 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
1081 fclose(tempfh);
1082 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
1083 fputs(dostext,tempfh);
1084 fclose(tempfh);
1085 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1086 fgets(btext,LLEN,tempfh);
1087 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
1088 fclose(tempfh);
1089 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1090 fgets(btext,LLEN,tempfh);
1091 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
1092
1093 fclose(tempfh);
1094 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1095 fgetws(wtextW,LLEN,tempfh);
1096 mytextW = AtoW (mytext);
1097 aptr = mytextW;
1098 wptr = wtextW;
1099
1100 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
1101 {
1102 diff_found |= (*aptr != *wptr);
1103 }
1104 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
1105 free(mytextW);
1106 fclose(tempfh);
1107 unlink(tempf);
1108 free(tempf);
1109 }
1110
1111 static void test_file_write_read( void )
1112 {
1113 char* tempf;
1114 int tempfd;
1115 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
1116 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
1117 char btext[LLEN];
1118 int ret, i;
1119
1120 tempf=_tempnam(".","wne");
1121 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
1122 _S_IREAD | _S_IWRITE);
1123 ok( tempfd != -1,
1124 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1125 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1126 "_write _O_BINARY bad return value\n");
1127 _close(tempfd);
1128 i = lstrlenA(mytext);
1129 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1130 ok(_read(tempfd,btext,i) == i,
1131 "_read _O_BINARY got bad length\n");
1132 ok( memcmp(dostext,btext,i) == 0,
1133 "problems with _O_BINARY _write / _read\n");
1134 _close(tempfd);
1135 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1136 ok(_read(tempfd,btext,i) == i-1,
1137 "_read _O_TEXT got bad length\n");
1138 ok( memcmp(mytext,btext,i-1) == 0,
1139 "problems with _O_BINARY _write / _O_TEXT _read\n");
1140 _close(tempfd);
1141 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
1142 _S_IREAD | _S_IWRITE);
1143 ok( tempfd != -1,
1144 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
1145 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
1146 "_write _O_TEXT bad return value\n");
1147 _close(tempfd);
1148 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1149 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1150 "_read _O_BINARY got bad length\n");
1151 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1152 "problems with _O_TEXT _write / _O_BINARY _read\n");
1153 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1154 _close(tempfd);
1155 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1156 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1157 "_read _O_TEXT got bad length\n");
1158 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1159 "problems with _O_TEXT _write / _read\n");
1160 _close(tempfd);
1161
1162 memset(btext, 0, LLEN);
1163 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1164 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1165 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1166 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1167 _close(tempfd);
1168
1169 /* Test reading only \n or \r */
1170 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1171 _lseek(tempfd, -1, FILE_END);
1172 ret = _read(tempfd,btext,LLEN);
1173 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1174 _lseek(tempfd, -2, FILE_END);
1175 ret = _read(tempfd,btext,LLEN);
1176 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1177 _lseek(tempfd, -2, FILE_END);
1178 ret = _read(tempfd,btext,1);
1179 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1180 ret = read(tempfd,btext,1);
1181 ok(ret == 0, "_read returned %d, expected 0\n", ret);
1182 _lseek(tempfd, -3, FILE_END);
1183 ret = _read(tempfd,btext,1);
1184 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1185 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1186 _lseek(tempfd, -3, FILE_END);
1187 ret = _read(tempfd,btext,2);
1188 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1189 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1190 _lseek(tempfd, -3, FILE_END);
1191 ret = _read(tempfd,btext,3);
1192 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1193 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1194 _close(tempfd);
1195
1196 ret = unlink(tempf);
1197 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1198 free(tempf);
1199
1200 tempf=_tempnam(".","wne");
1201 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1202 ok( tempfd != -1,
1203 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1204 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1205 "_write _O_BINARY bad return value\n");
1206 _close(tempfd);
1207 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1208 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1209 "_read _O_BINARY got bad length\n");
1210 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1211 "problems with _O_BINARY _write / _read\n");
1212 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1213 _close(tempfd);
1214 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1215 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1216 "_read _O_TEXT got bad length\n");
1217 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1218 "problems with _O_BINARY _write / _O_TEXT _read\n");
1219 _close(tempfd);
1220
1221 /* test _read with single bytes. CR should be skipped and LF pulled in */
1222 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1223 for (i=0; i<strlen(mytext); i++) /* */
1224 {
1225 _read(tempfd,btext, 1);
1226 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1227 }
1228 while (_read(tempfd,btext, 1));
1229 _close(tempfd);
1230
1231 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1232 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1233 i = _read(tempfd,btext, strlen(mytext));
1234 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1235 _close(tempfd);
1236
1237 /* test read/write in unicode mode */
1238 if(p_fopen_s)
1239 {
1240 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1241 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1242 ret = _write(tempfd, "a", 1);
1243 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1244 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1245 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1246 _close(tempfd);
1247
1248 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1249 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1250 ret = _read(tempfd, btext, sizeof(btext));
1251 ok(ret == 10, "_read returned %d, expected 10\n", ret);
1252 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1253 _close(tempfd);
1254
1255 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1256 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1257 errno = 0xdeadbeef;
1258 ret = _read(tempfd, btext, 3);
1259 ok(ret == -1, "_read returned %d, expected -1\n", ret);
1260 ok(errno == 22, "errno = %d\n", errno);
1261 ret = _read(tempfd, btext, sizeof(btext));
1262 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1263 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1264 _close(tempfd);
1265
1266 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1267 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1268 errno = 0xdeadbeef;
1269 ret = _write(tempfd, "a", 1);
1270 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1271 ok(errno == 22, "errno = %d\n", errno);
1272 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1273 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1274 _close(tempfd);
1275
1276 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1277 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1278 ret = _read(tempfd, btext, sizeof(btext));
1279 ok(ret == 7, "_read returned %d, expected 7\n", ret);
1280 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1281 _close(tempfd);
1282
1283 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1284 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1285 ret = _read(tempfd, btext, sizeof(btext));
1286 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1287 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1288
1289 /* when buffer is small read sometimes fails in native implementation */
1290 lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1291 ret = _read(tempfd, btext, 4);
1292 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1293
1294 lseek(tempfd, 6, SEEK_SET);
1295 ret = _read(tempfd, btext, 2);
1296 ok(ret == 2, "_read returned %d, expected 2\n", ret);
1297 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1298 _close(tempfd);
1299
1300 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1301 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1302 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1303 ok(ret == 12, "_write returned %d, expected 9\n", ret);
1304 _close(tempfd);
1305
1306 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1307 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1308 ret = _read(tempfd, btext, sizeof(btext));
1309 ok(ret == 12, "_read returned %d, expected 12\n", ret);
1310 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1311
1312 /* test invalid utf8 sequence */
1313 lseek(tempfd, 5, SEEK_SET);
1314 ret = _read(tempfd, btext, sizeof(btext));
1315 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1316 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1317 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1318 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1319 _close(tempfd);
1320 }
1321 else
1322 {
1323 win_skip("unicode mode tests on file\n");
1324 }
1325
1326 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1327 ok( ret == 0,
1328 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1329 ret = unlink(tempf);
1330 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1331 free(tempf);
1332 }
1333
1334 static void test_file_inherit_child(const char* fd_s)
1335 {
1336 int fd = atoi(fd_s);
1337 char buffer[32];
1338 int ret;
1339
1340 ret =write(fd, "Success", 8);
1341 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1342 lseek(fd, 0, SEEK_SET);
1343 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1344 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1345 }
1346
1347 static void test_file_inherit_child_no(const char* fd_s)
1348 {
1349 int fd = atoi(fd_s);
1350 int ret;
1351
1352 ret = write(fd, "Success", 8);
1353 ok( ret == -1 && errno == EBADF,
1354 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1355 }
1356
1357 static void create_io_inherit_block( STARTUPINFOA *startup, unsigned int count, const HANDLE *handles )
1358 {
1359 static BYTE block[1024];
1360 BYTE *wxflag_ptr;
1361 HANDLE *handle_ptr;
1362 unsigned int i;
1363
1364 startup->lpReserved2 = block;
1365 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1366 wxflag_ptr = block + sizeof(unsigned);
1367 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1368
1369 *(unsigned*)block = count;
1370 for (i = 0; i < count; i++)
1371 {
1372 wxflag_ptr[i] = 0x81;
1373 handle_ptr[i] = handles[i];
1374 }
1375 }
1376
1377 static const char *read_file( HANDLE file )
1378 {
1379 static char buffer[128];
1380 DWORD ret;
1381 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1382 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1383 buffer[ret] = 0;
1384 return buffer;
1385 }
1386
1387 static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1388 const char *descr )
1389 {
1390 const char *data;
1391 HANDLE hErrorFile;
1392 SECURITY_ATTRIBUTES sa;
1393 PROCESS_INFORMATION proc;
1394
1395 /* make file handle inheritable */
1396 sa.nLength = sizeof(sa);
1397 sa.lpSecurityDescriptor = NULL;
1398 sa.bInheritHandle = TRUE;
1399
1400 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1401 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1402 startup->dwFlags = STARTF_USESTDHANDLES;
1403 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1404 startup->hStdOutput = hErrorFile;
1405 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1406
1407 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1408 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1409 winetest_wait_child_process( proc.hProcess );
1410
1411 data = read_file( hErrorFile );
1412 if (expect_stdout)
1413 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1414 else
1415 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1416
1417 if (hstdout)
1418 {
1419 data = read_file( hstdout );
1420 if (expect_stdout)
1421 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1422 else
1423 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1424 }
1425
1426 CloseHandle( hErrorFile );
1427 DeleteFileA( "fdopen.err" );
1428 }
1429
1430 static void test_file_inherit( const char* selfname )
1431 {
1432 int fd;
1433 const char* arg_v[5];
1434 char buffer[16];
1435 char cmdline[MAX_PATH];
1436 STARTUPINFOA startup;
1437 SECURITY_ATTRIBUTES sa;
1438 HANDLE handles[3];
1439
1440 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1441 ok(fd != -1, "Couldn't create test file\n");
1442 arg_v[0] = get_base_name(selfname);
1443 arg_v[1] = "tests/file.c";
1444 arg_v[2] = "inherit";
1445 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1446 arg_v[4] = 0;
1447 _spawnvp(_P_WAIT, selfname, arg_v);
1448 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1449 lseek(fd, 0, SEEK_SET);
1450 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1451 close (fd);
1452 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1453
1454 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1455 ok(fd != -1, "Couldn't create test file\n");
1456 arg_v[1] = "tests/file.c";
1457 arg_v[2] = "inherit_no";
1458 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1459 arg_v[4] = 0;
1460 _spawnvp(_P_WAIT, selfname, arg_v);
1461 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1462 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1463 close (fd);
1464 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1465
1466 /* make file handle inheritable */
1467 sa.nLength = sizeof(sa);
1468 sa.lpSecurityDescriptor = NULL;
1469 sa.bInheritHandle = TRUE;
1470 sprintf(cmdline, "%s file inherit 1", selfname);
1471
1472 /* init an empty Reserved2, which should not be recognized as inherit-block */
1473 ZeroMemory(&startup, sizeof(startup));
1474 startup.cb = sizeof(startup);
1475 create_io_inherit_block( &startup, 0, NULL );
1476 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1477
1478 /* test with valid inheritblock */
1479 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1480 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1481 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1482 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1483 create_io_inherit_block( &startup, 3, handles );
1484 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1485 CloseHandle( handles[1] );
1486 DeleteFileA("fdopen.tst");
1487
1488 /* test inherit block starting with unsigned zero */
1489 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1490 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1491 create_io_inherit_block( &startup, 3, handles );
1492 *(unsigned int *)startup.lpReserved2 = 0;
1493 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1494 CloseHandle( handles[1] );
1495 DeleteFileA("fdopen.tst");
1496
1497 /* test inherit block with smaller size */
1498 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1499 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1500 create_io_inherit_block( &startup, 3, handles );
1501 startup.cbReserved2 -= 3;
1502 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1503 CloseHandle( handles[1] );
1504 DeleteFileA("fdopen.tst");
1505
1506 /* test inherit block with even smaller size */
1507 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1508 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1509 create_io_inherit_block( &startup, 3, handles );
1510 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1511 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1512 CloseHandle( handles[1] );
1513 DeleteFileA("fdopen.tst");
1514
1515 /* test inherit block with larger size */
1516 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1517 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1518 create_io_inherit_block( &startup, 3, handles );
1519 startup.cbReserved2 += 7;
1520 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1521 CloseHandle( handles[1] );
1522 DeleteFileA("fdopen.tst");
1523 }
1524
1525 static void test_tmpnam( void )
1526 {
1527 char name[MAX_PATH] = "abc";
1528 char *res;
1529
1530 res = tmpnam(NULL);
1531 ok(res != NULL, "tmpnam returned NULL\n");
1532 ok(res[0] == '\\', "first character is not a backslash\n");
1533 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1534 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1535
1536 res = tmpnam(name);
1537 ok(res != NULL, "tmpnam returned NULL\n");
1538 ok(res == name, "supplied buffer was not used\n");
1539 ok(res[0] == '\\', "first character is not a backslash\n");
1540 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1541 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1542 }
1543
1544 static void test_chsize( void )
1545 {
1546 int fd;
1547 LONG cur, pos, count;
1548 char temptext[] = "012345678";
1549 char *tempfile = _tempnam( ".", "tst" );
1550
1551 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1552
1553 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1554 ok( fd > 0, "Couldn't open test file\n" );
1555
1556 count = _write( fd, temptext, sizeof(temptext) );
1557 ok( count > 0, "Couldn't write to test file\n" );
1558
1559 /* get current file pointer */
1560 cur = _lseek( fd, 0, SEEK_CUR );
1561
1562 /* make the file smaller */
1563 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1564
1565 pos = _lseek( fd, 0, SEEK_CUR );
1566 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1567 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1568
1569 /* enlarge the file */
1570 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1571
1572 pos = _lseek( fd, 0, SEEK_CUR );
1573 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1574 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1575
1576 _close( fd );
1577 _unlink( tempfile );
1578 free( tempfile );
1579 }
1580
1581 static void test_fopen_fclose_fcloseall( void )
1582 {
1583 char fname1[] = "empty1";
1584 char fname2[] = "empty2";
1585 char fname3[] = "empty3";
1586 FILE *stream1, *stream2, *stream3, *stream4;
1587 int ret, numclosed;
1588
1589 /* testing fopen() */
1590 stream1 = fopen(fname1, "w+");
1591 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1592 stream2 = fopen(fname2, "w ");
1593 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1594 _unlink(fname3);
1595 stream3 = fopen(fname3, "r");
1596 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1597 stream3 = fopen(fname3, "w+");
1598 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1599 errno = 0xfaceabad;
1600 stream4 = fopen("", "w+");
1601 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1602 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1603 errno = 0xfaceabad;
1604 stream4 = fopen(NULL, "w+");
1605 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1606 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1607
1608 /* testing fclose() */
1609 ret = fclose(stream2);
1610 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1611 ret = fclose(stream3);
1612 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1613 ret = fclose(stream2);
1614 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1615 ret = fclose(stream3);
1616 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1617
1618 /* testing fcloseall() */
1619 numclosed = _fcloseall();
1620 /* fname1 should be closed here */
1621 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1622 numclosed = _fcloseall();
1623 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1624
1625 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1626 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1627 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1628 }
1629
1630 static void test_fopen_s( void )
1631 {
1632 const char name[] = "empty1";
1633 char buff[16];
1634 unsigned char *ubuff = (unsigned char*)buff;
1635 FILE *file, *file2;
1636 int ret;
1637 int len;
1638
1639 if (!p_fopen_s)
1640 {
1641 win_skip("Skipping fopen_s test\n");
1642 return;
1643 }
1644 /* testing fopen_s */
1645 ret = p_fopen_s(&file, name, "w");
1646 ok(ret == 0, "fopen_s failed with %d\n", ret);
1647 ok(file != 0, "fopen_s failed to return value\n");
1648 fwrite(name, sizeof(name), 1, file);
1649
1650 ret = fclose(file);
1651 ok(ret != EOF, "File failed to close\n");
1652
1653 file = fopen(name, "r");
1654 ok(file != 0, "fopen failed\n");
1655 len = fread(buff, 1, sizeof(name), file);
1656 ok(len == sizeof(name), "File length is %d\n", len);
1657 buff[sizeof(name)] = '\0';
1658 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1659
1660 ret = fclose(file);
1661 ok(ret != EOF, "File failed to close\n");
1662
1663 ret = p_fopen_s(&file, name, "w, ccs=UNIcode");
1664 ok(ret == 0, "fopen_s failed with %d\n", ret);
1665 ret = fwrite("a", 1, 2, file);
1666 ok(ret == 2, "fwrite returned %d\n", ret);
1667 fclose(file);
1668
1669 ret = p_fopen_s(&file, name, "r");
1670 ok(ret == 0, "fopen_s failed with %d\n", ret);
1671 len = fread(buff, 1, 2, file);
1672 ok(len == 2, "len = %d\n", len);
1673 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1674 ubuff[0], ubuff[1]);
1675 fclose(file);
1676
1677 ret = p_fopen_s(&file, name, "r,ccs=unicode");
1678 ok(ret == 0, "fopen_s failed with %d\n", ret);
1679 len = fread(buff, 1, 2, file);
1680 ok(len == 2, "len = %d\n", len);
1681 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1682 ubuff[0], ubuff[1]);
1683 fclose(file);
1684
1685 ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1686 ok(ret == 0, "fopen_s failed with %d\n", ret);
1687 len = fread(buff, 1, 2, file);
1688 ok(len == 2, "len = %d\n", len);
1689 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1690 ubuff[0], ubuff[1]);
1691 fclose(file);
1692
1693 ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1694 ok(ret == 0, "fopen_s failed with %d\n", ret);
1695 len = fread(buff, 1, 2, file);
1696 ok(len == 2, "len = %d\n", len);
1697 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1698 ubuff[0], ubuff[1]);
1699 fclose(file);
1700
1701 ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1702 ok(ret == 0, "fopen_s failed with %d\n", ret);
1703 fclose(file);
1704
1705 ret = p_fopen_s(&file, name, "r");
1706 ok(ret == 0, "fopen_s failed with %d\n", ret);
1707 len = fread(buff, 1, 3, file);
1708 ok(len == 2, "len = %d\n", len);
1709 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1710 ubuff[0], ubuff[1]);
1711 fclose(file);
1712
1713 ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1714 ok(ret == 0, "fopen_s failed with %d\n", ret);
1715 fclose(file);
1716
1717 ret = p_fopen_s(&file, name, "r");
1718 ok(ret == 0, "fopen_s failed with %d\n", ret);
1719 len = fread(buff, 1, 4, file);
1720 ok(len == 3, "len = %d\n", len);
1721 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1722 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1723 ubuff[0], ubuff[1], ubuff[2]);
1724 fclose(file);
1725
1726 /* test initial FILE values */
1727 memset(file, 0xfe, sizeof(*file));
1728 file->_flag = 0;
1729 ret = p_fopen_s(&file2, name, "r");
1730 ok(!ret, "fopen_s failed with %d\n", ret);
1731 ok(file == file2, "file != file2 %p %p\n", file, file2);
1732 ok(!file->_ptr, "file->_ptr != NULL\n");
1733 ok(!file->_cnt, "file->_cnt != 0\n");
1734 ok(!file->_base, "file->_base != NULL\n");
1735 ok(file->_flag == 1, "file->_flag = %x\n", file->_flag);
1736 ok(file->_file, "file->_file == 0\n");
1737 ok(file->_charbuf == 0xfefefefe, "file->_charbuf = %x\n", file->_charbuf);
1738 ok(file->_bufsiz == 0xfefefefe, "file->_bufsiz = %x\n", file->_bufsiz);
1739 ok(!file->_tmpfname, "file->_tmpfname != NULL\n");
1740 fclose(file2);
1741
1742 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1743 }
1744
1745 static void test__wfopen_s( void )
1746 {
1747 const char name[] = "empty1";
1748 const WCHAR wname[] = {
1749 'e','m','p','t','y','1',0
1750 };
1751 const WCHAR wmode[] = {
1752 'w',0
1753 };
1754 char buff[16];
1755 FILE *file;
1756 int ret;
1757 int len;
1758
1759 if (!p__wfopen_s)
1760 {
1761 win_skip("Skipping _wfopen_s test\n");
1762 return;
1763 }
1764 /* testing _wfopen_s */
1765 ret = p__wfopen_s(&file, wname, wmode);
1766 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1767 ok(file != 0, "_wfopen_s failed to return value\n");
1768 fwrite(name, sizeof(name), 1, file);
1769
1770 ret = fclose(file);
1771 ok(ret != EOF, "File failed to close\n");
1772
1773 file = fopen(name, "r");
1774 ok(file != 0, "fopen failed\n");
1775 len = fread(buff, 1, sizeof(name), file);
1776 ok(len == sizeof(name), "File length is %d\n", len);
1777 buff[sizeof(name)] = '\0';
1778 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1779
1780 ret = fclose(file);
1781 ok(ret != EOF, "File failed to close\n");
1782
1783 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1784 }
1785
1786 static void test_setmode(void)
1787 {
1788 const char name[] = "empty1";
1789 int fd, ret;
1790
1791 if(!p_fopen_s) {
1792 win_skip("unicode file modes are not available, skipping setmode tests\n");
1793 return;
1794 }
1795
1796 errno = 0xdeadbeef;
1797 ret = _setmode(-2, 0);
1798 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1799 ok(errno == EINVAL, "errno = %d\n", errno);
1800
1801 errno = 0xdeadbeef;
1802 ret = _setmode(-2, _O_TEXT);
1803 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1804 ok(errno == EBADF, "errno = %d\n", errno);
1805
1806 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1807 ok(fd != -1, "failed to open file\n");
1808
1809 errno = 0xdeadbeef;
1810 ret = _setmode(fd, 0xffffffff);
1811 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1812 ok(errno == EINVAL, "errno = %d\n", errno);
1813
1814 errno = 0xdeadbeef;
1815 ret = _setmode(fd, 0);
1816 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1817 ok(errno == EINVAL, "errno = %d\n", errno);
1818
1819 errno = 0xdeadbeef;
1820 ret = _setmode(fd, _O_BINARY|_O_TEXT);
1821 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1822 ok(errno == EINVAL, "errno = %d\n", errno);
1823
1824 errno = 0xdeadbeef;
1825 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1826 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1827 ok(errno == EINVAL, "errno = %d\n", errno);
1828
1829 ret = _setmode(fd, _O_BINARY);
1830 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1831
1832 ret = _setmode(fd, _O_WTEXT);
1833 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1834
1835 ret = _setmode(fd, _O_TEXT);
1836 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1837
1838 ret = _setmode(fd, _O_U16TEXT);
1839 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1840
1841 ret = _setmode(fd, _O_U8TEXT);
1842 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1843
1844 ret = _setmode(fd, _O_TEXT);
1845 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1846
1847 _close(fd);
1848 _unlink(name);
1849 }
1850
1851 static void test_get_osfhandle(void)
1852 {
1853 int fd;
1854 char fname[] = "t_get_osfhanle";
1855 DWORD bytes_written;
1856 HANDLE handle;
1857
1858 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1859 handle = (HANDLE)_get_osfhandle(fd);
1860 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1861 _close(fd);
1862 fd = _open(fname, _O_RDONLY, 0);
1863 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1864
1865 _close(fd);
1866 _unlink(fname);
1867
1868 errno = 0xdeadbeef;
1869 handle = (HANDLE)_get_osfhandle(fd);
1870 ok(handle == INVALID_HANDLE_VALUE, "_get_osfhandle returned %p\n", handle);
1871 ok(errno == EBADF, "errno = %d\n", errno);
1872 }
1873
1874 static void test_setmaxstdio(void)
1875 {
1876 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1877 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1878 }
1879
1880 static void test_stat(void)
1881 {
1882 int fd;
1883 int pipes[2];
1884 int ret;
1885 struct stat buf;
1886
1887 /* Tests for a file */
1888 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1889 if (fd >= 0)
1890 {
1891 ret = fstat(fd, &buf);
1892 ok(!ret, "fstat failed: errno=%d\n", errno);
1893 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1894 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1895 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1896 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1897 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1898 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1899
1900 ret = stat("stat.tst", &buf);
1901 ok(!ret, "stat failed: errno=%d\n", errno);
1902 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1903 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1904 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1905 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1906 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1907
1908 errno = 0xdeadbeef;
1909 ret = stat("stat.tst\\", &buf);
1910 ok(ret == -1, "stat returned %d\n", ret);
1911 ok(errno == ENOENT, "errno = %d\n", errno);
1912
1913 close(fd);
1914 remove("stat.tst");
1915 }
1916 else
1917 skip("open failed with errno %d\n", errno);
1918
1919 /* Tests for a char device */
1920 if (_dup2(0, 10) == 0)
1921 {
1922 ret = fstat(10, &buf);
1923 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1924 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1925 {
1926 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1927 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1928 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1929 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1930 }
1931 else
1932 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1933 close(10);
1934 }
1935 else
1936 skip("_dup2 failed with errno %d\n", errno);
1937
1938 /* Tests for pipes */
1939 if (_pipe(pipes, 1024, O_BINARY) == 0)
1940 {
1941 ret = fstat(pipes[0], &buf);
1942 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1943 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1944 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1945 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1946 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1947 close(pipes[0]);
1948 close(pipes[1]);
1949 }
1950 else
1951 skip("pipe failed with errno %d\n", errno);
1952
1953 /* Tests for directory */
1954 if(mkdir("stat.tst") == 0)
1955 {
1956 ret = stat("stat.tst ", &buf);
1957 ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1958 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1959 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1960 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1961 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1962
1963 errno = 0xdeadbeef;
1964 ret = stat("stat.tst\\ ", &buf);
1965 ok(ret == -1, "stat returned %d\n", ret);
1966 ok(errno == ENOENT, "errno = %d\n", errno);
1967 rmdir( "stat.tst" );
1968 }
1969 else
1970 skip("mkdir failed with errno %d\n", errno);
1971
1972 errno = 0xdeadbeef;
1973 ret = stat("c:", &buf);
1974 ok(ret == -1, "stat returned %d\n", ret);
1975 ok(errno == ENOENT, "errno = %d\n", errno);
1976
1977 ret = stat("c:/", &buf);
1978 ok(!ret, "stat returned %d\n", ret);
1979 ok(buf.st_dev == 2, "st_dev = %d\n", buf.st_dev);
1980 ok(buf.st_rdev == 2, "st_rdev = %d\n", buf.st_rdev);
1981 }
1982
1983 static const char* pipe_string="Hello world";
1984
1985 /* How many messages to transfer over the pipe */
1986 #define N_TEST_MESSAGES 3
1987
1988 static void test_pipes_child(int argc, char** args)
1989 {
1990 int fd;
1991 int nwritten;
1992 int i;
1993
1994 if (argc < 5)
1995 {
1996 ok(0, "not enough parameters: %d\n", argc);
1997 return;
1998 }
1999
2000 fd=atoi(args[3]);
2001 i=close(fd);
2002 ok(!i, "unable to close %d: %d\n", fd, errno);
2003
2004 fd=atoi(args[4]);
2005
2006 for (i=0; i<N_TEST_MESSAGES; i++) {
2007 nwritten=write(fd, pipe_string, strlen(pipe_string));
2008 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
2009 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
2010 if (i < N_TEST_MESSAGES-1)
2011 Sleep(100);
2012 }
2013
2014 i=close(fd);
2015 ok(!i, "unable to close %d: %d\n", fd, errno);
2016 }
2017
2018 static void test_pipes(const char* selfname)
2019 {
2020 int pipes[2];
2021 char str_fdr[12], str_fdw[12];
2022 FILE* file;
2023 const char* arg_v[6];
2024 char buf[4096];
2025 char expected[4096];
2026 int r;
2027 int i;
2028
2029 /* Test reading from a pipe with read() */
2030 if (_pipe(pipes, 1024, O_BINARY) < 0)
2031 {
2032 ok(0, "pipe failed with errno %d\n", errno);
2033 return;
2034 }
2035
2036 arg_v[0] = get_base_name(selfname);
2037 arg_v[1] = "tests/file.c";
2038 arg_v[2] = "pipes";
2039 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2040 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2041 arg_v[5] = NULL;
2042 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2043 i=close(pipes[1]);
2044 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2045
2046 for (i=0; i<N_TEST_MESSAGES; i++) {
2047 r=read(pipes[0], buf, sizeof(buf)-1);
2048 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
2049 if (r > 0)
2050 buf[r]='\0';
2051 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
2052 }
2053
2054 r=read(pipes[0], buf, sizeof(buf)-1);
2055 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
2056 i=close(pipes[0]);
2057 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
2058
2059 /* Test reading from a pipe with fread() */
2060 if (_pipe(pipes, 1024, O_BINARY) < 0)
2061 {
2062 ok(0, "pipe failed with errno %d\n", errno);
2063 return;
2064 }
2065
2066 arg_v[1] = "tests/file.c";
2067 arg_v[2] = "pipes";
2068 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
2069 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2070 arg_v[5] = NULL;
2071 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2072 i=close(pipes[1]);
2073 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2074 file=fdopen(pipes[0], "r");
2075
2076 /* In blocking mode, fread will keep calling read() until it gets
2077 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2078 * in cooked mode instead of a pipe, it would also stop on EOL.)
2079 */
2080 expected[0] = 0;
2081 for (i=0; i<N_TEST_MESSAGES; i++)
2082 strcat(expected, pipe_string);
2083 r=fread(buf, 1, sizeof(buf)-1, file);
2084 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
2085 if (r > 0)
2086 buf[r]='\0';
2087 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
2088
2089 /* Let child close the file before we read, so we can sense EOF reliably */
2090 Sleep(100);
2091 r=fread(buf, 1, sizeof(buf)-1, file);
2092 ok(r == 0, "fread() returned %d instead of 0\n", r);
2093 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
2094 ok(feof(file), "feof() is false!\n");
2095
2096 i=fclose(file);
2097 ok(!i, "unable to close the pipe: %d\n", errno);
2098
2099 /* test \r handling when it's the last character read */
2100 if (_pipe(pipes, 1024, O_BINARY) < 0)
2101 {
2102 ok(0, "pipe failed with errno %d\n", errno);
2103 return;
2104 }
2105 r = write(pipes[1], "\r\n\rab\r\n", 7);
2106 ok(r == 7, "write returned %d, errno = %d\n", r, errno);
2107 setmode(pipes[0], O_TEXT);
2108 r = read(pipes[0], buf, 1);
2109 ok(r == 1, "read returned %d, expected 1\n", r);
2110 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
2111 r = read(pipes[0], buf, 1);
2112 ok(r == 1, "read returned %d, expected 1\n", r);
2113 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
2114 r = read(pipes[0], buf, 1);
2115 ok(r == 1, "read returned %d, expected 1\n", r);
2116 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
2117 r = read(pipes[0], buf, 2);
2118 ok(r == 2, "read returned %d, expected 1\n", r);
2119 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
2120 ok(buf[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf[1]);
2121
2122 if (p_fopen_s)
2123 {
2124 /* test utf16 read with insufficient data */
2125 r = write(pipes[1], "a\0b", 3);
2126 ok(r == 3, "write returned %d, errno = %d\n", r, errno);
2127 buf[2] = 'z';
2128 buf[3] = 'z';
2129 setmode(pipes[0], _O_WTEXT);
2130 r = read(pipes[0], buf, 4);
2131 ok(r == 2, "read returned %d, expected 2\n", r);
2132 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
2133 r = write(pipes[1], "\0", 1);
2134 ok(r == 1, "write returned %d, errno = %d\n", r, errno);
2135 buf[0] = 'z';
2136 buf[1] = 'z';
2137 r = read(pipes[0], buf, 2);
2138 ok(r == 0, "read returned %d, expected 0\n", r);
2139 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
2140 }
2141 else
2142 {
2143 win_skip("unicode mode tests on pipe\n");
2144 }
2145
2146 close(pipes[1]);
2147 close(pipes[0]);
2148 }
2149
2150 static void test_unlink(void)
2151 {
2152 FILE* file;
2153 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2154 file = fopen("test_unlink\\empty", "w");
2155 ok(file != NULL, "unable to create test file\n");
2156 if(file)
2157 fclose(file);
2158 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2159 unlink("test_unlink\\empty");
2160 rmdir("test_unlink");
2161 }
2162
2163 static void test_dup2(void)
2164 {
2165 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2166 }
2167
2168 static void test_stdin(void)
2169 {
2170 HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
2171 int stdin_dup, fd;
2172 HANDLE h;
2173 DWORD r;
2174
2175 stdin_dup = _dup(STDIN_FILENO);
2176 ok(stdin_dup != -1, "_dup(STDIN_FILENO) failed\n");
2177
2178 ok(stdinh == (HANDLE)_get_osfhandle(STDIN_FILENO),
2179 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2180
2181 r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);
2182 ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r);
2183 h = GetStdHandle(STD_INPUT_HANDLE);
2184 ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h);
2185
2186 close(STDIN_FILENO);
2187 h = GetStdHandle(STD_INPUT_HANDLE);
2188 ok(h == NULL, "h != NULL\n");
2189
2190 fd = open("stdin.tst", O_WRONLY | O_CREAT, _S_IREAD |_S_IWRITE);
2191 ok(fd != -1, "open failed\n");
2192 ok(fd == STDIN_FILENO, "fd = %d, expected STDIN_FILENO\n", fd);
2193 h = GetStdHandle(STD_INPUT_HANDLE);
2194 ok(h != NULL, "h == NULL\n");
2195 close(fd);
2196 unlink("stdin.tst");
2197
2198 r = _dup2(stdin_dup, STDIN_FILENO);
2199 ok(r != -1, "_dup2 failed\n");
2200 h = GetStdHandle(STD_INPUT_HANDLE);
2201 ok(h != NULL, "h == NULL\n");
2202 }
2203
2204 static void test_mktemp(void)
2205 {
2206 char buf[16];
2207
2208 strcpy(buf, "a");
2209 ok(!_mktemp(buf), "_mktemp(\"a\") != NULL\n");
2210
2211 strcpy(buf, "testXXXXX");
2212 ok(!_mktemp(buf), "_mktemp(\"testXXXXX\") != NULL\n");
2213
2214 strcpy(buf, "testXXXXXX");
2215 ok(_mktemp(buf) != NULL, "_mktemp(\"testXXXXXX\") == NULL\n");
2216
2217 strcpy(buf, "testXXXXXXa");
2218 ok(!_mktemp(buf), "_mktemp(\"testXXXXXXa\") != NULL\n");
2219
2220 strcpy(buf, "**XXXXXX");
2221 ok(_mktemp(buf) != NULL, "_mktemp(\"**XXXXXX\") == NULL\n");
2222 }
2223
2224 static void test__open_osfhandle(void)
2225 {
2226 ioinfo *info;
2227 HANDLE h, tmp;
2228 int fd;
2229
2230 errno = 0xdeadbeef;
2231 fd = _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE, 0);
2232 ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2233 ok(errno == EBADF, "errno = %d\n", errno);
2234
2235 h = CreateFileA("open_osfhandle.tst", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2236 fd = _open_osfhandle((intptr_t)h, 0);
2237 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2238 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2239 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2240 ok(info->wxflag == 1, "info->wxflag = %x, expected 1\n", info->wxflag);
2241 close(fd);
2242 ok(info->handle == INVALID_HANDLE_VALUE, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info->handle);
2243 ok(info->wxflag == 0, "info->wxflag = %x, expected 0\n", info->wxflag);
2244 DeleteFileA("open_osfhandle.tst");
2245
2246 errno = 0xdeadbeef;
2247 fd = _open_osfhandle((intptr_t)h, 0);
2248 ok(fd == -1, "_open_osfhandle returned %d\n", fd);
2249 ok(errno == EBADF, "errno = %d\n", errno);
2250
2251 ok(CreatePipe(&h, &tmp, NULL, 0), "CreatePipe failed\n");
2252 fd = _open_osfhandle((intptr_t)h, 0);
2253 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno);
2254 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE];
2255 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h);
2256 ok(info->wxflag == 9, "info->wxflag = %x, expected 9\n", info->wxflag);
2257 close(fd);
2258 CloseHandle(tmp);
2259 }
2260
2261 static void test_write_flush_size(FILE *file, int bufsize)
2262 {
2263 char *inbuffer;
2264 char *outbuffer;
2265 int size, fd;
2266 fpos_t pos, pos2;
2267
2268 fd = fileno(file);
2269 inbuffer = calloc(1, bufsize + 1);
2270 outbuffer = calloc(1, bufsize + 1);
2271 _snprintf(outbuffer, bufsize + 1, "0,1,2,3,4,5,6,7,8,9");
2272
2273 for (size = bufsize + 1; size >= bufsize - 1; size--) {
2274 rewind(file);
2275 ok(file->_cnt == 0, "_cnt should be 0 after rewind, but is %d\n", file->_cnt);
2276 fwrite(outbuffer, 1, size, file);
2277 /* lseek() below intentionally redirects the write in fflush() to detect
2278 * if fwrite() has already flushed the whole buffer or not.
2279 */
2280 lseek(fd, 1, SEEK_SET);
2281 fflush(file);
2282 ok(file->_cnt == 0, "_cnt should be 0 after fflush, but is %d\n", file->_cnt);
2283 fseek(file, 0, SEEK_SET);
2284 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2285 if (size == bufsize)
2286 ok(memcmp(outbuffer, inbuffer, bufsize) == 0, "missing flush by %d byte write\n", size);
2287 else
2288 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d byte write\n", size);
2289 }
2290 rewind(file);
2291 fwrite(outbuffer, 1, bufsize / 2, file);
2292 fwrite(outbuffer + bufsize / 2, 1, bufsize / 2, file);
2293 lseek(fd, 1, SEEK_SET);
2294 fflush(file);
2295 fseek(file, 0, SEEK_SET);
2296 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n");
2297 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d/2 byte double write\n", bufsize);
2298
2299 ok(!fseek(file, -1, SEEK_END), "fseek failed\n");
2300 ok(!fgetpos(file, &pos), "fgetpos failed\n");
2301 ok(fread(inbuffer, 1, 1, file) == 1, "fread failed\n");
2302 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2303 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2304 ok(file->_ptr != file->_base, "file->_ptr == file->_base\n");
2305 ok(fwrite(outbuffer, 1, bufsize, file), "fwrite failed\n");
2306 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag);
2307 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt);
2308 ok(file->_ptr == file->_base, "file->_ptr == file->_base\n");
2309 ok(!fgetpos(file, &pos2), "fgetpos failed\n");
2310 ok(pos+bufsize+1 == pos2, "pos = %d (%d)\n", (int)pos, (int)pos2);
2311 free(inbuffer);
2312 free(outbuffer);
2313 }
2314
2315 static void test_write_flush(void)
2316 {
2317 char iobuf[1024];
2318 char *tempf;
2319 FILE *file;
2320
2321 tempf = _tempnam(".","wne");
2322 file = fopen(tempf, "wb+");
2323 ok(file != NULL, "unable to create test file\n");
2324 iobuf[0] = 0;
2325 ok(file->_bufsiz == 4096, "incorrect default buffer size: %d\n", file->_bufsiz);
2326 test_write_flush_size(file, file->_bufsiz);
2327 setvbuf(file, iobuf, _IOFBF, sizeof(iobuf));
2328 test_write_flush_size(file, sizeof(iobuf));
2329 fclose(file);
2330 unlink(tempf);
2331 free(tempf);
2332 }
2333
2334 static void test_close(void)
2335 {
2336 ioinfo *stdout_info, stdout_copy, *stderr_info, stderr_copy;
2337 int fd1, fd2, ret1, ret2, ret3, ret4;
2338 DWORD flags;
2339 HANDLE h;
2340
2341 /* test close on fds that use the same handle */
2342 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2343 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2344 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2345
2346 fd1 = _open_osfhandle((intptr_t)h, 0);
2347 ok(fd1 != -1, "_open_osfhandle failed (%d)\n", errno);
2348 fd2 = _open_osfhandle((intptr_t)h, 0);
2349 ok(fd2 != -1, "_open_osfhandle failed (%d)\n", errno);
2350 ok(fd1 != fd2, "fd1 == fd2\n");
2351
2352 ok((HANDLE)_get_osfhandle(fd1) == h, "handles mismatch (%p != %p)\n",
2353 (HANDLE)_get_osfhandle(fd1), h);
2354 ok((HANDLE)_get_osfhandle(fd2) == h, "handles mismatch (%p != %p)\n",
2355 (HANDLE)_get_osfhandle(fd2), h);
2356 ret1 = close(fd1);
2357 ok(!ret1, "close(fd1) failed (%d)\n", errno);
2358 ok(!GetHandleInformation(h, &flags), "GetHandleInformation succeeded\n");
2359 ok(close(fd2), "close(fd2) succeeded\n");
2360
2361 /* test close on stdout and stderr that use the same handle */
2362 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE,
2363 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
2364 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n");
2365
2366 /* tests output will not be visible from now on */
2367 stdout_info = &__pioinfo[STDOUT_FILENO/MSVCRT_FD_BLOCK_SIZE][STDOUT_FILENO%MSVCRT_FD_BLOCK_SIZE];
2368 stderr_info = &__pioinfo[STDERR_FILENO/MSVCRT_FD_BLOCK_SIZE][STDERR_FILENO%MSVCRT_FD_BLOCK_SIZE];
2369 stdout_copy = *stdout_info;
2370 stderr_copy = *stderr_info;
2371 stdout_info->handle = h;
2372 stderr_info->handle = h;
2373
2374 ret1 = close(STDOUT_FILENO);
2375 ret2 = GetHandleInformation(h, &flags);
2376 ret3 = close(STDERR_FILENO);
2377 ret4 = GetHandleInformation(h, &flags);
2378
2379 *stdout_info = stdout_copy;
2380 *stderr_info = stderr_copy;
2381 SetStdHandle(STD_OUTPUT_HANDLE, stdout_info->handle);
2382 SetStdHandle(STD_ERROR_HANDLE, stderr_info->handle);
2383 /* stdout and stderr restored */
2384
2385 ok(!ret1, "close(STDOUT_FILENO) failed\n");
2386 ok(ret2, "GetHandleInformation failed\n");
2387 ok(!ret3, "close(STDERR_FILENO) failed\n");
2388 ok(!ret4, "GetHandleInformation succeeded\n");
2389
2390 DeleteFileA( "fdopen.tst" );
2391 }
2392
2393 static void test__creat(void)
2394 {
2395 int fd, pos, count, readonly, old_fmode = 0, have_fmode;
2396 char buf[6], testdata[4] = {'a', '\n', 'b', '\n'};
2397
2398 have_fmode = p__get_fmode && p__set_fmode && !p__get_fmode(&old_fmode);
2399 if (!have_fmode)
2400 win_skip("_fmode can't be set, skipping mode tests\n");
2401
2402 if (have_fmode)
2403 p__set_fmode(_O_TEXT);
2404 fd = _creat("_creat.tst", 0);
2405 ok(fd > 0, "_creat failed\n");
2406 _write(fd, testdata, 4);
2407 if (have_fmode) {
2408 pos = _tell(fd);
2409 ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos);
2410 }
2411 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2412 count = _read(fd, buf, 6);
2413 ok(count == 4, "_read returned %d, expected 4\n", count);
2414 count = count > 0 ? count > 4 ? 4 : count : 0;
2415 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2416 _close(fd);
2417 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2418 ok(readonly, "expected read-only file\n");
2419 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2420 DeleteFileA("_creat.tst");
2421
2422 if (have_fmode)
2423 p__set_fmode(_O_BINARY);
2424 fd = _creat("_creat.tst", _S_IREAD | _S_IWRITE);
2425 ok(fd > 0, "_creat failed\n");
2426 _write(fd, testdata, 4);
2427 if (have_fmode) {
2428 pos = _tell(fd);
2429 ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos);
2430 }
2431 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
2432 count = _read(fd, buf, 6);
2433 ok(count == 4, "_read returned %d, expected 4\n", count);
2434 count = count > 0 ? count > 4 ? 4 : count : 0;
2435 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
2436 _close(fd);
2437 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
2438 ok(!readonly, "expected rw file\n");
2439 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
2440 DeleteFileA("_creat.tst");
2441
2442 if (have_fmode)
2443 p__set_fmode(old_fmode);
2444 }
2445
2446 START_TEST(file)
2447 {
2448 int arg_c;
2449 char** arg_v;
2450
2451 init();
2452
2453 arg_c = winetest_get_mainargs( &arg_v );
2454
2455 /* testing low-level I/O */
2456 if (arg_c >= 3)
2457 {
2458 if (strcmp(arg_v[2], "inherit") == 0)
2459 test_file_inherit_child(arg_v[3]);
2460 else if (strcmp(arg_v[2], "inherit_no") == 0)
2461 test_file_inherit_child_no(arg_v[3]);
2462 else if (strcmp(arg_v[2], "pipes") == 0)
2463 test_pipes_child(arg_c, arg_v);
2464 else
2465 ok(0, "invalid argument '%s'\n", arg_v[2]);
2466 return;
2467 }
2468 test_dup2();
2469 test_file_inherit(arg_v[0]);
2470 test_file_write_read();
2471 test_chsize();
2472 test_stat();
2473 test_unlink();
2474
2475 /* testing stream I/O */
2476 test_filbuf();
2477 test_fdopen();
2478 test_fopen_fclose_fcloseall();
2479 test_fopen_s();
2480 test__wfopen_s();
2481 test_setmode();
2482 test_fileops();
2483 test_asciimode();
2484 test_asciimode2();
2485 test_filemodeT();
2486 test_readmode(FALSE); /* binary mode */
2487 test_readmode(TRUE); /* ascii mode */
2488 test_readboundary();
2489 test_fgetc();
2490 test_fputc();
2491 test_flsbuf();
2492 test_fflush();
2493 test_fgetwc();
2494 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2495 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2496 /* \x83 is U+0192 */
2497 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2498 /* \x83 is U+0083 */
2499 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2500 test_fgetwc_unicode();
2501 test_fputwc();
2502 test_ctrlz();
2503 test_file_put_get();
2504 test_tmpnam();
2505 test_get_osfhandle();
2506 test_setmaxstdio();
2507 test_pipes(arg_v[0]);
2508 test_stdin();
2509 test_mktemp();
2510 test__open_osfhandle();
2511 test_write_flush();
2512 test_close();
2513 test__creat();
2514
2515 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2516 * file contains lines in the correct order
2517 */
2518 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);
2519 }