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