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