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"
38 static HANDLE proc_handles[2];
40 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
41 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
43 static void init(void)
45 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
47 setlocale(LC_CTYPE, "C");
49 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
50 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
53 static void test_filbuf( void )
59 fp = fopen("filbuf.tst", "wb");
60 fwrite("\n\n\n\n", 1, 4, fp);
63 fp = fopen("filbuf.tst", "rt");
65 ok(c == '\n', "read wrong byte\n");
66 /* See bug 16970 for why we care about _filbuf.
67 * ftell returns screwy values on files with lots
68 * of bare LFs in ascii mode because it assumes
69 * that ascii files contain only CRLFs, removes
70 * the CR's early in _filbuf, and adjusts the return
71 * value of ftell to compensate.
72 * native _filbuf will read the whole file, then consume and return
73 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
74 * pointing to a buffer of three bare LFs, so
75 * ftell will return 4 - 3 - 3 = -2.
77 ok(ftell(fp) == -2, "ascii crlf removal does not match native\n");
78 ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n");
79 ok(pos == -2, "ftell does not match fgetpos\n");
84 static void test_fdopen( void )
86 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
91 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
92 write (fd, buffer, sizeof (buffer));
95 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
96 lseek (fd, 5, SEEK_SET);
97 file = fdopen (fd, "rb");
98 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
99 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
101 unlink ("fdopen.tst");
104 static void test_fileops( void )
106 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
113 static const int bufmodes[] = {_IOFBF,_IONBF};
115 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
116 write (fd, outbuffer, sizeof (outbuffer));
119 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
121 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
122 file = fdopen (fd, "rb");
123 setvbuf(file,NULL,bufmodes[bufmode],2048);
124 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
125 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
126 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
127 ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
129 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
130 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]);
131 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
132 ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]);
133 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]);
136 for (i = 0; i < sizeof(outbuffer); i++)
138 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
140 ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
141 ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
142 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
143 ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
144 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
145 c = outbuffer[sizeof(outbuffer) - 1];
146 ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]);
147 ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
148 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
149 ok(c == outbuffer[sizeof(outbuffer) - 1],
150 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]);
151 ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]);
152 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
153 ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
156 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
157 ok(pos == 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
158 pos = sizeof (outbuffer);
159 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
160 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
161 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
165 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
166 file = fdopen (fd, "rt"); /* open in TEXT mode */
167 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
168 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
169 ok(feof(file) !=0,"feof doesn't signal EOF\n");
171 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
172 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
173 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
174 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
177 file = fopen("fdopen.tst", "rb");
178 ok( file != NULL, "fopen failed\n");
179 /* sizeof(buffer) > content of file */
180 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
181 /* feof should be set now */
182 ok(feof(file), "feof after fread failed\n");
185 unlink ("fdopen.tst");
188 #define IOMODE (ao?"ascii mode":"binary mode")
189 static void test_readmode( BOOL ascii_mode )
191 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";
192 static const char padbuffer[] = "ghjghjghjghj";
193 static const char nlbuffer[] = "\r\n";
194 char buffer[2*BUFSIZ+256];
203 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
204 /* an internal buffer of BUFSIZ is maintained, so make a file big
205 * enough to test operations that cross the buffer boundary
207 j = (2*BUFSIZ-4)/strlen(padbuffer);
209 write (fd, padbuffer, strlen(padbuffer));
210 j = (2*BUFSIZ-4)%strlen(padbuffer);
212 write (fd, &padbuffer[i], 1);
213 write (fd, nlbuffer, strlen(nlbuffer));
214 write (fd, outbuffer, sizeof (outbuffer));
218 /* Open file in ascii mode */
219 fd = open ("fdopen.tst", O_RDONLY);
220 file = fdopen (fd, "r");
221 ao = -1; /* on offset to account for carriage returns */
224 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
225 file = fdopen (fd, "rb");
229 /* first is a test of fgets, ftell, fseek */
230 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
231 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
234 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
235 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
236 lstrlenA(buffer), pl+ao, IOMODE);
237 for (fp=0; fp<strlen(outbuffer); fp++)
238 if (outbuffer[fp] == '\n') break;
240 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
242 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
243 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
244 lstrlenA(buffer), fp+ao, IOMODE);
245 /* test a seek back across the buffer boundary */
247 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
249 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
250 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
252 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
253 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
254 lstrlenA(buffer), fp+ao, IOMODE);
255 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
258 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
259 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
260 lstrlenA(buffer), 2+ao, IOMODE);
262 /* test fread across buffer boundary */
264 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
265 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
267 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
268 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
270 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);
272 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
276 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
278 if (ao && (*optr == '\r'))
281 /* fread should return the requested number of bytes if available */
283 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
284 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
286 i=fread(buffer,1,j,file);
287 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
289 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
290 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
291 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
292 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
293 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
294 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
295 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
296 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
297 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
298 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
300 /* test some additional functions */
302 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
303 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
305 ip = (const int *)outbuffer;
306 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
307 for (fp=0; fp<strlen(outbuffer); fp++)
308 if (outbuffer[fp] == '\n') break;
310 /* this will cause the next _getw to cross carriage return characters */
311 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
312 for (i=0, j=0; i<6; i++) {
313 if (ao==0 || outbuffer[fp-3+i] != '\r')
314 buffer[j++] = outbuffer[fp-3+i];
318 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
321 unlink ("fdopen.tst");
324 static void test_asciimode(void)
330 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
331 fp = fopen("ascii.tst", "wb");
334 fp = fopen("ascii.tst", "rt");
335 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
336 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
338 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
342 /* Simple test of foo ^Z [more than one block] bar handling */
343 fp = fopen("ascii.tst", "wb");
344 fputs("foo\032", fp); /* foo, logical EOF, ... */
345 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
346 fputs("bar", fp); /* ... bar */
348 fp = fopen("ascii.tst", "rt");
349 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
350 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
351 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
353 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
354 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
357 /* Show ASCII mode handling*/
358 fp= fopen("ascii.tst","wb");
359 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
362 fp = fopen("ascii.tst", "r");
364 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
366 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
367 fseek(fp,0,SEEK_CUR);
368 for(i=1; i<10; i++) {
369 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
370 fseek(fp,0,SEEK_CUR);
371 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
373 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
375 /* Show that fseek doesn't skip \\r !*/
378 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
379 fseek(fp, 2 ,SEEK_CUR);
380 for(i=1; i<10; i++) {
381 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
382 fseek(fp, 2 ,SEEK_CUR);
384 fseek(fp, 9*3 ,SEEK_SET);
386 ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c);
387 fseek(fp, -4 ,SEEK_CUR);
388 for(i= 8; i>=0; i--) {
389 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
390 fseek(fp, -4 ,SEEK_CUR);
392 /* Show what happens if fseek positions filepointer on \\r */
394 fp = fopen("ascii.tst", "r");
395 fseek(fp, 3 ,SEEK_SET);
396 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
402 static void test_asciimode2(void)
404 /* Error sequence from one app was getchar followed by small fread
405 * with one \r removed had last byte of buffer filled with
406 * next byte of *unbuffered* data rather than next byte from buffer
407 * Test case is a short string of one byte followed by a newline
408 * followed by filler to fill out the sector, then a sector of
409 * some different byte.
415 static const char obuf[] =
417 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
418 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
419 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
420 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
421 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
422 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
423 "000000000000000000\n"
424 "1111111111111111111";
426 fp = fopen("ascii2.tst", "wt");
427 fwrite(obuf, 1, sizeof(obuf), fp);
430 fp = fopen("ascii2.tst", "rt");
431 ok(getc(fp) == '0', "first char not 0\n");
432 memset(ibuf, 0, sizeof(ibuf));
433 i = fread(ibuf, 1, sizeof(ibuf), fp);
434 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
435 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
437 unlink("ascii2.tst");
440 static void test_filemodeT(void)
442 char DATA [] = {26, 't', 'e', 's' ,'t'};
444 char temppath[MAX_PATH];
445 char tempfile[MAX_PATH];
449 WIN32_FIND_DATA findData;
452 GetTempPath (MAX_PATH, temppath);
453 GetTempFileName (temppath, "", 0, tempfile);
455 f = fopen(tempfile, "w+bDT");
456 bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
458 bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
461 ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
462 "fopen file mode 'T' wrongly interpreted as 't'\n" );
464 h = FindFirstFile(tempfile, &findData);
466 ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
468 if (h != INVALID_HANDLE_VALUE) FindClose(h);
471 static WCHAR* AtoW( const char* p )
474 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
475 buffer = malloc( len * sizeof(WCHAR) );
476 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
480 /* Test reading in text mode when the 512'th character read is \r*/
481 static void test_readboundary(void)
484 char buf[513], rbuf[513];
486 for (i = 0; i < 511; i++)
488 j = (i%('~' - ' ')+ ' ');
493 fp = fopen("boundary.tst", "wt");
494 fwrite(buf, 512,1,fp);
496 fp = fopen("boundary.tst", "rt");
499 fseek(fp,0 , SEEK_CUR);
504 unlink("boundary.tst");
506 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
509 static void test_fgetc( void )
515 tempf=_tempnam(".","wne");
516 tempfh = fopen(tempf,"w+");
521 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
523 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
525 tempfh = fopen(tempf,"wt");
528 tempfh = fopen(tempf,"wt");
529 setbuf(tempfh, NULL);
531 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
537 static void test_fputc( void )
543 tempf=_tempnam(".","wne");
544 tempfh = fopen(tempf,"wb");
545 ret = fputc(0,tempfh);
546 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
547 ret = fputc(0xff,tempfh);
548 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
549 ret = fputc(0xffffffff,tempfh);
550 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
553 tempfh = fopen(tempf,"rb");
554 ret = fputc(0,tempfh);
555 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
562 static void test_flsbuf( void )
569 static const int bufmodes[] = {_IOFBF,_IONBF};
571 tempf=_tempnam(".","wne");
572 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
574 tempfh = fopen(tempf,"wb");
575 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
576 ret = _flsbuf(0,tempfh);
577 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
578 bufmodes[bufmode], 0, ret);
579 ret = _flsbuf(0xff,tempfh);
580 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
581 bufmodes[bufmode], 0xff, ret);
582 ret = _flsbuf(0xffffffff,tempfh);
583 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
584 bufmodes[bufmode], 0xff, ret);
588 tempfh->_base[1] = 'a';
589 ret = _flsbuf(0xab,tempfh);
590 ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
591 bufmodes[bufmode], ret);
592 ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
599 tempfh = fopen(tempf,"rb");
600 ret = _flsbuf(0,tempfh);
601 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
604 /* See bug 17123, exposed by WinAVR's make */
605 tempfh = fopen(tempf,"w");
606 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
607 setbuf(tempfh, NULL);
608 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
609 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
611 ret = _flsbuf('Q',tempfh);
612 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
613 /* ... and reset it to zero */
614 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
616 /* And just for grins, make sure the file is correct */
617 tempfh = fopen(tempf,"r");
619 ok(c == 'Q', "first byte should be 'Q'\n");
621 ok(c == EOF, "there should only be one byte\n");
628 static void test_fflush( void )
630 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
631 char buf1[16], buf2[24];
636 tempf=_tempnam(".","wne");
638 /* Prepare the file. */
639 tempfh = fopen(tempf,"wb");
640 ok(tempfh != NULL, "Can't open test file.\n");
641 fwrite(obuf, 1, sizeof(obuf), tempfh);
644 /* Open the file for input. */
645 tempfh = fopen(tempf,"rb");
646 ok(tempfh != NULL, "Can't open test file.\n");
647 fread(buf1, 1, sizeof(buf1), tempfh);
649 /* Using fflush() on input stream is undefined in ANSI.
650 * But MSDN says that it clears input buffer. */
651 _lseek(_fileno(tempfh), 0, SEEK_SET);
652 ret = fflush(tempfh);
653 ok(ret == 0, "expected 0, got %d\n", ret);
654 memset(buf2, '?', sizeof(buf2));
655 fread(buf2, 1, sizeof(buf2), tempfh);
656 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
658 /* fflush(NULL) doesn't clear input buffer. */
659 _lseek(_fileno(tempfh), 0, SEEK_SET);
661 ok(ret == 0, "expected 0, got %d\n", ret);
662 memset(buf2, '?', sizeof(buf2));
663 fread(buf2, 1, sizeof(buf2), tempfh);
664 ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]);
666 /* _flushall() clears input buffer. */
667 _lseek(_fileno(tempfh), 0, SEEK_SET);
669 ok(ret >= 0, "unexpected ret %d\n", ret);
670 memset(buf2, '?', sizeof(buf2));
671 fread(buf2, 1, sizeof(buf2), tempfh);
672 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
680 static void test_fgetwc( void )
686 static const char mytext[]= "This is test_fgetwc\r\n";
687 WCHAR wtextW[BUFSIZ+LLEN+1];
688 WCHAR *mytextW = NULL, *aptr, *wptr;
689 BOOL diff_found = FALSE;
694 tempf=_tempnam(".","wne");
695 tempfh = fopen(tempf,"wb");
697 /* pad to almost the length of the internal buffer */
698 for (i=0; i<BUFSIZ-4; i++)
704 fputs(mytext,tempfh);
706 /* in text mode, getws/c expects multibyte characters */
707 /*currently Wine only supports plain ascii, and that is all that is tested here */
708 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
709 fgetws(wtextW,LLEN,tempfh);
711 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
712 fgetws(wtextW,LLEN,tempfh);
714 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
715 mytextW = AtoW (mytext);
718 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
720 diff_found |= (*aptr != *wptr);
722 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
723 ok(*wptr == '\n', "Carriage return was not skipped\n");
727 tempfh = fopen(tempf,"wb");
729 /* pad to almost the length of the internal buffer. Use an odd number of bytes
730 to test that we can read wchars that are split across the internal buffer
732 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
738 fputws(wtextW,tempfh);
739 fputws(wtextW,tempfh);
741 /* in binary mode, getws/c expects wide characters */
742 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
743 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
744 fgetws(wtextW,j,tempfh);
746 j=(j-1)*sizeof(WCHAR);
747 ok(l==j, "ftell expected %d got %d\n", j, l);
749 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
752 ok(l==j, "ftell expected %d got %d\n", j, l);
753 fgetws(wtextW,3,tempfh);
754 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
755 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
758 ok(l==j, "ftell expected %d got %d\n", j, l);
759 for(i=0; i<strlen(mytext); i++)
761 /* the first time we get the string, it should be entirely within the local buffer */
762 fgetws(wtextW,LLEN,tempfh);
764 j += (strlen(mytext)-1)*sizeof(WCHAR);
765 ok(l==j, "ftell expected %d got %d\n", j, l);
769 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
771 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
772 diff_found |= (*aptr != *wptr);
774 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
775 ok(*wptr == '\n', "Should get newline\n");
776 for(i=0; i<strlen(mytext); i++)
778 /* the second time we get the string, it should cross the local buffer boundary.
779 One of the wchars should be split across the boundary */
780 fgetws(wtextW,LLEN,tempfh);
784 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
786 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
787 diff_found |= (*aptr != *wptr);
789 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
790 ok(*wptr == '\n', "Should get newline\n");
798 static void test_fgetwc_locale(const char* text, const char* locale, int codepage)
800 char temppath[MAX_PATH], tempfile[MAX_PATH];
802 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
803 WCHAR wtextW[BUFSIZ];
807 if (!setlocale(LC_CTYPE, locale))
809 win_skip("%s locale not available\n", locale);
813 GetTempPath(MAX_PATH, temppath);
814 GetTempFileName(temppath, "", 0, tempfile);
816 tempfh = fopen(tempfile, "wb");
817 ok(tempfh != NULL, "can't open tempfile\n");
818 fwrite(text, 1, strlen(text), tempfh);
823 /* mbstowcs rejects invalid multibyte sequence,
824 so we use MultiByteToWideChar here. */
825 ret = MultiByteToWideChar(codepage, 0, text, -1,
826 wtextW, sizeof(wtextW)/sizeof(wtextW[0]));
827 ok(ret > 0, "MultiByteToWideChar failed\n");
833 for (p = text; *p != '\0'; p++)
834 wtextW[ret++] = (unsigned char)*p;
838 tempfh = fopen(tempfile, "rt");
839 ok(tempfh != NULL, "can't open tempfile\n");
841 for (i = 0; i < ret-1; i++)
844 ok(ch == wtextW[i], "got %04hx, expected %04hx (cp%d[%d])\n", ch, wtextW[i], codepage, i);
847 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
850 tempfh = fopen(tempfile, "wb");
851 ok(tempfh != NULL, "can't open tempfile\n");
852 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
855 tempfh = fopen(tempfile, "rb");
856 ok(tempfh != NULL, "can't open tempfile\n");
857 for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
860 ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
863 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage);
868 static void test_fgetwc_unicode(void)
870 char temppath[MAX_PATH], tempfile[MAX_PATH];
872 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' };
873 char utf8_text[BUFSIZ];
877 GetTempPath(MAX_PATH, temppath);
878 GetTempFileName(temppath, "", 0, tempfile);
882 win_skip("fopen_s not available\n");
886 tempfh = fopen(tempfile, "wb");
887 ok(tempfh != NULL, "can't open tempfile\n");
888 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh);
891 tempfh = fopen(tempfile, "rt,ccs=unicode");
892 ok(tempfh != NULL, "can't open tempfile\n");
893 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
896 ok(ch == wchar_text[i],
897 "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1);
900 ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch);
903 tempfh = fopen(tempfile, "wb");
904 ok(tempfh != NULL, "can't open tempfile\n");
905 ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]),
906 utf8_text, sizeof(utf8_text), NULL, NULL);
907 ok(ret > 0, "utf-8 conversion failed\n");
908 fwrite(utf8_text, sizeof(char), ret, tempfh);
911 tempfh = fopen(tempfile, "rt, ccs=UTF-8");
912 ok(tempfh != NULL, "can't open tempfile\n");
913 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
916 ok(ch == wchar_text[i],
917 "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1);
920 ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch);
925 static void test_fputwc(void)
927 char temppath[MAX_PATH];
928 char tempfile[MAX_PATH];
933 GetTempPath (MAX_PATH, temppath);
934 GetTempFileName (temppath, "", 0, tempfile);
936 f = fopen(tempfile, "w");
937 ret = fputwc('a', f);
938 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
939 ret = fputwc('\n', f);
940 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
943 f = fopen(tempfile, "rb");
944 ret = fread(buf, 1, sizeof(buf), f);
945 ok(ret == 3, "fread returned %d, expected 3\n", ret);
946 ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n");
950 f = fopen(tempfile, "w,ccs=unicode");
951 ret = fputwc('a', f);
952 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
953 ret = fputwc('\n', f);
954 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
957 f = fopen(tempfile, "rb");
958 ret = fread(buf, 1, sizeof(buf), f);
959 ok(ret == 8, "fread returned %d, expected 8\n", ret);
960 ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
963 f = fopen(tempfile, "w,ccs=utf-8");
964 ret = fputwc('a', f);
965 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret);
966 ret = fputwc('\n', f);
967 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret);
970 f = fopen(tempfile, "rb");
971 ret = fread(buf, 1, sizeof(buf), f);
972 ok(ret == 6, "fread returned %d, expected 6\n", ret);
973 ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
976 win_skip("fputwc tests on unicode files\n");
982 static void test_ctrlz( void )
986 static const char mytext[]= "This is test_ctrlz";
991 tempf=_tempnam(".","wne");
992 tempfh = fopen(tempf,"wb");
993 fputs(mytext,tempfh);
994 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
1003 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1004 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1007 ok(i==j, "returned string length expected %d got %d\n", j, i);
1008 j+=4; /* ftell should indicate the true end of file */
1010 ok(l==j, "ftell expected %d got %d\n", j, l);
1011 ok(feof(tempfh), "did not get EOF\n");
1014 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
1015 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1017 j=strlen(mytext)+3; /* should get through newline */
1018 ok(i==j, "returned string length expected %d got %d\n", j, i);
1020 ok(l==j, "ftell expected %d got %d\n", j, l);
1021 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
1023 ok(i==1, "returned string length expected %d got %d\n", 1, i);
1024 ok(feof(tempfh), "did not get EOF\n");
1030 static void test_file_put_get( void )
1034 static const char mytext[]= "This is a test_file_put_get\n";
1035 static const char dostext[]= "This is a test_file_put_get\r\n";
1037 WCHAR wtextW[LLEN+1];
1038 WCHAR *mytextW = NULL, *aptr, *wptr;
1039 BOOL diff_found = FALSE;
1042 tempf=_tempnam(".","wne");
1043 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
1044 fputs(mytext,tempfh);
1046 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1047 fgets(btext,LLEN,tempfh);
1048 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
1049 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
1051 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
1052 fputs(dostext,tempfh);
1054 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1055 fgets(btext,LLEN,tempfh);
1056 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
1058 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
1059 fgets(btext,LLEN,tempfh);
1060 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
1063 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
1064 fgetws(wtextW,LLEN,tempfh);
1065 mytextW = AtoW (mytext);
1069 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
1071 diff_found |= (*aptr != *wptr);
1073 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
1080 static void test_file_write_read( void )
1084 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
1085 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
1089 tempf=_tempnam(".","wne");
1090 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
1091 _S_IREAD | _S_IWRITE);
1093 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1094 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1095 "_write _O_BINARY bad return value\n");
1097 i = lstrlenA(mytext);
1098 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1099 ok(_read(tempfd,btext,i) == i,
1100 "_read _O_BINARY got bad length\n");
1101 ok( memcmp(dostext,btext,i) == 0,
1102 "problems with _O_BINARY _write / _read\n");
1104 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1105 ok(_read(tempfd,btext,i) == i-1,
1106 "_read _O_TEXT got bad length\n");
1107 ok( memcmp(mytext,btext,i-1) == 0,
1108 "problems with _O_BINARY _write / _O_TEXT _read\n");
1110 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
1111 _S_IREAD | _S_IWRITE);
1113 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
1114 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
1115 "_write _O_TEXT bad return value\n");
1117 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1118 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1119 "_read _O_BINARY got bad length\n");
1120 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1121 "problems with _O_TEXT _write / _O_BINARY _read\n");
1122 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1124 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1125 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1126 "_read _O_TEXT got bad length\n");
1127 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1128 "problems with _O_TEXT _write / _read\n");
1131 memset(btext, 0, LLEN);
1132 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
1133 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
1134 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
1135 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
1138 /* Test reading only \n or \r */
1139 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1140 _lseek(tempfd, -1, FILE_END);
1141 ret = _read(tempfd,btext,LLEN);
1142 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
1143 _lseek(tempfd, -2, FILE_END);
1144 ret = _read(tempfd,btext,LLEN);
1145 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
1146 _lseek(tempfd, -2, FILE_END);
1147 ret = _read(tempfd,btext,1);
1148 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
1149 ret = read(tempfd,btext,1);
1150 ok(ret == 0, "_read returned %d, expected 0\n", ret);
1151 _lseek(tempfd, -3, FILE_END);
1152 ret = _read(tempfd,btext,1);
1153 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1154 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
1155 _lseek(tempfd, -3, FILE_END);
1156 ret = _read(tempfd,btext,2);
1157 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1158 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
1159 _lseek(tempfd, -3, FILE_END);
1160 ret = _read(tempfd,btext,3);
1161 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
1162 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
1165 ret = unlink(tempf);
1166 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1169 tempf=_tempnam(".","wne");
1170 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
1172 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
1173 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
1174 "_write _O_BINARY bad return value\n");
1176 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
1177 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
1178 "_read _O_BINARY got bad length\n");
1179 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
1180 "problems with _O_BINARY _write / _read\n");
1181 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
1183 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1184 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
1185 "_read _O_TEXT got bad length\n");
1186 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1187 "problems with _O_BINARY _write / _O_TEXT _read\n");
1190 /* test _read with single bytes. CR should be skipped and LF pulled in */
1191 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1192 for (i=0; i<strlen(mytext); i++) /* */
1194 _read(tempfd,btext, 1);
1195 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1197 while (_read(tempfd,btext, 1));
1200 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1201 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1202 i = _read(tempfd,btext, strlen(mytext));
1203 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1206 /* test read/write in unicode mode */
1209 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1210 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1211 ret = _write(tempfd, "a", 1);
1212 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1213 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1214 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1217 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1218 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1219 ret = _read(tempfd, btext, sizeof(btext));
1220 ok(ret == 10, "_read returned %d, expected 10\n", ret);
1221 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1224 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1225 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1227 ret = _read(tempfd, btext, 3);
1228 ok(ret == -1, "_read returned %d, expected -1\n", ret);
1229 ok(errno == 22, "errno = %d\n", errno);
1230 ret = _read(tempfd, btext, sizeof(btext));
1231 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1232 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1235 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1236 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1238 ret = _write(tempfd, "a", 1);
1239 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1240 ok(errno == 22, "errno = %d\n", errno);
1241 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1242 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1245 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1246 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1247 ret = _read(tempfd, btext, sizeof(btext));
1248 ok(ret == 7, "_read returned %d, expected 7\n", ret);
1249 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1252 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1253 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1254 ret = _read(tempfd, btext, sizeof(btext));
1255 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1256 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1258 /* when buffer is small read sometimes fails in native implementation */
1259 lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1260 ret = _read(tempfd, btext, 4);
1261 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1263 lseek(tempfd, 6, SEEK_SET);
1264 ret = _read(tempfd, btext, 2);
1265 ok(ret == 2, "_read returned %d, expected 2\n", ret);
1266 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1269 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1270 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1271 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1272 ok(ret == 12, "_write returned %d, expected 9\n", ret);
1275 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1276 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1277 ret = _read(tempfd, btext, sizeof(btext));
1278 ok(ret == 12, "_read returned %d, expected 12\n", ret);
1279 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1281 /* test invalid utf8 sequence */
1282 lseek(tempfd, 5, SEEK_SET);
1283 ret = _read(tempfd, btext, sizeof(btext));
1284 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1285 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1286 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1287 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1292 win_skip("unicode mode tests on file\n");
1295 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1297 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1298 ret = unlink(tempf);
1299 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1303 static void test_file_inherit_child(const char* fd_s)
1305 int fd = atoi(fd_s);
1309 ret =write(fd, "Success", 8);
1310 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1311 lseek(fd, 0, SEEK_SET);
1312 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1313 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1316 static void test_file_inherit_child_no(const char* fd_s)
1318 int fd = atoi(fd_s);
1321 ret = write(fd, "Success", 8);
1322 ok( ret == -1 && errno == EBADF,
1323 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1326 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1328 static BYTE block[1024];
1333 startup->lpReserved2 = block;
1334 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1335 wxflag_ptr = block + sizeof(unsigned);
1336 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1338 *(unsigned*)block = count;
1339 for (i = 0; i < count; i++)
1341 wxflag_ptr[i] = 0x81;
1342 handle_ptr[i] = handles[i];
1346 static const char *read_file( HANDLE file )
1348 static char buffer[128];
1350 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1351 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1356 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1361 SECURITY_ATTRIBUTES sa;
1362 PROCESS_INFORMATION proc;
1364 /* make file handle inheritable */
1365 sa.nLength = sizeof(sa);
1366 sa.lpSecurityDescriptor = NULL;
1367 sa.bInheritHandle = TRUE;
1369 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1370 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1371 startup->dwFlags = STARTF_USESTDHANDLES;
1372 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1373 startup->hStdOutput = hErrorFile;
1374 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1376 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1377 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1378 winetest_wait_child_process( proc.hProcess );
1380 data = read_file( hErrorFile );
1382 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1384 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1388 data = read_file( hstdout );
1390 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1392 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1395 CloseHandle( hErrorFile );
1396 DeleteFile( "fdopen.err" );
1399 static void test_file_inherit( const char* selfname )
1402 const char* arg_v[5];
1404 char cmdline[MAX_PATH];
1405 STARTUPINFO startup;
1406 SECURITY_ATTRIBUTES sa;
1409 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1410 ok(fd != -1, "Couldn't create test file\n");
1411 arg_v[0] = selfname;
1412 arg_v[1] = "tests/file.c";
1413 arg_v[2] = "inherit";
1414 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1416 _spawnvp(_P_WAIT, selfname, arg_v);
1417 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1418 lseek(fd, 0, SEEK_SET);
1419 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1421 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1423 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1424 ok(fd != -1, "Couldn't create test file\n");
1425 arg_v[0] = selfname;
1426 arg_v[1] = "tests/file.c";
1427 arg_v[2] = "inherit_no";
1428 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1430 _spawnvp(_P_WAIT, selfname, arg_v);
1431 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1432 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1434 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1436 /* make file handle inheritable */
1437 sa.nLength = sizeof(sa);
1438 sa.lpSecurityDescriptor = NULL;
1439 sa.bInheritHandle = TRUE;
1440 sprintf(cmdline, "%s file inherit 1", selfname);
1442 /* init an empty Reserved2, which should not be recognized as inherit-block */
1443 ZeroMemory(&startup, sizeof(STARTUPINFO));
1444 startup.cb = sizeof(startup);
1445 create_io_inherit_block( &startup, 0, NULL );
1446 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1448 /* test with valid inheritblock */
1449 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1450 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1451 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1452 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1453 create_io_inherit_block( &startup, 3, handles );
1454 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1455 CloseHandle( handles[1] );
1456 DeleteFile("fdopen.tst");
1458 /* test inherit block starting with unsigned zero */
1459 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1460 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1461 create_io_inherit_block( &startup, 3, handles );
1462 *(unsigned int *)startup.lpReserved2 = 0;
1463 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1464 CloseHandle( handles[1] );
1465 DeleteFile("fdopen.tst");
1467 /* test inherit block with smaller size */
1468 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1469 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1470 create_io_inherit_block( &startup, 3, handles );
1471 startup.cbReserved2 -= 3;
1472 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1473 CloseHandle( handles[1] );
1474 DeleteFile("fdopen.tst");
1476 /* test inherit block with even smaller size */
1477 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1478 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1479 create_io_inherit_block( &startup, 3, handles );
1480 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1481 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1482 CloseHandle( handles[1] );
1483 DeleteFile("fdopen.tst");
1485 /* test inherit block with larger size */
1486 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1487 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1488 create_io_inherit_block( &startup, 3, handles );
1489 startup.cbReserved2 += 7;
1490 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1491 CloseHandle( handles[1] );
1492 DeleteFile("fdopen.tst");
1495 static void test_tmpnam( void )
1497 char name[MAX_PATH] = "abc";
1501 ok(res != NULL, "tmpnam returned NULL\n");
1502 ok(res[0] == '\\', "first character is not a backslash\n");
1503 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1504 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1507 ok(res != NULL, "tmpnam returned NULL\n");
1508 ok(res == name, "supplied buffer was not used\n");
1509 ok(res[0] == '\\', "first character is not a backslash\n");
1510 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1511 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1514 static void test_chsize( void )
1517 LONG cur, pos, count;
1518 char temptext[] = "012345678";
1519 char *tempfile = _tempnam( ".", "tst" );
1521 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1523 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1524 ok( fd > 0, "Couldn't open test file\n" );
1526 count = _write( fd, temptext, sizeof(temptext) );
1527 ok( count > 0, "Couldn't write to test file\n" );
1529 /* get current file pointer */
1530 cur = _lseek( fd, 0, SEEK_CUR );
1532 /* make the file smaller */
1533 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1535 pos = _lseek( fd, 0, SEEK_CUR );
1536 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1537 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1539 /* enlarge the file */
1540 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1542 pos = _lseek( fd, 0, SEEK_CUR );
1543 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1544 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1547 _unlink( tempfile );
1551 static void test_fopen_fclose_fcloseall( void )
1553 char fname1[] = "empty1";
1554 char fname2[] = "empty2";
1555 char fname3[] = "empty3";
1556 FILE *stream1, *stream2, *stream3, *stream4;
1559 /* testing fopen() */
1560 stream1 = fopen(fname1, "w+");
1561 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1562 stream2 = fopen(fname2, "w ");
1563 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1565 stream3 = fopen(fname3, "r");
1566 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1567 stream3 = fopen(fname3, "w+");
1568 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1570 stream4 = fopen("", "w+");
1571 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1572 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1574 stream4 = fopen(NULL, "w+");
1575 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1576 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1578 /* testing fclose() */
1579 ret = fclose(stream2);
1580 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1581 ret = fclose(stream3);
1582 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1583 ret = fclose(stream2);
1584 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1585 ret = fclose(stream3);
1586 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1588 /* testing fcloseall() */
1589 numclosed = _fcloseall();
1590 /* fname1 should be closed here */
1591 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1592 numclosed = _fcloseall();
1593 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1595 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1596 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1597 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1600 static void test_fopen_s( void )
1602 const char name[] = "empty1";
1604 unsigned char *ubuff = (unsigned char*)buff;
1611 win_skip("Skipping fopen_s test\n");
1614 /* testing fopen_s */
1615 ret = p_fopen_s(&file, name, "w");
1616 ok(ret == 0, "fopen_s failed with %d\n", ret);
1617 ok(file != 0, "fopen_s failed to return value\n");
1618 fwrite(name, sizeof(name), 1, file);
1621 ok(ret != EOF, "File failed to close\n");
1623 file = fopen(name, "r");
1624 ok(file != 0, "fopen failed\n");
1625 len = fread(buff, 1, sizeof(name), file);
1626 ok(len == sizeof(name), "File length is %d\n", len);
1627 buff[sizeof(name)] = '\0';
1628 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1631 ok(ret != EOF, "File failed to close\n");
1633 ret = p_fopen_s(&file, name, "w, ccs=UNIcode");
1634 ok(ret == 0, "fopen_s failed with %d\n", ret);
1635 ret = fwrite("a", 1, 2, file);
1636 ok(ret == 2, "fwrite returned %d\n", ret);
1639 ret = p_fopen_s(&file, name, "r");
1640 ok(ret == 0, "fopen_s failed with %d\n", ret);
1641 len = fread(buff, 1, 2, file);
1642 ok(len == 2, "len = %d\n", len);
1643 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1644 ubuff[0], ubuff[1]);
1647 ret = p_fopen_s(&file, name, "r,ccs=unicode");
1648 ok(ret == 0, "fopen_s failed with %d\n", ret);
1649 len = fread(buff, 1, 2, file);
1650 ok(len == 2, "len = %d\n", len);
1651 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1652 ubuff[0], ubuff[1]);
1655 ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1656 ok(ret == 0, "fopen_s failed with %d\n", ret);
1657 len = fread(buff, 1, 2, file);
1658 ok(len == 2, "len = %d\n", len);
1659 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1660 ubuff[0], ubuff[1]);
1663 ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1664 ok(ret == 0, "fopen_s failed with %d\n", ret);
1665 len = fread(buff, 1, 2, file);
1666 ok(len == 2, "len = %d\n", len);
1667 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1668 ubuff[0], ubuff[1]);
1671 ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1672 ok(ret == 0, "fopen_s failed with %d\n", ret);
1675 ret = p_fopen_s(&file, name, "r");
1676 ok(ret == 0, "fopen_s failed with %d\n", ret);
1677 len = fread(buff, 1, 3, file);
1678 ok(len == 2, "len = %d\n", len);
1679 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1680 ubuff[0], ubuff[1]);
1683 ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1684 ok(ret == 0, "fopen_s failed with %d\n", ret);
1687 ret = p_fopen_s(&file, name, "r");
1688 ok(ret == 0, "fopen_s failed with %d\n", ret);
1689 len = fread(buff, 1, 4, file);
1690 ok(len == 3, "len = %d\n", len);
1691 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1692 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1693 ubuff[0], ubuff[1], ubuff[2]);
1696 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1699 static void test__wfopen_s( void )
1701 const char name[] = "empty1";
1702 const WCHAR wname[] = {
1703 'e','m','p','t','y','1',0
1705 const WCHAR wmode[] = {
1715 win_skip("Skipping _wfopen_s test\n");
1718 /* testing _wfopen_s */
1719 ret = p__wfopen_s(&file, wname, wmode);
1720 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1721 ok(file != 0, "_wfopen_s failed to return value\n");
1722 fwrite(name, sizeof(name), 1, file);
1725 ok(ret != EOF, "File failed to close\n");
1727 file = fopen(name, "r");
1728 ok(file != 0, "fopen failed\n");
1729 len = fread(buff, 1, sizeof(name), file);
1730 ok(len == sizeof(name), "File length is %d\n", len);
1731 buff[sizeof(name)] = '\0';
1732 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1735 ok(ret != EOF, "File failed to close\n");
1737 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1740 static void test_setmode(void)
1742 const char name[] = "empty1";
1746 win_skip("unicode file modes are not available, skipping setmode tests\n");
1750 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1751 ok(fd != -1, "failed to open file\n");
1754 ret = _setmode(fd, 0xffffffff);
1755 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1756 ok(errno == EINVAL, "errno = %d\n", errno);
1759 ret = _setmode(fd, 0);
1760 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1761 ok(errno == EINVAL, "errno = %d\n", errno);
1764 ret = _setmode(fd, _O_BINARY|_O_TEXT);
1765 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1766 ok(errno == EINVAL, "errno = %d\n", errno);
1769 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1770 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1771 ok(errno == EINVAL, "errno = %d\n", errno);
1773 ret = _setmode(fd, _O_BINARY);
1774 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1776 ret = _setmode(fd, _O_WTEXT);
1777 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1779 ret = _setmode(fd, _O_TEXT);
1780 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1782 ret = _setmode(fd, _O_U16TEXT);
1783 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1785 ret = _setmode(fd, _O_U8TEXT);
1786 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1788 ret = _setmode(fd, _O_TEXT);
1789 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1795 static void test_get_osfhandle(void)
1798 char fname[] = "t_get_osfhanle";
1799 DWORD bytes_written;
1802 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1803 handle = (HANDLE)_get_osfhandle(fd);
1804 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1806 fd = _open(fname, _O_RDONLY, 0);
1807 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1813 static void test_setmaxstdio(void)
1815 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1816 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1819 static void test_stat(void)
1826 /* Tests for a file */
1827 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1830 ret = fstat(fd, &buf);
1831 ok(!ret, "fstat failed: errno=%d\n", errno);
1832 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1833 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1834 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1835 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1836 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1837 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1839 ret = stat("stat.tst", &buf);
1840 ok(!ret, "stat failed: errno=%d\n", errno);
1841 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1842 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1843 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1844 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1845 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1848 ret = stat("stat.tst\\", &buf);
1849 ok(ret == -1, "stat returned %d\n", ret);
1850 ok(errno == ENOENT, "errno = %d\n", errno);
1856 skip("open failed with errno %d\n", errno);
1858 /* Tests for a char device */
1859 if (_dup2(0, 10) == 0)
1861 ret = fstat(10, &buf);
1862 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1863 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1865 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1866 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1867 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1868 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1871 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1875 skip("_dup2 failed with errno %d\n", errno);
1877 /* Tests for pipes */
1878 if (_pipe(pipes, 1024, O_BINARY) == 0)
1880 ret = fstat(pipes[0], &buf);
1881 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1882 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1883 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1884 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1885 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1890 skip("pipe failed with errno %d\n", errno);
1892 /* Tests for directory */
1893 if(mkdir("stat.tst") == 0)
1895 ret = stat("stat.tst ", &buf);
1896 ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1897 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1898 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1899 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1900 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1903 ret = stat("stat.tst\\ ", &buf);
1904 ok(ret == -1, "stat returned %d\n", ret);
1905 ok(errno == ENOENT, "errno = %d\n", errno);
1906 rmdir( "stat.tst" );
1909 skip("mkdir failed with errno %d\n", errno);
1912 static const char* pipe_string="Hello world";
1914 /* How many messages to transfer over the pipe */
1915 #define N_TEST_MESSAGES 3
1917 static void test_pipes_child(int argc, char** args)
1925 ok(0, "not enough parameters: %d\n", argc);
1931 ok(!i, "unable to close %d: %d\n", fd, errno);
1935 for (i=0; i<N_TEST_MESSAGES; i++) {
1936 nwritten=write(fd, pipe_string, strlen(pipe_string));
1937 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1938 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1939 if (i < N_TEST_MESSAGES-1)
1944 ok(!i, "unable to close %d: %d\n", fd, errno);
1947 static void test_pipes(const char* selfname)
1950 char str_fdr[12], str_fdw[12];
1952 const char* arg_v[6];
1954 char expected[4096];
1958 /* Test reading from a pipe with read() */
1959 if (_pipe(pipes, 1024, O_BINARY) < 0)
1961 ok(0, "pipe failed with errno %d\n", errno);
1965 arg_v[0] = selfname;
1966 arg_v[1] = "tests/file.c";
1968 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1969 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1971 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1973 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1975 for (i=0; i<N_TEST_MESSAGES; i++) {
1976 r=read(pipes[0], buf, sizeof(buf)-1);
1977 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1980 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1983 r=read(pipes[0], buf, sizeof(buf)-1);
1984 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1986 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1988 /* Test reading from a pipe with fread() */
1989 if (_pipe(pipes, 1024, O_BINARY) < 0)
1991 ok(0, "pipe failed with errno %d\n", errno);
1995 arg_v[0] = selfname;
1996 arg_v[1] = "tests/file.c";
1998 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1999 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
2001 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
2003 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
2004 file=fdopen(pipes[0], "r");
2006 /* In blocking mode, fread will keep calling read() until it gets
2007 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2008 * in cooked mode instead of a pipe, it would also stop on EOL.)
2011 for (i=0; i<N_TEST_MESSAGES; i++)
2012 strcat(expected, pipe_string);
2013 r=fread(buf, 1, sizeof(buf)-1, file);
2014 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
2017 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
2019 /* Let child close the file before we read, so we can sense EOF reliably */
2021 r=fread(buf, 1, sizeof(buf)-1, file);
2022 ok(r == 0, "fread() returned %d instead of 0\n", r);
2023 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
2024 ok(feof(file), "feof() is false!\n");
2027 ok(!i, "unable to close the pipe: %d\n", errno);
2029 /* test \r handling when it's the last character read */
2030 if (_pipe(pipes, 1024, O_BINARY) < 0)
2032 ok(0, "pipe failed with errno %d\n", errno);
2035 r = write(pipes[1], "\r\n\rab", 5);
2036 ok(r == 5, "write returned %d, errno = %d\n", r, errno);
2037 setmode(pipes[0], O_TEXT);
2038 r = read(pipes[0], buf, 1);
2039 ok(r == 1, "read returned %d, expected 1\n", r);
2040 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
2041 r = read(pipes[0], buf, 1);
2042 ok(r == 1, "read returned %d, expected 1\n", r);
2043 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
2044 r = read(pipes[0], buf, 1);
2045 ok(r == 1, "read returned %d, expected 1\n", r);
2046 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
2047 r = read(pipes[0], buf, 1);
2048 ok(r == 1, "read returned %d, expected 1\n", r);
2049 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
2053 /* test utf16 read with insufficient data */
2054 r = write(pipes[1], "a\0b", 3);
2055 ok(r == 3, "write returned %d, errno = %d\n", r, errno);
2058 setmode(pipes[0], _O_WTEXT);
2059 r = read(pipes[0], buf, 4);
2060 ok(r == 2, "read returned %d, expected 2\n", r);
2061 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
2062 r = write(pipes[1], "\0", 1);
2063 ok(r == 1, "write returned %d, errno = %d\n", r, errno);
2066 r = read(pipes[0], buf, 2);
2067 ok(r == 0, "read returned %d, expected 0\n", r);
2068 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
2072 win_skip("unicode mode tests on pipe\n");
2079 static void test_unlink(void)
2082 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2083 file = fopen("test_unlink\\empty", "w");
2084 ok(file != NULL, "unable to create test file\n");
2087 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2088 unlink("test_unlink\\empty");
2089 rmdir("test_unlink");
2092 static void test_dup2(void)
2094 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2097 static void test_stdin(void)
2099 HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
2104 stdin_dup = _dup(STDIN_FILENO);
2105 ok(stdin_dup != -1, "_dup(STDIN_FILENO) failed\n");
2107 ok(stdinh == (HANDLE)_get_osfhandle(STDIN_FILENO),
2108 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2110 r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE);
2111 ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r);
2112 h = GetStdHandle(STD_INPUT_HANDLE);
2113 ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h);
2115 close(STDIN_FILENO);
2116 h = GetStdHandle(STD_INPUT_HANDLE);
2117 ok(h == NULL, "h != NULL\n");
2119 fd = open("stdin.tst", O_WRONLY | O_CREAT, _S_IREAD |_S_IWRITE);
2120 ok(fd != -1, "open failed\n");
2121 ok(fd == STDIN_FILENO, "fd = %d, expected STDIN_FILENO\n", fd);
2122 h = GetStdHandle(STD_INPUT_HANDLE);
2123 ok(h != NULL, "h == NULL\n");
2125 unlink("stdin.tst");
2127 r = _dup2(stdin_dup, STDIN_FILENO);
2128 ok(r != -1, "_dup2 failed\n");
2129 h = GetStdHandle(STD_INPUT_HANDLE);
2130 ok(h != NULL, "h == NULL\n");
2140 arg_c = winetest_get_mainargs( &arg_v );
2142 /* testing low-level I/O */
2145 if (strcmp(arg_v[2], "inherit") == 0)
2146 test_file_inherit_child(arg_v[3]);
2147 else if (strcmp(arg_v[2], "inherit_no") == 0)
2148 test_file_inherit_child_no(arg_v[3]);
2149 else if (strcmp(arg_v[2], "pipes") == 0)
2150 test_pipes_child(arg_c, arg_v);
2152 ok(0, "invalid argument '%s'\n", arg_v[2]);
2156 test_file_inherit(arg_v[0]);
2157 test_file_write_read();
2162 /* testing stream I/O */
2165 test_fopen_fclose_fcloseall();
2173 test_readmode(FALSE); /* binary mode */
2174 test_readmode(TRUE); /* ascii mode */
2175 test_readboundary();
2181 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2182 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2183 /* \x83 is U+0192 */
2184 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2185 /* \x83 is U+0083 */
2186 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2187 test_fgetwc_unicode();
2190 test_file_put_get();
2192 test_get_osfhandle();
2194 test_pipes(arg_v[0]);
2197 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2198 * file contains lines in the correct order
2200 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);