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
),file
) !=0,"fgetws failed unexpected\n");
118 ok(fgetws(wbuffer
,sizeof(wbuffer
),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
),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_fgetwc( void )
343 static const char mytext
[]= "This is test_fgetwc\r\n";
344 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
345 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
346 BOOL diff_found
= FALSE
;
351 tempf
=_tempnam(".","wne");
352 tempfh
= fopen(tempf
,"wb");
354 /* pad to almost the length of the internal buffer */
355 for (i
=0; i
<BUFSIZ
-4; i
++)
361 fputs(mytext
,tempfh
);
363 /* in text mode, getws/c expects multibyte characters */
364 /*currently Wine only supports plain ascii, and that is all that is tested here */
365 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
366 fgetws(wtextW
,LLEN
,tempfh
);
368 ok(l
==BUFSIZ
-2, "ftell expected %d got %ld\n", BUFSIZ
-2, l
);
369 fgetws(wtextW
,LLEN
,tempfh
);
371 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %ld\n",
372 BUFSIZ
-2+strlen(mytext
), l
);
373 mytextW
= AtoW (mytext
);
376 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
378 diff_found
|= (*aptr
!= *wptr
);
380 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
381 ok(*wptr
== '\n', "Carriage return was not skipped\n");
385 tempfh
= fopen(tempf
,"wb");
387 /* pad to almost the length of the internal buffer. Use an odd number of bytes
388 to test that we can read wchars that are split across the internal buffer
390 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
396 fputws(wtextW
,tempfh
);
397 fputws(wtextW
,tempfh
);
399 /* in binary mode, getws/c expects wide characters */
400 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
401 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
402 fgetws(wtextW
,j
,tempfh
);
404 j
=(j
-1)*sizeof(WCHAR
);
405 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
407 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
410 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
411 fgetws(wtextW
,3,tempfh
);
412 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
413 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
416 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
417 for(i
=0; i
<strlen(mytext
); i
++)
419 /* the first time we get the string, it should be entirely within the local buffer */
420 fgetws(wtextW
,LLEN
,tempfh
);
422 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
423 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
427 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
429 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
430 diff_found
|= (*aptr
!= *wptr
);
432 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
433 ok(*wptr
== '\n', "Should get newline\n");
434 for(i
=0; i
<strlen(mytext
); i
++)
436 /* the second time we get the string, it should cross the local buffer boundary.
437 One of the wchars should be split across the boundary */
438 fgetws(wtextW
,LLEN
,tempfh
);
442 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
444 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
445 diff_found
|= (*aptr
!= *wptr
);
447 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
448 ok(*wptr
== '\n', "Should get newline\n");
455 static void test_ctrlz( void )
459 static const char mytext
[]= "This is test_ctrlz";
464 tempf
=_tempnam(".","wne");
465 tempfh
= fopen(tempf
,"wb");
466 fputs(mytext
,tempfh
);
467 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
476 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
477 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
480 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
481 j
+=4; /* ftell should indicate the true end of file */
483 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
484 ok(feof(tempfh
), "did not get EOF\n");
487 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
488 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
490 j
=strlen(mytext
)+3; /* should get through newline */
491 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
493 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
494 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
496 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
497 ok(feof(tempfh
), "did not get EOF\n");
502 static void test_file_put_get( void )
506 static const char mytext
[]= "This is a test_file_put_get\n";
507 static const char dostext
[]= "This is a test_file_put_get\r\n";
509 WCHAR wtextW
[LLEN
+1];
510 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
511 BOOL diff_found
= FALSE
;
514 tempf
=_tempnam(".","wne");
515 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
516 fputs(mytext
,tempfh
);
518 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
519 fgets(btext
,LLEN
,tempfh
);
520 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
521 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
523 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
524 fputs(dostext
,tempfh
);
526 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
527 fgets(btext
,LLEN
,tempfh
);
528 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
530 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
531 fgets(btext
,LLEN
,tempfh
);
532 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
535 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
536 fgetws(wtextW
,LLEN
,tempfh
);
537 mytextW
= AtoW (mytext
);
541 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
543 diff_found
|= (*aptr
!= *wptr
);
545 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
551 static void test_file_write_read( void )
555 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
556 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
560 tempf
=_tempnam(".","wne");
561 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
562 _S_IREAD
| _S_IWRITE
);
564 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
565 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
566 "_write _O_BINARY bad return value\n");
568 i
= lstrlenA(mytext
);
569 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
570 ok(_read(tempfd
,btext
,i
) == i
,
571 "_read _O_BINARY got bad length\n");
572 ok( memcmp(dostext
,btext
,i
) == 0,
573 "problems with _O_BINARY _write / _read\n");
575 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
576 ok(_read(tempfd
,btext
,i
) == i
-1,
577 "_read _O_TEXT got bad length\n");
578 ok( memcmp(mytext
,btext
,i
-1) == 0,
579 "problems with _O_BINARY _write / _O_TEXT _read\n");
581 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
582 _S_IREAD
| _S_IWRITE
);
584 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
585 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
586 "_write _O_TEXT bad return value\n");
588 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
589 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
590 "_read _O_BINARY got bad length\n");
591 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
592 "problems with _O_TEXT _write / _O_BINARY _read\n");
593 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
595 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
596 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
597 "_read _O_TEXT got bad length\n");
598 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
599 "problems with _O_TEXT _write / _read\n");
602 memset(btext
, 0, LLEN
);
603 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
604 ok(tell(tempfd
) == 0, "bad position %lu expecting 0\n", tell(tempfd
));
605 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
606 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
609 /* Test reading only \n or \r */
610 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
611 _lseek(tempfd
, -1, FILE_END
);
612 ret
= _read(tempfd
,btext
,LLEN
);
613 ok(ret
== 1, "_read expected 1 got bad length: %d\n", ret
);
614 _lseek(tempfd
, -2, FILE_END
);
615 ret
= _read(tempfd
,btext
,LLEN
);
616 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
617 _lseek(tempfd
, -3, FILE_END
);
618 ret
= _read(tempfd
,btext
,2);
619 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
620 ok(tell(tempfd
) == 42, "bad position %lu expecting 42\n", tell(tempfd
));
624 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
626 tempf
=_tempnam(".","wne");
627 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,0);
629 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
630 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
631 "_write _O_BINARY bad return value\n");
633 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
634 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
635 "_read _O_BINARY got bad length\n");
636 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
637 "problems with _O_BINARY _write / _read\n");
638 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
640 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
641 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
642 "_read _O_TEXT got bad length\n");
643 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
644 "problems with _O_BINARY _write / _O_TEXT _read\n");
647 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
649 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
651 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
654 static void test_file_inherit_child(const char* fd_s
)
660 ret
=write(fd
, "Success", 8);
661 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
662 lseek(fd
, 0, SEEK_SET
);
663 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
664 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
667 static void test_file_inherit_child_no(const char* fd_s
)
672 ret
= write(fd
, "Success", 8);
673 ok( ret
== -1 && errno
== EBADF
,
674 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
677 static void test_file_inherit( const char* selfname
)
680 const char* arg_v
[5];
683 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
684 ok(fd
!= -1, "Couldn't create test file\n");
686 arg_v
[1] = "tests/file.c";
687 arg_v
[2] = "inherit";
688 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
690 _spawnvp(_P_WAIT
, selfname
, arg_v
);
691 ok(tell(fd
) == 8, "bad position %lu expecting 8\n", tell(fd
));
692 lseek(fd
, 0, SEEK_SET
);
693 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
695 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
697 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
698 ok(fd
!= -1, "Couldn't create test file\n");
700 arg_v
[1] = "tests/file.c";
701 arg_v
[2] = "inherit_no";
702 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
704 _spawnvp(_P_WAIT
, selfname
, arg_v
);
705 ok(tell(fd
) == 0, "bad position %lu expecting 0\n", tell(fd
));
706 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
708 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
711 static void test_tmpnam( void )
713 char name
[MAX_PATH
] = "abc";
717 ok(res
!= NULL
, "tmpnam returned NULL\n");
718 ok(res
[0] == '\\', "first character is not a backslash\n");
719 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
720 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
723 ok(res
!= NULL
, "tmpnam returned NULL\n");
724 ok(res
== name
, "supplied buffer was not used\n");
725 ok(res
[0] == '\\', "first character is not a backslash\n");
726 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
727 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
730 static void test_chsize( void )
733 long cur
, pos
, count
;
734 char temptext
[] = "012345678";
735 char *tempfile
= _tempnam( ".", "tst" );
737 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
739 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
740 ok( fd
> 0, "Couldn't open test file\n" );
742 count
= _write( fd
, temptext
, sizeof(temptext
) );
743 ok( count
> 0, "Couldn't write to test file\n" );
745 /* get current file pointer */
746 cur
= _lseek( fd
, 0, SEEK_CUR
);
748 /* make the file smaller */
749 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
751 pos
= _lseek( fd
, 0, SEEK_CUR
);
752 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
753 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
755 /* enlarge the file */
756 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
758 pos
= _lseek( fd
, 0, SEEK_CUR
);
759 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
760 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
766 static void test_fopen_fclose_fcloseall( void )
768 char fname1
[] = "empty1";
769 char fname2
[] = "empty2";
770 char fname3
[] = "empty3";
771 FILE *stream1
, *stream2
, *stream3
, *stream4
;
774 /* testing fopen() */
775 stream1
= fopen(fname1
, "w+");
776 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
777 stream2
= fopen(fname2
, "w ");
778 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
780 stream3
= fopen(fname3
, "r");
781 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
782 stream3
= fopen(fname3
, "w+");
783 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
785 stream4
= fopen("", "w+");
786 ok(stream4
== NULL
&& errno
== ENOENT
,
787 "filename is empty, errno = %d (expected 2)\n", errno
);
789 stream4
= fopen(NULL
, "w+");
790 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
791 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
793 /* testing fclose() */
794 ret
= fclose(stream2
);
795 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
796 ret
= fclose(stream3
);
797 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
798 ret
= fclose(stream2
);
799 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
800 ret
= fclose(stream3
);
801 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
803 /* testing fcloseall() */
804 numclosed
= _fcloseall();
805 /* fname1 should be closed here */
806 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
807 numclosed
= _fcloseall();
808 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
810 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
811 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
812 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
815 static void test_get_osfhandle(void)
818 char fname
[] = "t_get_osfhanle";
822 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
823 handle
= (HANDLE
)_get_osfhandle(fd
);
824 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
826 fd
= _open(fname
, _O_RDONLY
, 0);
827 ok(fd
!= -1, "Coudn't open '%s' after _get_osfhanle()\n", fname
);
833 static void test_setmaxstdio(void)
835 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
836 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
839 static void test_stat(void)
845 /* Tests for a file */
846 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
849 if (fstat(fd
, &buf
) == 0)
851 if ((buf
.st_mode
& _S_IFMT
) == _S_IFREG
)
853 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
854 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n",
855 buf
.st_dev
, buf
.st_rdev
);
856 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
858 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n",
862 skip("file is not a file?\n");
865 skip("fstat failed, errno %d\n", errno
);
870 skip("open failed with errno %d\n", errno
);
872 /* Tests for a char device */
873 if (_dup2(0, 10) == 0)
875 if (fstat(10, &buf
) == 0)
877 if (buf
.st_mode
== _S_IFCHR
)
879 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
880 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
881 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
884 skip("stdin is not a char device?\n");
887 skip("fstat failed with errno %d\n", errno
);
891 skip("_dup2 failed with errno %d\n", errno
);
893 /* Tests for pipes */
894 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
896 if (fstat(pipes
[0], &buf
) == 0)
898 if (buf
.st_mode
== _S_IFIFO
)
900 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n",
901 buf
.st_dev
, pipes
[0]);
902 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n",
903 buf
.st_rdev
, pipes
[0]);
904 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
908 skip("pipe() didn't make a pipe?\n");
911 skip("fstat failed with errno %d\n", errno
);
916 skip("pipe failed with errno %d\n", errno
);
919 static const char* pipe_string
="Hello world";
921 /* How many messages to transfer over the pipe */
922 #define N_TEST_MESSAGES 3
924 static void test_pipes_child(int argc
, char** args
)
932 ok(0, "not enough parameters: %d\n", argc
);
937 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
941 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
942 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
943 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write %d bytes, wrote %d\n", i
, strlen(pipe_string
), nwritten
);
944 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
945 if (i
< N_TEST_MESSAGES
-1)
949 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
952 static void test_pipes(const char* selfname
)
955 char str_fdr
[12], str_fdw
[12];
957 const char* arg_v
[6];
963 /* Test reading from a pipe with read() */
964 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
966 ok(0, "pipe failed with errno %d\n", errno
);
971 arg_v
[1] = "tests/file.c";
973 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
974 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
976 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
977 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
979 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
980 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
981 ok(r
== strlen(pipe_string
), "i %d, expected to read %d bytes, got %d\n", i
, strlen(pipe_string
)+1, r
);
984 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
987 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
988 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
989 ok(close(pipes
[0]) == 0, "unable to close %d: %d\n", pipes
[0], errno
);
991 /* Test reading from a pipe with fread() */
992 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
994 ok(0, "pipe failed with errno %d\n", errno
);
999 arg_v
[1] = "tests/file.c";
1001 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
1002 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
1004 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
1005 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
1006 file
=fdopen(pipes
[0], "r");
1008 /* In blocking mode, fread will keep calling read() until it gets
1009 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1010 * in cooked mode instead of a pipe, it would also stop on EOL.)
1013 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
1014 strcat(expected
, pipe_string
);
1015 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1016 ok(r
== strlen(expected
), "fread() returned %d instead of %d: ferror=%d\n", r
, strlen(expected
), ferror(file
));
1019 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
1021 /* Let child close the file before we read, so we can sense EOF reliably */
1023 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
1024 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
1025 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
1026 ok(feof(file
), "feof() is false!\n");
1028 ok(fclose(file
) == 0, "unable to close the pipe: %d\n", errno
);
1036 arg_c
= winetest_get_mainargs( &arg_v
);
1038 /* testing low-level I/O */
1041 if (strcmp(arg_v
[2], "inherit") == 0)
1042 test_file_inherit_child(arg_v
[3]);
1043 else if (strcmp(arg_v
[2], "inherit_no") == 0)
1044 test_file_inherit_child_no(arg_v
[3]);
1045 else if (strcmp(arg_v
[2], "pipes") == 0)
1046 test_pipes_child(arg_c
, arg_v
);
1048 ok(0, "invalid argument '%s'\n", arg_v
[2]);
1051 test_file_inherit(arg_v
[0]);
1052 test_file_write_read();
1056 /* testing stream I/O */
1058 test_fopen_fclose_fcloseall();
1061 test_readmode(FALSE
); /* binary mode */
1062 test_readmode(TRUE
); /* ascii mode */
1066 test_file_put_get();
1068 test_get_osfhandle();
1070 test_pipes(arg_v
[0]);
1072 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1073 * file contains lines in the correct order
1075 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);