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 void test_fdopen( void )
39 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
44 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
45 write (fd
, buffer
, sizeof (buffer
));
48 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
49 lseek (fd
, 5, SEEK_SET
);
50 file
= fdopen (fd
, "rb");
51 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
52 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
54 unlink ("fdopen.tst");
57 static void test_fileops( void )
59 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
67 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
68 write (fd
, outbuffer
, sizeof (outbuffer
));
71 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
72 file
= fdopen (fd
, "rb");
73 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error\n");
74 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected\n");
75 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF\n");
76 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
78 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected\n");
79 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size\n");
80 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected\n");
81 ok(strlen(buffer
) == 1,"fgets dropped chars\n");
82 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars\n");
85 for (i
= 0, c
= EOF
; i
< sizeof(outbuffer
); i
++)
87 ok((c
= fgetc(file
)) == outbuffer
[i
], "fgetc returned wrong data\n");
89 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
90 ok(feof(file
), "feof did not return EOF\n");
91 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF\n");
92 ok(feof(file
), "feof after ungetc(EOF) did not return EOF\n");
93 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
94 c
= outbuffer
[sizeof(outbuffer
) - 1];
95 ok(ungetc(c
, file
) == c
, "ungetc did not return its input\n");
96 ok(!feof(file
), "feof after ungetc returned EOF\n");
97 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF\n");
98 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
99 "getc did not return ungetc'd data\n");
100 ok(!feof(file
), "feof after getc returned EOF prematurely\n");
101 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF\n");
102 ok(feof(file
), "feof after getc did not return EOF\n");
105 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
106 ok(pos
== 0, "Unexpected result of fgetpos 0x%Lx\n", pos
);
107 pos
= (ULONGLONG
)sizeof (outbuffer
);
108 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected\n");
109 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected\n");
110 ok(pos
== (ULONGLONG
)sizeof (outbuffer
), "Unexpected result of fgetpos 0x%Lx\n", pos
);
113 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
114 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
115 ok(fgetws(wbuffer
,sizeof(wbuffer
),file
) !=0,"fgetws failed unexpected\n");
116 ok(fgetws(wbuffer
,sizeof(wbuffer
),file
) ==0,"fgetws didn't signal EOF\n");
117 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
119 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
120 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
121 ok(fgetws(wbuffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected\n");
122 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
125 file
= fopen("fdopen.tst", "rb");
126 ok( file
!= NULL
, "fopen failed\n");
127 /* sizeof(buffer) > content of file */
128 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
129 /* feof should be set now */
130 ok(feof(file
), "feof after fread failed\n");
133 unlink ("fdopen.tst");
136 #define IOMODE (ao?"ascii mode":"binary mode")
137 static void test_readmode( BOOL ascii_mode
)
139 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";
140 static const char padbuffer
[] = "ghjghjghjghj";
141 static const char nlbuffer
[] = "\r\n";
142 char buffer
[2*BUFSIZ
+256];
151 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
152 /* an internal buffer of BUFSIZ is maintained, so make a file big
153 * enough to test operations that cross the buffer boundary
155 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
157 write (fd
, padbuffer
, strlen(padbuffer
));
158 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
160 write (fd
, &padbuffer
[i
], 1);
161 write (fd
, nlbuffer
, strlen(nlbuffer
));
162 write (fd
, outbuffer
, sizeof (outbuffer
));
166 /* Open file in ascii mode */
167 fd
= open ("fdopen.tst", O_RDONLY
);
168 file
= fdopen (fd
, "r");
169 ao
= -1; /* on offset to account for carriage returns */
172 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
173 file
= fdopen (fd
, "rb");
177 /* first is a test of fgets, ftell, fseek */
178 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
179 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
182 ok(l
== pl
,"padding line ftell got %ld should be %d in %s\n", l
, pl
, IOMODE
);
183 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
184 lstrlenA(buffer
), pl
+ao
, IOMODE
);
185 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
186 if (outbuffer
[fp
] == '\n') break;
188 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
190 ok(l
== pl
+fp
,"line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
191 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
192 lstrlenA(buffer
), fp
+ao
, IOMODE
);
193 /* test a seek back across the buffer boundary */
195 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
197 ok(l
== pl
,"ftell after seek got %ld should be %d in %s\n", l
, pl
, IOMODE
);
198 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
200 ok(l
== pl
+fp
,"second read of line 1 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
201 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
202 lstrlenA(buffer
), fp
+ao
, IOMODE
);
203 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
206 ok(l
== pl
+fp
,"line 2 ftell got %ld should be %d in %s\n", l
, pl
+fp
, IOMODE
);
207 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
208 lstrlenA(buffer
), 2+ao
, IOMODE
);
210 /* test fread across buffer boundary */
212 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
213 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
215 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
216 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
218 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
);
220 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
224 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
226 if (ao
&& (*optr
== '\r'))
229 /* fread should return the requested number of bytes if available */
231 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
232 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
234 i
=fread(buffer
,1,j
,file
);
235 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
237 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
238 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
239 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
240 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
241 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
242 todo_wine
ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
243 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
244 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
245 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
246 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
248 /* test some additional functions */
250 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
251 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
253 ip
= (const int *)outbuffer
;
254 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
255 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
256 if (outbuffer
[fp
] == '\n') break;
258 /* this will cause the next _getw to cross carriage return characters */
259 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
260 for (i
=0, j
=0; i
<6; i
++) {
261 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
262 buffer
[j
++] = outbuffer
[fp
-3+i
];
266 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
269 unlink ("fdopen.tst");
273 static WCHAR
* AtoW( const char* p
)
276 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
277 buffer
= malloc( len
* sizeof(WCHAR
) );
278 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
282 static void test_fgetc( void )
288 tempf
=_tempnam(".","wne");
289 tempfh
= fopen(tempf
,"w+");
294 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
296 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
301 static void test_fgetwc( void )
307 static const char mytext
[]= "This is test_fgetwc\r\n";
308 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
309 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
310 BOOL diff_found
= FALSE
;
315 tempf
=_tempnam(".","wne");
316 tempfh
= fopen(tempf
,"wb");
318 /* pad to almost the length of the internal buffer */
319 for (i
=0; i
<BUFSIZ
-4; i
++)
325 fputs(mytext
,tempfh
);
327 /* in text mode, getws/c expects multibyte characters */
328 /*currently Wine only supports plain ascii, and that is all that is tested here */
329 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
330 fgetws(wtextW
,LLEN
,tempfh
);
332 ok(l
==BUFSIZ
-2, "ftell expected %d got %ld\n", BUFSIZ
-2, l
);
333 fgetws(wtextW
,LLEN
,tempfh
);
335 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %ld\n",
336 BUFSIZ
-2+strlen(mytext
), l
);
337 mytextW
= AtoW (mytext
);
340 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
342 diff_found
|= (*aptr
!= *wptr
);
344 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
345 ok(*wptr
== '\n', "Carriage return was not skipped\n");
349 tempfh
= fopen(tempf
,"wb");
351 /* pad to almost the length of the internal buffer. Use an odd number of bytes
352 to test that we can read wchars that are split across the internal buffer
354 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
360 fputws(wtextW
,tempfh
);
361 fputws(wtextW
,tempfh
);
363 /* in binary mode, getws/c expects wide characters */
364 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
365 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
366 fgetws(wtextW
,j
,tempfh
);
368 j
=(j
-1)*sizeof(WCHAR
);
369 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
371 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
374 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
375 fgetws(wtextW
,3,tempfh
);
376 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
377 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
380 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
381 for(i
=0; i
<strlen(mytext
); i
++)
383 /* the first time we get the string, it should be entirely within the local buffer */
384 fgetws(wtextW
,LLEN
,tempfh
);
386 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
387 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
391 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
393 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
394 diff_found
|= (*aptr
!= *wptr
);
396 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
397 ok(*wptr
== '\n', "Should get newline\n");
398 for(i
=0; i
<strlen(mytext
); i
++)
400 /* the second time we get the string, it should cross the local buffer boundary.
401 One of the wchars should be split across the boundary */
402 fgetws(wtextW
,LLEN
,tempfh
);
406 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
408 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
409 diff_found
|= (*aptr
!= *wptr
);
411 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
412 ok(*wptr
== '\n', "Should get newline\n");
419 static void test_ctrlz( void )
423 static const char mytext
[]= "This is test_ctrlz";
428 tempf
=_tempnam(".","wne");
429 tempfh
= fopen(tempf
,"wb");
430 fputs(mytext
,tempfh
);
431 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
440 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
441 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
444 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
445 j
+=4; /* ftell should indicate the true end of file */
447 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
448 ok(feof(tempfh
), "did not get EOF\n");
451 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
452 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
454 j
=strlen(mytext
)+3; /* should get through newline */
455 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
457 ok(l
==j
, "ftell expected %d got %ld\n", j
, l
);
458 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
460 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
461 ok(feof(tempfh
), "did not get EOF\n");
466 static void test_file_put_get( void )
470 static const char mytext
[]= "This is a test_file_put_get\n";
471 static const char dostext
[]= "This is a test_file_put_get\r\n";
473 WCHAR wtextW
[LLEN
+1];
474 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
475 BOOL diff_found
= FALSE
;
478 tempf
=_tempnam(".","wne");
479 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
480 fputs(mytext
,tempfh
);
482 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
483 fgets(btext
,LLEN
,tempfh
);
484 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
485 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
487 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
488 fputs(dostext
,tempfh
);
490 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
491 fgets(btext
,LLEN
,tempfh
);
492 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
494 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
495 fgets(btext
,LLEN
,tempfh
);
496 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
499 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
500 fgetws(wtextW
,LLEN
,tempfh
);
501 mytextW
= AtoW (mytext
);
505 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
507 diff_found
|= (*aptr
!= *wptr
);
509 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
515 static void test_file_write_read( void )
519 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
520 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
524 tempf
=_tempnam(".","wne");
525 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
526 _S_IREAD
| _S_IWRITE
);
528 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
529 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
530 "_write _O_BINARY bad return value\n");
532 i
= lstrlenA(mytext
);
533 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
534 ok(_read(tempfd
,btext
,i
) == i
,
535 "_read _O_BINARY got bad length\n");
536 ok( memcmp(dostext
,btext
,i
) == 0,
537 "problems with _O_BINARY _write / _read\n");
539 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
540 ok(_read(tempfd
,btext
,i
) == i
-1,
541 "_read _O_TEXT got bad length\n");
542 ok( memcmp(mytext
,btext
,i
-1) == 0,
543 "problems with _O_BINARY _write / _O_TEXT _read\n");
545 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
546 _S_IREAD
| _S_IWRITE
);
548 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
549 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
550 "_write _O_TEXT bad return value\n");
552 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
553 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
554 "_read _O_BINARY got bad length\n");
555 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
556 "problems with _O_TEXT _write / _O_BINARY _read\n");
557 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
559 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
560 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
561 "_read _O_TEXT got bad length\n");
562 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
563 "problems with _O_TEXT _write / _read\n");
566 memset(btext
, 0, LLEN
);
567 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
568 ok(tell(tempfd
) == 0, "bad position %lu expecting 0\n", tell(tempfd
));
569 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
570 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
573 /* Test reading only \n or \r */
574 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
575 _lseek(tempfd
, -1, FILE_END
);
576 ret
= _read(tempfd
,btext
,LLEN
);
577 ok(ret
== 1, "_read expected 1 got bad length: %d\n", ret
);
578 _lseek(tempfd
, -2, FILE_END
);
579 ret
= _read(tempfd
,btext
,LLEN
);
580 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
581 _lseek(tempfd
, -3, FILE_END
);
582 ret
= _read(tempfd
,btext
,2);
583 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
584 ok(tell(tempfd
) == 42, "bad position %lu expecting 42\n", tell(tempfd
));
588 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
590 tempf
=_tempnam(".","wne");
591 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,0);
593 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
594 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
595 "_write _O_BINARY bad return value\n");
597 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
598 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
599 "_read _O_BINARY got bad length\n");
600 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
601 "problems with _O_BINARY _write / _read\n");
602 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
604 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
605 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
606 "_read _O_TEXT got bad length\n");
607 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
608 "problems with _O_BINARY _write / _O_TEXT _read\n");
611 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
613 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
615 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
618 static void test_file_inherit_child(const char* fd_s
)
624 ret
=write(fd
, "Success", 8);
625 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
626 lseek(fd
, 0, SEEK_SET
);
627 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
628 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
631 static void test_file_inherit_child_no(const char* fd_s
)
636 ret
= write(fd
, "Success", 8);
637 ok( ret
== -1 && errno
== EBADF
,
638 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
641 static void test_file_inherit( const char* selfname
)
644 const char* arg_v
[5];
647 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
648 ok(fd
!= -1, "Couldn't create test file\n");
650 arg_v
[1] = "tests/file.c";
651 arg_v
[2] = "inherit";
652 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
654 _spawnvp(_P_WAIT
, selfname
, arg_v
);
655 ok(tell(fd
) == 8, "bad position %lu expecting 8\n", tell(fd
));
656 lseek(fd
, 0, SEEK_SET
);
657 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
659 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
661 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
662 ok(fd
!= -1, "Couldn't create test file\n");
664 arg_v
[1] = "tests/file.c";
665 arg_v
[2] = "inherit_no";
666 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
668 _spawnvp(_P_WAIT
, selfname
, arg_v
);
669 ok(tell(fd
) == 0, "bad position %lu expecting 0\n", tell(fd
));
670 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
672 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
675 static void test_tmpnam( void )
677 char name
[MAX_PATH
] = "abc";
681 ok(res
!= NULL
, "tmpnam returned NULL\n");
682 ok(res
[0] == '\\', "first character is not a backslash\n");
683 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
684 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
687 ok(res
!= NULL
, "tmpnam returned NULL\n");
688 ok(res
== name
, "supplied buffer was not used\n");
689 ok(res
[0] == '\\', "first character is not a backslash\n");
690 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
691 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
694 static void test_chsize( void )
697 long cur
, pos
, count
;
698 char temptext
[] = "012345678";
699 char *tempfile
= _tempnam( ".", "tst" );
701 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
703 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
704 ok( fd
> 0, "Couldn't open test file\n" );
706 count
= _write( fd
, temptext
, sizeof(temptext
) );
707 ok( count
> 0, "Couldn't write to test file\n" );
709 /* get current file pointer */
710 cur
= _lseek( fd
, 0, SEEK_CUR
);
712 /* make the file smaller */
713 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
715 pos
= _lseek( fd
, 0, SEEK_CUR
);
716 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
717 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
719 /* enlarge the file */
720 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
722 pos
= _lseek( fd
, 0, SEEK_CUR
);
723 ok( cur
== pos
, "File pointer changed from: %ld to: %ld\n", cur
, pos
);
724 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
730 static void test_fopen_fclose_fcloseall( void )
732 char fname1
[] = "empty1";
733 char fname2
[] = "empty2";
734 char fname3
[] = "empty3";
735 FILE *stream1
, *stream2
, *stream3
, *stream4
;
738 /* testing fopen() */
739 stream1
= fopen(fname1
, "w+");
740 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
741 stream2
= fopen(fname2
, "w ");
742 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
744 stream3
= fopen(fname3
, "r");
745 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
746 stream3
= fopen(fname3
, "w+");
747 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
749 stream4
= fopen("", "w+");
750 ok(stream4
== NULL
&& errno
== ENOENT
,
751 "filename is empty, errno = %d (expected 2)\n", errno
);
753 stream4
= fopen(NULL
, "w+");
754 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
755 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
757 /* testing fclose() */
758 ret
= fclose(stream2
);
759 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
760 ret
= fclose(stream3
);
761 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
762 ret
= fclose(stream2
);
763 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
764 ret
= fclose(stream3
);
765 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
767 /* testing fcloseall() */
768 numclosed
= _fcloseall();
769 /* fname1 should be closed here */
770 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
771 numclosed
= _fcloseall();
772 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
774 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
775 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
776 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
779 static void test_get_osfhandle(void)
782 char fname
[] = "t_get_osfhanle";
786 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
787 handle
= (HANDLE
)_get_osfhandle(fd
);
788 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
790 fd
= _open(fname
, _O_RDONLY
, 0);
791 ok(fd
!= -1, "Coudn't open '%s' after _get_osfhanle()\n", fname
);
797 static void test_setmaxstdio(void)
799 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
800 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
803 static void test_stat(void)
809 /* Tests for a file */
810 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
813 if (fstat(fd
, &buf
) == 0)
815 if ((buf
.st_mode
& _S_IFMT
) == _S_IFREG
)
817 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
818 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n",
819 buf
.st_dev
, buf
.st_rdev
);
820 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
822 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n",
826 skip("file is not a file?\n");
829 skip("fstat failed, errno %d\n", errno
);
834 skip("open failed with errno %d\n", errno
);
836 /* Tests for a char device */
837 if (_dup2(0, 10) == 0)
839 if (fstat(10, &buf
) == 0)
841 if (buf
.st_mode
== _S_IFCHR
)
843 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
844 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
845 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
848 skip("stdin is not a char device?\n");
851 skip("fstat failed with errno %d\n", errno
);
855 skip("_dup2 failed with errno %d\n", errno
);
857 /* Tests for pipes */
858 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
860 if (fstat(pipes
[0], &buf
) == 0)
862 if (buf
.st_mode
== _S_IFIFO
)
864 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n",
865 buf
.st_dev
, pipes
[0]);
866 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n",
867 buf
.st_rdev
, pipes
[0]);
868 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n",
872 skip("pipe() didn't make a pipe?\n");
875 skip("fstat failed with errno %d\n", errno
);
880 skip("pipe failed with errno %d\n", errno
);
883 static const char* pipe_string
="Hello world";
885 static void test_pipes_child(int argc
, char** args
)
891 ok(0, "not enough parameters: %d\n", argc
);
896 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
899 write(fd
, pipe_string
, strlen(pipe_string
));
900 ok(close(fd
) == 0, "unable to close %d: %d\n", fd
, errno
);
903 static void test_pipes(const char* selfname
)
906 char str_fdr
[12], str_fdw
[12];
908 const char* arg_v
[6];
912 /* Test reading from a pipe with read() */
913 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
915 ok(0, "pipe failed with errno %d\n", errno
);
920 arg_v
[1] = "tests/file.c";
922 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
923 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
925 _spawnvp(_P_NOWAIT
, selfname
, arg_v
);
926 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
928 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
929 ok(r
== strlen(pipe_string
), "expected to read %d bytes, got %d\n", strlen(pipe_string
)+1, r
);
932 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
933 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
934 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
935 ok(close(pipes
[0]) == 0, "unable to close %d: %d\n", pipes
[0], errno
);
937 /* Test reading from a pipe with fread() */
938 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
940 ok(0, "pipe failed with errno %d\n", errno
);
945 arg_v
[1] = "tests/file.c";
947 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
948 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
950 _spawnvp(_P_NOWAIT
, selfname
, arg_v
);
951 ok(close(pipes
[1]) == 0, "unable to close %d: %d\n", pipes
[1], errno
);
952 file
=fdopen(pipes
[0], "r");
954 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
955 ok(r
== strlen(pipe_string
), "fread() returned %d instead of %d: ferror=%d\n", r
, strlen(pipe_string
), ferror(file
));
958 ok(strcmp(buf
, pipe_string
) == 0, "got '%s' expected '%s'\n", buf
, pipe_string
);
960 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
961 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
962 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
963 ok(feof(file
), "feof() is false!\n");
965 ok(fclose(file
) == 0, "unable to close the pipe: %d\n", errno
);
973 arg_c
= winetest_get_mainargs( &arg_v
);
975 /* testing low-level I/O */
978 if (strcmp(arg_v
[2], "inherit") == 0)
979 test_file_inherit_child(arg_v
[3]);
980 else if (strcmp(arg_v
[2], "inherit_no") == 0)
981 test_file_inherit_child_no(arg_v
[3]);
982 else if (strcmp(arg_v
[2], "pipes") == 0)
983 test_pipes_child(arg_c
, arg_v
);
985 ok(0, "invalid argument '%s'\n", arg_v
[2]);
988 test_file_inherit(arg_v
[0]);
989 test_file_write_read();
993 /* testing stream I/O */
995 test_fopen_fclose_fcloseall();
997 test_readmode(FALSE
); /* binary mode */
998 test_readmode(TRUE
); /* ascii mode */
1002 test_file_put_get();
1004 test_get_osfhandle();
1006 test_pipes(arg_v
[0]);