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";
110 static const int bufmodes[] = {_IOFBF,_IONBF};
112 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
113 write (fd, outbuffer, sizeof (outbuffer));
116 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
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]);
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]);
133 for (i = 0; i < sizeof(outbuffer); i++)
135 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
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]);
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]);
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");
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");
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");
182 unlink ("fdopen.tst");
185 #define IOMODE (ao?"ascii mode":"binary mode")
186 static void test_readmode( BOOL ascii_mode )
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];
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
204 j = (2*BUFSIZ-4)/strlen(padbuffer);
206 write (fd, padbuffer, strlen(padbuffer));
207 j = (2*BUFSIZ-4)%strlen(padbuffer);
209 write (fd, &padbuffer[i], 1);
210 write (fd, nlbuffer, strlen(nlbuffer));
211 write (fd, outbuffer, sizeof (outbuffer));
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 */
221 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
222 file = fdopen (fd, "rb");
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);
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;
237 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
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 */
244 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
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);
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);
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);
259 /* test fread across buffer boundary */
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);
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);
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);
269 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
273 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
275 if (ao && (*optr == '\r'))
278 /* fread should return the requested number of bytes if available */
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);
283 i=fread(buffer,1,j,file);
284 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
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);
297 /* test some additional functions */
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);
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;
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];
315 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
318 unlink ("fdopen.tst");
321 static void test_asciimode(void)
327 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
328 fp = fopen("ascii.tst", "wb");
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");
335 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
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 */
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");
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");
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);
359 fp = fopen("ascii.tst", "r");
361 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
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);
370 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
372 /* Show that fseek doesn't skip \\r !*/
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);
381 fseek(fp, 9*3 ,SEEK_SET);
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);
389 /* Show what happens if fseek positions filepointer on \\r */
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");
399 static void test_asciimode2(void)
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.
412 static const char obuf[] =
414 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
415 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
416 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
417 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
418 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
419 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
420 "000000000000000000\n"
421 "1111111111111111111";
423 fp = fopen("ascii2.tst", "wt");
424 fwrite(obuf, 1, sizeof(obuf), fp);
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");
434 unlink("ascii2.tst");
437 static void test_filemodeT(void)
439 char DATA [] = {26, 't', 'e', 's' ,'t'};
441 char temppath[MAX_PATH];
442 char tempfile[MAX_PATH];
446 WIN32_FIND_DATA findData;
449 GetTempPath (MAX_PATH, temppath);
450 GetTempFileName (temppath, "", 0, tempfile);
452 f = fopen(tempfile, "w+bDT");
453 bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
455 bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
458 ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
459 "fopen file mode 'T' wrongly interpreted as 't'\n" );
461 h = FindFirstFile(tempfile, &findData);
463 ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
465 if (h != INVALID_HANDLE_VALUE) FindClose(h);
468 static WCHAR* AtoW( const char* p )
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 );
477 /* Test reading in text mode when the 512'th character read is \r*/
478 static void test_readboundary(void)
481 char buf[513], rbuf[513];
483 for (i = 0; i < 511; i++)
485 j = (i%('~' - ' ')+ ' ');
490 fp = fopen("boundary.tst", "wt");
491 fwrite(buf, 512,1,fp);
493 fp = fopen("boundary.tst", "rt");
496 fseek(fp,0 , SEEK_CUR);
501 unlink("boundary.tst");
503 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
506 static void test_fgetc( void )
512 tempf=_tempnam(".","wne");
513 tempfh = fopen(tempf,"w+");
518 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
520 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
522 tempfh = fopen(tempf,"wt");
525 tempfh = fopen(tempf,"wt");
526 setbuf(tempfh, NULL);
528 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
534 static void test_fputc( void )
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);
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);
559 static void test_flsbuf( void )
566 static const int bufmodes[] = {_IOFBF,_IONBF};
568 tempf=_tempnam(".","wne");
569 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
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);
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",
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);
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... */
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);
613 /* And just for grins, make sure the file is correct */
614 tempfh = fopen(tempf,"r");
616 ok(c == 'Q', "first byte should be 'Q'\n");
618 ok(c == EOF, "there should only be one byte\n");
625 static void test_fflush( void )
627 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
628 char buf1[16], buf2[24];
633 tempf=_tempnam(".","wne");
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);
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);
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]);
655 /* fflush(NULL) doesn't clear input buffer. */
656 _lseek(_fileno(tempfh), 0, SEEK_SET);
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]);
663 /* _flushall() clears input buffer. */
664 _lseek(_fileno(tempfh), 0, SEEK_SET);
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]);
677 static void test_fgetwc( void )
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;
691 tempf=_tempnam(".","wne");
692 tempfh = fopen(tempf,"wb");
694 /* pad to almost the length of the internal buffer */
695 for (i=0; i<BUFSIZ-4; i++)
701 fputs(mytext,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);
708 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
709 fgetws(wtextW,LLEN,tempfh);
711 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
712 mytextW = AtoW (mytext);
715 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
717 diff_found |= (*aptr != *wptr);
719 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
720 ok(*wptr == '\n', "Carriage return was not skipped\n");
724 tempfh = fopen(tempf,"wb");
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
729 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
735 fputws(wtextW,tempfh);
736 fputws(wtextW,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);
743 j=(j-1)*sizeof(WCHAR);
744 ok(l==j, "ftell expected %d got %d\n", j, l);
746 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
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]);
755 ok(l==j, "ftell expected %d got %d\n", j, l);
756 for(i=0; i<strlen(mytext); i++)
758 /* the first time we get the string, it should be entirely within the local buffer */
759 fgetws(wtextW,LLEN,tempfh);
761 j += (strlen(mytext)-1)*sizeof(WCHAR);
762 ok(l==j, "ftell expected %d got %d\n", j, l);
766 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
768 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
769 diff_found |= (*aptr != *wptr);
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++)
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);
781 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
783 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
784 diff_found |= (*aptr != *wptr);
786 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
787 ok(*wptr == '\n', "Should get newline\n");
795 static void test_fputwc(void)
797 char temppath[MAX_PATH];
798 char tempfile[MAX_PATH];
803 GetTempPath (MAX_PATH, temppath);
804 GetTempFileName (temppath, "", 0, tempfile);
806 f = fopen(tempfile, "w");
807 ret = fputwc('a', f);
808 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
809 ret = fputwc('\n', f);
810 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
813 f = fopen(tempfile, "rb");
814 ret = fread(buf, 1, sizeof(buf), f);
815 ok(ret == 3, "fread returned %d, expected 3\n", ret);
816 ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
820 f = fopen(tempfile, "w,ccs=unicode");
821 ret = fputwc('a', f);
822 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
823 ret = fputwc('\n', f);
824 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
827 f = fopen(tempfile, "rb");
828 ret = fread(buf, 1, sizeof(buf), f);
829 ok(ret == 8, "fread returned %d, expected 8\n", ret);
830 ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
833 f = fopen(tempfile, "w,ccs=utf-8");
834 ret = fputwc('a', f);
835 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
836 ret = fputwc('\n', f);
837 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
840 f = fopen(tempfile, "rb");
841 ret = fread(buf, 1, sizeof(buf), f);
842 ok(ret == 6, "fread returned %d, expected 6\n", ret);
843 ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
846 win_skip("fputwc tests on unicode files\n");
852 static void test_ctrlz( void )
856 static const char mytext[]= "This is test_ctrlz";
861 tempf=_tempnam(".","wne");
862 tempfh = fopen(tempf,"wb");
863 fputs(mytext,tempfh);
864 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
873 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
874 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
877 ok(i==j, "returned string length expected %d got %d\n", j, i);
878 j+=4; /* ftell should indicate the true end of file */
880 ok(l==j, "ftell expected %d got %d\n", j, l);
881 ok(feof(tempfh), "did not get EOF\n");
884 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
885 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
887 j=strlen(mytext)+3; /* should get through newline */
888 ok(i==j, "returned string length expected %d got %d\n", j, i);
890 ok(l==j, "ftell expected %d got %d\n", j, l);
891 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
893 ok(i==1, "returned string length expected %d got %d\n", 1, i);
894 ok(feof(tempfh), "did not get EOF\n");
900 static void test_file_put_get( void )
904 static const char mytext[]= "This is a test_file_put_get\n";
905 static const char dostext[]= "This is a test_file_put_get\r\n";
907 WCHAR wtextW[LLEN+1];
908 WCHAR *mytextW = NULL, *aptr, *wptr;
909 BOOL diff_found = FALSE;
912 tempf=_tempnam(".","wne");
913 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
914 fputs(mytext,tempfh);
916 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
917 fgets(btext,LLEN,tempfh);
918 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
919 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
921 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
922 fputs(dostext,tempfh);
924 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
925 fgets(btext,LLEN,tempfh);
926 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
928 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
929 fgets(btext,LLEN,tempfh);
930 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
933 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
934 fgetws(wtextW,LLEN,tempfh);
935 mytextW = AtoW (mytext);
939 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
941 diff_found |= (*aptr != *wptr);
943 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
950 static void test_file_write_read( void )
954 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
955 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
959 tempf=_tempnam(".","wne");
960 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
961 _S_IREAD | _S_IWRITE);
963 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
964 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
965 "_write _O_BINARY bad return value\n");
967 i = lstrlenA(mytext);
968 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
969 ok(_read(tempfd,btext,i) == i,
970 "_read _O_BINARY got bad length\n");
971 ok( memcmp(dostext,btext,i) == 0,
972 "problems with _O_BINARY _write / _read\n");
974 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
975 ok(_read(tempfd,btext,i) == i-1,
976 "_read _O_TEXT got bad length\n");
977 ok( memcmp(mytext,btext,i-1) == 0,
978 "problems with _O_BINARY _write / _O_TEXT _read\n");
980 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
981 _S_IREAD | _S_IWRITE);
983 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
984 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
985 "_write _O_TEXT bad return value\n");
987 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
988 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
989 "_read _O_BINARY got bad length\n");
990 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
991 "problems with _O_TEXT _write / _O_BINARY _read\n");
992 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
994 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
995 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
996 "_read _O_TEXT got bad length\n");
997 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
998 "problems with _O_TEXT _write / _read\n");
1001 memset(btext, 0, LLEN);
1002 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1003 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1004 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1005 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1008 /* Test reading only \n or \r */
1009 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1010 _lseek(tempfd, -1, FILE_END);
1011 ret = _read(tempfd,btext,LLEN);
1012 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1013 _lseek(tempfd, -2, FILE_END);
1014 ret = _read(tempfd,btext,LLEN);
1015 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1016 _lseek(tempfd, -2, FILE_END);
1017 ret = _read(tempfd,btext,1);
1018 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1019 ret = read(tempfd,btext,1);
1020 ok(ret == 0, "_read returned %d, expected 0\n", ret);
1021 _lseek(tempfd, -3, FILE_END);
1022 ret = _read(tempfd,btext,1);
1023 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1024 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1025 _lseek(tempfd, -3, FILE_END);
1026 ret = _read(tempfd,btext,2);
1027 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1028 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1029 _lseek(tempfd, -3, FILE_END);
1030 ret = _read(tempfd,btext,3);
1031 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1032 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1035 ret = unlink(tempf);
1036 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1039 tempf=_tempnam(".","wne");
1040 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1042 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1043 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1044 "_write _O_BINARY bad return value\n");
1046 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1047 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1048 "_read _O_BINARY got bad length\n");
1049 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1050 "problems with _O_BINARY _write / _read\n");
1051 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1053 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1054 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1055 "_read _O_TEXT got bad length\n");
1056 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1057 "problems with _O_BINARY _write / _O_TEXT _read\n");
1060 /* test _read with single bytes. CR should be skipped and LF pulled in */
1061 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1062 for (i=0; i<strlen(mytext); i++) /* */
1064 _read(tempfd,btext, 1);
1065 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1067 while (_read(tempfd,btext, 1));
1070 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1071 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1072 i = _read(tempfd,btext, strlen(mytext));
1073 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1076 /* test read/write in unicode mode */
1079 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1080 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1081 ret = _write(tempfd, "a", 1);
1082 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1083 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1084 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1087 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1088 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1089 ret = _read(tempfd, btext, sizeof(btext));
1090 ok(ret == 10, "_read returned %d, expected 10\n", ret);
1091 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1094 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1095 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1097 ret = _read(tempfd, btext, 3);
1098 ok(ret == -1, "_read returned %d, expected -1\n", ret);
1099 ok(errno == 22, "errno = %d\n", errno);
1100 ret = _read(tempfd, btext, sizeof(btext));
1101 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1102 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1105 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1106 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1108 ret = _write(tempfd, "a", 1);
1109 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1110 ok(errno == 22, "errno = %d\n", errno);
1111 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1112 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1115 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1116 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1117 ret = _read(tempfd, btext, sizeof(btext));
1118 ok(ret == 7, "_read returned %d, expected 7\n", ret);
1119 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1122 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1123 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1124 ret = _read(tempfd, btext, sizeof(btext));
1125 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1126 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1128 /* when buffer is small read sometimes fails in native implementation */
1129 lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1130 ret = _read(tempfd, btext, 4);
1131 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1133 lseek(tempfd, 6, SEEK_SET);
1134 ret = _read(tempfd, btext, 2);
1135 ok(ret == 2, "_read returned %d, expected 2\n", ret);
1136 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1139 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1140 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1141 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1142 ok(ret == 12, "_write returned %d, expected 9\n", ret);
1145 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1146 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1147 ret = _read(tempfd, btext, sizeof(btext));
1148 ok(ret == 12, "_read returned %d, expected 12\n", ret);
1149 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1151 /* test invalid utf8 sequence */
1152 lseek(tempfd, 5, SEEK_SET);
1153 ret = _read(tempfd, btext, sizeof(btext));
1154 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1155 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1156 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1157 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1162 win_skip("unicode mode tests on file\n");
1165 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1167 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1168 ret = unlink(tempf);
1169 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1173 static void test_file_inherit_child(const char* fd_s)
1175 int fd = atoi(fd_s);
1179 ret =write(fd, "Success", 8);
1180 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1181 lseek(fd, 0, SEEK_SET);
1182 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1183 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1186 static void test_file_inherit_child_no(const char* fd_s)
1188 int fd = atoi(fd_s);
1191 ret = write(fd, "Success", 8);
1192 ok( ret == -1 && errno == EBADF,
1193 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1196 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1198 static BYTE block[1024];
1203 startup->lpReserved2 = block;
1204 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1205 wxflag_ptr = block + sizeof(unsigned);
1206 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1208 *(unsigned*)block = count;
1209 for (i = 0; i < count; i++)
1211 wxflag_ptr[i] = 0x81;
1212 handle_ptr[i] = handles[i];
1216 static const char *read_file( HANDLE file )
1218 static char buffer[128];
1220 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1221 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1226 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1231 SECURITY_ATTRIBUTES sa;
1232 PROCESS_INFORMATION proc;
1234 /* make file handle inheritable */
1235 sa.nLength = sizeof(sa);
1236 sa.lpSecurityDescriptor = NULL;
1237 sa.bInheritHandle = TRUE;
1239 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1240 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1241 startup->dwFlags = STARTF_USESTDHANDLES;
1242 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1243 startup->hStdOutput = hErrorFile;
1244 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1246 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1247 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1248 winetest_wait_child_process( proc.hProcess );
1250 data = read_file( hErrorFile );
1252 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1254 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1258 data = read_file( hstdout );
1260 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1262 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1265 CloseHandle( hErrorFile );
1266 DeleteFile( "fdopen.err" );
1269 static void test_file_inherit( const char* selfname )
1272 const char* arg_v[5];
1274 char cmdline[MAX_PATH];
1275 STARTUPINFO startup;
1276 SECURITY_ATTRIBUTES sa;
1279 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1280 ok(fd != -1, "Couldn't create test file\n");
1281 arg_v[0] = selfname;
1282 arg_v[1] = "tests/file.c";
1283 arg_v[2] = "inherit";
1284 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1286 _spawnvp(_P_WAIT, selfname, arg_v);
1287 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1288 lseek(fd, 0, SEEK_SET);
1289 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1291 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1293 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1294 ok(fd != -1, "Couldn't create test file\n");
1295 arg_v[0] = selfname;
1296 arg_v[1] = "tests/file.c";
1297 arg_v[2] = "inherit_no";
1298 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1300 _spawnvp(_P_WAIT, selfname, arg_v);
1301 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1302 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1304 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1306 /* make file handle inheritable */
1307 sa.nLength = sizeof(sa);
1308 sa.lpSecurityDescriptor = NULL;
1309 sa.bInheritHandle = TRUE;
1310 sprintf(cmdline, "%s file inherit 1", selfname);
1312 /* init an empty Reserved2, which should not be recognized as inherit-block */
1313 ZeroMemory(&startup, sizeof(STARTUPINFO));
1314 startup.cb = sizeof(startup);
1315 create_io_inherit_block( &startup, 0, NULL );
1316 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1318 /* test with valid inheritblock */
1319 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1320 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1321 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1322 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1323 create_io_inherit_block( &startup, 3, handles );
1324 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1325 CloseHandle( handles[1] );
1326 DeleteFile("fdopen.tst");
1328 /* test inherit block starting with unsigned zero */
1329 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1330 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1331 create_io_inherit_block( &startup, 3, handles );
1332 *(unsigned int *)startup.lpReserved2 = 0;
1333 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1334 CloseHandle( handles[1] );
1335 DeleteFile("fdopen.tst");
1337 /* test inherit block with smaller size */
1338 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1339 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1340 create_io_inherit_block( &startup, 3, handles );
1341 startup.cbReserved2 -= 3;
1342 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1343 CloseHandle( handles[1] );
1344 DeleteFile("fdopen.tst");
1346 /* test inherit block with even smaller size */
1347 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1348 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1349 create_io_inherit_block( &startup, 3, handles );
1350 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1351 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1352 CloseHandle( handles[1] );
1353 DeleteFile("fdopen.tst");
1355 /* test inherit block with larger size */
1356 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1357 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1358 create_io_inherit_block( &startup, 3, handles );
1359 startup.cbReserved2 += 7;
1360 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1361 CloseHandle( handles[1] );
1362 DeleteFile("fdopen.tst");
1365 static void test_tmpnam( void )
1367 char name[MAX_PATH] = "abc";
1371 ok(res != NULL, "tmpnam returned NULL\n");
1372 ok(res[0] == '\\', "first character is not a backslash\n");
1373 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1374 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1377 ok(res != NULL, "tmpnam returned NULL\n");
1378 ok(res == name, "supplied buffer was not used\n");
1379 ok(res[0] == '\\', "first character is not a backslash\n");
1380 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1381 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1384 static void test_chsize( void )
1387 LONG cur, pos, count;
1388 char temptext[] = "012345678";
1389 char *tempfile = _tempnam( ".", "tst" );
1391 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1393 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1394 ok( fd > 0, "Couldn't open test file\n" );
1396 count = _write( fd, temptext, sizeof(temptext) );
1397 ok( count > 0, "Couldn't write to test file\n" );
1399 /* get current file pointer */
1400 cur = _lseek( fd, 0, SEEK_CUR );
1402 /* make the file smaller */
1403 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1405 pos = _lseek( fd, 0, SEEK_CUR );
1406 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1407 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1409 /* enlarge the file */
1410 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1412 pos = _lseek( fd, 0, SEEK_CUR );
1413 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1414 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1417 _unlink( tempfile );
1421 static void test_fopen_fclose_fcloseall( void )
1423 char fname1[] = "empty1";
1424 char fname2[] = "empty2";
1425 char fname3[] = "empty3";
1426 FILE *stream1, *stream2, *stream3, *stream4;
1429 /* testing fopen() */
1430 stream1 = fopen(fname1, "w+");
1431 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1432 stream2 = fopen(fname2, "w ");
1433 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1435 stream3 = fopen(fname3, "r");
1436 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1437 stream3 = fopen(fname3, "w+");
1438 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1440 stream4 = fopen("", "w+");
1441 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1442 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1444 stream4 = fopen(NULL, "w+");
1445 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1446 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1448 /* testing fclose() */
1449 ret = fclose(stream2);
1450 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1451 ret = fclose(stream3);
1452 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1453 ret = fclose(stream2);
1454 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1455 ret = fclose(stream3);
1456 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1458 /* testing fcloseall() */
1459 numclosed = _fcloseall();
1460 /* fname1 should be closed here */
1461 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1462 numclosed = _fcloseall();
1463 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1465 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1466 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1467 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1470 static void test_fopen_s( void )
1472 const char name[] = "empty1";
1474 unsigned char *ubuff = (unsigned char*)buff;
1481 win_skip("Skipping fopen_s test\n");
1484 /* testing fopen_s */
1485 ret = p_fopen_s(&file, name, "w");
1486 ok(ret == 0, "fopen_s failed with %d\n", ret);
1487 ok(file != 0, "fopen_s failed to return value\n");
1488 fwrite(name, sizeof(name), 1, file);
1491 ok(ret != EOF, "File failed to close\n");
1493 file = fopen(name, "r");
1494 ok(file != 0, "fopen failed\n");
1495 len = fread(buff, 1, sizeof(name), file);
1496 ok(len == sizeof(name), "File length is %d\n", len);
1497 buff[sizeof(name)] = '\0';
1498 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1501 ok(ret != EOF, "File failed to close\n");
1503 ret = p_fopen_s(&file, name, "w, ccs=UNIcode");
1504 ok(ret == 0, "fopen_s failed with %d\n", ret);
1505 ret = fwrite("a", 1, 2, file);
1506 ok(ret == 2, "fwrite returned %d\n", ret);
1509 ret = p_fopen_s(&file, name, "r");
1510 ok(ret == 0, "fopen_s failed with %d\n", ret);
1511 len = fread(buff, 1, 2, file);
1512 ok(len == 2, "len = %d\n", len);
1513 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1514 ubuff[0], ubuff[1]);
1517 ret = p_fopen_s(&file, name, "r,ccs=unicode");
1518 ok(ret == 0, "fopen_s failed with %d\n", ret);
1519 len = fread(buff, 1, 2, file);
1520 ok(len == 2, "len = %d\n", len);
1521 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1522 ubuff[0], ubuff[1]);
1525 ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1526 ok(ret == 0, "fopen_s failed with %d\n", ret);
1527 len = fread(buff, 1, 2, file);
1528 ok(len == 2, "len = %d\n", len);
1529 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1530 ubuff[0], ubuff[1]);
1533 ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1534 ok(ret == 0, "fopen_s failed with %d\n", ret);
1535 len = fread(buff, 1, 2, file);
1536 ok(len == 2, "len = %d\n", len);
1537 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1538 ubuff[0], ubuff[1]);
1541 ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1542 ok(ret == 0, "fopen_s failed with %d\n", ret);
1545 ret = p_fopen_s(&file, name, "r");
1546 ok(ret == 0, "fopen_s failed with %d\n", ret);
1547 len = fread(buff, 1, 3, file);
1548 ok(len == 2, "len = %d\n", len);
1549 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1550 ubuff[0], ubuff[1]);
1553 ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1554 ok(ret == 0, "fopen_s failed with %d\n", ret);
1557 ret = p_fopen_s(&file, name, "r");
1558 ok(ret == 0, "fopen_s failed with %d\n", ret);
1559 len = fread(buff, 1, 4, file);
1560 ok(len == 3, "len = %d\n", len);
1561 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1562 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1563 ubuff[0], ubuff[1], ubuff[2]);
1566 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1569 static void test__wfopen_s( void )
1571 const char name[] = "empty1";
1572 const WCHAR wname[] = {
1573 'e','m','p','t','y','1',0
1575 const WCHAR wmode[] = {
1585 win_skip("Skipping _wfopen_s test\n");
1588 /* testing _wfopen_s */
1589 ret = p__wfopen_s(&file, wname, wmode);
1590 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1591 ok(file != 0, "_wfopen_s failed to return value\n");
1592 fwrite(name, sizeof(name), 1, file);
1595 ok(ret != EOF, "File failed to close\n");
1597 file = fopen(name, "r");
1598 ok(file != 0, "fopen failed\n");
1599 len = fread(buff, 1, sizeof(name), file);
1600 ok(len == sizeof(name), "File length is %d\n", len);
1601 buff[sizeof(name)] = '\0';
1602 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1605 ok(ret != EOF, "File failed to close\n");
1607 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1610 static void test_setmode(void)
1612 const char name[] = "empty1";
1616 win_skip("unicode file modes are not available, skipping setmode tests\n");
1620 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1621 ok(fd != -1, "failed to open file\n");
1624 ret = _setmode(fd, 0xffffffff);
1625 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1626 ok(errno == EINVAL, "errno = %d\n", errno);
1629 ret = _setmode(fd, 0);
1630 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1631 ok(errno == EINVAL, "errno = %d\n", errno);
1634 ret = _setmode(fd, _O_BINARY|_O_TEXT);
1635 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1636 ok(errno == EINVAL, "errno = %d\n", errno);
1639 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1640 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1641 ok(errno == EINVAL, "errno = %d\n", errno);
1643 ret = _setmode(fd, _O_BINARY);
1644 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1646 ret = _setmode(fd, _O_WTEXT);
1647 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1649 ret = _setmode(fd, _O_TEXT);
1650 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1652 ret = _setmode(fd, _O_U16TEXT);
1653 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1655 ret = _setmode(fd, _O_U8TEXT);
1656 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1658 ret = _setmode(fd, _O_TEXT);
1659 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1665 static void test_get_osfhandle(void)
1668 char fname[] = "t_get_osfhanle";
1669 DWORD bytes_written;
1672 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1673 handle = (HANDLE)_get_osfhandle(fd);
1674 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1676 fd = _open(fname, _O_RDONLY, 0);
1677 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1683 static void test_setmaxstdio(void)
1685 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1686 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1689 static void test_stat(void)
1696 /* Tests for a file */
1697 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1700 ret = fstat(fd, &buf);
1701 ok(!ret, "fstat failed: errno=%d\n", errno);
1702 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1703 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1704 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1705 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1706 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1707 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1709 ret = stat("stat.tst", &buf);
1710 ok(!ret, "stat failed: errno=%d\n", errno);
1711 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1712 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1713 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1714 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1715 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1718 ret = stat("stat.tst\\", &buf);
1719 ok(ret == -1, "stat returned %d\n", ret);
1720 ok(errno == ENOENT, "errno = %d\n", errno);
1726 skip("open failed with errno %d\n", errno);
1728 /* Tests for a char device */
1729 if (_dup2(0, 10) == 0)
1731 ret = fstat(10, &buf);
1732 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1733 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1735 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1736 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1737 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1738 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1741 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1745 skip("_dup2 failed with errno %d\n", errno);
1747 /* Tests for pipes */
1748 if (_pipe(pipes, 1024, O_BINARY) == 0)
1750 ret = fstat(pipes[0], &buf);
1751 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1752 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1753 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1754 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1755 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1760 skip("pipe failed with errno %d\n", errno);
1762 /* Tests for directory */
1763 if(mkdir("stat.tst") == 0)
1765 ret = stat("stat.tst ", &buf);
1766 ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1767 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1768 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1769 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1770 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1773 ret = stat("stat.tst\\ ", &buf);
1774 ok(ret == -1, "stat returned %d\n", ret);
1775 ok(errno == ENOENT, "errno = %d\n", errno);
1776 rmdir( "stat.tst" );
1779 skip("mkdir failed with errno %d\n", errno);
1782 static const char* pipe_string="Hello world";
1784 /* How many messages to transfer over the pipe */
1785 #define N_TEST_MESSAGES 3
1787 static void test_pipes_child(int argc, char** args)
1795 ok(0, "not enough parameters: %d\n", argc);
1801 ok(!i, "unable to close %d: %d\n", fd, errno);
1805 for (i=0; i<N_TEST_MESSAGES; i++) {
1806 nwritten=write(fd, pipe_string, strlen(pipe_string));
1807 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1808 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1809 if (i < N_TEST_MESSAGES-1)
1814 ok(!i, "unable to close %d: %d\n", fd, errno);
1817 static void test_pipes(const char* selfname)
1820 char str_fdr[12], str_fdw[12];
1822 const char* arg_v[6];
1824 char expected[4096];
1828 /* Test reading from a pipe with read() */
1829 if (_pipe(pipes, 1024, O_BINARY) < 0)
1831 ok(0, "pipe failed with errno %d\n", errno);
1835 arg_v[0] = selfname;
1836 arg_v[1] = "tests/file.c";
1838 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1839 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1841 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1843 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1845 for (i=0; i<N_TEST_MESSAGES; i++) {
1846 r=read(pipes[0], buf, sizeof(buf)-1);
1847 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1850 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1853 r=read(pipes[0], buf, sizeof(buf)-1);
1854 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1856 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1858 /* Test reading from a pipe with fread() */
1859 if (_pipe(pipes, 1024, O_BINARY) < 0)
1861 ok(0, "pipe failed with errno %d\n", errno);
1865 arg_v[0] = selfname;
1866 arg_v[1] = "tests/file.c";
1868 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1869 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1871 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1873 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1874 file=fdopen(pipes[0], "r");
1876 /* In blocking mode, fread will keep calling read() until it gets
1877 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1878 * in cooked mode instead of a pipe, it would also stop on EOL.)
1881 for (i=0; i<N_TEST_MESSAGES; i++)
1882 strcat(expected, pipe_string);
1883 r=fread(buf, 1, sizeof(buf)-1, file);
1884 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1887 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1889 /* Let child close the file before we read, so we can sense EOF reliably */
1891 r=fread(buf, 1, sizeof(buf)-1, file);
1892 ok(r == 0, "fread() returned %d instead of 0\n", r);
1893 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1894 ok(feof(file), "feof() is false!\n");
1897 ok(!i, "unable to close the pipe: %d\n", errno);
1899 /* test \r handling when it's the last character read */
1900 if (_pipe(pipes, 1024, O_BINARY) < 0)
1902 ok(0, "pipe failed with errno %d\n", errno);
1905 r = write(pipes[1], "\r\n\rab", 5);
1906 ok(r == 5, "write returned %d, errno = %d\n", r, errno);
1907 setmode(pipes[0], O_TEXT);
1908 r = read(pipes[0], buf, 1);
1909 ok(r == 1, "read returned %d, expected 1\n", r);
1910 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
1911 r = read(pipes[0], buf, 1);
1912 ok(r == 1, "read returned %d, expected 1\n", r);
1913 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
1914 r = read(pipes[0], buf, 1);
1915 ok(r == 1, "read returned %d, expected 1\n", r);
1916 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
1917 r = read(pipes[0], buf, 1);
1918 ok(r == 1, "read returned %d, expected 1\n", r);
1919 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
1923 /* test utf16 read with insufficient data */
1924 r = write(pipes[1], "a\0b", 3);
1925 ok(r == 3, "write returned %d, errno = %d\n", r, errno);
1928 setmode(pipes[0], _O_WTEXT);
1929 r = read(pipes[0], buf, 4);
1930 ok(r == 2, "read returned %d, expected 2\n", r);
1931 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
1932 r = write(pipes[1], "\0", 1);
1933 ok(r == 1, "write returned %d, errno = %d\n", r, errno);
1936 r = read(pipes[0], buf, 2);
1937 ok(r == 0, "read returned %d, expected 0\n", r);
1938 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
1942 win_skip("unicode mode tests on pipe\n");
1949 static void test_unlink(void)
1952 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1953 file = fopen("test_unlink\\empty", "w");
1954 ok(file != NULL, "unable to create test file\n");
1957 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1958 unlink("test_unlink\\empty");
1959 rmdir("test_unlink");
1962 static void test_dup2(void)
1964 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1974 arg_c = winetest_get_mainargs( &arg_v );
1976 /* testing low-level I/O */
1979 if (strcmp(arg_v[2], "inherit") == 0)
1980 test_file_inherit_child(arg_v[3]);
1981 else if (strcmp(arg_v[2], "inherit_no") == 0)
1982 test_file_inherit_child_no(arg_v[3]);
1983 else if (strcmp(arg_v[2], "pipes") == 0)
1984 test_pipes_child(arg_c, arg_v);
1986 ok(0, "invalid argument '%s'\n", arg_v[2]);
1990 test_file_inherit(arg_v[0]);
1991 test_file_write_read();
1996 /* testing stream I/O */
1999 test_fopen_fclose_fcloseall();
2007 test_readmode(FALSE); /* binary mode */
2008 test_readmode(TRUE); /* ascii mode */
2009 test_readboundary();
2017 test_file_put_get();
2019 test_get_osfhandle();
2021 test_pipes(arg_v[0]);
2023 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2024 * file contains lines in the correct order
2026 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);