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_ctrlz( void )
799 static const char mytext[]= "This is test_ctrlz";
804 tempf=_tempnam(".","wne");
805 tempfh = fopen(tempf,"wb");
806 fputs(mytext,tempfh);
807 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
816 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
817 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
820 ok(i==j, "returned string length expected %d got %d\n", j, i);
821 j+=4; /* ftell should indicate the true end of file */
823 ok(l==j, "ftell expected %d got %d\n", j, l);
824 ok(feof(tempfh), "did not get EOF\n");
827 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
828 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
830 j=strlen(mytext)+3; /* should get through newline */
831 ok(i==j, "returned string length expected %d got %d\n", j, i);
833 ok(l==j, "ftell expected %d got %d\n", j, l);
834 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
836 ok(i==1, "returned string length expected %d got %d\n", 1, i);
837 ok(feof(tempfh), "did not get EOF\n");
843 static void test_file_put_get( void )
847 static const char mytext[]= "This is a test_file_put_get\n";
848 static const char dostext[]= "This is a test_file_put_get\r\n";
850 WCHAR wtextW[LLEN+1];
851 WCHAR *mytextW = NULL, *aptr, *wptr;
852 BOOL diff_found = FALSE;
855 tempf=_tempnam(".","wne");
856 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
857 fputs(mytext,tempfh);
859 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
860 fgets(btext,LLEN,tempfh);
861 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
862 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
864 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
865 fputs(dostext,tempfh);
867 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
868 fgets(btext,LLEN,tempfh);
869 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
871 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
872 fgets(btext,LLEN,tempfh);
873 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
876 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
877 fgetws(wtextW,LLEN,tempfh);
878 mytextW = AtoW (mytext);
882 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
884 diff_found |= (*aptr != *wptr);
886 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
893 static void test_file_write_read( void )
897 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
898 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
902 tempf=_tempnam(".","wne");
903 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
904 _S_IREAD | _S_IWRITE);
906 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
907 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
908 "_write _O_BINARY bad return value\n");
910 i = lstrlenA(mytext);
911 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
912 ok(_read(tempfd,btext,i) == i,
913 "_read _O_BINARY got bad length\n");
914 ok( memcmp(dostext,btext,i) == 0,
915 "problems with _O_BINARY _write / _read\n");
917 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
918 ok(_read(tempfd,btext,i) == i-1,
919 "_read _O_TEXT got bad length\n");
920 ok( memcmp(mytext,btext,i-1) == 0,
921 "problems with _O_BINARY _write / _O_TEXT _read\n");
923 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
924 _S_IREAD | _S_IWRITE);
926 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
927 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
928 "_write _O_TEXT bad return value\n");
930 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
931 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
932 "_read _O_BINARY got bad length\n");
933 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
934 "problems with _O_TEXT _write / _O_BINARY _read\n");
935 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
937 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
938 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
939 "_read _O_TEXT got bad length\n");
940 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
941 "problems with _O_TEXT _write / _read\n");
944 memset(btext, 0, LLEN);
945 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
946 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
947 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
948 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
951 /* Test reading only \n or \r */
952 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
953 _lseek(tempfd, -1, FILE_END);
954 ret = _read(tempfd,btext,LLEN);
955 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
956 _lseek(tempfd, -2, FILE_END);
957 ret = _read(tempfd,btext,LLEN);
958 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
959 _lseek(tempfd, -2, FILE_END);
960 ret = _read(tempfd,btext,1);
961 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext);
962 ret = read(tempfd,btext,1);
963 ok(ret == 0, "_read returned %d, expected 0\n", ret);
964 _lseek(tempfd, -3, FILE_END);
965 ret = _read(tempfd,btext,1);
966 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
967 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
968 _lseek(tempfd, -3, FILE_END);
969 ret = _read(tempfd,btext,2);
970 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
971 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
972 _lseek(tempfd, -3, FILE_END);
973 ret = _read(tempfd,btext,3);
974 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
975 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
979 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
982 tempf=_tempnam(".","wne");
983 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE);
985 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
986 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
987 "_write _O_BINARY bad return value\n");
989 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
990 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
991 "_read _O_BINARY got bad length\n");
992 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
993 "problems with _O_BINARY _write / _read\n");
994 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
996 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
997 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
998 "_read _O_TEXT got bad length\n");
999 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
1000 "problems with _O_BINARY _write / _O_TEXT _read\n");
1003 /* test _read with single bytes. CR should be skipped and LF pulled in */
1004 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1005 for (i=0; i<strlen(mytext); i++) /* */
1007 _read(tempfd,btext, 1);
1008 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
1010 while (_read(tempfd,btext, 1));
1013 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1014 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
1015 i = _read(tempfd,btext, strlen(mytext));
1016 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
1019 /* test read/write in unicode mode */
1022 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE);
1023 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1024 ret = _write(tempfd, "a", 1);
1025 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1026 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6);
1027 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1030 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1031 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1032 ret = _read(tempfd, btext, sizeof(btext));
1033 ok(ret == 10, "_read returned %d, expected 10\n", ret);
1034 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1037 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1038 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1040 ret = _read(tempfd, btext, 3);
1041 ok(ret == -1, "_read returned %d, expected -1\n", ret);
1042 ok(errno == 22, "errno = %d\n", errno);
1043 ret = _read(tempfd, btext, sizeof(btext));
1044 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1045 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1048 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE);
1049 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1051 ret = _write(tempfd, "a", 1);
1052 ok(ret == -1, "_write returned %d, expected -1\n", ret);
1053 ok(errno == 22, "errno = %d\n", errno);
1054 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6);
1055 ok(ret == 6, "_write returned %d, expected 6\n", ret);
1058 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0);
1059 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1060 ret = _read(tempfd, btext, sizeof(btext));
1061 ok(ret == 7, "_read returned %d, expected 7\n", ret);
1062 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1065 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1066 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1067 ret = _read(tempfd, btext, sizeof(btext));
1068 ok(ret == 6, "_read returned %d, expected 6\n", ret);
1069 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1071 /* when buffer is small read sometimes fails in native implementation */
1072 lseek(tempfd, 3 /* skip bom */, SEEK_SET);
1073 ret = _read(tempfd, btext, 4);
1074 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret);
1076 lseek(tempfd, 6, SEEK_SET);
1077 ret = _read(tempfd, btext, 2);
1078 ok(ret == 2, "_read returned %d, expected 2\n", ret);
1079 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n");
1082 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE);
1083 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1084 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1085 ok(ret == 12, "_write returned %d, expected 9\n", ret);
1088 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0);
1089 ok(tempfd != -1, "_open failed with error: %d\n", errno);
1090 ret = _read(tempfd, btext, sizeof(btext));
1091 ok(ret == 12, "_read returned %d, expected 12\n", ret);
1092 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1094 /* test invalid utf8 sequence */
1095 lseek(tempfd, 5, SEEK_SET);
1096 ret = _read(tempfd, btext, sizeof(btext));
1097 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret);
1098 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1099 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1100 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1105 win_skip("unicode mode tests on file\n");
1108 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
1110 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
1111 ret = unlink(tempf);
1112 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
1116 static void test_file_inherit_child(const char* fd_s)
1118 int fd = atoi(fd_s);
1122 ret =write(fd, "Success", 8);
1123 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
1124 lseek(fd, 0, SEEK_SET);
1125 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1126 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1129 static void test_file_inherit_child_no(const char* fd_s)
1131 int fd = atoi(fd_s);
1134 ret = write(fd, "Success", 8);
1135 ok( ret == -1 && errno == EBADF,
1136 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1139 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1141 static BYTE block[1024];
1146 startup->lpReserved2 = block;
1147 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1148 wxflag_ptr = block + sizeof(unsigned);
1149 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1151 *(unsigned*)block = count;
1152 for (i = 0; i < count; i++)
1154 wxflag_ptr[i] = 0x81;
1155 handle_ptr[i] = handles[i];
1159 static const char *read_file( HANDLE file )
1161 static char buffer[128];
1163 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1164 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1169 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1174 SECURITY_ATTRIBUTES sa;
1175 PROCESS_INFORMATION proc;
1177 /* make file handle inheritable */
1178 sa.nLength = sizeof(sa);
1179 sa.lpSecurityDescriptor = NULL;
1180 sa.bInheritHandle = TRUE;
1182 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1183 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1184 startup->dwFlags = STARTF_USESTDHANDLES;
1185 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1186 startup->hStdOutput = hErrorFile;
1187 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1189 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1190 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1191 winetest_wait_child_process( proc.hProcess );
1193 data = read_file( hErrorFile );
1195 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1197 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1201 data = read_file( hstdout );
1203 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1205 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1208 CloseHandle( hErrorFile );
1209 DeleteFile( "fdopen.err" );
1212 static void test_file_inherit( const char* selfname )
1215 const char* arg_v[5];
1217 char cmdline[MAX_PATH];
1218 STARTUPINFO startup;
1219 SECURITY_ATTRIBUTES sa;
1222 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1223 ok(fd != -1, "Couldn't create test file\n");
1224 arg_v[0] = selfname;
1225 arg_v[1] = "tests/file.c";
1226 arg_v[2] = "inherit";
1227 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1229 _spawnvp(_P_WAIT, selfname, arg_v);
1230 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1231 lseek(fd, 0, SEEK_SET);
1232 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1234 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1236 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1237 ok(fd != -1, "Couldn't create test file\n");
1238 arg_v[0] = selfname;
1239 arg_v[1] = "tests/file.c";
1240 arg_v[2] = "inherit_no";
1241 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1243 _spawnvp(_P_WAIT, selfname, arg_v);
1244 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1245 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1247 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1249 /* make file handle inheritable */
1250 sa.nLength = sizeof(sa);
1251 sa.lpSecurityDescriptor = NULL;
1252 sa.bInheritHandle = TRUE;
1253 sprintf(cmdline, "%s file inherit 1", selfname);
1255 /* init an empty Reserved2, which should not be recognized as inherit-block */
1256 ZeroMemory(&startup, sizeof(STARTUPINFO));
1257 startup.cb = sizeof(startup);
1258 create_io_inherit_block( &startup, 0, NULL );
1259 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1261 /* test with valid inheritblock */
1262 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1263 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1264 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1265 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1266 create_io_inherit_block( &startup, 3, handles );
1267 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1268 CloseHandle( handles[1] );
1269 DeleteFile("fdopen.tst");
1271 /* test inherit block starting with unsigned zero */
1272 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1273 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1274 create_io_inherit_block( &startup, 3, handles );
1275 *(unsigned int *)startup.lpReserved2 = 0;
1276 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1277 CloseHandle( handles[1] );
1278 DeleteFile("fdopen.tst");
1280 /* test inherit block with smaller size */
1281 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1282 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1283 create_io_inherit_block( &startup, 3, handles );
1284 startup.cbReserved2 -= 3;
1285 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1286 CloseHandle( handles[1] );
1287 DeleteFile("fdopen.tst");
1289 /* test inherit block with even smaller size */
1290 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1291 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1292 create_io_inherit_block( &startup, 3, handles );
1293 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1294 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1295 CloseHandle( handles[1] );
1296 DeleteFile("fdopen.tst");
1298 /* test inherit block with larger size */
1299 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1300 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1301 create_io_inherit_block( &startup, 3, handles );
1302 startup.cbReserved2 += 7;
1303 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1304 CloseHandle( handles[1] );
1305 DeleteFile("fdopen.tst");
1308 static void test_tmpnam( void )
1310 char name[MAX_PATH] = "abc";
1314 ok(res != NULL, "tmpnam returned NULL\n");
1315 ok(res[0] == '\\', "first character is not a backslash\n");
1316 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1317 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1320 ok(res != NULL, "tmpnam returned NULL\n");
1321 ok(res == name, "supplied buffer was not used\n");
1322 ok(res[0] == '\\', "first character is not a backslash\n");
1323 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1324 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1327 static void test_chsize( void )
1330 LONG cur, pos, count;
1331 char temptext[] = "012345678";
1332 char *tempfile = _tempnam( ".", "tst" );
1334 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1336 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1337 ok( fd > 0, "Couldn't open test file\n" );
1339 count = _write( fd, temptext, sizeof(temptext) );
1340 ok( count > 0, "Couldn't write to test file\n" );
1342 /* get current file pointer */
1343 cur = _lseek( fd, 0, SEEK_CUR );
1345 /* make the file smaller */
1346 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1348 pos = _lseek( fd, 0, SEEK_CUR );
1349 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1350 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1352 /* enlarge the file */
1353 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1355 pos = _lseek( fd, 0, SEEK_CUR );
1356 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1357 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1360 _unlink( tempfile );
1364 static void test_fopen_fclose_fcloseall( void )
1366 char fname1[] = "empty1";
1367 char fname2[] = "empty2";
1368 char fname3[] = "empty3";
1369 FILE *stream1, *stream2, *stream3, *stream4;
1372 /* testing fopen() */
1373 stream1 = fopen(fname1, "w+");
1374 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1375 stream2 = fopen(fname2, "w ");
1376 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1378 stream3 = fopen(fname3, "r");
1379 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1380 stream3 = fopen(fname3, "w+");
1381 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1383 stream4 = fopen("", "w+");
1384 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1385 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1387 stream4 = fopen(NULL, "w+");
1388 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1389 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1391 /* testing fclose() */
1392 ret = fclose(stream2);
1393 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1394 ret = fclose(stream3);
1395 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1396 ret = fclose(stream2);
1397 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1398 ret = fclose(stream3);
1399 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1401 /* testing fcloseall() */
1402 numclosed = _fcloseall();
1403 /* fname1 should be closed here */
1404 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1405 numclosed = _fcloseall();
1406 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1408 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1409 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1410 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1413 static void test_fopen_s( void )
1415 const char name[] = "empty1";
1417 unsigned char *ubuff = (unsigned char*)buff;
1424 win_skip("Skipping fopen_s test\n");
1427 /* testing fopen_s */
1428 ret = p_fopen_s(&file, name, "w");
1429 ok(ret == 0, "fopen_s failed with %d\n", ret);
1430 ok(file != 0, "fopen_s failed to return value\n");
1431 fwrite(name, sizeof(name), 1, file);
1434 ok(ret != EOF, "File failed to close\n");
1436 file = fopen(name, "r");
1437 ok(file != 0, "fopen failed\n");
1438 len = fread(buff, 1, sizeof(name), file);
1439 ok(len == sizeof(name), "File length is %d\n", len);
1440 buff[sizeof(name)] = '\0';
1441 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1444 ok(ret != EOF, "File failed to close\n");
1446 ret = p_fopen_s(&file, name, "w, ccs=UNIcode");
1447 ok(ret == 0, "fopen_s failed with %d\n", ret);
1448 ret = fwrite("a", 1, 2, file);
1449 ok(ret == 2, "fwrite returned %d\n", ret);
1452 ret = p_fopen_s(&file, name, "r");
1453 ok(ret == 0, "fopen_s failed with %d\n", ret);
1454 len = fread(buff, 1, 2, file);
1455 ok(len == 2, "len = %d\n", len);
1456 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1457 ubuff[0], ubuff[1]);
1460 ret = p_fopen_s(&file, name, "r,ccs=unicode");
1461 ok(ret == 0, "fopen_s failed with %d\n", ret);
1462 len = fread(buff, 1, 2, file);
1463 ok(len == 2, "len = %d\n", len);
1464 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1465 ubuff[0], ubuff[1]);
1468 ret = p_fopen_s(&file, name, "r,ccs=utf-16le");
1469 ok(ret == 0, "fopen_s failed with %d\n", ret);
1470 len = fread(buff, 1, 2, file);
1471 ok(len == 2, "len = %d\n", len);
1472 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1473 ubuff[0], ubuff[1]);
1476 ret = p_fopen_s(&file, name, "r,ccs=utf-8");
1477 ok(ret == 0, "fopen_s failed with %d\n", ret);
1478 len = fread(buff, 1, 2, file);
1479 ok(len == 2, "len = %d\n", len);
1480 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1481 ubuff[0], ubuff[1]);
1484 ret = p_fopen_s(&file, name, "w,ccs=utf-16le");
1485 ok(ret == 0, "fopen_s failed with %d\n", ret);
1488 ret = p_fopen_s(&file, name, "r");
1489 ok(ret == 0, "fopen_s failed with %d\n", ret);
1490 len = fread(buff, 1, 3, file);
1491 ok(len == 2, "len = %d\n", len);
1492 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1493 ubuff[0], ubuff[1]);
1496 ret = p_fopen_s(&file, name, "w,ccs=utf-8");
1497 ok(ret == 0, "fopen_s failed with %d\n", ret);
1500 ret = p_fopen_s(&file, name, "r");
1501 ok(ret == 0, "fopen_s failed with %d\n", ret);
1502 len = fread(buff, 1, 4, file);
1503 ok(len == 3, "len = %d\n", len);
1504 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf,
1505 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1506 ubuff[0], ubuff[1], ubuff[2]);
1509 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1512 static void test__wfopen_s( void )
1514 const char name[] = "empty1";
1515 const WCHAR wname[] = {
1516 'e','m','p','t','y','1',0
1518 const WCHAR wmode[] = {
1528 win_skip("Skipping _wfopen_s test\n");
1531 /* testing _wfopen_s */
1532 ret = p__wfopen_s(&file, wname, wmode);
1533 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1534 ok(file != 0, "_wfopen_s failed to return value\n");
1535 fwrite(name, sizeof(name), 1, file);
1538 ok(ret != EOF, "File failed to close\n");
1540 file = fopen(name, "r");
1541 ok(file != 0, "fopen failed\n");
1542 len = fread(buff, 1, sizeof(name), file);
1543 ok(len == sizeof(name), "File length is %d\n", len);
1544 buff[sizeof(name)] = '\0';
1545 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1548 ok(ret != EOF, "File failed to close\n");
1550 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1553 static void test_setmode(void)
1555 const char name[] = "empty1";
1559 win_skip("unicode file modes are not available, skipping setmode tests\n");
1563 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE);
1564 ok(fd != -1, "failed to open file\n");
1567 ret = _setmode(fd, 0xffffffff);
1568 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1569 ok(errno == EINVAL, "errno = %d\n", errno);
1572 ret = _setmode(fd, 0);
1573 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1574 ok(errno == EINVAL, "errno = %d\n", errno);
1577 ret = _setmode(fd, _O_BINARY|_O_TEXT);
1578 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1579 ok(errno == EINVAL, "errno = %d\n", errno);
1582 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT);
1583 ok(ret == -1, "_setmode returned %x, expected -1\n", ret);
1584 ok(errno == EINVAL, "errno = %d\n", errno);
1586 ret = _setmode(fd, _O_BINARY);
1587 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1589 ret = _setmode(fd, _O_WTEXT);
1590 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret);
1592 ret = _setmode(fd, _O_TEXT);
1593 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1595 ret = _setmode(fd, _O_U16TEXT);
1596 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret);
1598 ret = _setmode(fd, _O_U8TEXT);
1599 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1601 ret = _setmode(fd, _O_TEXT);
1602 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret);
1608 static void test_get_osfhandle(void)
1611 char fname[] = "t_get_osfhanle";
1612 DWORD bytes_written;
1615 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1616 handle = (HANDLE)_get_osfhandle(fd);
1617 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1619 fd = _open(fname, _O_RDONLY, 0);
1620 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1626 static void test_setmaxstdio(void)
1628 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1629 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1632 static void test_stat(void)
1639 /* Tests for a file */
1640 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1643 ret = fstat(fd, &buf);
1644 ok(!ret, "fstat failed: errno=%d\n", errno);
1645 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1646 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1647 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1648 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1649 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1650 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1652 ret = stat("stat.tst", &buf);
1653 ok(!ret, "stat failed: errno=%d\n", errno);
1654 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1655 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1656 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1657 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1658 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1661 ret = stat("stat.tst\\", &buf);
1662 ok(ret == -1, "stat returned %d\n", ret);
1663 ok(errno == ENOENT, "errno = %d\n", errno);
1669 skip("open failed with errno %d\n", errno);
1671 /* Tests for a char device */
1672 if (_dup2(0, 10) == 0)
1674 ret = fstat(10, &buf);
1675 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1676 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1678 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1679 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1680 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1681 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1684 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1688 skip("_dup2 failed with errno %d\n", errno);
1690 /* Tests for pipes */
1691 if (_pipe(pipes, 1024, O_BINARY) == 0)
1693 ret = fstat(pipes[0], &buf);
1694 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1695 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1696 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1697 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1698 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1703 skip("pipe failed with errno %d\n", errno);
1705 /* Tests for directory */
1706 if(mkdir("stat.tst") == 0)
1708 ret = stat("stat.tst ", &buf);
1709 ok(!ret, "stat(directory) failed: errno=%d\n", errno);
1710 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode);
1711 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode);
1712 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1713 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1716 ret = stat("stat.tst\\ ", &buf);
1717 ok(ret == -1, "stat returned %d\n", ret);
1718 ok(errno == ENOENT, "errno = %d\n", errno);
1719 rmdir( "stat.tst" );
1722 skip("mkdir failed with errno %d\n", errno);
1725 static const char* pipe_string="Hello world";
1727 /* How many messages to transfer over the pipe */
1728 #define N_TEST_MESSAGES 3
1730 static void test_pipes_child(int argc, char** args)
1738 ok(0, "not enough parameters: %d\n", argc);
1744 ok(!i, "unable to close %d: %d\n", fd, errno);
1748 for (i=0; i<N_TEST_MESSAGES; i++) {
1749 nwritten=write(fd, pipe_string, strlen(pipe_string));
1750 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1751 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1752 if (i < N_TEST_MESSAGES-1)
1757 ok(!i, "unable to close %d: %d\n", fd, errno);
1760 static void test_pipes(const char* selfname)
1763 char str_fdr[12], str_fdw[12];
1765 const char* arg_v[6];
1767 char expected[4096];
1771 /* Test reading from a pipe with read() */
1772 if (_pipe(pipes, 1024, O_BINARY) < 0)
1774 ok(0, "pipe failed with errno %d\n", errno);
1778 arg_v[0] = selfname;
1779 arg_v[1] = "tests/file.c";
1781 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1782 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1784 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1786 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1788 for (i=0; i<N_TEST_MESSAGES; i++) {
1789 r=read(pipes[0], buf, sizeof(buf)-1);
1790 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1793 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1796 r=read(pipes[0], buf, sizeof(buf)-1);
1797 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1799 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1801 /* Test reading from a pipe with fread() */
1802 if (_pipe(pipes, 1024, O_BINARY) < 0)
1804 ok(0, "pipe failed with errno %d\n", errno);
1808 arg_v[0] = selfname;
1809 arg_v[1] = "tests/file.c";
1811 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1812 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1814 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1816 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1817 file=fdopen(pipes[0], "r");
1819 /* In blocking mode, fread will keep calling read() until it gets
1820 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1821 * in cooked mode instead of a pipe, it would also stop on EOL.)
1824 for (i=0; i<N_TEST_MESSAGES; i++)
1825 strcat(expected, pipe_string);
1826 r=fread(buf, 1, sizeof(buf)-1, file);
1827 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1830 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1832 /* Let child close the file before we read, so we can sense EOF reliably */
1834 r=fread(buf, 1, sizeof(buf)-1, file);
1835 ok(r == 0, "fread() returned %d instead of 0\n", r);
1836 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1837 ok(feof(file), "feof() is false!\n");
1840 ok(!i, "unable to close the pipe: %d\n", errno);
1842 /* test \r handling when it's the last character read */
1843 if (_pipe(pipes, 1024, O_BINARY) < 0)
1845 ok(0, "pipe failed with errno %d\n", errno);
1848 r = write(pipes[1], "\r\n\rab", 5);
1849 ok(r == 5, "write returned %d, errno = %d\n", r, errno);
1850 setmode(pipes[0], O_TEXT);
1851 r = read(pipes[0], buf, 1);
1852 ok(r == 1, "read returned %d, expected 1\n", r);
1853 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]);
1854 r = read(pipes[0], buf, 1);
1855 ok(r == 1, "read returned %d, expected 1\n", r);
1856 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]);
1857 r = read(pipes[0], buf, 1);
1858 ok(r == 1, "read returned %d, expected 1\n", r);
1859 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]);
1860 r = read(pipes[0], buf, 1);
1861 ok(r == 1, "read returned %d, expected 1\n", r);
1862 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]);
1866 /* test utf16 read with insufficient data */
1867 r = write(pipes[1], "a\0b", 3);
1868 ok(r == 3, "write returned %d, errno = %d\n", r, errno);
1871 setmode(pipes[0], _O_WTEXT);
1872 r = read(pipes[0], buf, 4);
1873 ok(r == 2, "read returned %d, expected 2\n", r);
1874 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n");
1875 r = write(pipes[1], "\0", 1);
1876 ok(r == 1, "write returned %d, errno = %d\n", r, errno);
1879 r = read(pipes[0], buf, 2);
1880 ok(r == 0, "read returned %d, expected 0\n", r);
1881 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n");
1885 win_skip("unicode mode tests on pipe\n");
1892 static void test_unlink(void)
1895 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1896 file = fopen("test_unlink\\empty", "w");
1897 ok(file != NULL, "unable to create test file\n");
1900 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1901 unlink("test_unlink\\empty");
1902 rmdir("test_unlink");
1905 static void test_dup2(void)
1907 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1917 arg_c = winetest_get_mainargs( &arg_v );
1919 /* testing low-level I/O */
1922 if (strcmp(arg_v[2], "inherit") == 0)
1923 test_file_inherit_child(arg_v[3]);
1924 else if (strcmp(arg_v[2], "inherit_no") == 0)
1925 test_file_inherit_child_no(arg_v[3]);
1926 else if (strcmp(arg_v[2], "pipes") == 0)
1927 test_pipes_child(arg_c, arg_v);
1929 ok(0, "invalid argument '%s'\n", arg_v[2]);
1933 test_file_inherit(arg_v[0]);
1934 test_file_write_read();
1939 /* testing stream I/O */
1942 test_fopen_fclose_fcloseall();
1950 test_readmode(FALSE); /* binary mode */
1951 test_readmode(TRUE); /* ascii mode */
1952 test_readboundary();
1959 test_file_put_get();
1961 test_get_osfhandle();
1963 test_pipes(arg_v[0]);
1965 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1966 * file contains lines in the correct order
1968 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);