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