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