2 * Unit test suite for file functions
4 * Copyright 2002 Bill Currie
5 * Copyright 2005 Paul Rupe
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.
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.
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
22 #include "wine/test.h"
37 static HANDLE proc_handles[2];
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*);
42 static void init(void)
44 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
46 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
47 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
50 static void test_filbuf( void )
56 fp = fopen("filbuf.tst", "wb");
57 fwrite("\n\n\n\n", 1, 4, fp);
60 fp = fopen("filbuf.tst", "rt");
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.
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");
81 static void test_fdopen( void )
83 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
88 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
89 write (fd, buffer, sizeof (buffer));
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");
98 unlink ("fdopen.tst");
101 static void test_fileops( void )
103 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
111 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
112 write (fd, outbuffer, sizeof (outbuffer));
115 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
116 file = fdopen (fd, "rb");
117 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
118 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
119 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
120 ok(feof(file) !=0,"feof doesn't signal EOF\n");
122 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
123 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size\n");
124 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
125 ok(strlen(buffer) == 1,"fgets dropped chars\n");
126 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
129 for (i = 0, c = EOF; i < sizeof(outbuffer); i++)
131 ok((c = fgetc(file)) == outbuffer[i], "fgetc returned wrong data\n");
133 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
134 ok(feof(file), "feof did not return EOF\n");
135 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF\n");
136 ok(feof(file), "feof after ungetc(EOF) did not return EOF\n");
137 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
138 c = outbuffer[sizeof(outbuffer) - 1];
139 ok(ungetc(c, file) == c, "ungetc did not return its input\n");
140 ok(!feof(file), "feof after ungetc returned EOF\n");
141 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF\n");
142 ok(c == outbuffer[sizeof(outbuffer) - 1],
143 "getc did not return ungetc'd data\n");
144 ok(!feof(file), "feof after getc returned EOF prematurely\n");
145 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
146 ok(feof(file), "feof after getc did not return EOF\n");
149 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
150 ok(pos == 0, "Unexpected result of fgetpos %x%08x\n", (DWORD)(pos >> 32), (DWORD)pos);
151 pos = sizeof (outbuffer);
152 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected\n");
153 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
154 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %x%08x\n", (DWORD)(pos >> 32), (DWORD)pos);
157 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
158 file = fdopen (fd, "rt"); /* open in TEXT mode */
159 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
160 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
161 ok(feof(file) !=0,"feof doesn't signal EOF\n");
163 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
164 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
165 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
166 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
169 file = fopen("fdopen.tst", "rb");
170 ok( file != NULL, "fopen failed\n");
171 /* sizeof(buffer) > content of file */
172 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
173 /* feof should be set now */
174 ok(feof(file), "feof after fread failed\n");
177 unlink ("fdopen.tst");
180 #define IOMODE (ao?"ascii mode":"binary mode")
181 static void test_readmode( BOOL ascii_mode )
183 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";
184 static const char padbuffer[] = "ghjghjghjghj";
185 static const char nlbuffer[] = "\r\n";
186 char buffer[2*BUFSIZ+256];
195 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
196 /* an internal buffer of BUFSIZ is maintained, so make a file big
197 * enough to test operations that cross the buffer boundary
199 j = (2*BUFSIZ-4)/strlen(padbuffer);
201 write (fd, padbuffer, strlen(padbuffer));
202 j = (2*BUFSIZ-4)%strlen(padbuffer);
204 write (fd, &padbuffer[i], 1);
205 write (fd, nlbuffer, strlen(nlbuffer));
206 write (fd, outbuffer, sizeof (outbuffer));
210 /* Open file in ascii mode */
211 fd = open ("fdopen.tst", O_RDONLY);
212 file = fdopen (fd, "r");
213 ao = -1; /* on offset to account for carriage returns */
216 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
217 file = fdopen (fd, "rb");
221 /* first is a test of fgets, ftell, fseek */
222 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
223 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
226 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
227 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
228 lstrlenA(buffer), pl+ao, IOMODE);
229 for (fp=0; fp<strlen(outbuffer); fp++)
230 if (outbuffer[fp] == '\n') break;
232 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
234 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
235 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
236 lstrlenA(buffer), fp+ao, IOMODE);
237 /* test a seek back across the buffer boundary */
239 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
241 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
242 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
244 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
245 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
246 lstrlenA(buffer), fp+ao, IOMODE);
247 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
250 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
251 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
252 lstrlenA(buffer), 2+ao, IOMODE);
254 /* test fread across buffer boundary */
256 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
257 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
259 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
260 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
262 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);
264 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
268 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
270 if (ao && (*optr == '\r'))
273 /* fread should return the requested number of bytes if available */
275 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
276 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
278 i=fread(buffer,1,j,file);
279 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
281 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
282 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
283 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
284 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
285 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
286 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
287 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
288 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
289 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
290 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
292 /* test some additional functions */
294 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
295 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
297 ip = (const int *)outbuffer;
298 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
299 for (fp=0; fp<strlen(outbuffer); fp++)
300 if (outbuffer[fp] == '\n') break;
302 /* this will cause the next _getw to cross carriage return characters */
303 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
304 for (i=0, j=0; i<6; i++) {
305 if (ao==0 || outbuffer[fp-3+i] != '\r')
306 buffer[j++] = outbuffer[fp-3+i];
310 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
313 unlink ("fdopen.tst");
316 static void test_asciimode(void)
322 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
323 fp = fopen("ascii.tst", "wb");
326 fp = fopen("ascii.tst", "rt");
327 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
328 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
330 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
334 /* Simple test of foo ^Z [more than one block] bar handling */
335 fp = fopen("ascii.tst", "wb");
336 fputs("foo\032", fp); /* foo, logical EOF, ... */
337 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
338 fputs("bar", fp); /* ... bar */
340 fp = fopen("ascii.tst", "rt");
341 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
342 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
343 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
345 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
346 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
349 /* Show ASCII mode handling*/
350 fp= fopen("ascii.tst","wb");
351 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
354 fp = fopen("ascii.tst", "r");
357 fseek(fp,0,SEEK_CUR);
358 for(i=1; i<10; i++) {
359 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
360 fseek(fp,0,SEEK_CUR);
361 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
364 /* Show that fseek doesn't skip \\r !*/
367 fseek(fp, 2 ,SEEK_CUR);
368 for(i=1; i<10; i++) {
369 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
370 fseek(fp, 2 ,SEEK_CUR);
372 fseek(fp, 9*3 ,SEEK_SET);
374 fseek(fp, -4 ,SEEK_CUR);
375 for(i= 8; i>=0; i--) {
376 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
377 fseek(fp, -4 ,SEEK_CUR);
379 /* Show what happens if fseek positions filepointer on \\r */
381 fp = fopen("ascii.tst", "r");
382 fseek(fp, 3 ,SEEK_SET);
383 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
389 static void test_asciimode2(void)
391 /* Error sequence from one app was getchar followed by small fread
392 * with one \r removed had last byte of buffer filled with
393 * next byte of *unbuffered* data rather than next byte from buffer
394 * Test case is a short string of one byte followed by a newline
395 * followed by filler to fill out the sector, then a sector of
396 * some different byte.
402 static const char obuf[] =
404 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
405 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
406 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
407 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
408 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
409 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
410 "000000000000000000\n"
411 "1111111111111111111";
413 fp = fopen("ascii2.tst", "wt");
414 fwrite(obuf, 1, sizeof(obuf), fp);
417 fp = fopen("ascii2.tst", "rt");
418 ok(getc(fp) == '0', "first char not 0\n");
419 memset(ibuf, 0, sizeof(ibuf));
420 i = fread(ibuf, 1, sizeof(ibuf), fp);
421 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
422 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
424 unlink("ascii2.tst");
427 static WCHAR* AtoW( const char* p )
430 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
431 buffer = malloc( len * sizeof(WCHAR) );
432 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
436 /* Test reading in text mode when the 512'th character read is \r*/
437 static void test_readboundary(void)
440 char buf[513], rbuf[513];
442 for (i = 0; i < 511; i++)
444 j = (i%('~' - ' ')+ ' ');
449 fp = fopen("boundary.tst", "wt");
450 fwrite(buf, 512,1,fp);
452 fp = fopen("boundary.tst", "rt");
455 fseek(fp,0 , SEEK_CUR);
460 unlink("boundary.tst");
462 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
465 static void test_fgetc( void )
471 tempf=_tempnam(".","wne");
472 tempfh = fopen(tempf,"w+");
477 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
479 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
481 tempfh = fopen(tempf,"wt");
484 tempfh = fopen(tempf,"wt");
485 setbuf(tempfh, NULL);
487 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
493 static void test_fputc( void )
499 tempf=_tempnam(".","wne");
500 tempfh = fopen(tempf,"wb");
501 ret = fputc(0,tempfh);
502 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
503 ret = fputc(0xff,tempfh);
504 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
505 ret = fputc(0xffffffff,tempfh);
506 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
509 tempfh = fopen(tempf,"rb");
510 ret = fputc(0,tempfh);
511 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
518 static void test_flsbuf( void )
525 static const int bufmodes[] = {_IOFBF,_IONBF};
527 tempf=_tempnam(".","wne");
528 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
530 tempfh = fopen(tempf,"wb");
531 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
532 ret = _flsbuf(0,tempfh);
533 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
534 bufmodes[bufmode], 0, ret);
535 ret = _flsbuf(0xff,tempfh);
536 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
537 bufmodes[bufmode], 0, ret);
538 ret = _flsbuf(0xffffffff,tempfh);
539 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
540 bufmodes[bufmode], 0, ret);
544 tempfh = fopen(tempf,"rb");
545 ret = _flsbuf(0,tempfh);
546 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
549 /* See bug 17123, exposed by WinAVR's make */
550 tempfh = fopen(tempf,"w");
551 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
552 setbuf(tempfh, NULL);
553 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
554 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
556 ret = _flsbuf('Q',tempfh);
557 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
558 /* ... and reset it to zero */
559 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
561 /* And just for grins, make sure the file is correct */
562 tempfh = fopen(tempf,"r");
564 ok(c == 'Q', "first byte should be 'Q'\n");
566 ok(c == EOF, "there should only be one byte\n");
573 static void test_fgetwc( void )
579 static const char mytext[]= "This is test_fgetwc\r\n";
580 WCHAR wtextW[BUFSIZ+LLEN+1];
581 WCHAR *mytextW = NULL, *aptr, *wptr;
582 BOOL diff_found = FALSE;
587 tempf=_tempnam(".","wne");
588 tempfh = fopen(tempf,"wb");
590 /* pad to almost the length of the internal buffer */
591 for (i=0; i<BUFSIZ-4; i++)
597 fputs(mytext,tempfh);
599 /* in text mode, getws/c expects multibyte characters */
600 /*currently Wine only supports plain ascii, and that is all that is tested here */
601 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
602 fgetws(wtextW,LLEN,tempfh);
604 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
605 fgetws(wtextW,LLEN,tempfh);
607 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
608 mytextW = AtoW (mytext);
611 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
613 diff_found |= (*aptr != *wptr);
615 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
616 ok(*wptr == '\n', "Carriage return was not skipped\n");
620 tempfh = fopen(tempf,"wb");
622 /* pad to almost the length of the internal buffer. Use an odd number of bytes
623 to test that we can read wchars that are split across the internal buffer
625 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
631 fputws(wtextW,tempfh);
632 fputws(wtextW,tempfh);
634 /* in binary mode, getws/c expects wide characters */
635 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
636 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
637 fgetws(wtextW,j,tempfh);
639 j=(j-1)*sizeof(WCHAR);
640 ok(l==j, "ftell expected %d got %d\n", j, l);
642 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
645 ok(l==j, "ftell expected %d got %d\n", j, l);
646 fgetws(wtextW,3,tempfh);
647 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
648 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
651 ok(l==j, "ftell expected %d got %d\n", j, l);
652 for(i=0; i<strlen(mytext); i++)
654 /* the first time we get the string, it should be entirely within the local buffer */
655 fgetws(wtextW,LLEN,tempfh);
657 j += (strlen(mytext)-1)*sizeof(WCHAR);
658 ok(l==j, "ftell expected %d got %d\n", j, l);
662 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
664 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
665 diff_found |= (*aptr != *wptr);
667 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
668 ok(*wptr == '\n', "Should get newline\n");
669 for(i=0; i<strlen(mytext); i++)
671 /* the second time we get the string, it should cross the local buffer boundary.
672 One of the wchars should be split across the boundary */
673 fgetws(wtextW,LLEN,tempfh);
677 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
679 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
680 diff_found |= (*aptr != *wptr);
682 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
683 ok(*wptr == '\n', "Should get newline\n");
691 static void test_ctrlz( void )
695 static const char mytext[]= "This is test_ctrlz";
700 tempf=_tempnam(".","wne");
701 tempfh = fopen(tempf,"wb");
702 fputs(mytext,tempfh);
703 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
712 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
713 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
716 ok(i==j, "returned string length expected %d got %d\n", j, i);
717 j+=4; /* ftell should indicate the true end of file */
719 ok(l==j, "ftell expected %d got %d\n", j, l);
720 ok(feof(tempfh), "did not get EOF\n");
723 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
724 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
726 j=strlen(mytext)+3; /* should get through newline */
727 ok(i==j, "returned string length expected %d got %d\n", j, i);
729 ok(l==j, "ftell expected %d got %d\n", j, l);
730 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
732 ok(i==1, "returned string length expected %d got %d\n", 1, i);
733 ok(feof(tempfh), "did not get EOF\n");
739 static void test_file_put_get( void )
743 static const char mytext[]= "This is a test_file_put_get\n";
744 static const char dostext[]= "This is a test_file_put_get\r\n";
746 WCHAR wtextW[LLEN+1];
747 WCHAR *mytextW = NULL, *aptr, *wptr;
748 BOOL diff_found = FALSE;
751 tempf=_tempnam(".","wne");
752 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
753 fputs(mytext,tempfh);
755 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
756 fgets(btext,LLEN,tempfh);
757 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
758 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
760 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
761 fputs(dostext,tempfh);
763 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
764 fgets(btext,LLEN,tempfh);
765 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
767 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
768 fgets(btext,LLEN,tempfh);
769 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
772 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
773 fgetws(wtextW,LLEN,tempfh);
774 mytextW = AtoW (mytext);
778 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
780 diff_found |= (*aptr != *wptr);
782 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
789 static void test_file_write_read( void )
793 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
794 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
798 tempf=_tempnam(".","wne");
799 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
800 _S_IREAD | _S_IWRITE);
802 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
803 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
804 "_write _O_BINARY bad return value\n");
806 i = lstrlenA(mytext);
807 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
808 ok(_read(tempfd,btext,i) == i,
809 "_read _O_BINARY got bad length\n");
810 ok( memcmp(dostext,btext,i) == 0,
811 "problems with _O_BINARY _write / _read\n");
813 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
814 ok(_read(tempfd,btext,i) == i-1,
815 "_read _O_TEXT got bad length\n");
816 ok( memcmp(mytext,btext,i-1) == 0,
817 "problems with _O_BINARY _write / _O_TEXT _read\n");
819 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
820 _S_IREAD | _S_IWRITE);
822 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
823 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
824 "_write _O_TEXT bad return value\n");
826 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
827 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
828 "_read _O_BINARY got bad length\n");
829 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
830 "problems with _O_TEXT _write / _O_BINARY _read\n");
831 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
833 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
834 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
835 "_read _O_TEXT got bad length\n");
836 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
837 "problems with _O_TEXT _write / _read\n");
840 memset(btext, 0, LLEN);
841 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
842 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
843 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
844 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
847 /* Test reading only \n or \r */
848 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
849 _lseek(tempfd, -1, FILE_END);
850 ret = _read(tempfd,btext,LLEN);
851 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
852 _lseek(tempfd, -2, FILE_END);
853 ret = _read(tempfd,btext,LLEN);
854 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
855 _lseek(tempfd, -3, FILE_END);
856 ret = _read(tempfd,btext,1);
857 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
858 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
859 _lseek(tempfd, -3, FILE_END);
860 ret = _read(tempfd,btext,2);
861 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
862 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
863 _lseek(tempfd, -3, FILE_END);
864 ret = _read(tempfd,btext,3);
865 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
866 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
870 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
873 tempf=_tempnam(".","wne");
874 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
876 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
877 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
878 "_write _O_BINARY bad return value\n");
880 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
881 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
882 "_read _O_BINARY got bad length\n");
883 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
884 "problems with _O_BINARY _write / _read\n");
885 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
887 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
888 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
889 "_read _O_TEXT got bad length\n");
890 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
891 "problems with _O_BINARY _write / _O_TEXT _read\n");
894 /* test _read with single bytes. CR should be skipped and LF pulled in */
895 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
896 for (i=0; i<strlen(mytext); i++) /* */
898 _read(tempfd,btext, 1);
899 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
901 while (_read(tempfd,btext, 1));
904 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
905 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
906 i = _read(tempfd,btext, strlen(mytext));
907 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
910 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
912 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
914 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
918 static void test_file_inherit_child(const char* fd_s)
924 ret =write(fd, "Success", 8);
925 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
926 lseek(fd, 0, SEEK_SET);
927 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
928 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
931 static void test_file_inherit_child_no(const char* fd_s)
936 ret = write(fd, "Success", 8);
937 ok( ret == -1 && errno == EBADF,
938 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
941 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
943 static BYTE block[1024];
948 startup->lpReserved2 = block;
949 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
950 wxflag_ptr = block + sizeof(unsigned);
951 handle_ptr = (HANDLE *)(wxflag_ptr + count);
953 *(unsigned*)block = count;
954 for (i = 0; i < count; i++)
956 wxflag_ptr[i] = 0x81;
957 handle_ptr[i] = handles[i];
961 static const char *read_file( HANDLE file )
963 static char buffer[128];
965 SetFilePointer( file, 0, NULL, FILE_BEGIN );
966 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
971 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
976 SECURITY_ATTRIBUTES sa;
977 PROCESS_INFORMATION proc;
979 /* make file handle inheritable */
980 sa.nLength = sizeof(sa);
981 sa.lpSecurityDescriptor = NULL;
982 sa.bInheritHandle = TRUE;
984 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
985 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
986 startup->dwFlags = STARTF_USESTDHANDLES;
987 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
988 startup->hStdOutput = hErrorFile;
989 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
991 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
992 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
993 winetest_wait_child_process( proc.hProcess );
995 data = read_file( hErrorFile );
997 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
999 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1003 data = read_file( hstdout );
1005 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1007 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1010 CloseHandle( hErrorFile );
1011 DeleteFile( "fdopen.err" );
1014 static void test_file_inherit( const char* selfname )
1017 const char* arg_v[5];
1019 char cmdline[MAX_PATH];
1020 STARTUPINFO startup;
1021 SECURITY_ATTRIBUTES sa;
1024 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1025 ok(fd != -1, "Couldn't create test file\n");
1026 arg_v[0] = selfname;
1027 arg_v[1] = "tests/file.c";
1028 arg_v[2] = "inherit";
1029 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1031 _spawnvp(_P_WAIT, selfname, arg_v);
1032 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1033 lseek(fd, 0, SEEK_SET);
1034 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1036 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1038 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1039 ok(fd != -1, "Couldn't create test file\n");
1040 arg_v[0] = selfname;
1041 arg_v[1] = "tests/file.c";
1042 arg_v[2] = "inherit_no";
1043 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1045 _spawnvp(_P_WAIT, selfname, arg_v);
1046 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1047 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1049 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1051 /* make file handle inheritable */
1052 sa.nLength = sizeof(sa);
1053 sa.lpSecurityDescriptor = NULL;
1054 sa.bInheritHandle = TRUE;
1055 sprintf(cmdline, "%s file inherit 1", selfname);
1057 /* init an empty Reserved2, which should not be recognized as inherit-block */
1058 ZeroMemory(&startup, sizeof(STARTUPINFO));
1059 startup.cb = sizeof(startup);
1060 create_io_inherit_block( &startup, 0, NULL );
1061 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1063 /* test with valid inheritblock */
1064 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1065 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1066 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1067 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1068 create_io_inherit_block( &startup, 3, handles );
1069 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1070 CloseHandle( handles[1] );
1071 DeleteFile("fdopen.tst");
1073 /* test inherit block starting with unsigned zero */
1074 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1075 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1076 create_io_inherit_block( &startup, 3, handles );
1077 *(unsigned int *)startup.lpReserved2 = 0;
1078 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1079 CloseHandle( handles[1] );
1080 DeleteFile("fdopen.tst");
1082 /* test inherit block with smaller size */
1083 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1084 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1085 create_io_inherit_block( &startup, 3, handles );
1086 startup.cbReserved2 -= 3;
1087 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1088 CloseHandle( handles[1] );
1089 DeleteFile("fdopen.tst");
1091 /* test inherit block with even smaller size */
1092 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1093 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1094 create_io_inherit_block( &startup, 3, handles );
1095 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1096 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1097 CloseHandle( handles[1] );
1098 DeleteFile("fdopen.tst");
1100 /* test inherit block with larger size */
1101 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1102 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1103 create_io_inherit_block( &startup, 3, handles );
1104 startup.cbReserved2 += 7;
1105 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1106 CloseHandle( handles[1] );
1107 DeleteFile("fdopen.tst");
1110 static void test_tmpnam( void )
1112 char name[MAX_PATH] = "abc";
1116 ok(res != NULL, "tmpnam returned NULL\n");
1117 ok(res[0] == '\\', "first character is not a backslash\n");
1118 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1119 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1122 ok(res != NULL, "tmpnam returned NULL\n");
1123 ok(res == name, "supplied buffer was not used\n");
1124 ok(res[0] == '\\', "first character is not a backslash\n");
1125 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1126 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1129 static void test_chsize( void )
1132 LONG cur, pos, count;
1133 char temptext[] = "012345678";
1134 char *tempfile = _tempnam( ".", "tst" );
1136 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1138 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1139 ok( fd > 0, "Couldn't open test file\n" );
1141 count = _write( fd, temptext, sizeof(temptext) );
1142 ok( count > 0, "Couldn't write to test file\n" );
1144 /* get current file pointer */
1145 cur = _lseek( fd, 0, SEEK_CUR );
1147 /* make the file smaller */
1148 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1150 pos = _lseek( fd, 0, SEEK_CUR );
1151 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1152 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1154 /* enlarge the file */
1155 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1157 pos = _lseek( fd, 0, SEEK_CUR );
1158 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1159 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1162 _unlink( tempfile );
1166 static void test_fopen_fclose_fcloseall( void )
1168 char fname1[] = "empty1";
1169 char fname2[] = "empty2";
1170 char fname3[] = "empty3";
1171 FILE *stream1, *stream2, *stream3, *stream4;
1174 /* testing fopen() */
1175 stream1 = fopen(fname1, "w+");
1176 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1177 stream2 = fopen(fname2, "w ");
1178 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1180 stream3 = fopen(fname3, "r");
1181 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1182 stream3 = fopen(fname3, "w+");
1183 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1185 stream4 = fopen("", "w+");
1186 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1187 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1189 stream4 = fopen(NULL, "w+");
1190 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1191 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1193 /* testing fclose() */
1194 ret = fclose(stream2);
1195 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1196 ret = fclose(stream3);
1197 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1198 ret = fclose(stream2);
1199 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1200 ret = fclose(stream3);
1201 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1203 /* testing fcloseall() */
1204 numclosed = _fcloseall();
1205 /* fname1 should be closed here */
1206 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1207 numclosed = _fcloseall();
1208 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1210 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1211 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1212 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1215 static void test_fopen_s( void )
1217 const char name[] = "empty1";
1225 win_skip("Skipping fopen_s test\n");
1228 /* testing fopen_s */
1229 ret = p_fopen_s(&file, name, "w");
1230 ok(ret == 0, "fopen_s failed with %d\n", ret);
1231 ok(file != 0, "fopen_s failed to return value\n");
1232 fwrite(name, sizeof(name), 1, file);
1235 ok(ret != EOF, "File failed to close\n");
1237 file = fopen(name, "r");
1238 ok(file != 0, "fopen failed\n");
1239 len = fread(buff, 1, sizeof(name), file);
1240 ok(len == sizeof(name), "File length is %d\n", len);
1241 buff[sizeof(name)] = '\0';
1242 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1245 ok(ret != EOF, "File failed to close\n");
1247 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1250 static void test__wfopen_s( void )
1252 const char name[] = "empty1";
1253 const WCHAR wname[] = {
1254 'e','m','p','t','y','1',0
1256 const WCHAR wmode[] = {
1266 win_skip("Skipping _wfopen_s test\n");
1269 /* testing _wfopen_s */
1270 ret = p__wfopen_s(&file, wname, wmode);
1271 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1272 ok(file != 0, "_wfopen_s failed to return value\n");
1273 fwrite(name, sizeof(name), 1, file);
1276 ok(ret != EOF, "File failed to close\n");
1278 file = fopen(name, "r");
1279 ok(file != 0, "fopen failed\n");
1280 len = fread(buff, 1, sizeof(name), file);
1281 ok(len == sizeof(name), "File length is %d\n", len);
1282 buff[sizeof(name)] = '\0';
1283 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1286 ok(ret != EOF, "File failed to close\n");
1288 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1291 static void test_get_osfhandle(void)
1294 char fname[] = "t_get_osfhanle";
1295 DWORD bytes_written;
1298 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1299 handle = (HANDLE)_get_osfhandle(fd);
1300 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1302 fd = _open(fname, _O_RDONLY, 0);
1303 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
1309 static void test_setmaxstdio(void)
1311 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1312 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1315 static void test_stat(void)
1321 /* Tests for a file */
1322 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1325 ok(fstat(fd, &buf) == 0, "fstat failed: errno=%d\n", errno);
1326 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1327 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1328 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1329 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1330 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1331 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1333 ok(stat("stat.tst", &buf) == 0, "stat failed: errno=%d\n", errno);
1334 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1335 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1336 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1337 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1338 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1344 skip("open failed with errno %d\n", errno);
1346 /* Tests for a char device */
1347 if (_dup2(0, 10) == 0)
1349 ok(fstat(10, &buf) == 0, "fstat(stdin) failed: errno=%d\n", errno);
1350 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1352 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1353 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1354 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1355 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1358 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1362 skip("_dup2 failed with errno %d\n", errno);
1364 /* Tests for pipes */
1365 if (_pipe(pipes, 1024, O_BINARY) == 0)
1367 ok(fstat(pipes[0], &buf) == 0, "fstat(pipe) failed: errno=%d\n", errno);
1368 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1369 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1370 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1371 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1376 skip("pipe failed with errno %d\n", errno);
1379 static const char* pipe_string="Hello world";
1381 /* How many messages to transfer over the pipe */
1382 #define N_TEST_MESSAGES 3
1384 static void test_pipes_child(int argc, char** args)
1392 ok(0, "not enough parameters: %d\n", argc);
1397 ok(close(fd) == 0, "unable to close %d: %d\n", fd, errno);
1401 for (i=0; i<N_TEST_MESSAGES; i++) {
1402 nwritten=write(fd, pipe_string, strlen(pipe_string));
1403 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1404 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1405 if (i < N_TEST_MESSAGES-1)
1409 ok(close(fd) == 0, "unable to close %d: %d\n", fd, errno);
1412 static void test_pipes(const char* selfname)
1415 char str_fdr[12], str_fdw[12];
1417 const char* arg_v[6];
1419 char expected[4096];
1423 /* Test reading from a pipe with read() */
1424 if (_pipe(pipes, 1024, O_BINARY) < 0)
1426 ok(0, "pipe failed with errno %d\n", errno);
1430 arg_v[0] = selfname;
1431 arg_v[1] = "tests/file.c";
1433 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1434 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1436 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1437 ok(close(pipes[1]) == 0, "unable to close %d: %d\n", pipes[1], errno);
1439 for (i=0; i<N_TEST_MESSAGES; i++) {
1440 r=read(pipes[0], buf, sizeof(buf)-1);
1441 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1444 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1447 r=read(pipes[0], buf, sizeof(buf)-1);
1448 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1449 ok(close(pipes[0]) == 0, "unable to close %d: %d\n", pipes[0], errno);
1451 /* Test reading from a pipe with fread() */
1452 if (_pipe(pipes, 1024, O_BINARY) < 0)
1454 ok(0, "pipe failed with errno %d\n", errno);
1458 arg_v[0] = selfname;
1459 arg_v[1] = "tests/file.c";
1461 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1462 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1464 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1465 ok(close(pipes[1]) == 0, "unable to close %d: %d\n", pipes[1], errno);
1466 file=fdopen(pipes[0], "r");
1468 /* In blocking mode, fread will keep calling read() until it gets
1469 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1470 * in cooked mode instead of a pipe, it would also stop on EOL.)
1473 for (i=0; i<N_TEST_MESSAGES; i++)
1474 strcat(expected, pipe_string);
1475 r=fread(buf, 1, sizeof(buf)-1, file);
1476 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1479 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1481 /* Let child close the file before we read, so we can sense EOF reliably */
1483 r=fread(buf, 1, sizeof(buf)-1, file);
1484 ok(r == 0, "fread() returned %d instead of 0\n", r);
1485 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1486 ok(feof(file), "feof() is false!\n");
1488 ok(fclose(file) == 0, "unable to close the pipe: %d\n", errno);
1491 static void test_unlink(void)
1494 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1495 file = fopen("test_unlink\\empty", "w");
1496 ok(file != NULL, "unable to create test file\n");
1499 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1500 unlink("test_unlink\\empty");
1501 rmdir("test_unlink");
1504 static void test_dup2(void)
1506 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1516 arg_c = winetest_get_mainargs( &arg_v );
1518 /* testing low-level I/O */
1521 if (strcmp(arg_v[2], "inherit") == 0)
1522 test_file_inherit_child(arg_v[3]);
1523 else if (strcmp(arg_v[2], "inherit_no") == 0)
1524 test_file_inherit_child_no(arg_v[3]);
1525 else if (strcmp(arg_v[2], "pipes") == 0)
1526 test_pipes_child(arg_c, arg_v);
1528 ok(0, "invalid argument '%s'\n", arg_v[2]);
1532 test_file_inherit(arg_v[0]);
1533 test_file_write_read();
1538 /* testing stream I/O */
1541 test_fopen_fclose_fcloseall();
1547 test_readmode(FALSE); /* binary mode */
1548 test_readmode(TRUE); /* ascii mode */
1549 test_readboundary();
1555 test_file_put_get();
1557 test_get_osfhandle();
1559 test_pipes(arg_v[0]);
1561 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1562 * file contains lines in the correct order
1564 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);