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 void test_filbuf( void )
45 fp
= fopen("filbuf.tst", "wb");
46 fwrite("\n\n\n\n", 1, 4, fp
);
49 fp
= fopen("filbuf.tst", "rt");
51 ok(c
== '\n', "read wrong byte\n");
52 /* See bug 16970 for why we care about _filbuf.
53 * ftell returns screwy values on files with lots
54 * of bare LFs in ascii mode because it assumes
55 * that ascii files contain only CRLFs, removes
56 * the CR's early in _filbuf, and adjusts the return
57 * value of ftell to compensate.
58 * native _filbuf will read the whole file, then consume and return
59 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
60 * pointing to a buffer of three bare LFs, so
61 * ftell will return 4 - 3 - 3 = -2.
63 ok(ftell(fp
) == -2, "ascii crlf removal does not match native\n");
64 ok(fgetpos(fp
, &pos
) == 0, "fgetpos fail\n");
65 ok(pos
== -2, "ftell does not match fgetpos\n");
70 static void test_fdopen( void )
72 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
77 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
78 write (fd
, buffer
, sizeof (buffer
));
81 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
82 lseek (fd
, 5, SEEK_SET
);
83 file
= fdopen (fd
, "rb");
84 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
85 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
87 unlink ("fdopen.tst");
90 static void test_fileops( void )
92 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
100 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
101 write (fd
, outbuffer
, sizeof (outbuffer
));
104 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
105 file
= fdopen (fd
, "rb");
106 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error\n");
107 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected\n");
108 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF\n");
109 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
111 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected\n");
112 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size\n");
113 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected\n");
114 ok(strlen(buffer
) == 1,"fgets dropped chars\n");
115 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars\n");
118 for (i
= 0, c
= EOF
; i
< sizeof(outbuffer
); i
++)
120 ok((c
= fgetc(file
)) == outbuffer
[i
], "fgetc returned wrong data\n");
122 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
123 ok(feof(file
), "feof did not return EOF\n");
124 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF\n");
125 ok(feof(file
), "feof after ungetc(EOF) did not return EOF\n");
126 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
127 c
= outbuffer
[sizeof(outbuffer
) - 1];
128 ok(ungetc(c
, file
) == c
, "ungetc did not return its input\n");
129 ok(!feof(file
), "feof after ungetc returned EOF\n");
130 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF\n");
131 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
132 "getc did not return ungetc'd data\n");
133 ok(!feof(file
), "feof after getc returned EOF prematurely\n");
134 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
135 ok(feof(file
), "feof after getc did not return EOF\n");
138 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
139 ok(pos
== 0, "Unexpected result of fgetpos %x%08x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
140 pos
= sizeof (outbuffer
);
141 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected\n");
142 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
143 ok(pos
== sizeof (outbuffer
), "Unexpected result of fgetpos %x%08x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
146 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
147 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
148 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) !=0,"fgetws failed unexpected\n");
149 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) ==0,"fgetws didn't signal EOF\n");
150 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
152 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
153 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
154 ok(fgetws(wbuffer
,sizeof(outbuffer
)/sizeof(outbuffer
[0]),file
) !=0,"fgets failed unexpected\n");
155 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
158 file
= fopen("fdopen.tst", "rb");
159 ok( file
!= NULL
, "fopen failed\n");
160 /* sizeof(buffer) > content of file */
161 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
162 /* feof should be set now */
163 ok(feof(file
), "feof after fread failed\n");
166 unlink ("fdopen.tst");
169 #define IOMODE (ao?"ascii mode":"binary mode")
170 static void test_readmode( BOOL ascii_mode
)
172 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";
173 static const char padbuffer
[] = "ghjghjghjghj";
174 static const char nlbuffer
[] = "\r\n";
175 char buffer
[2*BUFSIZ
+256];
184 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
185 /* an internal buffer of BUFSIZ is maintained, so make a file big
186 * enough to test operations that cross the buffer boundary
188 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
190 write (fd
, padbuffer
, strlen(padbuffer
));
191 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
193 write (fd
, &padbuffer
[i
], 1);
194 write (fd
, nlbuffer
, strlen(nlbuffer
));
195 write (fd
, outbuffer
, sizeof (outbuffer
));
199 /* Open file in ascii mode */
200 fd
= open ("fdopen.tst", O_RDONLY
);
201 file
= fdopen (fd
, "r");
202 ao
= -1; /* on offset to account for carriage returns */
205 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
206 file
= fdopen (fd
, "rb");
210 /* first is a test of fgets, ftell, fseek */
211 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
212 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
215 ok(l
== pl
,"padding line ftell got %ld should be %d in %s\n", l
, pl
, IOMODE
);
216 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
217 lstrlenA(buffer
), pl
+ao
, IOMODE
);
218 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
219 if (outbuffer
[fp
] == '\n') break;
221 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
223 ok(l
== pl
+fp
,"line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
224 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
225 lstrlenA(buffer
), fp
+ao
, IOMODE
);
226 /* test a seek back across the buffer boundary */
228 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
230 ok(l
== pl
,"ftell after seek got %ld should be %d in %s\n", l
, pl
, IOMODE
);
231 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
233 ok(l
== pl
+fp
,"second read of line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
234 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
235 lstrlenA(buffer
), fp
+ao
, IOMODE
);
236 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
239 ok(l
== pl
+fp
,"line 2 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
240 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
241 lstrlenA(buffer
), 2+ao
, IOMODE
);
243 /* test fread across buffer boundary */
245 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
246 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
248 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
249 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
251 ok(l
== pl
+j
-(ao
*4)-5,"ftell after fread got %ld should be %d in %s\n", l
, pl
+j
-(ao
*4)-5, IOMODE
);
253 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
257 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
259 if (ao
&& (*optr
== '\r'))
262 /* fread should return the requested number of bytes if available */
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,j
,file
);
268 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
270 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
271 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
272 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
273 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
274 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
275 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
276 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
277 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
278 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
279 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
281 /* test some additional functions */
283 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
284 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
286 ip
= (const int *)outbuffer
;
287 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
288 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
289 if (outbuffer
[fp
] == '\n') break;
291 /* this will cause the next _getw to cross carriage return characters */
292 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
293 for (i
=0, j
=0; i
<6; i
++) {
294 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
295 buffer
[j
++] = outbuffer
[fp
-3+i
];
299 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
302 unlink ("fdopen.tst");
305 static void test_asciimode(void)
311 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
312 fp
= fopen("ascii.tst", "wb");
315 fp
= fopen("ascii.tst", "rt");
316 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets\n");
317 ok(0 == strcmp(buf
, "\r\n"), "CR CR LF not read as CR LF\n");
319 ok((fread(buf
, 1, sizeof(buf
), fp
) == 2) && (0 == strcmp(buf
, "\r\n")), "CR CR LF not read as CR LF\n");
323 /* Simple test of foo ^Z [more than one block] bar handling */
324 fp
= fopen("ascii.tst", "wb");
325 fputs("foo\032", fp
); /* foo, logical EOF, ... */
326 fseek(fp
, 65536L, SEEK_SET
); /* ... more than MSVCRT_BUFSIZ, ... */
327 fputs("bar", fp
); /* ... bar */
329 fp
= fopen("ascii.tst", "rt");
330 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets foo\n");
331 ok(0 == strcmp(buf
, "foo"), "foo ^Z not read as foo by fgets\n");
332 ok(fgets(buf
, sizeof(buf
), fp
) == NULL
, "fgets after logical EOF\n");
334 ok((fread(buf
, 1, sizeof(buf
), fp
) == 3) && (0 == strcmp(buf
, "foo")), "foo ^Z not read as foo by fread\n");
335 ok((fread(buf
, 1, sizeof(buf
), fp
) == 0), "fread after logical EOF\n");
338 /* Show ASCII mode handling*/
339 fp
= fopen("ascii.tst","wb");
340 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp
);
343 fp
= fopen("ascii.tst", "r");
346 fseek(fp
,0,SEEK_CUR
);
347 for(i
=1; i
<10; i
++) {
348 ok((j
= ftell(fp
)) == i
*3, "ftell fails in TEXT mode\n");
349 fseek(fp
,0,SEEK_CUR
);
350 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek failed in line %d\n", i
);
353 /* Show that fseek doesn't skip \\r !*/
356 fseek(fp
, 2 ,SEEK_CUR
);
357 for(i
=1; i
<10; i
++) {
358 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with pos Offset failed in line %d\n", i
);
359 fseek(fp
, 2 ,SEEK_CUR
);
361 fseek(fp
, 9*3 ,SEEK_SET
);
363 fseek(fp
, -4 ,SEEK_CUR
);
364 for(i
= 8; i
>=0; i
--) {
365 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with neg Offset failed in line %d\n", i
);
366 fseek(fp
, -4 ,SEEK_CUR
);
368 /* Show what happens is fseek positions filepointer on \\r */
370 fp
= fopen("ascii.tst", "r");
371 fseek(fp
, 3 ,SEEK_SET
);
372 ok((c
= fgetc(fp
)) == '1', "fgetc fails to read next char when positioned on \\r\n");
378 static void test_asciimode2(void)
380 /* Error sequence from one app was getchar followed by small fread
381 * with one \r removed had last byte of buffer filled with
382 * next byte of *unbuffered* data rather than next byte from buffer
383 * Test case is a short string of one byte followed by a newline
384 * followed by filler to fill out the sector, then a sector of
385 * some different byte.
391 static const char obuf
[] =
393 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
394 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
395 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
396 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
397 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
398 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
399 "000000000000000000\n"
400 "1111111111111111111";
402 fp
= fopen("ascii2.tst", "wt");
403 fwrite(obuf
, 1, sizeof(obuf
), fp
);
406 fp
= fopen("ascii2.tst", "rt");
407 ok(getc(fp
) == '0', "first char not 0\n");
408 memset(ibuf
, 0, sizeof(ibuf
));
409 i
= fread(ibuf
, 1, sizeof(ibuf
), fp
);
410 ok(i
== sizeof(ibuf
), "fread i %d != sizeof(ibuf)\n", i
);
411 ok(0 == strncmp(ibuf
, obuf
+1, sizeof(ibuf
)), "ibuf != obuf\n");
413 unlink("ascii2.tst");
416 static WCHAR
* AtoW( const char* p
)
419 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
420 buffer
= malloc( len
* sizeof(WCHAR
) );
421 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
425 static void test_fgetc( void )
431 tempf
=_tempnam(".","wne");
432 tempfh
= fopen(tempf
,"w+");
437 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
439 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
444 static void test_fputc( void )
450 tempf
=_tempnam(".","wne");
451 tempfh
= fopen(tempf
,"wb");
452 ret
= fputc(0,tempfh
);
453 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
454 ret
= fputc(0xff,tempfh
);
455 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
456 ret
= fputc(0xffffffff,tempfh
);
457 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
460 tempfh
= fopen(tempf
,"rb");
461 ret
= fputc(0,tempfh
);
462 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
468 static void test_flsbuf( void )
475 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
477 tempf
=_tempnam(".","wne");
478 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
480 tempfh
= fopen(tempf
,"wb");
481 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
482 ret
= _flsbuf(0,tempfh
);
483 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
484 bufmodes
[bufmode
], 0, ret
);
485 ret
= _flsbuf(0xff,tempfh
);
486 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
487 bufmodes
[bufmode
], 0, ret
);
488 ret
= _flsbuf(0xffffffff,tempfh
);
489 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
490 bufmodes
[bufmode
], 0, ret
);
494 tempfh
= fopen(tempf
,"rb");
495 ret
= _flsbuf(0,tempfh
);
496 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
499 /* See bug 17123, exposed by WinAVR's make */
500 tempfh
= fopen(tempf
,"w");
501 ok(tempfh
->_cnt
== 0, "_cnt on freshly opened file was %d\n", tempfh
->_cnt
);
502 setbuf(tempfh
, NULL
);
503 ok(tempfh
->_cnt
== 0, "_cnt on unbuffered file was %d\n", tempfh
->_cnt
);
504 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
506 ret
= _flsbuf('Q',tempfh
);
507 ok('Q' == ret
, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret
);
508 /* ... and reset it to zero */
509 ok(tempfh
->_cnt
== 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh
->_cnt
);
511 /* And just for grins, make sure the file is correct */
512 tempfh
= fopen(tempf
,"r");
514 ok(c
== 'Q', "first byte should be 'Q'\n");
516 ok(c
== EOF
, "there should only be one byte\n");
522 static void test_fgetwc( void )
528 static const char mytext
[]= "This is test_fgetwc\r\n";
529 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
530 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
531 BOOL diff_found
= FALSE
;
536 tempf
=_tempnam(".","wne");
537 tempfh
= fopen(tempf
,"wb");
539 /* pad to almost the length of the internal buffer */
540 for (i
=0; i
<BUFSIZ
-4; i
++)
546 fputs(mytext
,tempfh
);
548 /* in text mode, getws/c expects multibyte characters */
549 /*currently Wine only supports plain ascii, and that is all that is tested here */
550 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
551 fgetws(wtextW
,LLEN
,tempfh
);
553 ok(l
==BUFSIZ
-2, "ftell expected %d got %ld\n", BUFSIZ
-2, l
);
554 fgetws(wtextW
,LLEN
,tempfh
);
556 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %ld\n", BUFSIZ
-2+strlen(mytext
), l
);
557 mytextW
= AtoW (mytext
);
560 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
562 diff_found
|= (*aptr
!= *wptr
);
564 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
565 ok(*wptr
== '\n', "Carriage return was not skipped\n");
569 tempfh
= fopen(tempf
,"wb");
571 /* pad to almost the length of the internal buffer. Use an odd number of bytes
572 to test that we can read wchars that are split across the internal buffer
574 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
580 fputws(wtextW
,tempfh
);
581 fputws(wtextW
,tempfh
);
583 /* in binary mode, getws/c expects wide characters */
584 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
585 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
586 fgetws(wtextW
,j
,tempfh
);
588 j
=(j
-1)*sizeof(WCHAR
);
589 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
591 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
594 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
595 fgetws(wtextW
,3,tempfh
);
596 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
597 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
600 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
601 for(i
=0; i
<strlen(mytext
); i
++)
603 /* the first time we get the string, it should be entirely within the local buffer */
604 fgetws(wtextW
,LLEN
,tempfh
);
606 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
607 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
611 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
613 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
614 diff_found
|= (*aptr
!= *wptr
);
616 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
617 ok(*wptr
== '\n', "Should get newline\n");
618 for(i
=0; i
<strlen(mytext
); i
++)
620 /* the second time we get the string, it should cross the local buffer boundary.
621 One of the wchars should be split across the boundary */
622 fgetws(wtextW
,LLEN
,tempfh
);
626 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
628 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
629 diff_found
|= (*aptr
!= *wptr
);
631 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
632 ok(*wptr
== '\n', "Should get newline\n");
639 static void test_ctrlz( void )
643 static const char mytext
[]= "This is test_ctrlz";
648 tempf
=_tempnam(".","wne");
649 tempfh
= fopen(tempf
,"wb");
650 fputs(mytext
,tempfh
);
651 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
660 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
661 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
664 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
665 j
+=4; /* ftell should indicate the true end of file */
667 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
668 ok(feof(tempfh
), "did not get EOF\n");
671 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
672 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
674 j
=strlen(mytext
)+3; /* should get through newline */
675 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
677 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
678 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
680 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
681 ok(feof(tempfh
), "did not get EOF\n");
686 static void test_file_put_get( void )
690 static const char mytext
[]= "This is a test_file_put_get\n";
691 static const char dostext
[]= "This is a test_file_put_get\r\n";
693 WCHAR wtextW
[LLEN
+1];
694 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
695 BOOL diff_found
= FALSE
;
698 tempf
=_tempnam(".","wne");
699 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
700 fputs(mytext
,tempfh
);
702 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
703 fgets(btext
,LLEN
,tempfh
);
704 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
705 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
707 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
708 fputs(dostext
,tempfh
);
710 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
711 fgets(btext
,LLEN
,tempfh
);
712 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
714 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
715 fgets(btext
,LLEN
,tempfh
);
716 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
719 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
720 fgetws(wtextW
,LLEN
,tempfh
);
721 mytextW
= AtoW (mytext
);
725 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
727 diff_found
|= (*aptr
!= *wptr
);
729 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
735 static void test_file_write_read( void )
739 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
740 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
744 tempf
=_tempnam(".","wne");
745 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
746 _S_IREAD
| _S_IWRITE
);
748 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
749 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
750 "_write _O_BINARY bad return value\n");
752 i
= lstrlenA(mytext
);
753 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
754 ok(_read(tempfd
,btext
,i
) == i
,
755 "_read _O_BINARY got bad length\n");
756 ok( memcmp(dostext
,btext
,i
) == 0,
757 "problems with _O_BINARY _write / _read\n");
759 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
760 ok(_read(tempfd
,btext
,i
) == i
-1,
761 "_read _O_TEXT got bad length\n");
762 ok( memcmp(mytext
,btext
,i
-1) == 0,
763 "problems with _O_BINARY _write / _O_TEXT _read\n");
765 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
766 _S_IREAD
| _S_IWRITE
);
768 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
769 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
770 "_write _O_TEXT bad return value\n");
772 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
773 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
774 "_read _O_BINARY got bad length\n");
775 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
776 "problems with _O_TEXT _write / _O_BINARY _read\n");
777 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
779 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
780 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
781 "_read _O_TEXT got bad length\n");
782 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
783 "problems with _O_TEXT _write / _read\n");
786 memset(btext
, 0, LLEN
);
787 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
788 ok(tell(tempfd
) == 0, "bad position %lu expecting 0\n", tell(tempfd
));
789 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
790 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
793 /* Test reading only \n or \r */
794 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
795 _lseek(tempfd
, -1, FILE_END
);
796 ret
= _read(tempfd
,btext
,LLEN
);
797 ok(ret
== 1, "_read expected 1 got bad length: %d\n", ret
);
798 _lseek(tempfd
, -2, FILE_END
);
799 ret
= _read(tempfd
,btext
,LLEN
);
800 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
801 _lseek(tempfd
, -3, FILE_END
);
802 ret
= _read(tempfd
,btext
,2);
803 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
804 ok(tell(tempfd
) == 42, "bad position %lu expecting 42\n", tell(tempfd
));
808 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
810 tempf
=_tempnam(".","wne");
811 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,0);
813 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
814 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
815 "_write _O_BINARY bad return value\n");
817 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
818 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
819 "_read _O_BINARY got bad length\n");
820 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
821 "problems with _O_BINARY _write / _read\n");
822 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
824 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
825 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
826 "_read _O_TEXT got bad length\n");
827 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
828 "problems with _O_BINARY _write / _O_TEXT _read\n");
831 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
833 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
835 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
838 static void test_file_inherit_child(const char* fd_s
)
844 ret
=write(fd
, "Success", 8);
845 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
846 lseek(fd
, 0, SEEK_SET
);
847 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
848 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
851 static void test_file_inherit_child_no(const char* fd_s
)
856 ret
= write(fd
, "Success", 8);
857 ok( ret
== -1 && errno
== EBADF
,
858 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
861 static void test_file_inherit( const char* selfname
)
864 const char* arg_v
[5];
867 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
868 ok(fd
!= -1, "Couldn't create test file\n");
870 arg_v
[1] = "tests/file.c";
871 arg_v
[2] = "inherit";
872 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
874 _spawnvp(_P_WAIT
, selfname
, arg_v
);
875 ok(tell(fd
) == 8, "bad position %lu expecting 8\n", tell(fd
));
876 lseek(fd
, 0, SEEK_SET
);
877 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
879 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
881 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
882 ok(fd
!= -1, "Couldn't create test file\n");
884 arg_v
[1] = "tests/file.c";
885 arg_v
[2] = "inherit_no";
886 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
888 _spawnvp(_P_WAIT
, selfname
, arg_v
);
889 ok(tell(fd
) == 0, "bad position %lu expecting 0\n", tell(fd
));
890 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
892 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
895 static void test_tmpnam( void )
897 char name
[MAX_PATH
] = "abc";
901 ok(res
!= NULL
, "tmpnam returned NULL\n");
902 ok(res
[0] == '\\', "first character is not a backslash\n");
903 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
904 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
907 ok(res
!= NULL
, "tmpnam returned NULL\n");
908 ok(res
== name
, "supplied buffer was not used\n");
909 ok(res
[0] == '\\', "first character is not a backslash\n");
910 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
911 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
914 static void test_chsize( void )
917 long cur
, pos
, count
;
918 char temptext
[] = "012345678";
919 char *tempfile
= _tempnam( ".", "tst" );
921 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
923 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
924 ok( fd
> 0, "Couldn't open test file\n" );
926 count
= _write( fd
, temptext
, sizeof(temptext
) );
927 ok( count
> 0, "Couldn't write to test file\n" );
929 /* get current file pointer */
930 cur
= _lseek( fd
, 0, SEEK_CUR
);
932 /* make the file smaller */
933 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
935 pos
= _lseek( fd
, 0, SEEK_CUR
);
936 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
937 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
939 /* enlarge the file */
940 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
942 pos
= _lseek( fd
, 0, SEEK_CUR
);
943 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
944 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
950 static void test_fopen_fclose_fcloseall( void )
952 char fname1
[] = "empty1";
953 char fname2
[] = "empty2";
954 char fname3
[] = "empty3";
955 FILE *stream1
, *stream2
, *stream3
, *stream4
;
958 /* testing fopen() */
959 stream1
= fopen(fname1
, "w+");
960 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
961 stream2
= fopen(fname2
, "w ");
962 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
964 stream3
= fopen(fname3
, "r");
965 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
966 stream3
= fopen(fname3
, "w+");
967 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
969 stream4
= fopen("", "w+");
970 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
971 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
973 stream4
= fopen(NULL
, "w+");
974 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
975 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
977 /* testing fclose() */
978 ret
= fclose(stream2
);
979 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
980 ret
= fclose(stream3
);
981 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
982 ret
= fclose(stream2
);
983 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
984 ret
= fclose(stream3
);
985 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
987 /* testing fcloseall() */
988 numclosed
= _fcloseall();
989 /* fname1 should be closed here */
990 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
991 numclosed
= _fcloseall();
992 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
994 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
995 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
996 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
999 static void test_get_osfhandle(void)
1002 char fname
[] = "t_get_osfhanle";
1003 DWORD bytes_written
;
1006 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
1007 handle
= (HANDLE
)_get_osfhandle(fd
);
1008 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
1010 fd
= _open(fname
, _O_RDONLY
, 0);
1011 ok(fd
!= -1, "Coudn't open '%s' after _get_osfhanle()\n", fname
);
1017 static void test_setmaxstdio(void)
1019 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1020 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1023 static void test_stat(void)
1029 /* Tests for a file */
1030 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1033 ok(fstat(fd
, &buf
) == 0, "fstat failed: errno=%d\n", errno
);
1034 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1035 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1036 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
1037 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1038 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1039 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1041 ok(stat("stat.tst", &buf
) == 0, "stat failed: errno=%d\n", errno
);
1042 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1043 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1044 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1045 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1046 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1052 skip("open failed with errno %d\n", errno
);
1054 /* Tests for a char device */
1055 if (_dup2(0, 10) == 0)
1057 ok(fstat(10, &buf
) == 0, "fstat(stdin) failed: errno=%d\n", errno
);
1058 if ((buf
.st_mode
& _S_IFMT
) == _S_IFCHR
)
1060 ok(buf
.st_mode
== _S_IFCHR
, "bad st_mode=%06o\n", buf
.st_mode
);
1061 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
1062 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
1063 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1066 skip("stdin is not a char device? st_mode=%06o\n", buf
.st_mode
);
1070 skip("_dup2 failed with errno %d\n", errno
);
1072 /* Tests for pipes */
1073 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
1075 ok(fstat(pipes
[0], &buf
) == 0, "fstat(pipe) failed: errno=%d\n", errno
);
1076 ok(buf
.st_mode
== _S_IFIFO
, "bad st_mode=%06o\n", buf
.st_mode
);
1077 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n", buf
.st_dev
, pipes
[0]);
1078 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n", buf
.st_rdev
, pipes
[0]);
1079 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1084 skip("pipe failed with errno %d\n", errno
);
1087 static const char* pipe_string
="Hello world";
1089 /* How many messages to transfer over the pipe */
1090 #define N_TEST_MESSAGES 3
1092 static void test_pipes_child(int argc
, char** args
)
1100 ok(0, "not enough parameters: %d\n", argc
);
1105 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
1109 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1110 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
1111 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write '%s' wrote %d\n", i
, pipe_string
, nwritten
);
1112 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1113 if (i
< N_TEST_MESSAGES
-1)
1117 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
1120 static void test_pipes(const char* selfname
)
1123 char str_fdr
[12], str_fdw
[12];
1125 const char* arg_v
[6];
1127 char expected
[4096];
1131 /* Test reading from a pipe with read() */
1132 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1134 ok(0, "pipe failed with errno %d\n", errno
);
1138 arg_v
[0] = selfname
;
1139 arg_v
[1] = "tests/file.c";
1141 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1142 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1144 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1145 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1147 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1148 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1149 ok(r
== strlen(pipe_string
), "i %d, got %d\n", i
, r
);
1152 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
1155 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1156 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
1157 ok(close(pipes
[0]) == 0, "unable to close %d: %d\n", pipes
[0], errno
);
1159 /* Test reading from a pipe with fread() */
1160 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1162 ok(0, "pipe failed with errno %d\n", errno
);
1166 arg_v
[0] = selfname
;
1167 arg_v
[1] = "tests/file.c";
1169 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1170 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1172 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1173 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1174 file
=fdopen(pipes
[0], "r");
1176 /* In blocking mode, fread will keep calling read() until it gets
1177 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1178 * in cooked mode instead of a pipe, it would also stop on EOL.)
1181 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
1182 strcat(expected
, pipe_string
);
1183 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1184 ok(r
== strlen(expected
), "fread() returned %d: ferror=%d\n", r
, ferror(file
));
1187 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
1189 /* Let child close the file before we read, so we can sense EOF reliably */
1191 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1192 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
1193 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
1194 ok(feof(file
), "feof() is false!\n");
1196 ok(fclose(file
) == 0, "unable to close the pipe: %d\n", errno
);
1199 static void test_unlink(void)
1202 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1203 file
= fopen("test_unlink\\empty", "w");
1204 ok(file
!= NULL
, "unable to create test file\n");
1207 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1208 unlink("test_unlink\\empty");
1209 rmdir("test_unlink");
1217 arg_c
= winetest_get_mainargs( &arg_v
);
1219 /* testing low-level I/O */
1222 if (strcmp(arg_v
[2], "inherit") == 0)
1223 test_file_inherit_child(arg_v
[3]);
1224 else if (strcmp(arg_v
[2], "inherit_no") == 0)
1225 test_file_inherit_child_no(arg_v
[3]);
1226 else if (strcmp(arg_v
[2], "pipes") == 0)
1227 test_pipes_child(arg_c
, arg_v
);
1229 ok(0, "invalid argument '%s'\n", arg_v
[2]);
1232 test_file_inherit(arg_v
[0]);
1233 test_file_write_read();
1238 /* testing stream I/O */
1241 test_fopen_fclose_fcloseall();
1245 test_readmode(FALSE
); /* binary mode */
1246 test_readmode(TRUE
); /* ascii mode */
1252 test_file_put_get();
1254 test_get_osfhandle();
1256 test_pipes(arg_v
[0]);
1258 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1259 * file contains lines in the correct order
1261 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);