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 %d 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 %d 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 %d 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 %d 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 %d 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 %d 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 if 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
);
445 static void test_fputc( void )
451 tempf
=_tempnam(".","wne");
452 tempfh
= fopen(tempf
,"wb");
453 ret
= fputc(0,tempfh
);
454 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
455 ret
= fputc(0xff,tempfh
);
456 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
457 ret
= fputc(0xffffffff,tempfh
);
458 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
461 tempfh
= fopen(tempf
,"rb");
462 ret
= fputc(0,tempfh
);
463 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
470 static void test_flsbuf( void )
477 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
479 tempf
=_tempnam(".","wne");
480 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
482 tempfh
= fopen(tempf
,"wb");
483 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
484 ret
= _flsbuf(0,tempfh
);
485 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
486 bufmodes
[bufmode
], 0, ret
);
487 ret
= _flsbuf(0xff,tempfh
);
488 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
489 bufmodes
[bufmode
], 0, ret
);
490 ret
= _flsbuf(0xffffffff,tempfh
);
491 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
492 bufmodes
[bufmode
], 0, ret
);
496 tempfh
= fopen(tempf
,"rb");
497 ret
= _flsbuf(0,tempfh
);
498 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
501 /* See bug 17123, exposed by WinAVR's make */
502 tempfh
= fopen(tempf
,"w");
503 ok(tempfh
->_cnt
== 0, "_cnt on freshly opened file was %d\n", tempfh
->_cnt
);
504 setbuf(tempfh
, NULL
);
505 ok(tempfh
->_cnt
== 0, "_cnt on unbuffered file was %d\n", tempfh
->_cnt
);
506 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
508 ret
= _flsbuf('Q',tempfh
);
509 ok('Q' == ret
, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret
);
510 /* ... and reset it to zero */
511 ok(tempfh
->_cnt
== 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh
->_cnt
);
513 /* And just for grins, make sure the file is correct */
514 tempfh
= fopen(tempf
,"r");
516 ok(c
== 'Q', "first byte should be 'Q'\n");
518 ok(c
== EOF
, "there should only be one byte\n");
525 static void test_fgetwc( void )
531 static const char mytext
[]= "This is test_fgetwc\r\n";
532 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
533 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
534 BOOL diff_found
= FALSE
;
539 tempf
=_tempnam(".","wne");
540 tempfh
= fopen(tempf
,"wb");
542 /* pad to almost the length of the internal buffer */
543 for (i
=0; i
<BUFSIZ
-4; i
++)
549 fputs(mytext
,tempfh
);
551 /* in text mode, getws/c expects multibyte characters */
552 /*currently Wine only supports plain ascii, and that is all that is tested here */
553 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
554 fgetws(wtextW
,LLEN
,tempfh
);
556 ok(l
==BUFSIZ
-2, "ftell expected %d got %d\n", BUFSIZ
-2, l
);
557 fgetws(wtextW
,LLEN
,tempfh
);
559 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %d\n", BUFSIZ
-2+lstrlen(mytext
), l
);
560 mytextW
= AtoW (mytext
);
563 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
565 diff_found
|= (*aptr
!= *wptr
);
567 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
568 ok(*wptr
== '\n', "Carriage return was not skipped\n");
572 tempfh
= fopen(tempf
,"wb");
574 /* pad to almost the length of the internal buffer. Use an odd number of bytes
575 to test that we can read wchars that are split across the internal buffer
577 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
583 fputws(wtextW
,tempfh
);
584 fputws(wtextW
,tempfh
);
586 /* in binary mode, getws/c expects wide characters */
587 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
588 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
589 fgetws(wtextW
,j
,tempfh
);
591 j
=(j
-1)*sizeof(WCHAR
);
592 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
594 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
597 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
598 fgetws(wtextW
,3,tempfh
);
599 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
600 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
603 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
604 for(i
=0; i
<strlen(mytext
); i
++)
606 /* the first time we get the string, it should be entirely within the local buffer */
607 fgetws(wtextW
,LLEN
,tempfh
);
609 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
610 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
614 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
616 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
617 diff_found
|= (*aptr
!= *wptr
);
619 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
620 ok(*wptr
== '\n', "Should get newline\n");
621 for(i
=0; i
<strlen(mytext
); i
++)
623 /* the second time we get the string, it should cross the local buffer boundary.
624 One of the wchars should be split across the boundary */
625 fgetws(wtextW
,LLEN
,tempfh
);
629 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
631 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
632 diff_found
|= (*aptr
!= *wptr
);
634 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
635 ok(*wptr
== '\n', "Should get newline\n");
643 static void test_ctrlz( void )
647 static const char mytext
[]= "This is test_ctrlz";
652 tempf
=_tempnam(".","wne");
653 tempfh
= fopen(tempf
,"wb");
654 fputs(mytext
,tempfh
);
655 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
664 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
665 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
668 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
669 j
+=4; /* ftell should indicate the true end of file */
671 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
672 ok(feof(tempfh
), "did not get EOF\n");
675 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
676 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
678 j
=strlen(mytext
)+3; /* should get through newline */
679 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
681 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
682 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
684 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
685 ok(feof(tempfh
), "did not get EOF\n");
691 static void test_file_put_get( void )
695 static const char mytext
[]= "This is a test_file_put_get\n";
696 static const char dostext
[]= "This is a test_file_put_get\r\n";
698 WCHAR wtextW
[LLEN
+1];
699 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
700 BOOL diff_found
= FALSE
;
703 tempf
=_tempnam(".","wne");
704 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
705 fputs(mytext
,tempfh
);
707 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
708 fgets(btext
,LLEN
,tempfh
);
709 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
710 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
712 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
713 fputs(dostext
,tempfh
);
715 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
716 fgets(btext
,LLEN
,tempfh
);
717 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
719 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
720 fgets(btext
,LLEN
,tempfh
);
721 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
724 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
725 fgetws(wtextW
,LLEN
,tempfh
);
726 mytextW
= AtoW (mytext
);
730 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
732 diff_found
|= (*aptr
!= *wptr
);
734 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
741 static void test_file_write_read( void )
745 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
746 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
750 tempf
=_tempnam(".","wne");
751 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
752 _S_IREAD
| _S_IWRITE
);
754 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
755 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
756 "_write _O_BINARY bad return value\n");
758 i
= lstrlenA(mytext
);
759 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
760 ok(_read(tempfd
,btext
,i
) == i
,
761 "_read _O_BINARY got bad length\n");
762 ok( memcmp(dostext
,btext
,i
) == 0,
763 "problems with _O_BINARY _write / _read\n");
765 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
766 ok(_read(tempfd
,btext
,i
) == i
-1,
767 "_read _O_TEXT got bad length\n");
768 ok( memcmp(mytext
,btext
,i
-1) == 0,
769 "problems with _O_BINARY _write / _O_TEXT _read\n");
771 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
772 _S_IREAD
| _S_IWRITE
);
774 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
775 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
776 "_write _O_TEXT bad return value\n");
778 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
779 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
780 "_read _O_BINARY got bad length\n");
781 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
782 "problems with _O_TEXT _write / _O_BINARY _read\n");
783 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
785 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
786 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
787 "_read _O_TEXT got bad length\n");
788 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
789 "problems with _O_TEXT _write / _read\n");
792 memset(btext
, 0, LLEN
);
793 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
794 ok(tell(tempfd
) == 0, "bad position %u expecting 0\n", tell(tempfd
));
795 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
796 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
799 /* Test reading only \n or \r */
800 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
801 _lseek(tempfd
, -1, FILE_END
);
802 ret
= _read(tempfd
,btext
,LLEN
);
803 ok(ret
== 1, "_read expected 1 got bad length: %d\n", ret
);
804 _lseek(tempfd
, -2, FILE_END
);
805 ret
= _read(tempfd
,btext
,LLEN
);
806 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
807 _lseek(tempfd
, -3, FILE_END
);
808 ret
= _read(tempfd
,btext
,2);
809 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
810 ok(tell(tempfd
) == 42, "bad position %u expecting 42\n", tell(tempfd
));
814 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
817 tempf
=_tempnam(".","wne");
818 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,0);
820 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
821 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
822 "_write _O_BINARY bad return value\n");
824 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
825 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
826 "_read _O_BINARY got bad length\n");
827 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
828 "problems with _O_BINARY _write / _read\n");
829 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
831 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
832 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
833 "_read _O_TEXT got bad length\n");
834 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
835 "problems with _O_BINARY _write / _O_TEXT _read\n");
838 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
840 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
842 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
846 static void test_file_inherit_child(const char* fd_s
)
852 ret
=write(fd
, "Success", 8);
853 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
854 lseek(fd
, 0, SEEK_SET
);
855 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
856 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
859 static void test_file_inherit_child_no(const char* fd_s
)
864 ret
= write(fd
, "Success", 8);
865 ok( ret
== -1 && errno
== EBADF
,
866 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
869 static void create_io_inherit_block( STARTUPINFO
*startup
, unsigned int count
, const HANDLE
*handles
)
871 static BYTE block
[1024];
876 startup
->lpReserved2
= block
;
877 startup
->cbReserved2
= sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE
)) * count
;
878 wxflag_ptr
= block
+ sizeof(unsigned);
879 handle_ptr
= (HANDLE
*)(wxflag_ptr
+ count
);
881 *(unsigned*)block
= count
;
882 for (i
= 0; i
< count
; i
++)
884 wxflag_ptr
[i
] = 0x81;
885 handle_ptr
[i
] = handles
[i
];
889 static const char *read_file( HANDLE file
)
891 static char buffer
[128];
893 SetFilePointer( file
, 0, NULL
, FILE_BEGIN
);
894 if (!ReadFile( file
, buffer
, sizeof(buffer
) - 1, &ret
, NULL
)) ret
= 0;
899 static void test_stdout_handle( STARTUPINFO
*startup
, char *cmdline
, HANDLE hstdout
, BOOL expect_stdout
,
904 SECURITY_ATTRIBUTES sa
;
905 PROCESS_INFORMATION proc
;
907 /* make file handle inheritable */
908 sa
.nLength
= sizeof(sa
);
909 sa
.lpSecurityDescriptor
= NULL
;
910 sa
.bInheritHandle
= TRUE
;
912 hErrorFile
= CreateFileA( "fdopen.err", GENERIC_READ
|GENERIC_WRITE
,
913 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
914 startup
->dwFlags
= STARTF_USESTDHANDLES
;
915 startup
->hStdInput
= GetStdHandle( STD_INPUT_HANDLE
);
916 startup
->hStdOutput
= hErrorFile
;
917 startup
->hStdError
= GetStdHandle( STD_ERROR_HANDLE
);
919 CreateProcessA( NULL
, cmdline
, NULL
, NULL
, TRUE
,
920 CREATE_DEFAULT_ERROR_MODE
| NORMAL_PRIORITY_CLASS
, NULL
, NULL
, startup
, &proc
);
921 winetest_wait_child_process( proc
.hProcess
);
923 data
= read_file( hErrorFile
);
925 ok( strcmp( data
, "Success" ), "%s: Error file shouldn't contain data\n", descr
);
927 ok( !strcmp( data
, "Success" ), "%s: Wrong error data (%s)\n", descr
, data
);
931 data
= read_file( hstdout
);
933 ok( !strcmp( data
, "Success" ), "%s: Wrong stdout data (%s)\n", descr
, data
);
935 ok( strcmp( data
, "Success" ), "%s: Stdout file shouldn't contain data\n", descr
);
938 CloseHandle( hErrorFile
);
939 DeleteFile( "fdopen.err" );
942 static void test_file_inherit( const char* selfname
)
945 const char* arg_v
[5];
947 char cmdline
[MAX_PATH
];
949 SECURITY_ATTRIBUTES sa
;
952 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
953 ok(fd
!= -1, "Couldn't create test file\n");
955 arg_v
[1] = "tests/file.c";
956 arg_v
[2] = "inherit";
957 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
959 _spawnvp(_P_WAIT
, selfname
, arg_v
);
960 ok(tell(fd
) == 8, "bad position %u expecting 8\n", tell(fd
));
961 lseek(fd
, 0, SEEK_SET
);
962 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
964 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
966 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
967 ok(fd
!= -1, "Couldn't create test file\n");
969 arg_v
[1] = "tests/file.c";
970 arg_v
[2] = "inherit_no";
971 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
973 _spawnvp(_P_WAIT
, selfname
, arg_v
);
974 ok(tell(fd
) == 0, "bad position %u expecting 0\n", tell(fd
));
975 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
977 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
979 /* make file handle inheritable */
980 sa
.nLength
= sizeof(sa
);
981 sa
.lpSecurityDescriptor
= NULL
;
982 sa
.bInheritHandle
= TRUE
;
983 sprintf(cmdline
, "%s file inherit 1", selfname
);
985 /* init an empty Reserved2, which should not be recognized as inherit-block */
986 ZeroMemory(&startup
, sizeof(STARTUPINFO
));
987 startup
.cb
= sizeof(startup
);
988 create_io_inherit_block( &startup
, 0, NULL
);
989 test_stdout_handle( &startup
, cmdline
, 0, FALSE
, "empty block" );
991 /* test with valid inheritblock */
992 handles
[0] = GetStdHandle( STD_INPUT_HANDLE
);
993 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
994 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
995 handles
[2] = GetStdHandle( STD_ERROR_HANDLE
);
996 create_io_inherit_block( &startup
, 3, handles
);
997 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "valid block" );
998 CloseHandle( handles
[1] );
999 DeleteFile("fdopen.tst");
1001 /* test inherit block starting with unsigned zero */
1002 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1003 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1004 create_io_inherit_block( &startup
, 3, handles
);
1005 *(unsigned int *)startup
.lpReserved2
= 0;
1006 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "zero count block" );
1007 CloseHandle( handles
[1] );
1008 DeleteFile("fdopen.tst");
1010 /* test inherit block with smaller size */
1011 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1012 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1013 create_io_inherit_block( &startup
, 3, handles
);
1014 startup
.cbReserved2
-= 3;
1015 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "small size block" );
1016 CloseHandle( handles
[1] );
1017 DeleteFile("fdopen.tst");
1019 /* test inherit block with even smaller size */
1020 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1021 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1022 create_io_inherit_block( &startup
, 3, handles
);
1023 startup
.cbReserved2
= sizeof(unsigned int) + sizeof(HANDLE
) + sizeof(char);
1024 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "smaller size block" );
1025 CloseHandle( handles
[1] );
1026 DeleteFile("fdopen.tst");
1028 /* test inherit block with larger size */
1029 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1030 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1031 create_io_inherit_block( &startup
, 3, handles
);
1032 startup
.cbReserved2
+= 7;
1033 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "large size block" );
1034 CloseHandle( handles
[1] );
1035 DeleteFile("fdopen.tst");
1038 static void test_tmpnam( void )
1040 char name
[MAX_PATH
] = "abc";
1044 ok(res
!= NULL
, "tmpnam returned NULL\n");
1045 ok(res
[0] == '\\', "first character is not a backslash\n");
1046 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1047 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
1050 ok(res
!= NULL
, "tmpnam returned NULL\n");
1051 ok(res
== name
, "supplied buffer was not used\n");
1052 ok(res
[0] == '\\', "first character is not a backslash\n");
1053 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1054 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
1057 static void test_chsize( void )
1060 LONG cur
, pos
, count
;
1061 char temptext
[] = "012345678";
1062 char *tempfile
= _tempnam( ".", "tst" );
1064 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
1066 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
1067 ok( fd
> 0, "Couldn't open test file\n" );
1069 count
= _write( fd
, temptext
, sizeof(temptext
) );
1070 ok( count
> 0, "Couldn't write to test file\n" );
1072 /* get current file pointer */
1073 cur
= _lseek( fd
, 0, SEEK_CUR
);
1075 /* make the file smaller */
1076 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
1078 pos
= _lseek( fd
, 0, SEEK_CUR
);
1079 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1080 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
1082 /* enlarge the file */
1083 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
1085 pos
= _lseek( fd
, 0, SEEK_CUR
);
1086 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1087 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
1090 _unlink( tempfile
);
1094 static void test_fopen_fclose_fcloseall( void )
1096 char fname1
[] = "empty1";
1097 char fname2
[] = "empty2";
1098 char fname3
[] = "empty3";
1099 FILE *stream1
, *stream2
, *stream3
, *stream4
;
1102 /* testing fopen() */
1103 stream1
= fopen(fname1
, "w+");
1104 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
1105 stream2
= fopen(fname2
, "w ");
1106 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
1108 stream3
= fopen(fname3
, "r");
1109 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
1110 stream3
= fopen(fname3
, "w+");
1111 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
1113 stream4
= fopen("", "w+");
1114 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1115 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
1117 stream4
= fopen(NULL
, "w+");
1118 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1119 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
1121 /* testing fclose() */
1122 ret
= fclose(stream2
);
1123 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
1124 ret
= fclose(stream3
);
1125 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
1126 ret
= fclose(stream2
);
1127 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
1128 ret
= fclose(stream3
);
1129 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
1131 /* testing fcloseall() */
1132 numclosed
= _fcloseall();
1133 /* fname1 should be closed here */
1134 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
1135 numclosed
= _fcloseall();
1136 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
1138 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
1139 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
1140 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
1143 static void test_get_osfhandle(void)
1146 char fname
[] = "t_get_osfhanle";
1147 DWORD bytes_written
;
1150 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
1151 handle
= (HANDLE
)_get_osfhandle(fd
);
1152 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
1154 fd
= _open(fname
, _O_RDONLY
, 0);
1155 ok(fd
!= -1, "Coudn't open '%s' after _get_osfhanle()\n", fname
);
1161 static void test_setmaxstdio(void)
1163 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1164 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1167 static void test_stat(void)
1173 /* Tests for a file */
1174 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1177 ok(fstat(fd
, &buf
) == 0, "fstat failed: errno=%d\n", errno
);
1178 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1179 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1180 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
1181 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1182 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1183 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1185 ok(stat("stat.tst", &buf
) == 0, "stat failed: errno=%d\n", errno
);
1186 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1187 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1188 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1189 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1190 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1196 skip("open failed with errno %d\n", errno
);
1198 /* Tests for a char device */
1199 if (_dup2(0, 10) == 0)
1201 ok(fstat(10, &buf
) == 0, "fstat(stdin) failed: errno=%d\n", errno
);
1202 if ((buf
.st_mode
& _S_IFMT
) == _S_IFCHR
)
1204 ok(buf
.st_mode
== _S_IFCHR
, "bad st_mode=%06o\n", buf
.st_mode
);
1205 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
1206 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
1207 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1210 skip("stdin is not a char device? st_mode=%06o\n", buf
.st_mode
);
1214 skip("_dup2 failed with errno %d\n", errno
);
1216 /* Tests for pipes */
1217 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
1219 ok(fstat(pipes
[0], &buf
) == 0, "fstat(pipe) failed: errno=%d\n", errno
);
1220 ok(buf
.st_mode
== _S_IFIFO
, "bad st_mode=%06o\n", buf
.st_mode
);
1221 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n", buf
.st_dev
, pipes
[0]);
1222 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n", buf
.st_rdev
, pipes
[0]);
1223 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1228 skip("pipe failed with errno %d\n", errno
);
1231 static const char* pipe_string
="Hello world";
1233 /* How many messages to transfer over the pipe */
1234 #define N_TEST_MESSAGES 3
1236 static void test_pipes_child(int argc
, char** args
)
1244 ok(0, "not enough parameters: %d\n", argc
);
1249 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
1253 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1254 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
1255 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write '%s' wrote %d\n", i
, pipe_string
, nwritten
);
1256 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1257 if (i
< N_TEST_MESSAGES
-1)
1261 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
1264 static void test_pipes(const char* selfname
)
1267 char str_fdr
[12], str_fdw
[12];
1269 const char* arg_v
[6];
1271 char expected
[4096];
1275 /* Test reading from a pipe with read() */
1276 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1278 ok(0, "pipe failed with errno %d\n", errno
);
1282 arg_v
[0] = selfname
;
1283 arg_v
[1] = "tests/file.c";
1285 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1286 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1288 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1289 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1291 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1292 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1293 ok(r
== strlen(pipe_string
), "i %d, got %d\n", i
, r
);
1296 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
1299 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1300 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
1301 ok(close(pipes
[0]) == 0, "unable to close %d: %d\n", pipes
[0], errno
);
1303 /* Test reading from a pipe with fread() */
1304 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1306 ok(0, "pipe failed with errno %d\n", errno
);
1310 arg_v
[0] = selfname
;
1311 arg_v
[1] = "tests/file.c";
1313 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1314 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1316 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1317 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1318 file
=fdopen(pipes
[0], "r");
1320 /* In blocking mode, fread will keep calling read() until it gets
1321 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1322 * in cooked mode instead of a pipe, it would also stop on EOL.)
1325 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
1326 strcat(expected
, pipe_string
);
1327 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1328 ok(r
== strlen(expected
), "fread() returned %d: ferror=%d\n", r
, ferror(file
));
1331 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
1333 /* Let child close the file before we read, so we can sense EOF reliably */
1335 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1336 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
1337 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
1338 ok(feof(file
), "feof() is false!\n");
1340 ok(fclose(file
) == 0, "unable to close the pipe: %d\n", errno
);
1343 static void test_unlink(void)
1346 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1347 file
= fopen("test_unlink\\empty", "w");
1348 ok(file
!= NULL
, "unable to create test file\n");
1351 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1352 unlink("test_unlink\\empty");
1353 rmdir("test_unlink");
1361 arg_c
= winetest_get_mainargs( &arg_v
);
1363 /* testing low-level I/O */
1366 if (strcmp(arg_v
[2], "inherit") == 0)
1367 test_file_inherit_child(arg_v
[3]);
1368 else if (strcmp(arg_v
[2], "inherit_no") == 0)
1369 test_file_inherit_child_no(arg_v
[3]);
1370 else if (strcmp(arg_v
[2], "pipes") == 0)
1371 test_pipes_child(arg_c
, arg_v
);
1373 ok(0, "invalid argument '%s'\n", arg_v
[2]);
1376 test_file_inherit(arg_v
[0]);
1377 test_file_write_read();
1382 /* testing stream I/O */
1385 test_fopen_fclose_fcloseall();
1389 test_readmode(FALSE
); /* binary mode */
1390 test_readmode(TRUE
); /* ascii mode */
1396 test_file_put_get();
1398 test_get_osfhandle();
1400 test_pipes(arg_v
[0]);
1402 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1403 * file contains lines in the correct order
1405 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);