crypt32: Free the encoded msg (Coverity).
[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, -2, FILE_END);
960   ret = _read(tempfd,btext,1);
961   ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
962   ret = read(tempfd,btext,1);
963   ok(ret == 0, "_read returned %d, expected 0\n", ret);
964   _lseek(tempfd, -3, FILE_END);
965   ret = _read(tempfd,btext,1);
966   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
967   ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
968   _lseek(tempfd, -3, FILE_END);
969   ret = _read(tempfd,btext,2);
970   ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
971   ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
972   _lseek(tempfd, -3, FILE_END);
973   ret = _read(tempfd,btext,3);
974   ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
975   ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
976    _close(tempfd);
977
978   ret = unlink(tempf);
979   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
980   free(tempf);
981
982   tempf=_tempnam(".","wne");
983   tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
984   ok( tempfd != -1,
985      "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
986   ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
987      "_write _O_BINARY bad return value\n");
988   _close(tempfd);
989   tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
990   ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
991      "_read _O_BINARY got bad length\n");
992   ok( memcmp(dostext,btext,strlen(dostext)) == 0,
993       "problems with _O_BINARY _write / _read\n");
994   ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
995   _close(tempfd);
996   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
997   ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
998      "_read _O_TEXT got bad length\n");
999   ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1000       "problems with _O_BINARY _write / _O_TEXT _read\n");
1001   _close(tempfd);
1002
1003   /* test _read with single bytes. CR should be skipped and LF pulled in */
1004   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1005   for (i=0; i<strlen(mytext); i++)  /* */
1006     {
1007       _read(tempfd,btext, 1);
1008       ok(btext[0] ==  mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1009     }
1010   while (_read(tempfd,btext, 1));
1011   _close(tempfd);
1012
1013   /* test _read in buffered mode. Last CR should be skipped but  LF not pulled in */
1014   tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1015   i = _read(tempfd,btext, strlen(mytext));
1016   ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1017   _close(tempfd);
1018
1019   /* test read/write in unicode mode */
1020   if(p_fopen_s)
1021   {
1022       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1023       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1024       ret = _write(tempfd, "a", 1);
1025       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1026       ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1027       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1028       _close(tempfd);
1029
1030       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1031       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1032       ret = _read(tempfd, btext, sizeof(btext));
1033       ok(ret == 10, "_read returned %d, expected 10\n", ret);
1034       ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1035       _close(tempfd);
1036
1037       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1038       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1039       errno = 0xdeadbeef;
1040       ret = _read(tempfd, btext, 3);
1041       ok(ret == -1, "_read returned %d, expected -1\n", ret);
1042       ok(errno == 22, "errno = %d\n", errno);
1043       ret = _read(tempfd, btext, sizeof(btext));
1044       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1045       ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1046       _close(tempfd);
1047
1048       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1049       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1050       errno = 0xdeadbeef;
1051       ret = _write(tempfd, "a", 1);
1052       ok(ret == -1, "_write returned %d, expected -1\n", ret);
1053       ok(errno == 22, "errno = %d\n", errno);
1054       ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1055       ok(ret == 6, "_write returned %d, expected 6\n", ret);
1056       _close(tempfd);
1057
1058       tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1059       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1060       ret = _read(tempfd, btext, sizeof(btext));
1061       ok(ret == 7, "_read returned %d, expected 7\n", ret);
1062       ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1063       _close(tempfd);
1064
1065       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1066       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1067       ret = _read(tempfd, btext, sizeof(btext));
1068       ok(ret == 6, "_read returned %d, expected 6\n", ret);
1069       ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1070
1071       /* when buffer is small read sometimes fails in native implementation */
1072       lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1073       ret = _read(tempfd, btext, 4);
1074       todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1075
1076       lseek(tempfd, 6, SEEK_SET);
1077       ret = _read(tempfd, btext, 2);
1078       ok(ret == 2, "_read returned %d, expected 2\n", ret);
1079       ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1080       _close(tempfd);
1081
1082       tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1083       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1084       ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1085       ok(ret == 12, "_write returned %d, expected 9\n", ret);
1086       _close(tempfd);
1087
1088       tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1089       ok(tempfd != -1, "_open failed with error: %d\n", errno);
1090       ret = _read(tempfd, btext, sizeof(btext));
1091       ok(ret == 12, "_read returned %d, expected 12\n", ret);
1092       ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1093
1094       /* test invalid utf8 sequence */
1095       lseek(tempfd, 5, SEEK_SET);
1096       ret = _read(tempfd, btext, sizeof(btext));
1097       todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1098       /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1099       todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1100       ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1101       _close(tempfd);
1102   }
1103   else
1104   {
1105       win_skip("unicode mode tests on file\n");
1106   }
1107
1108   ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1109   ok( ret == 0,
1110      "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1111   ret = unlink(tempf);
1112   ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1113   free(tempf);
1114 }
1115
1116 static void test_file_inherit_child(const char* fd_s)
1117 {
1118     int fd = atoi(fd_s);
1119     char buffer[32];
1120     int ret;
1121
1122     ret =write(fd, "Success", 8);
1123     ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1124     lseek(fd, 0, SEEK_SET);
1125     ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1126     ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1127 }
1128
1129 static void test_file_inherit_child_no(const char* fd_s)
1130 {
1131     int fd = atoi(fd_s);
1132     int ret;
1133
1134     ret = write(fd, "Success", 8);
1135     ok( ret == -1 && errno == EBADF, 
1136        "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1137 }
1138
1139 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1140 {
1141     static BYTE block[1024];
1142     BYTE *wxflag_ptr;
1143     HANDLE *handle_ptr;
1144     unsigned int i;
1145
1146     startup->lpReserved2 = block;
1147     startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1148     wxflag_ptr = block + sizeof(unsigned);
1149     handle_ptr = (HANDLE *)(wxflag_ptr + count);
1150
1151     *(unsigned*)block = count;
1152     for (i = 0; i < count; i++)
1153     {
1154         wxflag_ptr[i] = 0x81;
1155         handle_ptr[i] = handles[i];
1156     }
1157 }
1158
1159 static const char *read_file( HANDLE file )
1160 {
1161     static char buffer[128];
1162     DWORD ret;
1163     SetFilePointer( file, 0, NULL, FILE_BEGIN );
1164     if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1165     buffer[ret] = 0;
1166     return buffer;
1167 }
1168
1169 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1170                                 const char *descr )
1171 {
1172     const char *data;
1173     HANDLE hErrorFile;
1174     SECURITY_ATTRIBUTES sa;
1175     PROCESS_INFORMATION proc;
1176
1177     /* make file handle inheritable */
1178     sa.nLength = sizeof(sa);
1179     sa.lpSecurityDescriptor = NULL;
1180     sa.bInheritHandle = TRUE;
1181
1182     hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1183                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1184     startup->dwFlags    = STARTF_USESTDHANDLES;
1185     startup->hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
1186     startup->hStdOutput = hErrorFile;
1187     startup->hStdError  = GetStdHandle( STD_ERROR_HANDLE );
1188
1189     CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1190                     CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1191     winetest_wait_child_process( proc.hProcess );
1192
1193     data = read_file( hErrorFile );
1194     if (expect_stdout)
1195         ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1196     else
1197         ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1198
1199     if (hstdout)
1200     {
1201         data = read_file( hstdout );
1202         if (expect_stdout)
1203             ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1204         else
1205             ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1206     }
1207
1208     CloseHandle( hErrorFile );
1209     DeleteFile( "fdopen.err" );
1210 }
1211
1212 static void test_file_inherit( const char* selfname )
1213 {
1214     int                 fd;
1215     const char*         arg_v[5];
1216     char                buffer[16];
1217     char cmdline[MAX_PATH];
1218     STARTUPINFO startup;
1219     SECURITY_ATTRIBUTES sa;
1220     HANDLE handles[3];
1221
1222     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1223     ok(fd != -1, "Couldn't create test file\n");
1224     arg_v[0] = selfname;
1225     arg_v[1] = "tests/file.c";
1226     arg_v[2] = "inherit";
1227     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1228     arg_v[4] = 0;
1229     _spawnvp(_P_WAIT, selfname, arg_v);
1230     ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1231     lseek(fd, 0, SEEK_SET);
1232     ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1233     close (fd);
1234     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1235     
1236     fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1237     ok(fd != -1, "Couldn't create test file\n");
1238     arg_v[0] = selfname;
1239     arg_v[1] = "tests/file.c";
1240     arg_v[2] = "inherit_no";
1241     arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1242     arg_v[4] = 0;
1243     _spawnvp(_P_WAIT, selfname, arg_v);
1244     ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1245     ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1246     close (fd);
1247     ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1248
1249     /* make file handle inheritable */
1250     sa.nLength = sizeof(sa);
1251     sa.lpSecurityDescriptor = NULL;
1252     sa.bInheritHandle = TRUE;
1253     sprintf(cmdline, "%s file inherit 1", selfname);
1254
1255     /* init an empty Reserved2, which should not be recognized as inherit-block */
1256     ZeroMemory(&startup, sizeof(STARTUPINFO));
1257     startup.cb = sizeof(startup);
1258     create_io_inherit_block( &startup, 0, NULL );
1259     test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1260
1261     /* test with valid inheritblock */
1262     handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1263     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1264                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1265     handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1266     create_io_inherit_block( &startup, 3, handles );
1267     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1268     CloseHandle( handles[1] );
1269     DeleteFile("fdopen.tst");
1270
1271     /* test inherit block starting with unsigned zero */
1272     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1273                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1274     create_io_inherit_block( &startup, 3, handles );
1275     *(unsigned int *)startup.lpReserved2 = 0;
1276     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1277     CloseHandle( handles[1] );
1278     DeleteFile("fdopen.tst");
1279
1280     /* test inherit block with smaller size */
1281     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1282                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1283     create_io_inherit_block( &startup, 3, handles );
1284     startup.cbReserved2 -= 3;
1285     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1286     CloseHandle( handles[1] );
1287     DeleteFile("fdopen.tst");
1288
1289     /* test inherit block with even smaller size */
1290     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1291                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1292     create_io_inherit_block( &startup, 3, handles );
1293     startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1294     test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1295     CloseHandle( handles[1] );
1296     DeleteFile("fdopen.tst");
1297
1298     /* test inherit block with larger size */
1299     handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1300                               FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1301     create_io_inherit_block( &startup, 3, handles );
1302     startup.cbReserved2 += 7;
1303     test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1304     CloseHandle( handles[1] );
1305     DeleteFile("fdopen.tst");
1306 }
1307
1308 static void test_tmpnam( void )
1309 {
1310   char name[MAX_PATH] = "abc";
1311   char *res;
1312
1313   res = tmpnam(NULL);
1314   ok(res != NULL, "tmpnam returned NULL\n");
1315   ok(res[0] == '\\', "first character is not a backslash\n");
1316   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1317   ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1318
1319   res = tmpnam(name);
1320   ok(res != NULL, "tmpnam returned NULL\n");
1321   ok(res == name, "supplied buffer was not used\n");
1322   ok(res[0] == '\\', "first character is not a backslash\n");
1323   ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1324   ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1325 }
1326
1327 static void test_chsize( void )
1328 {
1329     int fd;
1330     LONG cur, pos, count;
1331     char temptext[] = "012345678";
1332     char *tempfile = _tempnam( ".", "tst" );
1333     
1334     ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1335
1336     fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1337     ok( fd > 0, "Couldn't open test file\n" );
1338
1339     count = _write( fd, temptext, sizeof(temptext) );
1340     ok( count > 0, "Couldn't write to test file\n" );
1341
1342     /* get current file pointer */
1343     cur = _lseek( fd, 0, SEEK_CUR );
1344
1345     /* make the file smaller */
1346     ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1347
1348     pos = _lseek( fd, 0, SEEK_CUR );
1349     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1350     ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1351
1352     /* enlarge the file */
1353     ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); 
1354
1355     pos = _lseek( fd, 0, SEEK_CUR );
1356     ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1357     ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1358
1359     _close( fd );
1360     _unlink( tempfile );
1361     free( tempfile );
1362 }
1363
1364 static void test_fopen_fclose_fcloseall( void )
1365 {
1366     char fname1[] = "empty1";
1367     char fname2[] = "empty2";
1368     char fname3[] = "empty3";
1369     FILE *stream1, *stream2, *stream3, *stream4;
1370     int ret, numclosed;
1371
1372     /* testing fopen() */
1373     stream1 = fopen(fname1, "w+");
1374     ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1375     stream2 = fopen(fname2, "w ");
1376     ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1377     _unlink(fname3);
1378     stream3 = fopen(fname3, "r");
1379     ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1380     stream3 = fopen(fname3, "w+");
1381     ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1382     errno = 0xfaceabad;
1383     stream4 = fopen("", "w+");
1384     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1385        "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1386     errno = 0xfaceabad;
1387     stream4 = fopen(NULL, "w+");
1388     ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), 
1389        "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1390
1391     /* testing fclose() */
1392     ret = fclose(stream2);
1393     ok(ret == 0, "The file '%s' was not closed\n", fname2);
1394     ret = fclose(stream3);
1395     ok(ret == 0, "The file '%s' was not closed\n", fname3);
1396     ret = fclose(stream2);
1397     ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1398     ret = fclose(stream3);
1399     ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1400
1401     /* testing fcloseall() */
1402     numclosed = _fcloseall();
1403     /* fname1 should be closed here */
1404     ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1405     numclosed = _fcloseall();
1406     ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1407
1408     ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1409     ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1410     ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1411 }
1412
1413 static void test_fopen_s( void )
1414 {
1415     const char name[] = "empty1";
1416     char buff[16];
1417     unsigned char *ubuff = (unsigned char*)buff;
1418     FILE *file;
1419     int ret;
1420     int len;
1421
1422     if (!p_fopen_s)
1423     {
1424         win_skip("Skipping fopen_s test\n");
1425         return;
1426     }
1427     /* testing fopen_s */
1428     ret = p_fopen_s(&file, name, "w");
1429     ok(ret == 0, "fopen_s failed with %d\n", ret);
1430     ok(file != 0, "fopen_s failed to return value\n");
1431     fwrite(name, sizeof(name), 1, file);
1432
1433     ret = fclose(file);
1434     ok(ret != EOF, "File failed to close\n");
1435
1436     file = fopen(name, "r");
1437     ok(file != 0, "fopen failed\n");
1438     len = fread(buff, 1, sizeof(name), file);
1439     ok(len == sizeof(name), "File length is %d\n", len);
1440     buff[sizeof(name)] = '\0';
1441     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1442
1443     ret = fclose(file);
1444     ok(ret != EOF, "File failed to close\n");
1445
1446     ret = p_fopen_s(&file, name, "w,  ccs=UNIcode");
1447     ok(ret == 0, "fopen_s failed with %d\n", ret);
1448     ret = fwrite("a", 1, 2, file);
1449     ok(ret == 2, "fwrite returned %d\n", ret);
1450     fclose(file);
1451
1452     ret = p_fopen_s(&file, name, "r");
1453     ok(ret == 0, "fopen_s failed with %d\n", ret);
1454     len = fread(buff, 1, 2, file);
1455     ok(len == 2, "len = %d\n", len);
1456     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1457             ubuff[0], ubuff[1]);
1458     fclose(file);
1459
1460     ret = p_fopen_s(&file, name, "r,ccs=unicode");
1461     ok(ret == 0, "fopen_s failed with %d\n", ret);
1462     len = fread(buff, 1, 2, file);
1463     ok(len == 2, "len = %d\n", len);
1464     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1465             ubuff[0], ubuff[1]);
1466     fclose(file);
1467
1468     ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1469     ok(ret == 0, "fopen_s failed with %d\n", ret);
1470     len = fread(buff, 1, 2, file);
1471     ok(len == 2, "len = %d\n", len);
1472     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1473             ubuff[0], ubuff[1]);
1474     fclose(file);
1475
1476     ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1477     ok(ret == 0, "fopen_s failed with %d\n", ret);
1478     len = fread(buff, 1, 2, file);
1479     ok(len == 2, "len = %d\n", len);
1480     ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1481             ubuff[0], ubuff[1]);
1482     fclose(file);
1483
1484     ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1485     ok(ret == 0, "fopen_s failed with %d\n", ret);
1486     fclose(file);
1487
1488     ret = p_fopen_s(&file, name, "r");
1489     ok(ret == 0, "fopen_s failed with %d\n", ret);
1490     len = fread(buff, 1, 3, file);
1491     ok(len == 2, "len = %d\n", len);
1492     ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1493             ubuff[0], ubuff[1]);
1494     fclose(file);
1495
1496     ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1497     ok(ret == 0, "fopen_s failed with %d\n", ret);
1498     fclose(file);
1499
1500     ret = p_fopen_s(&file, name, "r");
1501     ok(ret == 0, "fopen_s failed with %d\n", ret);
1502     len = fread(buff, 1, 4, file);
1503     ok(len == 3, "len = %d\n", len);
1504     ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1505             "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1506             ubuff[0], ubuff[1], ubuff[2]);
1507     fclose(file);
1508
1509     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1510 }
1511
1512 static void test__wfopen_s( void )
1513 {
1514     const char name[] = "empty1";
1515     const WCHAR wname[] = {
1516        'e','m','p','t','y','1',0
1517     };
1518     const WCHAR wmode[] = {
1519        'w',0
1520     };
1521     char buff[16];
1522     FILE *file;
1523     int ret;
1524     int len;
1525
1526     if (!p__wfopen_s)
1527     {
1528         win_skip("Skipping _wfopen_s test\n");
1529         return;
1530     }
1531     /* testing _wfopen_s */
1532     ret = p__wfopen_s(&file, wname, wmode);
1533     ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1534     ok(file != 0, "_wfopen_s failed to return value\n");
1535     fwrite(name, sizeof(name), 1, file);
1536
1537     ret = fclose(file);
1538     ok(ret != EOF, "File failed to close\n");
1539
1540     file = fopen(name, "r");
1541     ok(file != 0, "fopen failed\n");
1542     len = fread(buff, 1, sizeof(name), file);
1543     ok(len == sizeof(name), "File length is %d\n", len);
1544     buff[sizeof(name)] = '\0';
1545     ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1546
1547     ret = fclose(file);
1548     ok(ret != EOF, "File failed to close\n");
1549
1550     ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1551 }
1552
1553 static void test_setmode(void)
1554 {
1555     const char name[] = "empty1";
1556     int fd, ret;
1557
1558     if(!p_fopen_s) {
1559         win_skip("unicode file modes are not available, skipping setmode tests\n");
1560         return;
1561     }
1562
1563     fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1564     ok(fd != -1, "failed to open file\n");
1565
1566     errno = 0xdeadbeef;
1567     ret = _setmode(fd, 0xffffffff);
1568     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1569     ok(errno == EINVAL, "errno = %d\n", errno);
1570
1571     errno = 0xdeadbeef;
1572     ret = _setmode(fd, 0);
1573     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1574     ok(errno == EINVAL, "errno = %d\n", errno);
1575
1576     errno = 0xdeadbeef;
1577     ret = _setmode(fd, _O_BINARY|_O_TEXT);
1578     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1579     ok(errno == EINVAL, "errno = %d\n", errno);
1580
1581     errno = 0xdeadbeef;
1582     ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1583     ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1584     ok(errno == EINVAL, "errno = %d\n", errno);
1585
1586     ret = _setmode(fd, _O_BINARY);
1587     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1588
1589     ret = _setmode(fd, _O_WTEXT);
1590     ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1591
1592     ret = _setmode(fd, _O_TEXT);
1593     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1594
1595     ret = _setmode(fd, _O_U16TEXT);
1596     ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1597
1598     ret = _setmode(fd, _O_U8TEXT);
1599     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1600
1601     ret = _setmode(fd, _O_TEXT);
1602     ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1603
1604     _close(fd);
1605     _unlink(name);
1606 }
1607
1608 static void test_get_osfhandle(void)
1609 {
1610     int fd;
1611     char fname[] = "t_get_osfhanle";
1612     DWORD bytes_written;
1613     HANDLE handle;
1614
1615     fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1616     handle = (HANDLE)_get_osfhandle(fd);
1617     WriteFile(handle, "bar", 3, &bytes_written, NULL);
1618     _close(fd);
1619     fd = _open(fname, _O_RDONLY, 0);
1620     ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1621
1622     _close(fd);
1623     _unlink(fname);
1624 }
1625
1626 static void test_setmaxstdio(void)
1627 {
1628     ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1629     ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1630 }
1631
1632 static void test_stat(void)
1633 {
1634     int fd;
1635     int pipes[2];
1636     int ret;
1637     struct stat buf;
1638
1639     /* Tests for a file */
1640     fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1641     if (fd >= 0)
1642     {
1643         ret = fstat(fd, &buf);
1644         ok(!ret, "fstat failed: errno=%d\n", errno);
1645         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1646         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1647         ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1648         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1649         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1650         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1651
1652         ret = stat("stat.tst", &buf);
1653         ok(!ret, "stat failed: errno=%d\n", errno);
1654         ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1655         ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1656         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1657         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1658         ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1659
1660         errno = 0xdeadbeef;
1661         ret = stat("stat.tst\\", &buf);
1662         ok(ret == -1, "stat returned %d\n", ret);
1663         ok(errno == ENOENT, "errno = %d\n", errno);
1664
1665         close(fd);
1666         remove("stat.tst");
1667     }
1668     else
1669         skip("open failed with errno %d\n", errno);
1670
1671     /* Tests for a char device */
1672     if (_dup2(0, 10) == 0)
1673     {
1674         ret = fstat(10, &buf);
1675         ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1676         if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1677         {
1678             ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1679             ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1680             ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1681             ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1682         }
1683         else
1684             skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1685         close(10);
1686     }
1687     else
1688         skip("_dup2 failed with errno %d\n", errno);
1689
1690     /* Tests for pipes */
1691     if (_pipe(pipes, 1024, O_BINARY) == 0)
1692     {
1693         ret = fstat(pipes[0], &buf);
1694         ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1695         ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1696         ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1697         ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1698         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1699         close(pipes[0]);
1700         close(pipes[1]);
1701     }
1702     else
1703         skip("pipe failed with errno %d\n", errno);
1704
1705     /* Tests for directory */
1706     if(mkdir("stat.tst") == 0)
1707     {
1708         ret = stat("stat.tst                         ", &buf);
1709         ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1710         ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1711         ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1712         ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1713         ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1714
1715         errno = 0xdeadbeef;
1716         ret = stat("stat.tst\\ ", &buf);
1717         ok(ret == -1, "stat returned %d\n", ret);
1718         ok(errno == ENOENT, "errno = %d\n", errno);
1719         rmdir( "stat.tst" );
1720     }
1721     else
1722         skip("mkdir failed with errno %d\n", errno);
1723 }
1724
1725 static const char* pipe_string="Hello world";
1726
1727 /* How many messages to transfer over the pipe */
1728 #define N_TEST_MESSAGES 3
1729
1730 static void test_pipes_child(int argc, char** args)
1731 {
1732     int fd;
1733     int nwritten;
1734     int i;
1735
1736     if (argc < 5)
1737     {
1738         ok(0, "not enough parameters: %d\n", argc);
1739         return;
1740     }
1741
1742     fd=atoi(args[3]);
1743     i=close(fd);
1744     ok(!i, "unable to close %d: %d\n", fd, errno);
1745
1746     fd=atoi(args[4]);
1747
1748     for (i=0; i<N_TEST_MESSAGES; i++) {
1749        nwritten=write(fd, pipe_string, strlen(pipe_string));
1750        ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1751        /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1752        if (i < N_TEST_MESSAGES-1)
1753            Sleep(100);
1754     }
1755
1756     i=close(fd);
1757     ok(!i, "unable to close %d: %d\n", fd, errno);
1758 }
1759
1760 static void test_pipes(const char* selfname)
1761 {
1762     int pipes[2];
1763     char str_fdr[12], str_fdw[12];
1764     FILE* file;
1765     const char* arg_v[6];
1766     char buf[4096];
1767     char expected[4096];
1768     int r;
1769     int i;
1770
1771     /* Test reading from a pipe with read() */
1772     if (_pipe(pipes, 1024, O_BINARY) < 0)
1773     {
1774         ok(0, "pipe failed with errno %d\n", errno);
1775         return;
1776     }
1777
1778     arg_v[0] = selfname;
1779     arg_v[1] = "tests/file.c";
1780     arg_v[2] = "pipes";
1781     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1782     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1783     arg_v[5] = NULL;
1784     proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1785     i=close(pipes[1]);
1786     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1787
1788     for (i=0; i<N_TEST_MESSAGES; i++) {
1789        r=read(pipes[0], buf, sizeof(buf)-1);
1790        ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1791        if (r > 0)
1792            buf[r]='\0';
1793        ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1794    }
1795
1796     r=read(pipes[0], buf, sizeof(buf)-1);
1797     ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1798     i=close(pipes[0]);
1799     ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1800
1801     /* Test reading from a pipe with fread() */
1802     if (_pipe(pipes, 1024, O_BINARY) < 0)
1803     {
1804         ok(0, "pipe failed with errno %d\n", errno);
1805         return;
1806     }
1807
1808     arg_v[0] = selfname;
1809     arg_v[1] = "tests/file.c";
1810     arg_v[2] = "pipes";
1811     arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1812     arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1813     arg_v[5] = NULL;
1814     proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1815     i=close(pipes[1]);
1816     ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1817     file=fdopen(pipes[0], "r");
1818
1819     /* In blocking mode, fread will keep calling read() until it gets
1820      * enough bytes, or EOF, even on Unix.  (If this were a Unix terminal
1821      * in cooked mode instead of a pipe, it would also stop on EOL.)
1822      */
1823     expected[0] = 0;
1824     for (i=0; i<N_TEST_MESSAGES; i++)
1825        strcat(expected, pipe_string);
1826     r=fread(buf, 1, sizeof(buf)-1, file);
1827     ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1828     if (r > 0)
1829        buf[r]='\0';
1830     ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1831
1832     /* Let child close the file before we read, so we can sense EOF reliably */
1833     Sleep(100);
1834     r=fread(buf, 1, sizeof(buf)-1, file);
1835     ok(r == 0, "fread() returned %d instead of 0\n", r);
1836     ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1837     ok(feof(file), "feof() is false!\n");
1838
1839     i=fclose(file);
1840     ok(!i, "unable to close the pipe: %d\n", errno);
1841
1842     /* test \r handling when it's the last character read */
1843     if (_pipe(pipes, 1024, O_BINARY) < 0)
1844     {
1845         ok(0, "pipe failed with errno %d\n", errno);
1846         return;
1847     }
1848     r = write(pipes[1], "\r\n\rab", 5);
1849     ok(r == 5, "write returned %d, errno = %d\n", r, errno);
1850     setmode(pipes[0], O_TEXT);
1851     r = read(pipes[0], buf, 1);
1852     ok(r == 1, "read returned %d, expected 1\n", r);
1853     ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
1854     r = read(pipes[0], buf, 1);
1855     ok(r == 1, "read returned %d, expected 1\n", r);
1856     ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
1857     r = read(pipes[0], buf, 1);
1858     ok(r == 1, "read returned %d, expected 1\n", r);
1859     ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
1860     r = read(pipes[0], buf, 1);
1861     ok(r == 1, "read returned %d, expected 1\n", r);
1862     ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
1863
1864     if (p_fopen_s)
1865     {
1866         /* test utf16 read with insufficient data */
1867         r = write(pipes[1], "a\0b", 3);
1868         ok(r == 3, "write returned %d, errno = %d\n", r, errno);
1869         buf[2] = 'z';
1870         buf[3] = 'z';
1871         setmode(pipes[0], _O_WTEXT);
1872         r = read(pipes[0], buf, 4);
1873         ok(r == 2, "read returned %d, expected 2\n", r);
1874         ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
1875         r = write(pipes[1], "\0", 1);
1876         ok(r == 1, "write returned %d, errno = %d\n", r, errno);
1877         buf[0] = 'z';
1878         buf[1] = 'z';
1879         r = read(pipes[0], buf, 2);
1880         ok(r == 0, "read returned %d, expected 0\n", r);
1881         ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
1882     }
1883     else
1884     {
1885         win_skip("unicode mode tests on pipe\n");
1886     }
1887
1888     close(pipes[1]);
1889     close(pipes[0]);
1890 }
1891
1892 static void test_unlink(void)
1893 {
1894     FILE* file;
1895     ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1896     file = fopen("test_unlink\\empty", "w");
1897     ok(file != NULL, "unable to create test file\n");
1898     if(file)
1899       fclose(file);
1900     ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1901     unlink("test_unlink\\empty");
1902     rmdir("test_unlink");
1903 }
1904
1905 static void test_dup2(void)
1906 {
1907     ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1908 }
1909
1910 START_TEST(file)
1911 {
1912     int arg_c;
1913     char** arg_v;
1914
1915     init();
1916
1917     arg_c = winetest_get_mainargs( &arg_v );
1918
1919     /* testing low-level I/O */
1920     if (arg_c >= 3)
1921     {
1922         if (strcmp(arg_v[2], "inherit") == 0)
1923             test_file_inherit_child(arg_v[3]);
1924         else if (strcmp(arg_v[2], "inherit_no") == 0)
1925             test_file_inherit_child_no(arg_v[3]);
1926         else if (strcmp(arg_v[2], "pipes") == 0)
1927             test_pipes_child(arg_c, arg_v);
1928         else
1929             ok(0, "invalid argument '%s'\n", arg_v[2]);
1930         return;
1931     }
1932     test_dup2();
1933     test_file_inherit(arg_v[0]);
1934     test_file_write_read();
1935     test_chsize();
1936     test_stat();
1937     test_unlink();
1938
1939     /* testing stream I/O */
1940     test_filbuf();
1941     test_fdopen();
1942     test_fopen_fclose_fcloseall();
1943     test_fopen_s();
1944     test__wfopen_s();
1945     test_setmode();
1946     test_fileops();
1947     test_asciimode();
1948     test_asciimode2();
1949     test_filemodeT();
1950     test_readmode(FALSE); /* binary mode */
1951     test_readmode(TRUE);  /* ascii mode */
1952     test_readboundary();
1953     test_fgetc();
1954     test_fputc();
1955     test_flsbuf();
1956     test_fflush();
1957     test_fgetwc();
1958     test_ctrlz();
1959     test_file_put_get();
1960     test_tmpnam();
1961     test_get_osfhandle();
1962     test_setmaxstdio();
1963     test_pipes(arg_v[0]);
1964
1965     /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1966      * file contains lines in the correct order
1967      */
1968     WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);
1969 }