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_fdopen( void )
41 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
46 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
47 write (fd
, buffer
, sizeof (buffer
));
50 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
51 lseek (fd
, 5, SEEK_SET
);
52 file
= fdopen (fd
, "rb");
53 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
54 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
56 unlink ("fdopen.tst");
59 static void test_fileops( void )
61 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
69 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
70 write (fd
, outbuffer
, sizeof (outbuffer
));
73 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
74 file
= fdopen (fd
, "rb");
75 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error\n");
76 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected\n");
77 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF\n");
78 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
80 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected\n");
81 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size\n");
82 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected\n");
83 ok(strlen(buffer
) == 1,"fgets dropped chars\n");
84 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars\n");
87 for (i
= 0, c
= EOF
; i
< sizeof(outbuffer
); i
++)
89 ok((c
= fgetc(file
)) == outbuffer
[i
], "fgetc returned wrong data\n");
91 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
92 ok(feof(file
), "feof did not return EOF\n");
93 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF\n");
94 ok(feof(file
), "feof after ungetc(EOF) did not return EOF\n");
95 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
96 c
= outbuffer
[sizeof(outbuffer
) - 1];
97 ok(ungetc(c
, file
) == c
, "ungetc did not return its input\n");
98 ok(!feof(file
), "feof after ungetc returned EOF\n");
99 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF\n");
100 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
101 "getc did not return ungetc'd data\n");
102 ok(!feof(file
), "feof after getc returned EOF prematurely\n");
103 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
104 ok(feof(file
), "feof after getc did not return EOF\n");
107 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
108 ok(pos
== 0, "Unexpected result of fgetpos 0x%Lx\n", pos
);
109 pos
= (ULONGLONG
)sizeof (outbuffer
);
110 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected\n");
111 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
112 ok(pos
== (ULONGLONG
)sizeof (outbuffer
), "Unexpected result of fgetpos 0x%Lx\n", pos
);
115 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
116 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
117 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) !=0,"fgetws failed unexpected\n");
118 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) ==0,"fgetws didn't signal EOF\n");
119 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
121 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
122 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
123 ok(fgetws(wbuffer
,sizeof(outbuffer
)/sizeof(outbuffer
[0]),file
) !=0,"fgets failed unexpected\n");
124 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
127 file
= fopen("fdopen.tst", "rb");
128 ok( file
!= NULL
, "fopen failed\n");
129 /* sizeof(buffer) > content of file */
130 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
131 /* feof should be set now */
132 ok(feof(file
), "feof after fread failed\n");
135 unlink ("fdopen.tst");
138 #define IOMODE (ao?"ascii mode":"binary mode")
139 static void test_readmode( BOOL ascii_mode
)
141 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";
142 static const char padbuffer
[] = "ghjghjghjghj";
143 static const char nlbuffer
[] = "\r\n";
144 char buffer
[2*BUFSIZ
+256];
153 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
154 /* an internal buffer of BUFSIZ is maintained, so make a file big
155 * enough to test operations that cross the buffer boundary
157 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
159 write (fd
, padbuffer
, strlen(padbuffer
));
160 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
162 write (fd
, &padbuffer
[i
], 1);
163 write (fd
, nlbuffer
, strlen(nlbuffer
));
164 write (fd
, outbuffer
, sizeof (outbuffer
));
168 /* Open file in ascii mode */
169 fd
= open ("fdopen.tst", O_RDONLY
);
170 file
= fdopen (fd
, "r");
171 ao
= -1; /* on offset to account for carriage returns */
174 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
175 file
= fdopen (fd
, "rb");
179 /* first is a test of fgets, ftell, fseek */
180 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
181 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
184 ok(l
== pl
,"padding line ftell got %ld should be %d in %s\n", l
, pl
, IOMODE
);
185 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
186 lstrlenA(buffer
), pl
+ao
, IOMODE
);
187 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
188 if (outbuffer
[fp
] == '\n') break;
190 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
192 ok(l
== pl
+fp
,"line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
193 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
194 lstrlenA(buffer
), fp
+ao
, IOMODE
);
195 /* test a seek back across the buffer boundary */
197 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
199 ok(l
== pl
,"ftell after seek got %ld should be %d in %s\n", l
, pl
, IOMODE
);
200 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
202 ok(l
== pl
+fp
,"second read of line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
203 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
204 lstrlenA(buffer
), fp
+ao
, IOMODE
);
205 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
208 ok(l
== pl
+fp
,"line 2 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
209 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
210 lstrlenA(buffer
), 2+ao
, IOMODE
);
212 /* test fread across buffer boundary */
214 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
215 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
217 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
218 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
220 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
);
222 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
226 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
228 if (ao
&& (*optr
== '\r'))
231 /* fread should return the requested number of bytes if available */
233 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
234 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
236 i
=fread(buffer
,1,j
,file
);
237 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
239 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
240 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
241 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
242 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
243 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
244 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
245 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
246 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
247 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
248 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
250 /* test some additional functions */
252 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
253 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
255 ip
= (const int *)outbuffer
;
256 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
257 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
258 if (outbuffer
[fp
] == '\n') break;
260 /* this will cause the next _getw to cross carriage return characters */
261 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
262 for (i
=0, j
=0; i
<6; i
++) {
263 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
264 buffer
[j
++] = outbuffer
[fp
-3+i
];
268 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
271 unlink ("fdopen.tst");
274 static void test_asciimode(void)
279 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
280 fp
= fopen("ascii.tst", "wb");
283 fp
= fopen("ascii.tst", "rt");
284 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets\n");
285 ok(0 == strcmp(buf
, "\r\n"), "CR CR LF not read as CR LF\n");
287 ok((fread(buf
, 1, sizeof(buf
), fp
) == 2) && (0 == strcmp(buf
, "\r\n")), "CR CR LF not read as CR LF\n");
291 /* Simple test of foo ^Z [more than one block] bar handling */
292 fp
= fopen("ascii.tst", "wb");
293 fputs("foo\032", fp
); /* foo, logical EOF, ... */
294 fseek(fp
, 65536L, SEEK_SET
); /* ... more than MSVCRT_BUFSIZ, ... */
295 fputs("bar", fp
); /* ... bar */
297 fp
= fopen("ascii.tst", "rt");
298 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets foo\n");
299 ok(0 == strcmp(buf
, "foo"), "foo ^Z not read as foo by fgets\n");
300 ok(fgets(buf
, sizeof(buf
), fp
) == NULL
, "fgets after logical EOF\n");
302 ok((fread(buf
, 1, sizeof(buf
), fp
) == 3) && (0 == strcmp(buf
, "foo")), "foo ^Z not read as foo by fread\n");
303 ok((fread(buf
, 1, sizeof(buf
), fp
) == 0), "fread after logical EOF\n");
309 static WCHAR
* AtoW( const char* p
)
312 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
313 buffer
= malloc( len
* sizeof(WCHAR
) );
314 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
318 static void test_fgetc( void )
324 tempf
=_tempnam(".","wne");
325 tempfh
= fopen(tempf
,"w+");
330 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
332 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
337 static void test_fputc( void )
343 tempf
=_tempnam(".","wne");
344 tempfh
= fopen(tempf
,"wb");
345 ret
= fputc(0,tempfh
);
346 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
347 ret
= fputc(0xff,tempfh
);
348 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
349 ret
= fputc(0xffffffff,tempfh
);
350 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
353 tempfh
= fopen(tempf
,"rb");
354 ret
= fputc(0,tempfh
);
355 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
361 static void test_flsbuf( void )
367 int bufmodes
[] = {_IOFBF
,_IONBF
};
369 tempf
=_tempnam(".","wne");
370 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
372 tempfh
= fopen(tempf
,"wb");
373 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
374 ret
= _flsbuf(0,tempfh
);
375 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
376 bufmodes
[bufmode
], 0, ret
);
377 ret
= _flsbuf(0xff,tempfh
);
378 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
379 bufmodes
[bufmode
], 0, ret
);
380 ret
= _flsbuf(0xffffffff,tempfh
);
381 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
382 bufmodes
[bufmode
], 0, ret
);
386 tempfh
= fopen(tempf
,"rb");
387 ret
= _flsbuf(0,tempfh
);
388 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
394 static void test_fgetwc( void )
400 static const char mytext
[]= "This is test_fgetwc\r\n";
401 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
402 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
403 BOOL diff_found
= FALSE
;
408 tempf
=_tempnam(".","wne");
409 tempfh
= fopen(tempf
,"wb");
411 /* pad to almost the length of the internal buffer */
412 for (i
=0; i
<BUFSIZ
-4; i
++)
418 fputs(mytext
,tempfh
);
420 /* in text mode, getws/c expects multibyte characters */
421 /*currently Wine only supports plain ascii, and that is all that is tested here */
422 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
423 fgetws(wtextW
,LLEN
,tempfh
);
425 ok(l
==BUFSIZ
-2, "ftell expected %d got %ld\n", BUFSIZ
-2, l
);
426 fgetws(wtextW
,LLEN
,tempfh
);
428 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %ld\n",
429 BUFSIZ
-2+strlen(mytext
), l
);
430 mytextW
= AtoW (mytext
);
433 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
435 diff_found
|= (*aptr
!= *wptr
);
437 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
438 ok(*wptr
== '\n', "Carriage return was not skipped\n");
442 tempfh
= fopen(tempf
,"wb");
444 /* pad to almost the length of the internal buffer. Use an odd number of bytes
445 to test that we can read wchars that are split across the internal buffer
447 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
453 fputws(wtextW
,tempfh
);
454 fputws(wtextW
,tempfh
);
456 /* in binary mode, getws/c expects wide characters */
457 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
458 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
459 fgetws(wtextW
,j
,tempfh
);
461 j
=(j
-1)*sizeof(WCHAR
);
462 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
464 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
467 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
468 fgetws(wtextW
,3,tempfh
);
469 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
470 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
473 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
474 for(i
=0; i
<strlen(mytext
); i
++)
476 /* the first time we get the string, it should be entirely within the local buffer */
477 fgetws(wtextW
,LLEN
,tempfh
);
479 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
480 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
484 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
486 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
487 diff_found
|= (*aptr
!= *wptr
);
489 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
490 ok(*wptr
== '\n', "Should get newline\n");
491 for(i
=0; i
<strlen(mytext
); i
++)
493 /* the second time we get the string, it should cross the local buffer boundary.
494 One of the wchars should be split across the boundary */
495 fgetws(wtextW
,LLEN
,tempfh
);
499 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
501 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
502 diff_found
|= (*aptr
!= *wptr
);
504 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
505 ok(*wptr
== '\n', "Should get newline\n");
512 static void test_ctrlz( void )
516 static const char mytext
[]= "This is test_ctrlz";
521 tempf
=_tempnam(".","wne");
522 tempfh
= fopen(tempf
,"wb");
523 fputs(mytext
,tempfh
);
524 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
533 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
534 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
537 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
538 j
+=4; /* ftell should indicate the true end of file */
540 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
541 ok(feof(tempfh
), "did not get EOF\n");
544 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
545 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
547 j
=strlen(mytext
)+3; /* should get through newline */
548 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
550 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
551 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
553 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
554 ok(feof(tempfh
), "did not get EOF\n");
559 static void test_file_put_get( void )
563 static const char mytext
[]= "This is a test_file_put_get\n";
564 static const char dostext
[]= "This is a test_file_put_get\r\n";
566 WCHAR wtextW
[LLEN
+1];
567 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
568 BOOL diff_found
= FALSE
;
571 tempf
=_tempnam(".","wne");
572 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
573 fputs(mytext
,tempfh
);
575 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
576 fgets(btext
,LLEN
,tempfh
);
577 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
578 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
580 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
581 fputs(dostext
,tempfh
);
583 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
584 fgets(btext
,LLEN
,tempfh
);
585 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
587 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
588 fgets(btext
,LLEN
,tempfh
);
589 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
592 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
593 fgetws(wtextW
,LLEN
,tempfh
);
594 mytextW
= AtoW (mytext
);
598 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
600 diff_found
|= (*aptr
!= *wptr
);
602 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
608 static void test_file_write_read( void )
612 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
613 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
617 tempf
=_tempnam(".","wne");
618 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
619 _S_IREAD
| _S_IWRITE
);
621 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
622 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
623 "_write _O_BINARY bad return value\n");
625 i
= lstrlenA(mytext
);
626 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
627 ok(_read(tempfd
,btext
,i
) == i
,
628 "_read _O_BINARY got bad length\n");
629 ok( memcmp(dostext
,btext
,i
) == 0,
630 "problems with _O_BINARY _write / _read\n");
632 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
633 ok(_read(tempfd
,btext
,i
) == i
-1,
634 "_read _O_TEXT got bad length\n");
635 ok( memcmp(mytext
,btext
,i
-1) == 0,
636 "problems with _O_BINARY _write / _O_TEXT _read\n");
638 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
639 _S_IREAD
| _S_IWRITE
);
641 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
642 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
643 "_write _O_TEXT bad return value\n");
645 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
646 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
647 "_read _O_BINARY got bad length\n");
648 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
649 "problems with _O_TEXT _write / _O_BINARY _read\n");
650 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
652 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
653 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
654 "_read _O_TEXT got bad length\n");
655 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
656 "problems with _O_TEXT _write / _read\n");
659 memset(btext
, 0, LLEN
);
660 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
661 ok(tell(tempfd
) == 0, "bad position %lu expecting 0\n", tell(tempfd
));
662 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
663 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
666 /* Test reading only \n or \r */
667 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
668 _lseek(tempfd
, -1, FILE_END
);
669 ret
= _read(tempfd
,btext
,LLEN
);
670 ok(ret
== 1, "_read expected 1 got bad length: %d\n", ret
);
671 _lseek(tempfd
, -2, FILE_END
);
672 ret
= _read(tempfd
,btext
,LLEN
);
673 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
674 _lseek(tempfd
, -3, FILE_END
);
675 ret
= _read(tempfd
,btext
,2);
676 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
677 ok(tell(tempfd
) == 42, "bad position %lu expecting 42\n", tell(tempfd
));
681 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
683 tempf
=_tempnam(".","wne");
684 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,0);
686 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
687 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
688 "_write _O_BINARY bad return value\n");
690 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
691 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
692 "_read _O_BINARY got bad length\n");
693 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
694 "problems with _O_BINARY _write / _read\n");
695 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
697 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
698 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
699 "_read _O_TEXT got bad length\n");
700 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
701 "problems with _O_BINARY _write / _O_TEXT _read\n");
704 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
706 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
708 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
711 static void test_file_inherit_child(const char* fd_s
)
717 ret
=write(fd
, "Success", 8);
718 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
719 lseek(fd
, 0, SEEK_SET
);
720 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
721 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
724 static void test_file_inherit_child_no(const char* fd_s
)
729 ret
= write(fd
, "Success", 8);
730 ok( ret
== -1 && errno
== EBADF
,
731 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
734 static void test_file_inherit( const char* selfname
)
737 const char* arg_v
[5];
740 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
741 ok(fd
!= -1, "Couldn't create test file\n");
743 arg_v
[1] = "tests/file.c";
744 arg_v
[2] = "inherit";
745 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
747 _spawnvp(_P_WAIT
, selfname
, arg_v
);
748 ok(tell(fd
) == 8, "bad position %lu expecting 8\n", tell(fd
));
749 lseek(fd
, 0, SEEK_SET
);
750 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
752 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
754 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
755 ok(fd
!= -1, "Couldn't create test file\n");
757 arg_v
[1] = "tests/file.c";
758 arg_v
[2] = "inherit_no";
759 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
761 _spawnvp(_P_WAIT
, selfname
, arg_v
);
762 ok(tell(fd
) == 0, "bad position %lu expecting 0\n", tell(fd
));
763 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
765 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
768 static void test_tmpnam( void )
770 char name
[MAX_PATH
] = "abc";
774 ok(res
!= NULL
, "tmpnam returned NULL\n");
775 ok(res
[0] == '\\', "first character is not a backslash\n");
776 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
777 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
780 ok(res
!= NULL
, "tmpnam returned NULL\n");
781 ok(res
== name
, "supplied buffer was not used\n");
782 ok(res
[0] == '\\', "first character is not a backslash\n");
783 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
784 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
787 static void test_chsize( void )
790 long cur
, pos
, count
;
791 char temptext
[] = "012345678";
792 char *tempfile
= _tempnam( ".", "tst" );
794 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
796 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
797 ok( fd
> 0, "Couldn't open test file\n" );
799 count
= _write( fd
, temptext
, sizeof(temptext
) );
800 ok( count
> 0, "Couldn't write to test file\n" );
802 /* get current file pointer */
803 cur
= _lseek( fd
, 0, SEEK_CUR
);
805 /* make the file smaller */
806 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
808 pos
= _lseek( fd
, 0, SEEK_CUR
);
809 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
810 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
812 /* enlarge the file */
813 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
815 pos
= _lseek( fd
, 0, SEEK_CUR
);
816 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
817 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
823 static void test_fopen_fclose_fcloseall( void )
825 char fname1
[] = "empty1";
826 char fname2
[] = "empty2";
827 char fname3
[] = "empty3";
828 FILE *stream1
, *stream2
, *stream3
, *stream4
;
831 /* testing fopen() */
832 stream1
= fopen(fname1
, "w+");
833 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
834 stream2
= fopen(fname2
, "w ");
835 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
837 stream3
= fopen(fname3
, "r");
838 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
839 stream3
= fopen(fname3
, "w+");
840 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
842 stream4
= fopen("", "w+");
843 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
844 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
846 stream4
= fopen(NULL
, "w+");
847 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
848 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
850 /* testing fclose() */
851 ret
= fclose(stream2
);
852 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
853 ret
= fclose(stream3
);
854 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
855 ret
= fclose(stream2
);
856 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
857 ret
= fclose(stream3
);
858 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
860 /* testing fcloseall() */
861 numclosed
= _fcloseall();
862 /* fname1 should be closed here */
863 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
864 numclosed
= _fcloseall();
865 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
867 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
868 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
869 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
872 static void test_get_osfhandle(void)
875 char fname
[] = "t_get_osfhanle";
879 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
880 handle
= (HANDLE
)_get_osfhandle(fd
);
881 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
883 fd
= _open(fname
, _O_RDONLY
, 0);
884 ok(fd
!= -1, "Coudn't open '%s' after _get_osfhanle()\n", fname
);
890 static void test_setmaxstdio(void)
892 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
893 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
896 static void test_stat(void)
902 /* Tests for a file */
903 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
906 if (fstat(fd
, &buf
) == 0)
908 if ((buf
.st_mode
& _S_IFMT
) == _S_IFREG
)
910 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
911 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n",
912 buf
.st_dev
, buf
.st_rdev
);
913 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
915 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n",
919 skip("file is not a file?\n");
922 skip("fstat failed, errno %d\n", errno
);
927 skip("open failed with errno %d\n", errno
);
929 /* Tests for a char device */
930 if (_dup2(0, 10) == 0)
932 if (fstat(10, &buf
) == 0)
934 if (buf
.st_mode
== _S_IFCHR
)
936 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
937 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
938 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
941 skip("stdin is not a char device?\n");
944 skip("fstat failed with errno %d\n", errno
);
948 skip("_dup2 failed with errno %d\n", errno
);
950 /* Tests for pipes */
951 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
953 if (fstat(pipes
[0], &buf
) == 0)
955 if (buf
.st_mode
== _S_IFIFO
)
957 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n",
958 buf
.st_dev
, pipes
[0]);
959 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n",
960 buf
.st_rdev
, pipes
[0]);
961 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
965 skip("pipe() didn't make a pipe?\n");
968 skip("fstat failed with errno %d\n", errno
);
973 skip("pipe failed with errno %d\n", errno
);
976 static const char* pipe_string
="Hello world";
978 /* How many messages to transfer over the pipe */
979 #define N_TEST_MESSAGES 3
981 static void test_pipes_child(int argc
, char** args
)
989 ok(0, "not enough parameters: %d\n", argc
);
994 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
998 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
999 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
1000 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write %d bytes, wrote %d\n", i
, strlen(pipe_string
), nwritten
);
1001 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1002 if (i
< N_TEST_MESSAGES
-1)
1006 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
1009 static void test_pipes(const char* selfname
)
1012 char str_fdr
[12], str_fdw
[12];
1014 const char* arg_v
[6];
1016 char expected
[4096];
1020 /* Test reading from a pipe with read() */
1021 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1023 ok(0, "pipe failed with errno %d\n", errno
);
1027 arg_v
[0] = selfname
;
1028 arg_v
[1] = "tests/file.c";
1030 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1031 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1033 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1034 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1036 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1037 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1038 ok(r
== strlen(pipe_string
), "i %d, expected to read %d bytes, got %d\n", i
, strlen(pipe_string
)+1, r
);
1041 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
1044 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
1045 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
1046 ok(close(pipes
[0]) == 0, "unable to close %d: %d\n", pipes
[0], errno
);
1048 /* Test reading from a pipe with fread() */
1049 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1051 ok(0, "pipe failed with errno %d\n", errno
);
1055 arg_v
[0] = selfname
;
1056 arg_v
[1] = "tests/file.c";
1058 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1059 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1061 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1062 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1063 file
=fdopen(pipes
[0], "r");
1065 /* In blocking mode, fread will keep calling read() until it gets
1066 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1067 * in cooked mode instead of a pipe, it would also stop on EOL.)
1070 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
1071 strcat(expected
, pipe_string
);
1072 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1073 ok(r
== strlen(expected
), "fread() returned %d instead of %d: ferror=%d\n", r
, strlen(expected
), ferror(file
));
1076 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
1078 /* Let child close the file before we read, so we can sense EOF reliably */
1080 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1081 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
1082 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
1083 ok(feof(file
), "feof() is false!\n");
1085 ok(fclose(file
) == 0, "unable to close the pipe: %d\n", errno
);
1088 static void test_unlink(void)
1091 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1092 file
= fopen("test_unlink\\empty", "w");
1093 ok(file
!= NULL
, "unable to create test file\n");
1096 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1097 unlink("test_unlink\\empty");
1098 rmdir("test_unlink");
1106 arg_c
= winetest_get_mainargs( &arg_v
);
1108 /* testing low-level I/O */
1111 if (strcmp(arg_v
[2], "inherit") == 0)
1112 test_file_inherit_child(arg_v
[3]);
1113 else if (strcmp(arg_v
[2], "inherit_no") == 0)
1114 test_file_inherit_child_no(arg_v
[3]);
1115 else if (strcmp(arg_v
[2], "pipes") == 0)
1116 test_pipes_child(arg_c
, arg_v
);
1118 ok(0, "invalid argument '%s'\n", arg_v
[2]);
1121 test_file_inherit(arg_v
[0]);
1122 test_file_write_read();
1127 /* testing stream I/O */
1129 test_fopen_fclose_fcloseall();
1132 test_readmode(FALSE
); /* binary mode */
1133 test_readmode(TRUE
); /* ascii mode */
1139 test_file_put_get();
1141 test_get_osfhandle();
1143 test_pipes(arg_v
[0]);
1145 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1146 * file contains lines in the correct order
1148 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);