wbemprox: Both signature parameters are optional in IWbemClassObject::GetMethod.
[wine] / dlls / msvcrt / tests / 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
37 static HANDLE proc_handles[2];
38
39 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
40 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
41
42 static void init(void)
43 {
44     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
45
46     p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
47     p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
48 }
49
50 static void test_filbuf( void )
51 {
52     FILE *fp;
53     int c;
54     fpos_t pos;
55
56     fp = fopen("filbuf.tst", "wb");
57     fwrite("\n\n\n\n", 1, 4, fp);
58     fclose(fp);
59
60     fp = fopen("filbuf.tst", "rt");
61     c = _filbuf(fp);
62     ok(c == '\n', "read wrong byte\n");
63     /* See bug 16970 for why we care about _filbuf.
64      * ftell returns screwy values on files with lots
65      * of bare LFs in ascii mode because it assumes
66      * that ascii files contain only CRLFs, removes
67      * the CR's early in _filbuf, and adjusts the return
68      * value of ftell to compensate.
69      * native _filbuf will read the whole file, then consume and return
70      * the first one.  That leaves fp->_fd at offset 4, and fp->_ptr
71      * pointing to a buffer of three bare LFs, so
72      * ftell will return 4 - 3 - 3 = -2.
73      */
74     ok(ftell(fp) == -2, "ascii crlf removal does not match native\n");
75     ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n");
76     ok(pos == -2, "ftell does not match fgetpos\n");
77     fclose(fp);
78     unlink("filbuf.tst");
79 }
80
81 static void test_fdopen( void )
82 {
83     static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
84     char ibuf[10];
85     int fd;
86     FILE *file;
87
88     fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
89     write (fd, buffer, sizeof (buffer));
90     close (fd);
91
92     fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
93     lseek (fd, 5, SEEK_SET);
94     file = fdopen (fd, "rb");
95     ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
96     ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
97     fclose (file);
98     unlink ("fdopen.tst");
99 }
100
101 static void test_fileops( void )
102 {
103     static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
104     char buffer[256];
105     WCHAR wbuffer[256];
106     int fd;
107     FILE *file;
108     fpos_t pos;
109     int i, c, bufmode;
110     static const int bufmodes[] = {_IOFBF,_IONBF};
111
112     fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
113     write (fd, outbuffer, sizeof (outbuffer));
114     close (fd);
115
116     for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
117     {
118         fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
119         file = fdopen (fd, "rb");
120         setvbuf(file,NULL,bufmodes[bufmode],2048);
121         ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
122         ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
123         ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
124         ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
125         rewind(file);
126         ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
127         ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]);
128         ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
129         ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]);
130         ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]);
131
132         rewind(file);
133         for (i = 0; i < sizeof(outbuffer); i++)
134         {
135             ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
136         }
137         ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
138         ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
139         ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
140         ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
141         ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
142         c = outbuffer[sizeof(outbuffer) - 1];
143         ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]);
144         ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
145         ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
146         ok(c == outbuffer[sizeof(outbuffer) - 1],
147            "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]);
148         ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]);
149         ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
150         ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
151
152         rewind(file);
153         ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
154         ok(pos == 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
155         pos = sizeof (outbuffer);
156         ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
157         ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
158         ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
159
160         fclose (file);
161     }
162     fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
163     file = fdopen (fd, "rt"); /* open in TEXT mode */
164     ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
165     ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
166     ok(feof(file) !=0,"feof doesn't signal EOF\n");
167     rewind(file);
168     ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
169     ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
170     ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
171     ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
172     fclose (file);
173
174     file = fopen("fdopen.tst", "rb");
175     ok( file != NULL, "fopen failed\n");
176     /* sizeof(buffer) > content of file */
177     ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
178     /* feof should be set now */
179     ok(feof(file), "feof after fread failed\n");
180     fclose (file);
181
182     unlink ("fdopen.tst");
183 }
184
185 #define IOMODE (ao?"ascii mode":"binary mode")
186 static void test_readmode( BOOL ascii_mode )
187 {
188     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";
189     static const char padbuffer[] = "ghjghjghjghj";
190     static const char nlbuffer[] = "\r\n";
191     char buffer[2*BUFSIZ+256];
192     const char *optr;
193     int fd;
194     FILE *file;
195     const int *ip;
196     int i, j, m, ao, pl;
197     unsigned int fp;
198     LONG l;
199
200     fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
201     /* an internal buffer of BUFSIZ is maintained, so make a file big
202      * enough to test operations that cross the buffer boundary 
203      */
204     j = (2*BUFSIZ-4)/strlen(padbuffer);
205     for (i=0; i<j; i++)
206         write (fd, padbuffer, strlen(padbuffer));
207     j = (2*BUFSIZ-4)%strlen(padbuffer);
208     for (i=0; i<j; i++)
209         write (fd, &padbuffer[i], 1);
210     write (fd, nlbuffer, strlen(nlbuffer));
211     write (fd, outbuffer, sizeof (outbuffer));
212     close (fd);
213     
214     if (ascii_mode) {
215         /* Open file in ascii mode */
216         fd = open ("fdopen.tst", O_RDONLY);
217         file = fdopen (fd, "r");
218         ao = -1; /* on offset to account for carriage returns */
219     }
220     else {
221         fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
222         file = fdopen (fd, "rb");
223         ao = 0;
224     }
225     
226     /* first is a test of fgets, ftell, fseek */
227     ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
228     ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
229     l = ftell(file);
230     pl = 2*BUFSIZ-2;
231     ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
232     ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
233      lstrlenA(buffer), pl+ao, IOMODE);
234     for (fp=0; fp<strlen(outbuffer); fp++)
235         if (outbuffer[fp] == '\n') break;
236     fp++;
237     ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
238     l = ftell(file);
239     ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
240     ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
241      lstrlenA(buffer), fp+ao, IOMODE);
242     /* test a seek back across the buffer boundary */
243     l = pl;
244     ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
245     l = ftell(file);
246     ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
247     ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
248     l = ftell(file);
249     ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
250     ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
251      lstrlenA(buffer), fp+ao, IOMODE);
252     ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
253     fp += 2;
254     l = ftell(file);
255     ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
256     ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
257      lstrlenA(buffer), 2+ao, IOMODE);
258     
259     /* test fread across buffer boundary */
260     rewind(file);
261     ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
262     ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
263     j=strlen(outbuffer);
264     i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
265     ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
266     l = ftell(file);
267     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);
268     for (m=0; m<3; m++)
269         ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
270     m+=BUFSIZ+2+ao;
271     optr = outbuffer;
272     for (; m<i; m++) {
273         ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
274         optr++;
275         if (ao && (*optr == '\r'))
276             optr++;
277     }
278     /* fread should return the requested number of bytes if available */
279     rewind(file);
280     ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
281     ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
282     j = fp+10;
283     i=fread(buffer,1,j,file);
284     ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
285     /* test fread eof */
286     ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
287     ok(feof(file)==0,"feof failure in %s\n", IOMODE);
288     ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
289     ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
290     ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
291     ok(feof(file)==0,"feof failure in %s\n", IOMODE);
292     ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
293     ok(feof(file)==0,"feof failure in %s\n", IOMODE);
294     ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
295     ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
296     
297     /* test some additional functions */
298     rewind(file);
299     ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
300     ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
301     i = _getw(file);
302     ip = (const int *)outbuffer;
303     ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
304     for (fp=0; fp<strlen(outbuffer); fp++)
305         if (outbuffer[fp] == '\n') break;
306     fp++;
307     /* this will cause the next _getw to cross carriage return characters */
308     ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
309     for (i=0, j=0; i<6; i++) {
310         if (ao==0 || outbuffer[fp-3+i] != '\r')
311             buffer[j++] = outbuffer[fp-3+i];
312     }
313     i = _getw(file);
314     ip = (int *)buffer;
315     ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
316
317     fclose (file);
318     unlink ("fdopen.tst");
319 }
320
321 static void test_asciimode(void)
322 {
323     FILE *fp;
324     char buf[64];
325     int c, i, j;
326
327     /* Simple test of CR CR LF handling.  Test both fgets and fread code paths, they're different! */
328     fp = fopen("ascii.tst", "wb");
329     fputs("\r\r\n", fp);
330     fclose(fp);
331     fp = fopen("ascii.tst", "rt");
332     ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
333     ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
334     rewind(fp);
335     ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
336     fclose(fp);
337     unlink("ascii.tst");
338
339     /* Simple test of foo ^Z [more than one block] bar handling */
340     fp = fopen("ascii.tst", "wb");
341     fputs("foo\032", fp);  /* foo, logical EOF, ... */
342     fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
343     fputs("bar", fp); /* ... bar */
344     fclose(fp);
345     fp = fopen("ascii.tst", "rt");
346     ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
347     ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
348     ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
349     rewind(fp);
350     ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
351     ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
352     fclose(fp);
353
354     /* Show ASCII mode handling*/
355     fp= fopen("ascii.tst","wb");
356     fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
357     fclose(fp);
358
359     fp = fopen("ascii.tst", "r");
360     c= fgetc(fp);
361     ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
362     c= fgetc(fp);
363     ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
364     fseek(fp,0,SEEK_CUR);
365     for(i=1; i<10; i++) {
366         ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
367         fseek(fp,0,SEEK_CUR);
368         ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
369         c= fgetc(fp);
370         ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
371     }
372     /* Show that fseek doesn't skip \\r !*/
373     rewind(fp);
374     c= fgetc(fp);
375     ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
376     fseek(fp, 2 ,SEEK_CUR);
377     for(i=1; i<10; i++) {
378         ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
379         fseek(fp, 2 ,SEEK_CUR);
380     }
381     fseek(fp, 9*3 ,SEEK_SET);
382     c = fgetc(fp);
383     ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c);
384     fseek(fp, -4 ,SEEK_CUR);
385     for(i= 8; i>=0; i--) {
386         ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
387         fseek(fp, -4 ,SEEK_CUR);
388     }
389     /* Show what happens if fseek positions filepointer on \\r */
390     fclose(fp);
391     fp = fopen("ascii.tst", "r");
392     fseek(fp, 3 ,SEEK_SET);
393     ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
394     fclose(fp);
395
396     unlink("ascii.tst");
397 }
398
399 static void test_asciimode2(void)
400 {
401     /* Error sequence from one app was getchar followed by small fread
402      * with one \r removed had last byte of buffer filled with
403      * next byte of *unbuffered* data rather than next byte from buffer
404      * Test case is a short string of one byte followed by a newline
405      * followed by filler to fill out the sector, then a sector of
406      * some different byte.
407      */
408
409     FILE *fp;
410     char ibuf[4];
411     int i;
412     static const char obuf[] =
413 "00\n"
414 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
415 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
416 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
417 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
418 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
419 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
420 "000000000000000000\n"
421 "1111111111111111111";
422
423     fp = fopen("ascii2.tst", "wt");
424     fwrite(obuf, 1, sizeof(obuf), fp);
425     fclose(fp);
426
427     fp = fopen("ascii2.tst", "rt");
428     ok(getc(fp) == '0', "first char not 0\n");
429     memset(ibuf, 0, sizeof(ibuf));
430     i = fread(ibuf, 1, sizeof(ibuf), fp);
431     ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
432     ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
433     fclose(fp);
434     unlink("ascii2.tst");
435 }
436
437 static void test_filemodeT(void)
438 {
439     char DATA  [] = {26, 't', 'e', 's' ,'t'};
440     char DATA2 [100];
441     char temppath[MAX_PATH];
442     char tempfile[MAX_PATH];
443     FILE* f;
444     size_t bytesWritten;
445     size_t bytesRead;
446     WIN32_FIND_DATA findData;
447     HANDLE h;
448
449     GetTempPath (MAX_PATH, temppath);
450     GetTempFileName (temppath, "", 0, tempfile);
451
452     f = fopen(tempfile, "w+bDT");
453     bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
454     rewind(f);
455     bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
456     fclose(f);
457
458     ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
459         "fopen file mode 'T' wrongly interpreted as 't'\n" );
460
461     h = FindFirstFile(tempfile, &findData);
462
463     ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
464
465     if (h != INVALID_HANDLE_VALUE) FindClose(h);
466 }
467
468 static WCHAR* AtoW( const char* p )
469 {
470     WCHAR* buffer;
471     DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
472     buffer = malloc( len * sizeof(WCHAR) );
473     MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
474     return buffer;
475 }
476
477 /* Test reading in text mode when the 512'th character read is \r*/
478 static void test_readboundary(void)
479 {
480   FILE *fp;
481   char buf[513], rbuf[513];
482   int i, j;
483   for (i = 0; i < 511; i++)
484     {
485       j = (i%('~' - ' ')+ ' ');
486       buf[i] = j;
487     }
488   buf[511] = '\n';
489   buf[512] =0;
490   fp = fopen("boundary.tst", "wt");
491   fwrite(buf, 512,1,fp);
492   fclose(fp);
493   fp = fopen("boundary.tst", "rt");
494   for(i=0; i<512; i++)
495     {
496       fseek(fp,0 , SEEK_CUR);
497       rbuf[i] = fgetc(fp);
498     }
499   rbuf[512] =0;
500   fclose(fp);
501   unlink("boundary.tst");
502
503   ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
504   }
505
506 static void test_fgetc( void )
507 {
508   char* tempf;
509   FILE *tempfh;
510   int  ich=0xe0, ret;
511
512   tempf=_tempnam(".","wne");
513   tempfh = fopen(tempf,"w+");
514   fputc(ich, tempfh);
515   fputc(ich, tempfh);
516   rewind(tempfh);
517   ret = fgetc(tempfh);
518   ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
519   ret = fgetc(tempfh);
520   ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
521   fclose(tempfh);
522   tempfh = fopen(tempf,"wt");
523   fputc('\n', tempfh);
524   fclose(tempfh);
525   tempfh = fopen(tempf,"wt");
526   setbuf(tempfh, NULL);
527   ret = fgetc(tempfh);
528   ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
529   fclose(tempfh);
530   unlink(tempf);
531   free(tempf);
532 }
533
534 static void test_fputc( void )
535 {
536   char* tempf;
537   FILE *tempfh;
538   int  ret;
539
540   tempf=_tempnam(".","wne");
541   tempfh = fopen(tempf,"wb");
542   ret = fputc(0,tempfh);
543   ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
544   ret = fputc(0xff,tempfh);
545   ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
546   ret = fputc(0xffffffff,tempfh);
547   ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
548   fclose(tempfh);
549
550   tempfh = fopen(tempf,"rb");
551   ret = fputc(0,tempfh);
552   ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
553   fclose(tempfh);
554
555   unlink(tempf);
556   free(tempf);
557 }
558
559 static void test_flsbuf( void )
560 {
561   char* tempf;
562   FILE *tempfh;
563   int  c;
564   int  ret;
565   int  bufmode;
566   static const int bufmodes[] = {_IOFBF,_IONBF};
567
568   tempf=_tempnam(".","wne");
569   for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
570   {
571     tempfh = fopen(tempf,"wb");
572     setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
573     ret = _flsbuf(0,tempfh);
574     ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
575                          bufmodes[bufmode], 0, ret);
576     ret = _flsbuf(0xff,tempfh);
577     ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
578                          bufmodes[bufmode], 0xff, ret);
579     ret = _flsbuf(0xffffffff,tempfh);
580     ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
581                          bufmodes[bufmode], 0xff, ret);
582     if(tempfh->_base) {
583         fputc('x', tempfh);
584         tempfh->_cnt = -1;
585         tempfh->_base[1] = 'a';
586         ret = _flsbuf(0xab,tempfh);
587         ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
588                 bufmodes[bufmode], ret);
589         ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
590                 tempfh->_base[1]);
591     }
592
593     fclose(tempfh);
594   }
595
596   tempfh = fopen(tempf,"rb");
597   ret = _flsbuf(0,tempfh);
598   ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
599   fclose(tempfh);
600
601   /* See bug 17123, exposed by WinAVR's make */
602   tempfh = fopen(tempf,"w");
603   ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
604   setbuf(tempfh, NULL);
605   ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
606   /* Inlined putchar sets _cnt to -1.  Native seems to ignore the value... */
607   tempfh->_cnt = 1234;
608   ret = _flsbuf('Q',tempfh);
609   ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
610   /* ... and reset it to zero */
611   ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
612   fclose(tempfh);
613   /* And just for grins, make sure the file is correct */
614   tempfh = fopen(tempf,"r");
615   c = fgetc(tempfh);
616   ok(c == 'Q', "first byte should be 'Q'\n");
617   c = fgetc(tempfh);
618   ok(c == EOF, "there should only be one byte\n");
619   fclose(tempfh);
620
621   unlink(tempf);
622   free(tempf);
623 }
624
625 static void test_fflush( void )
626 {
627   static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
628   char buf1[16], buf2[24];
629   char *tempf;
630   FILE *tempfh;
631   int ret;
632
633   tempf=_tempnam(".","wne");
634
635   /* Prepare the file. */
636   tempfh = fopen(tempf,"wb");
637   ok(tempfh != NULL, "Can't open test file.\n");
638   fwrite(obuf, 1, sizeof(obuf), tempfh);
639   fclose(tempfh);
640
641   /* Open the file for input. */
642   tempfh = fopen(tempf,"rb");
643   ok(tempfh != NULL, "Can't open test file.\n");
644   fread(buf1, 1, sizeof(buf1), tempfh);
645
646   /* Using fflush() on input stream is undefined in ANSI.
647    * But MSDN says that it clears input buffer. */
648   _lseek(_fileno(tempfh), 0, SEEK_SET);
649   ret = fflush(tempfh);
650   ok(ret == 0, "expected 0, got %d\n", ret);
651   memset(buf2, '?', sizeof(buf2));
652   fread(buf2, 1, sizeof(buf2), tempfh);
653   ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
654
655   /* fflush(NULL) doesn't clear input buffer. */
656   _lseek(_fileno(tempfh), 0, SEEK_SET);
657   ret = fflush(NULL);
658   ok(ret == 0, "expected 0, got %d\n", ret);
659   memset(buf2, '?', sizeof(buf2));
660   fread(buf2, 1, sizeof(buf2), tempfh);
661   ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]);
662
663   /* _flushall() clears input buffer. */
664   _lseek(_fileno(tempfh), 0, SEEK_SET);
665   ret = _flushall();
666   ok(ret >= 0, "unexpected ret %d\n", ret);
667   memset(buf2, '?', sizeof(buf2));
668   fread(buf2, 1, sizeof(buf2), tempfh);
669   ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
670
671   fclose(tempfh);
672
673   unlink(tempf);
674   free(tempf);
675 }
676
677 static void test_fgetwc( void )
678 {
679 #define LLEN 512
680
681   char* tempf;
682   FILE *tempfh;
683   static const char mytext[]= "This is test_fgetwc\r\n";
684   WCHAR wtextW[BUFSIZ+LLEN+1];
685   WCHAR *mytextW = NULL, *aptr, *wptr;
686   BOOL diff_found = FALSE;
687   int j;
688   unsigned int i;
689   LONG l;
690
691   tempf=_tempnam(".","wne");
692   tempfh = fopen(tempf,"wb");
693   j = 'a';
694   /* pad to almost the length of the internal buffer */
695   for (i=0; i<BUFSIZ-4; i++)
696     fputc(j,tempfh);
697   j = '\r';
698   fputc(j,tempfh);
699   j = '\n';
700   fputc(j,tempfh);
701   fputs(mytext,tempfh);
702   fclose(tempfh);
703   /* in text mode, getws/c expects multibyte characters */
704   /*currently Wine only supports plain ascii, and that is all that is tested here */
705   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
706   fgetws(wtextW,LLEN,tempfh);
707   l=ftell(tempfh);
708   ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
709   fgetws(wtextW,LLEN,tempfh);
710   l=ftell(tempfh);
711   ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
712   mytextW = AtoW (mytext);
713   aptr = mytextW;
714   wptr = wtextW;
715   for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
716     {
717       diff_found |= (*aptr != *wptr);
718     }
719   ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
720   ok(*wptr == '\n', "Carriage return was not skipped\n");
721   fclose(tempfh);
722   unlink(tempf);
723   
724   tempfh = fopen(tempf,"wb");
725   j = 'a';
726   /* pad to almost the length of the internal buffer. Use an odd number of bytes
727      to test that we can read wchars that are split across the internal buffer
728      boundary */
729   for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
730     fputc(j,tempfh);
731   j = '\r';
732   fputwc(j,tempfh);
733   j = '\n';
734   fputwc(j,tempfh);
735   fputws(wtextW,tempfh);
736   fputws(wtextW,tempfh);
737   fclose(tempfh);
738   /* in binary mode, getws/c expects wide characters */
739   tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
740   j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
741   fgetws(wtextW,j,tempfh);
742   l=ftell(tempfh);
743   j=(j-1)*sizeof(WCHAR);
744   ok(l==j, "ftell expected %d got %d\n", j, l);
745   i=fgetc(tempfh);
746   ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
747   l=ftell(tempfh);
748   j++;
749   ok(l==j, "ftell expected %d got %d\n", j, l);
750   fgetws(wtextW,3,tempfh);
751   ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
752   ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
753   l=ftell(tempfh);
754   j += 4;
755   ok(l==j, "ftell expected %d got %d\n", j, l);
756   for(i=0; i<strlen(mytext); i++)
757     wtextW[i] = 0;
758   /* the first time we get the string, it should be entirely within the local buffer */
759   fgetws(wtextW,LLEN,tempfh);
760   l=ftell(tempfh);
761   j += (strlen(mytext)-1)*sizeof(WCHAR);
762   ok(l==j, "ftell expected %d got %d\n", j, l);
763   diff_found = FALSE;
764   aptr = mytextW;
765   wptr = wtextW;
766   for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
767     {
768       ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
769       diff_found |= (*aptr != *wptr);
770     }
771   ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
772   ok(*wptr == '\n', "Should get newline\n");
773   for(i=0; i<strlen(mytext); i++)
774     wtextW[i] = 0;
775   /* the second time we get the string, it should cross the local buffer boundary.
776      One of the wchars should be split across the boundary */
777   fgetws(wtextW,LLEN,tempfh);
778   diff_found = FALSE;
779   aptr = mytextW;
780   wptr = wtextW;
781   for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
782     {
783       ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
784       diff_found |= (*aptr != *wptr);
785     }
786   ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
787   ok(*wptr == '\n', "Should get newline\n");
788
789   free(mytextW);
790   fclose(tempfh);
791   unlink(tempf);
792   free(tempf);
793 }
794
795 static void test_fputwc(void)
796 {
797     char temppath[MAX_PATH];
798     char tempfile[MAX_PATH];
799     FILE *f;
800     char buf[1024];
801     int ret;
802
803     GetTempPath (MAX_PATH, temppath);
804     GetTempFileName (temppath, "", 0, tempfile);
805
806     f = fopen(tempfile, "w");
807     ret = fputwc('a', f);
808     ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
809     ret = fputwc('\n', f);
810     ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
811     fclose(f);
812
813     f = fopen(tempfile, "rb");
814     ret = fread(buf, 1, sizeof(buf), f);
815     ok(ret == 3, "fread returned %d, expected 3\n", ret);
816     ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
817     fclose(f);
818
819     if(p_fopen_s) {
820         f = fopen(tempfile, "w,ccs=unicode");
821         ret = fputwc('a', f);
822         ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
823         ret = fputwc('\n', f);
824         ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
825         fclose(f);
826
827         f = fopen(tempfile, "rb");
828         ret = fread(buf, 1, sizeof(buf), f);
829         ok(ret == 8, "fread returned %d, expected 8\n", ret);
830         ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
831         fclose(f);
832
833         f = fopen(tempfile, "w,ccs=utf-8");
834         ret = fputwc('a', f);
835         ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
836         ret = fputwc('\n', f);
837         ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
838         fclose(f);
839
840         f = fopen(tempfile, "rb");
841         ret = fread(buf, 1, sizeof(buf), f);
842         ok(ret == 6, "fread returned %d, expected 6\n", ret);
843         ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
844         fclose(f);
845     }else {
846         win_skip("fputwc tests on unicode files\n");
847     }
848
849     _unlink(tempfile);
850 }
851
852 static void test_ctrlz( void )
853 {
854   char* tempf;
855   FILE *tempfh;
856   static const char mytext[]= "This is test_ctrlz";
857   char buffer[256];
858   int i, j;
859   LONG l;
860
861   tempf=_tempnam(".","wne");
862   tempfh = fopen(tempf,"wb");
863   fputs(mytext,tempfh);
864   j = 0x1a; /* a ctrl-z character signals EOF in text mode */
865   fputc(j,tempfh);
866   j = '\r';
867   fputc(j,tempfh);
868   j = '\n';
869   fputc(j,tempfh);
870   j = 'a';
871   fputc(j,tempfh);
872   fclose(tempfh);
873   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
874   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
875   i=strlen(buffer);
876   j=strlen(mytext);
877   ok(i==j, "returned string length expected %d got %d\n", j, i);
878   j+=4; /* ftell should indicate the true end of file */
879   l=ftell(tempfh);
880   ok(l==j, "ftell expected %d got %d\n", j, l);
881   ok(feof(tempfh), "did not get EOF\n");
882   fclose(tempfh);
883   
884   tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
885   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
886   i=strlen(buffer);
887   j=strlen(mytext)+3; /* should get through newline */
888   ok(i==j, "returned string length expected %d got %d\n", j, i);
889   l=ftell(tempfh);
890   ok(l==j, "ftell expected %d got %d\n", j, l);
891   ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
892   i=strlen(buffer);
893   ok(i==1, "returned string length expected %d got %d\n", 1, i);
894   ok(feof(tempfh), "did not get EOF\n");
895   fclose(tempfh);
896   unlink(tempf);
897   free(tempf);
898 }
899
900 static void test_file_put_get( void )
901 {
902   char* tempf;
903   FILE *tempfh;
904   static const char mytext[]=  "This is a test_file_put_get\n";
905   static const char dostext[]= "This is a test_file_put_get\r\n";
906   char btext[LLEN];
907   WCHAR wtextW[LLEN+1];
908   WCHAR *mytextW = NULL, *aptr, *wptr;
909   BOOL diff_found = FALSE;
910   unsigned int i;
911
912   tempf=_tempnam(".","wne");
913   tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
914   fputs(mytext,tempfh);
915   fclose(tempfh);
916   tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
917   fgets(btext,LLEN,tempfh);
918   ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
919   ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
920   fclose(tempfh);
921   tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
922   fputs(dostext,tempfh);
923   fclose(tempfh);
924   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
925   fgets(btext,LLEN,tempfh);
926   ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
927   fclose(tempfh);
928   tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
929   fgets(btext,LLEN,tempfh);
930   ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
931
932   fclose(tempfh);
933   tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
934   fgetws(wtextW,LLEN,tempfh);
935   mytextW = AtoW (mytext);
936   aptr = mytextW;
937   wptr = wtextW;
938
939   for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
940     {
941       diff_found |= (*aptr != *wptr);
942     }
943   ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
944   free(mytextW);
945   fclose(tempfh);
946   unlink(tempf);
947   free(tempf);
948 }
949
950 static void test_file_write_read( void )
951 {
952   char* tempf;
953   int tempfd;
954   static const char mytext[]=  "This is test_file_write_read\nsecond line\n";
955   static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
956   char btext[LLEN];
957   int ret, i;
958
959   tempf=_tempnam(".","wne");
960   tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
961                      _S_IREAD | _S_IWRITE);
962   ok( tempfd != -1,
963      "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
964   ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
965      "_write _O_BINARY bad return value\n");
966   _close(tempfd);
967   i = lstrlenA(mytext);
968   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
969   ok(_read(tempfd,btext,i) == i,
970      "_read _O_BINARY got bad length\n");
971   ok( memcmp(dostext,btext,i) == 0,
972       "problems with _O_BINARY  _write / _read\n");
973   _close(tempfd);
974   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
975   ok(_read(tempfd,btext,i) == i-1,
976      "_read _O_TEXT got bad length\n");
977   ok( memcmp(mytext,btext,i-1) == 0,
978       "problems with _O_BINARY _write / _O_TEXT _read\n");
979   _close(tempfd);
980   tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
981                      _S_IREAD | _S_IWRITE);
982   ok( tempfd != -1,
983      "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
984   ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
985      "_write _O_TEXT bad return value\n");
986   _close(tempfd);
987   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
988   ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
989      "_read _O_BINARY got bad length\n");
990   ok( memcmp(dostext,btext,strlen(dostext)) == 0,
991       "problems with _O_TEXT _write / _O_BINARY _read\n");
992   ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
993   _close(tempfd);
994   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
995   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
996      "_read _O_TEXT got bad length\n");
997   ok( memcmp(mytext,btext,strlen(mytext)) == 0,
998       "problems with _O_TEXT _write / _read\n");
999   _close(tempfd);
1000
1001   memset(btext, 0, LLEN);
1002   tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1003   ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1004   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1005   ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1006   _close(tempfd);
1007
1008   /* Test reading only \n or \r */
1009   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1010   _lseek(tempfd, -1, FILE_END);
1011   ret = _read(tempfd,btext,LLEN);
1012   ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1013   _lseek(tempfd, -2, FILE_END);
1014   ret = _read(tempfd,btext,LLEN);
1015   ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1016   _lseek(tempfd, -2, FILE_END);
1017   ret = _read(tempfd,btext,1);
1018   ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1019   ret = read(tempfd,btext,1);
1020   ok(ret == 0, "_read returned %d, expected 0\n", ret);
1021   _lseek(tempfd, -3, FILE_END);
1022   ret = _read(tempfd,btext,1);
1023   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1024   ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1025   _lseek(tempfd, -3, FILE_END);
1026   ret = _read(tempfd,btext,2);
1027   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1028   ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1029   _lseek(tempfd, -3, FILE_END);
1030   ret = _read(tempfd,btext,3);
1031   ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1032   ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1033    _close(tempfd);
1034
1035   ret = unlink(tempf);
1036   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1037   free(tempf);
1038
1039   tempf=_tempnam(".","wne");
1040   tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1041   ok( tempfd != -1,
1042      "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1043   ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1044      "_write _O_BINARY bad return value\n");
1045   _close(tempfd);
1046   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1047   ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1048      "_read _O_BINARY got bad length\n");
1049   ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1050       "problems with _O_BINARY _write / _read\n");
1051   ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1052   _close(tempfd);
1053   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1054   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1055      "_read _O_TEXT got bad length\n");
1056   ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1057       "problems with _O_BINARY _write / _O_TEXT _read\n");
1058   _close(tempfd);
1059
1060   /* test _read with single bytes. CR should be skipped and LF pulled in */
1061   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1062   for (i=0; i<strlen(mytext); i++)  /* */
1063     {
1064       _read(tempfd,btext, 1);
1065       ok(btext[0] ==  mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1066     }
1067   while (_read(tempfd,btext, 1));
1068   _close(tempfd);
1069
1070   /* test _read in buffered mode. Last CR should be skipped but  LF not pulled in */
1071   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1072   i = _read(tempfd,btext, strlen(mytext));
1073   ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1074   _close(tempfd);
1075
1076   /* test read/write in unicode mode */
1077   if(p_fopen_s)
1078   {
1079       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1080       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1081       ret = _write(tempfd, "a", 1);
1082       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1083       ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1084       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1085       _close(tempfd);
1086
1087       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1088       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1089       ret = _read(tempfd, btext, sizeof(btext));
1090       ok(ret == 10, "_read returned %d, expected 10\n", ret);
1091       ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1092       _close(tempfd);
1093
1094       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1095       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1096       errno = 0xdeadbeef;
1097       ret = _read(tempfd, btext, 3);
1098       ok(ret == -1, "_read returned %d, expected -1\n", ret);
1099       ok(errno == 22, "errno = %d\n", errno);
1100       ret = _read(tempfd, btext, sizeof(btext));
1101       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1102       ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1103       _close(tempfd);
1104
1105       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1106       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1107       errno = 0xdeadbeef;
1108       ret = _write(tempfd, "a", 1);
1109       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1110       ok(errno == 22, "errno = %d\n", errno);
1111       ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1112       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1113       _close(tempfd);
1114
1115       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1116       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1117       ret = _read(tempfd, btext, sizeof(btext));
1118       ok(ret == 7, "_read returned %d, expected 7\n", ret);
1119       ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1120       _close(tempfd);
1121
1122       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1123       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1124       ret = _read(tempfd, btext, sizeof(btext));
1125       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1126       ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1127
1128       /* when buffer is small read sometimes fails in native implementation */
1129       lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1130       ret = _read(tempfd, btext, 4);
1131       todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1132
1133       lseek(tempfd, 6, SEEK_SET);
1134       ret = _read(tempfd, btext, 2);
1135       ok(ret == 2, "_read returned %d, expected 2\n", ret);
1136       ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1137       _close(tempfd);
1138
1139       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1140       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1141       ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1142       ok(ret == 12, "_write returned %d, expected 9\n", ret);
1143       _close(tempfd);
1144
1145       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1146       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1147       ret = _read(tempfd, btext, sizeof(btext));
1148       ok(ret == 12, "_read returned %d, expected 12\n", ret);
1149       ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1150
1151       /* test invalid utf8 sequence */
1152       lseek(tempfd, 5, SEEK_SET);
1153       ret = _read(tempfd, btext, sizeof(btext));
1154       todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1155       /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1156       todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1157       ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1158       _close(tempfd);
1159   }
1160   else
1161   {
1162       win_skip("unicode mode tests on file\n");
1163   }
1164
1165   ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1166   ok( ret == 0,
1167      "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1168   ret = unlink(tempf);
1169   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1170   free(tempf);
1171 }
1172
1173 static void test_file_inherit_child(const char* fd_s)
1174 {
1175     int fd = atoi(fd_s);
1176     char buffer[32];
1177     int ret;
1178
1179     ret =write(fd, "Success", 8);
1180     ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1181     lseek(fd, 0, SEEK_SET);
1182     ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1183     ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1184 }
1185
1186 static void test_file_inherit_child_no(const char* fd_s)
1187 {
1188     int fd = atoi(fd_s);
1189     int ret;
1190
1191     ret = write(fd, "Success", 8);
1192     ok( ret == -1 && errno == EBADF, 
1193        "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1194 }
1195
1196 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1197 {
1198     static BYTE block[1024];
1199     BYTE *wxflag_ptr;
1200     HANDLE *handle_ptr;
1201     unsigned int i;
1202
1203     startup->lpReserved2 = block;
1204     startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1205     wxflag_ptr = block + sizeof(unsigned);
1206     handle_ptr = (HANDLE *)(wxflag_ptr + count);
1207
1208     *(unsigned*)block = count;
1209     for (i = 0; i < count; i++)
1210     {
1211         wxflag_ptr[i] = 0x81;
1212         handle_ptr[i] = handles[i];
1213     }
1214 }
1215
1216 static const char *read_file( HANDLE file )
1217 {
1218     static char buffer[128];
1219     DWORD ret;
1220     SetFilePointer( file, 0, NULL, FILE_BEGIN );
1221     if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1222     buffer[ret] = 0;
1223     return buffer;
1224 }
1225
1226 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1227                                 const char *descr )
1228 {
1229     const char *data;
1230     HANDLE hErrorFile;
1231     SECURITY_ATTRIBUTES sa;
1232     PROCESS_INFORMATION proc;
1233
1234     /* make file handle inheritable */
1235     sa.nLength = sizeof(sa);
1236     sa.lpSecurityDescriptor = NULL;
1237     sa.bInheritHandle = TRUE;
1238
1239     hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1240                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1241     startup->dwFlags    = STARTF_USESTDHANDLES;
1242     startup->hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
1243     startup->hStdOutput = hErrorFile;
1244     startup->hStdError  = GetStdHandle( STD_ERROR_HANDLE );
1245
1246     CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1247                     CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1248     winetest_wait_child_process( proc.hProcess );
1249
1250     data = read_file( hErrorFile );
1251     if (expect_stdout)
1252         ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1253     else
1254         ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1255
1256     if (hstdout)
1257     {
1258         data = read_file( hstdout );
1259         if (expect_stdout)
1260             ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1261         else
1262             ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1263     }
1264
1265     CloseHandle( hErrorFile );
1266     DeleteFile( "fdopen.err" );
1267 }
1268
1269 static void test_file_inherit( const char* selfname )
1270 {
1271     int                 fd;
1272     const char*         arg_v[5];
1273     char                buffer[16];
1274     char cmdline[MAX_PATH];
1275     STARTUPINFO startup;
1276     SECURITY_ATTRIBUTES sa;
1277     HANDLE handles[3];
1278
1279     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1280     ok(fd != -1, "Couldn't create test file\n");
1281     arg_v[0] = selfname;
1282     arg_v[1] = "tests/file.c";
1283     arg_v[2] = "inherit";
1284     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1285     arg_v[4] = 0;
1286     _spawnvp(_P_WAIT, selfname, arg_v);
1287     ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1288     lseek(fd, 0, SEEK_SET);
1289     ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1290     close (fd);
1291     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1292     
1293     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1294     ok(fd != -1, "Couldn't create test file\n");
1295     arg_v[0] = selfname;
1296     arg_v[1] = "tests/file.c";
1297     arg_v[2] = "inherit_no";
1298     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1299     arg_v[4] = 0;
1300     _spawnvp(_P_WAIT, selfname, arg_v);
1301     ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1302     ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1303     close (fd);
1304     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1305
1306     /* make file handle inheritable */
1307     sa.nLength = sizeof(sa);
1308     sa.lpSecurityDescriptor = NULL;
1309     sa.bInheritHandle = TRUE;
1310     sprintf(cmdline, "%s file inherit 1", selfname);
1311
1312     /* init an empty Reserved2, which should not be recognized as inherit-block */
1313     ZeroMemory(&startup, sizeof(STARTUPINFO));
1314     startup.cb = sizeof(startup);
1315     create_io_inherit_block( &startup, 0, NULL );
1316     test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1317
1318     /* test with valid inheritblock */
1319     handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1320     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1321                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1322     handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1323     create_io_inherit_block( &startup, 3, handles );
1324     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1325     CloseHandle( handles[1] );
1326     DeleteFile("fdopen.tst");
1327
1328     /* test inherit block starting with unsigned zero */
1329     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1330                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1331     create_io_inherit_block( &startup, 3, handles );
1332     *(unsigned int *)startup.lpReserved2 = 0;
1333     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1334     CloseHandle( handles[1] );
1335     DeleteFile("fdopen.tst");
1336
1337     /* test inherit block with smaller size */
1338     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1339                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1340     create_io_inherit_block( &startup, 3, handles );
1341     startup.cbReserved2 -= 3;
1342     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1343     CloseHandle( handles[1] );
1344     DeleteFile("fdopen.tst");
1345
1346     /* test inherit block with even smaller size */
1347     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1348                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1349     create_io_inherit_block( &startup, 3, handles );
1350     startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1351     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1352     CloseHandle( handles[1] );
1353     DeleteFile("fdopen.tst");
1354
1355     /* test inherit block with larger size */
1356     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1357                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1358     create_io_inherit_block( &startup, 3, handles );
1359     startup.cbReserved2 += 7;
1360     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1361     CloseHandle( handles[1] );
1362     DeleteFile("fdopen.tst");
1363 }
1364
1365 static void test_tmpnam( void )
1366 {
1367   char name[MAX_PATH] = "abc";
1368   char *res;
1369
1370   res = tmpnam(NULL);
1371   ok(res != NULL, "tmpnam returned NULL\n");
1372   ok(res[0] == '\\', "first character is not a backslash\n");
1373   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1374   ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1375
1376   res = tmpnam(name);
1377   ok(res != NULL, "tmpnam returned NULL\n");
1378   ok(res == name, "supplied buffer was not used\n");
1379   ok(res[0] == '\\', "first character is not a backslash\n");
1380   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1381   ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1382 }
1383
1384 static void test_chsize( void )
1385 {
1386     int fd;
1387     LONG cur, pos, count;
1388     char temptext[] = "012345678";
1389     char *tempfile = _tempnam( ".", "tst" );
1390     
1391     ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1392
1393     fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1394     ok( fd > 0, "Couldn't open test file\n" );
1395
1396     count = _write( fd, temptext, sizeof(temptext) );
1397     ok( count > 0, "Couldn't write to test file\n" );
1398
1399     /* get current file pointer */
1400     cur = _lseek( fd, 0, SEEK_CUR );
1401
1402     /* make the file smaller */
1403     ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1404
1405     pos = _lseek( fd, 0, SEEK_CUR );
1406     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1407     ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1408
1409     /* enlarge the file */
1410     ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); 
1411
1412     pos = _lseek( fd, 0, SEEK_CUR );
1413     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1414     ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1415
1416     _close( fd );
1417     _unlink( tempfile );
1418     free( tempfile );
1419 }
1420
1421 static void test_fopen_fclose_fcloseall( void )
1422 {
1423     char fname1[] = "empty1";
1424     char fname2[] = "empty2";
1425     char fname3[] = "empty3";
1426     FILE *stream1, *stream2, *stream3, *stream4;
1427     int ret, numclosed;
1428
1429     /* testing fopen() */
1430     stream1 = fopen(fname1, "w+");
1431     ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1432     stream2 = fopen(fname2, "w ");
1433     ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1434     _unlink(fname3);
1435     stream3 = fopen(fname3, "r");
1436     ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1437     stream3 = fopen(fname3, "w+");
1438     ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1439     errno = 0xfaceabad;
1440     stream4 = fopen("", "w+");
1441     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1442        "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1443     errno = 0xfaceabad;
1444     stream4 = fopen(NULL, "w+");
1445     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), 
1446        "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1447
1448     /* testing fclose() */
1449     ret = fclose(stream2);
1450     ok(ret == 0, "The file '%s' was not closed\n", fname2);
1451     ret = fclose(stream3);
1452     ok(ret == 0, "The file '%s' was not closed\n", fname3);
1453     ret = fclose(stream2);
1454     ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1455     ret = fclose(stream3);
1456     ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1457
1458     /* testing fcloseall() */
1459     numclosed = _fcloseall();
1460     /* fname1 should be closed here */
1461     ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1462     numclosed = _fcloseall();
1463     ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1464
1465     ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1466     ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1467     ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1468 }
1469
1470 static void test_fopen_s( void )
1471 {
1472     const char name[] = "empty1";
1473     char buff[16];
1474     unsigned char *ubuff = (unsigned char*)buff;
1475     FILE *file;
1476     int ret;
1477     int len;
1478
1479     if (!p_fopen_s)
1480     {
1481         win_skip("Skipping fopen_s test\n");
1482         return;
1483     }
1484     /* testing fopen_s */
1485     ret = p_fopen_s(&file, name, "w");
1486     ok(ret == 0, "fopen_s failed with %d\n", ret);
1487     ok(file != 0, "fopen_s failed to return value\n");
1488     fwrite(name, sizeof(name), 1, file);
1489
1490     ret = fclose(file);
1491     ok(ret != EOF, "File failed to close\n");
1492
1493     file = fopen(name, "r");
1494     ok(file != 0, "fopen failed\n");
1495     len = fread(buff, 1, sizeof(name), file);
1496     ok(len == sizeof(name), "File length is %d\n", len);
1497     buff[sizeof(name)] = '\0';
1498     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1499
1500     ret = fclose(file);
1501     ok(ret != EOF, "File failed to close\n");
1502
1503     ret = p_fopen_s(&file, name, "w,  ccs=UNIcode");
1504     ok(ret == 0, "fopen_s failed with %d\n", ret);
1505     ret = fwrite("a", 1, 2, file);
1506     ok(ret == 2, "fwrite returned %d\n", ret);
1507     fclose(file);
1508
1509     ret = p_fopen_s(&file, name, "r");
1510     ok(ret == 0, "fopen_s failed with %d\n", ret);
1511     len = fread(buff, 1, 2, file);
1512     ok(len == 2, "len = %d\n", len);
1513     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1514             ubuff[0], ubuff[1]);
1515     fclose(file);
1516
1517     ret = p_fopen_s(&file, name, "r,ccs=unicode");
1518     ok(ret == 0, "fopen_s failed with %d\n", ret);
1519     len = fread(buff, 1, 2, file);
1520     ok(len == 2, "len = %d\n", len);
1521     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1522             ubuff[0], ubuff[1]);
1523     fclose(file);
1524
1525     ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1526     ok(ret == 0, "fopen_s failed with %d\n", ret);
1527     len = fread(buff, 1, 2, file);
1528     ok(len == 2, "len = %d\n", len);
1529     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1530             ubuff[0], ubuff[1]);
1531     fclose(file);
1532
1533     ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1534     ok(ret == 0, "fopen_s failed with %d\n", ret);
1535     len = fread(buff, 1, 2, file);
1536     ok(len == 2, "len = %d\n", len);
1537     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1538             ubuff[0], ubuff[1]);
1539     fclose(file);
1540
1541     ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1542     ok(ret == 0, "fopen_s failed with %d\n", ret);
1543     fclose(file);
1544
1545     ret = p_fopen_s(&file, name, "r");
1546     ok(ret == 0, "fopen_s failed with %d\n", ret);
1547     len = fread(buff, 1, 3, file);
1548     ok(len == 2, "len = %d\n", len);
1549     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1550             ubuff[0], ubuff[1]);
1551     fclose(file);
1552
1553     ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1554     ok(ret == 0, "fopen_s failed with %d\n", ret);
1555     fclose(file);
1556
1557     ret = p_fopen_s(&file, name, "r");
1558     ok(ret == 0, "fopen_s failed with %d\n", ret);
1559     len = fread(buff, 1, 4, file);
1560     ok(len == 3, "len = %d\n", len);
1561     ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1562             "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1563             ubuff[0], ubuff[1], ubuff[2]);
1564     fclose(file);
1565
1566     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1567 }
1568
1569 static void test__wfopen_s( void )
1570 {
1571     const char name[] = "empty1";
1572     const WCHAR wname[] = {
1573        'e','m','p','t','y','1',0
1574     };
1575     const WCHAR wmode[] = {
1576        'w',0
1577     };
1578     char buff[16];
1579     FILE *file;
1580     int ret;
1581     int len;
1582
1583     if (!p__wfopen_s)
1584     {
1585         win_skip("Skipping _wfopen_s test\n");
1586         return;
1587     }
1588     /* testing _wfopen_s */
1589     ret = p__wfopen_s(&file, wname, wmode);
1590     ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1591     ok(file != 0, "_wfopen_s failed to return value\n");
1592     fwrite(name, sizeof(name), 1, file);
1593
1594     ret = fclose(file);
1595     ok(ret != EOF, "File failed to close\n");
1596
1597     file = fopen(name, "r");
1598     ok(file != 0, "fopen failed\n");
1599     len = fread(buff, 1, sizeof(name), file);
1600     ok(len == sizeof(name), "File length is %d\n", len);
1601     buff[sizeof(name)] = '\0';
1602     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1603
1604     ret = fclose(file);
1605     ok(ret != EOF, "File failed to close\n");
1606
1607     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1608 }
1609
1610 static void test_setmode(void)
1611 {
1612     const char name[] = "empty1";
1613     int fd, ret;
1614
1615     if(!p_fopen_s) {
1616         win_skip("unicode file modes are not available, skipping setmode tests\n");
1617         return;
1618     }
1619
1620     fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1621     ok(fd != -1, "failed to open file\n");
1622
1623     errno = 0xdeadbeef;
1624     ret = _setmode(fd, 0xffffffff);
1625     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1626     ok(errno == EINVAL, "errno = %d\n", errno);
1627
1628     errno = 0xdeadbeef;
1629     ret = _setmode(fd, 0);
1630     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1631     ok(errno == EINVAL, "errno = %d\n", errno);
1632
1633     errno = 0xdeadbeef;
1634     ret = _setmode(fd, _O_BINARY|_O_TEXT);
1635     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1636     ok(errno == EINVAL, "errno = %d\n", errno);
1637
1638     errno = 0xdeadbeef;
1639     ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1640     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1641     ok(errno == EINVAL, "errno = %d\n", errno);
1642
1643     ret = _setmode(fd, _O_BINARY);
1644     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1645
1646     ret = _setmode(fd, _O_WTEXT);
1647     ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1648
1649     ret = _setmode(fd, _O_TEXT);
1650     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1651
1652     ret = _setmode(fd, _O_U16TEXT);
1653     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1654
1655     ret = _setmode(fd, _O_U8TEXT);
1656     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1657
1658     ret = _setmode(fd, _O_TEXT);
1659     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1660
1661     _close(fd);
1662     _unlink(name);
1663 }
1664
1665 static void test_get_osfhandle(void)
1666 {
1667     int fd;
1668     char fname[] = "t_get_osfhanle";
1669     DWORD bytes_written;
1670     HANDLE handle;
1671
1672     fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1673     handle = (HANDLE)_get_osfhandle(fd);
1674     WriteFile(handle, "bar", 3, &bytes_written, NULL);
1675     _close(fd);
1676     fd = _open(fname, _O_RDONLY, 0);
1677     ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1678
1679     _close(fd);
1680     _unlink(fname);
1681 }
1682
1683 static void test_setmaxstdio(void)
1684 {
1685     ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1686     ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1687 }
1688
1689 static void test_stat(void)
1690 {
1691     int fd;
1692     int pipes[2];
1693     int ret;
1694     struct stat buf;
1695
1696     /* Tests for a file */
1697     fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1698     if (fd >= 0)
1699     {
1700         ret = fstat(fd, &buf);
1701         ok(!ret, "fstat failed: errno=%d\n", errno);
1702         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1703         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1704         ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1705         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1706         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1707         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1708
1709         ret = stat("stat.tst", &buf);
1710         ok(!ret, "stat failed: errno=%d\n", errno);
1711         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1712         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1713         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1714         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1715         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1716
1717         errno = 0xdeadbeef;
1718         ret = stat("stat.tst\\", &buf);
1719         ok(ret == -1, "stat returned %d\n", ret);
1720         ok(errno == ENOENT, "errno = %d\n", errno);
1721
1722         close(fd);
1723         remove("stat.tst");
1724     }
1725     else
1726         skip("open failed with errno %d\n", errno);
1727
1728     /* Tests for a char device */
1729     if (_dup2(0, 10) == 0)
1730     {
1731         ret = fstat(10, &buf);
1732         ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1733         if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1734         {
1735             ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1736             ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1737             ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1738             ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1739         }
1740         else
1741             skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1742         close(10);
1743     }
1744     else
1745         skip("_dup2 failed with errno %d\n", errno);
1746
1747     /* Tests for pipes */
1748     if (_pipe(pipes, 1024, O_BINARY) == 0)
1749     {
1750         ret = fstat(pipes[0], &buf);
1751         ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1752         ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1753         ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1754         ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1755         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1756         close(pipes[0]);
1757         close(pipes[1]);
1758     }
1759     else
1760         skip("pipe failed with errno %d\n", errno);
1761
1762     /* Tests for directory */
1763     if(mkdir("stat.tst") == 0)
1764     {
1765         ret = stat("stat.tst                         ", &buf);
1766         ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1767         ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1768         ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1769         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1770         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1771
1772         errno = 0xdeadbeef;
1773         ret = stat("stat.tst\\ ", &buf);
1774         ok(ret == -1, "stat returned %d\n", ret);
1775         ok(errno == ENOENT, "errno = %d\n", errno);
1776         rmdir( "stat.tst" );
1777     }
1778     else
1779         skip("mkdir failed with errno %d\n", errno);
1780 }
1781
1782 static const char* pipe_string="Hello world";
1783
1784 /* How many messages to transfer over the pipe */
1785 #define N_TEST_MESSAGES 3
1786
1787 static void test_pipes_child(int argc, char** args)
1788 {
1789     int fd;
1790     int nwritten;
1791     int i;
1792
1793     if (argc < 5)
1794     {
1795         ok(0, "not enough parameters: %d\n", argc);
1796         return;
1797     }
1798
1799     fd=atoi(args[3]);
1800     i=close(fd);
1801     ok(!i, "unable to close %d: %d\n", fd, errno);
1802
1803     fd=atoi(args[4]);
1804
1805     for (i=0; i<N_TEST_MESSAGES; i++) {
1806        nwritten=write(fd, pipe_string, strlen(pipe_string));
1807        ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1808        /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1809        if (i < N_TEST_MESSAGES-1)
1810            Sleep(100);
1811     }
1812
1813     i=close(fd);
1814     ok(!i, "unable to close %d: %d\n", fd, errno);
1815 }
1816
1817 static void test_pipes(const char* selfname)
1818 {
1819     int pipes[2];
1820     char str_fdr[12], str_fdw[12];
1821     FILE* file;
1822     const char* arg_v[6];
1823     char buf[4096];
1824     char expected[4096];
1825     int r;
1826     int i;
1827
1828     /* Test reading from a pipe with read() */
1829     if (_pipe(pipes, 1024, O_BINARY) < 0)
1830     {
1831         ok(0, "pipe failed with errno %d\n", errno);
1832         return;
1833     }
1834
1835     arg_v[0] = selfname;
1836     arg_v[1] = "tests/file.c";
1837     arg_v[2] = "pipes";
1838     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1839     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1840     arg_v[5] = NULL;
1841     proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1842     i=close(pipes[1]);
1843     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1844
1845     for (i=0; i<N_TEST_MESSAGES; i++) {
1846        r=read(pipes[0], buf, sizeof(buf)-1);
1847        ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1848        if (r > 0)
1849            buf[r]='\0';
1850        ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1851    }
1852
1853     r=read(pipes[0], buf, sizeof(buf)-1);
1854     ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1855     i=close(pipes[0]);
1856     ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1857
1858     /* Test reading from a pipe with fread() */
1859     if (_pipe(pipes, 1024, O_BINARY) < 0)
1860     {
1861         ok(0, "pipe failed with errno %d\n", errno);
1862         return;
1863     }
1864
1865     arg_v[0] = selfname;
1866     arg_v[1] = "tests/file.c";
1867     arg_v[2] = "pipes";
1868     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1869     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1870     arg_v[5] = NULL;
1871     proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1872     i=close(pipes[1]);
1873     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1874     file=fdopen(pipes[0], "r");
1875
1876     /* In blocking mode, fread will keep calling read() until it gets
1877      * enough bytes, or EOF, even on Unix.  (If this were a Unix terminal
1878      * in cooked mode instead of a pipe, it would also stop on EOL.)
1879      */
1880     expected[0] = 0;
1881     for (i=0; i<N_TEST_MESSAGES; i++)
1882        strcat(expected, pipe_string);
1883     r=fread(buf, 1, sizeof(buf)-1, file);
1884     ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1885     if (r > 0)
1886        buf[r]='\0';
1887     ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1888
1889     /* Let child close the file before we read, so we can sense EOF reliably */
1890     Sleep(100);
1891     r=fread(buf, 1, sizeof(buf)-1, file);
1892     ok(r == 0, "fread() returned %d instead of 0\n", r);
1893     ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1894     ok(feof(file), "feof() is false!\n");
1895
1896     i=fclose(file);
1897     ok(!i, "unable to close the pipe: %d\n", errno);
1898
1899     /* test \r handling when it's the last character read */
1900     if (_pipe(pipes, 1024, O_BINARY) < 0)
1901     {
1902         ok(0, "pipe failed with errno %d\n", errno);
1903         return;
1904     }
1905     r = write(pipes[1], "\r\n\rab", 5);
1906     ok(r == 5, "write returned %d, errno = %d\n", r, errno);
1907     setmode(pipes[0], O_TEXT);
1908     r = read(pipes[0], buf, 1);
1909     ok(r == 1, "read returned %d, expected 1\n", r);
1910     ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
1911     r = read(pipes[0], buf, 1);
1912     ok(r == 1, "read returned %d, expected 1\n", r);
1913     ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
1914     r = read(pipes[0], buf, 1);
1915     ok(r == 1, "read returned %d, expected 1\n", r);
1916     ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
1917     r = read(pipes[0], buf, 1);
1918     ok(r == 1, "read returned %d, expected 1\n", r);
1919     ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
1920
1921     if (p_fopen_s)
1922     {
1923         /* test utf16 read with insufficient data */
1924         r = write(pipes[1], "a\0b", 3);
1925         ok(r == 3, "write returned %d, errno = %d\n", r, errno);
1926         buf[2] = 'z';
1927         buf[3] = 'z';
1928         setmode(pipes[0], _O_WTEXT);
1929         r = read(pipes[0], buf, 4);
1930         ok(r == 2, "read returned %d, expected 2\n", r);
1931         ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
1932         r = write(pipes[1], "\0", 1);
1933         ok(r == 1, "write returned %d, errno = %d\n", r, errno);
1934         buf[0] = 'z';
1935         buf[1] = 'z';
1936         r = read(pipes[0], buf, 2);
1937         ok(r == 0, "read returned %d, expected 0\n", r);
1938         ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
1939     }
1940     else
1941     {
1942         win_skip("unicode mode tests on pipe\n");
1943     }
1944
1945     close(pipes[1]);
1946     close(pipes[0]);
1947 }
1948
1949 static void test_unlink(void)
1950 {
1951     FILE* file;
1952     ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1953     file = fopen("test_unlink\\empty", "w");
1954     ok(file != NULL, "unable to create test file\n");
1955     if(file)
1956       fclose(file);
1957     ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1958     unlink("test_unlink\\empty");
1959     rmdir("test_unlink");
1960 }
1961
1962 static void test_dup2(void)
1963 {
1964     ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1965 }
1966
1967 START_TEST(file)
1968 {
1969     int arg_c;
1970     char** arg_v;
1971
1972     init();
1973
1974     arg_c = winetest_get_mainargs( &arg_v );
1975
1976     /* testing low-level I/O */
1977     if (arg_c >= 3)
1978     {
1979         if (strcmp(arg_v[2], "inherit") == 0)
1980             test_file_inherit_child(arg_v[3]);
1981         else if (strcmp(arg_v[2], "inherit_no") == 0)
1982             test_file_inherit_child_no(arg_v[3]);
1983         else if (strcmp(arg_v[2], "pipes") == 0)
1984             test_pipes_child(arg_c, arg_v);
1985         else
1986             ok(0, "invalid argument '%s'\n", arg_v[2]);
1987         return;
1988     }
1989     test_dup2();
1990     test_file_inherit(arg_v[0]);
1991     test_file_write_read();
1992     test_chsize();
1993     test_stat();
1994     test_unlink();
1995
1996     /* testing stream I/O */
1997     test_filbuf();
1998     test_fdopen();
1999     test_fopen_fclose_fcloseall();
2000     test_fopen_s();
2001     test__wfopen_s();
2002     test_setmode();
2003     test_fileops();
2004     test_asciimode();
2005     test_asciimode2();
2006     test_filemodeT();
2007     test_readmode(FALSE); /* binary mode */
2008     test_readmode(TRUE);  /* ascii mode */
2009     test_readboundary();
2010     test_fgetc();
2011     test_fputc();
2012     test_flsbuf();
2013     test_fflush();
2014     test_fgetwc();
2015     test_fputwc();
2016     test_ctrlz();
2017     test_file_put_get();
2018     test_tmpnam();
2019     test_get_osfhandle();
2020     test_setmaxstdio();
2021     test_pipes(arg_v[0]);
2022
2023     /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2024      * file contains lines in the correct order
2025      */
2026     WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);
2027 }