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