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[MSVCRT_BUFSIZ+256];
145 int i, j, fp, ao, *ip, pl;
148 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
149 /* an internal buffer of MSVCRT_BUFSIZ is maintained, so make a file big
150 * enough to test operations that cross the buffer boundary
152 j = (MSVCRT_BUFSIZ-4)/strlen(padbuffer);
154 write (fd, padbuffer, strlen(padbuffer));
155 j = (MSVCRT_BUFSIZ-4)%strlen(padbuffer);
157 write (fd, &padbuffer[i], 1);
158 write (fd, nlbuffer, strlen(nlbuffer));
159 write (fd, outbuffer, sizeof (outbuffer));
163 /* Open file in ascii mode */
164 fd = open ("fdopen.tst", O_RDONLY);
165 file = fdopen (fd, "r");
166 ao = -1; /* on offset to account for carriage returns */
169 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
170 file = fdopen (fd, "rb");
174 /* first is a test of fgets, ftell, fseek */
175 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
176 ok(fgets(buffer,MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
178 pl = MSVCRT_BUFSIZ-2;
179 ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE);
180 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
181 lstrlenA(buffer), pl+ao, IOMODE);
182 for (fp=0; fp<strlen(outbuffer); fp++)
183 if (outbuffer[fp] == '\n') break;
185 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
187 ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
188 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
189 lstrlenA(buffer), fp+ao, IOMODE);
190 /* test a seek back across the buffer boundary */
192 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
194 ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE);
195 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
197 ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
198 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
199 lstrlenA(buffer), fp+ao, IOMODE);
200 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
203 ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
204 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
205 lstrlenA(buffer), 2+ao, IOMODE);
207 /* test fread across buffer boundary */
209 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
210 ok(fgets(buffer,MSVCRT_BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
212 i=fread(buffer,1,256,file);
213 ok(i==j+6+ao*4,"fread failed, expected %d got %d in %s\n", j+6+ao*4, i, IOMODE);
215 ok(l == pl+j+1,"ftell after fread got %ld should be %d in %s\n", l, pl+j+1, IOMODE);
216 /* fread should return the requested number of bytes if available */
218 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
219 ok(fgets(buffer,MSVCRT_BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
221 i=fread(buffer,1,j,file);
222 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
224 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
225 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
226 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
227 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
228 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
229 todo_wine ok(feof(file)==0,"feof failure in %s\n", IOMODE);
230 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
231 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
232 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
233 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
235 /* test some additional functions */
237 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
238 ok(fgets(buffer,MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
240 ip = (int *)outbuffer;
241 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
242 for (fp=0; fp<strlen(outbuffer); fp++)
243 if (outbuffer[fp] == '\n') break;
245 /* this will cause the next _getw to cross carriage return characters */
246 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
247 for (i=0, j=0; i<6; i++) {
248 if (ao==0 || outbuffer[fp-3+i] != '\r')
249 buffer[j++] = outbuffer[fp-3+i];
253 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
256 unlink ("fdopen.tst");
260 static WCHAR* AtoW( char* p )
263 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
264 buffer = malloc( len * sizeof(WCHAR) );
265 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
269 static void test_fgetc( void )
275 tempf=_tempnam(".","wne");
276 tempfh = fopen(tempf,"w+");
281 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
283 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
287 static void test_fgetwc( void )
293 static const char mytext[]= "This is test_fgetwc\r\n";
294 WCHAR wtextW[MSVCRT_BUFSIZ+LLEN+1];
295 WCHAR *mytextW = NULL, *aptr, *wptr;
296 BOOL diff_found = FALSE;
300 tempf=_tempnam(".","wne");
301 tempfh = fopen(tempf,"wb");
303 /* pad to almost the length of the internal buffer */
304 for (i=0; i<MSVCRT_BUFSIZ-4; i++)
310 fputs(mytext,tempfh);
312 /* in text mode, getws/c expects multibyte characters */
313 /*currently Wine only supports plain ascii, and that is all that is tested here */
314 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
315 fgetws(wtextW,LLEN,tempfh);
317 ok(l==MSVCRT_BUFSIZ-2, "ftell expected %d got %ld\n", MSVCRT_BUFSIZ-2, l);
318 fgetws(wtextW,LLEN,tempfh);
320 ok(l==MSVCRT_BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
321 MSVCRT_BUFSIZ-2+strlen(mytext), l);
322 mytextW = AtoW ((char*)mytext);
325 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
327 diff_found |= (*aptr != *wptr);
329 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
330 ok(*wptr == '\n', "Carriage return was not skipped\n");
334 tempfh = fopen(tempf,"wb");
336 /* pad to almost the length of the internal buffer. Use an odd number of bytes
337 to test that we can read wchars that are split across the internal buffer
339 for (i=0; i<MSVCRT_BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
345 fputws(wtextW,tempfh);
346 fputws(wtextW,tempfh);
348 /* in binary mode, getws/c expects wide characters */
349 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
350 j=(MSVCRT_BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
351 fgetws(wtextW,j,tempfh);
353 j=(j-1)*sizeof(WCHAR);
354 ok(l==j, "ftell expected %d got %ld\n", j, l);
356 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
359 ok(l==j, "ftell expected %d got %ld\n", j, l);
360 fgetws(wtextW,3,tempfh);
361 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
362 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
365 ok(l==j, "ftell expected %d got %ld\n", j, l);
366 for(i=0; i<strlen(mytext); i++)
368 /* the first time we get the string, it should be entirely within the local buffer */
369 fgetws(wtextW,LLEN,tempfh);
371 j += (strlen(mytext)-1)*sizeof(WCHAR);
372 ok(l==j, "ftell expected %d got %ld\n", j, l);
376 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
378 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
379 diff_found |= (*aptr != *wptr);
381 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
382 ok(*wptr == '\n', "Should get newline\n");
383 for(i=0; i<strlen(mytext); i++)
385 /* the second time we get the string, it should cross the local buffer boundary.
386 One of the wchars should be split across the boundary */
387 fgetws(wtextW,LLEN,tempfh);
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");
404 static void test_ctrlz( void )
408 static const char mytext[]= "This is test_ctrlz";
413 tempf=_tempnam(".","wne");
414 tempfh = fopen(tempf,"wb");
415 fputs(mytext,tempfh);
416 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
425 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
426 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
429 ok(i==j, "returned string length expected %d got %d\n", j, i);
430 j+=4; /* ftell should indicate the true end of file */
432 ok(l==j, "ftell expected %d got %ld\n", j, l);
433 ok(feof(tempfh), "did not get EOF\n");
436 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
437 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
439 j=strlen(mytext)+3; /* should get through newline */
440 ok(i==j, "returned string length expected %d got %d\n", j, i);
442 ok(l==j, "ftell expected %d got %ld\n", j, l);
443 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
445 ok(i==1, "returned string length expected %d got %d\n", 1, i);
446 ok(feof(tempfh), "did not get EOF\n");
451 static void test_file_put_get( void )
455 static const char mytext[]= "This is a test_file_put_get\n";
456 static const char dostext[]= "This is a test_file_put_get\r\n";
458 WCHAR wtextW[LLEN+1];
459 WCHAR *mytextW = NULL, *aptr, *wptr;
460 BOOL diff_found = FALSE;
463 tempf=_tempnam(".","wne");
464 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
465 fputs(mytext,tempfh);
467 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
468 fgets(btext,LLEN,tempfh);
469 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
470 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
472 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
473 fputs(dostext,tempfh);
475 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
476 fgets(btext,LLEN,tempfh);
477 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
479 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
480 fgets(btext,LLEN,tempfh);
481 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
484 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
485 fgetws(wtextW,LLEN,tempfh);
486 mytextW = AtoW ((char*)mytext);
490 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
492 diff_found |= (*aptr != *wptr);
494 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
500 static void test_file_write_read( void )
504 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
505 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
509 tempf=_tempnam(".","wne");
510 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
511 _S_IREAD | _S_IWRITE);
513 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
514 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
515 "_write _O_BINARY bad return value\n");
517 i = lstrlenA(mytext);
518 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
519 ok(_read(tempfd,btext,i) == i,
520 "_read _O_BINARY got bad length\n");
521 ok( memcmp(dostext,btext,i) == 0,
522 "problems with _O_BINARY _write / _read\n");
524 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
525 ok(_read(tempfd,btext,i) == i-1,
526 "_read _O_TEXT got bad length\n");
527 ok( memcmp(mytext,btext,i-1) == 0,
528 "problems with _O_BINARY _write / _O_TEXT _read\n");
530 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
531 _S_IREAD | _S_IWRITE);
533 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
534 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
535 "_write _O_TEXT bad return value\n");
537 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
538 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
539 "_read _O_BINARY got bad length\n");
540 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
541 "problems with _O_TEXT _write / _O_BINARY _read\n");
542 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
544 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
545 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
546 "_read _O_TEXT got bad length\n");
547 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
548 "problems with _O_TEXT _write / _read\n");
551 memset(btext, 0, LLEN);
552 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
553 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
554 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
555 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
558 /* Test reading only \n or \r */
559 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
560 _lseek(tempfd, -1, FILE_END);
561 ret = _read(tempfd,btext,LLEN);
562 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
563 _lseek(tempfd, -2, FILE_END);
564 ret = _read(tempfd,btext,LLEN);
565 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
566 _lseek(tempfd, -3, FILE_END);
567 ret = _read(tempfd,btext,2);
568 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
569 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
573 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
575 tempf=_tempnam(".","wne");
576 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
578 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
579 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
580 "_write _O_BINARY bad return value\n");
582 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
583 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
584 "_read _O_BINARY got bad length\n");
585 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
586 "problems with _O_BINARY _write / _read\n");
587 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
589 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
590 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
591 "_read _O_TEXT got bad length\n");
592 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
593 "problems with _O_BINARY _write / _O_TEXT _read\n");
596 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
598 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
600 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
603 static void test_file_inherit_child(const char* fd_s)
609 ret =write(fd, "Success", 8);
610 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
611 lseek(fd, 0, SEEK_SET);
612 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
613 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
616 static void test_file_inherit_child_no(const char* fd_s)
621 ret = write(fd, "Success", 8);
622 ok( ret == -1 && errno == EBADF,
623 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
626 static void test_file_inherit( const char* selfname )
629 const char* arg_v[5];
632 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
633 ok(fd != -1, "Couldn't create test file\n");
635 arg_v[1] = "tests/file.c";
636 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
638 _spawnvp(_P_WAIT, selfname, arg_v);
639 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
640 lseek(fd, 0, SEEK_SET);
641 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
643 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
645 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
646 ok(fd != -1, "Couldn't create test file\n");
648 arg_v[1] = "tests/file.c";
649 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
652 _spawnvp(_P_WAIT, selfname, arg_v);
653 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
654 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
656 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
659 static void test_tmpnam( void )
661 char name[MAX_PATH] = "abc";
665 ok(res != NULL, "tmpnam returned NULL\n");
666 ok(res[0] == '\\', "first character is not a backslash\n");
667 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
668 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
671 ok(res != NULL, "tmpnam returned NULL\n");
672 ok(res == name, "supplied buffer was not used\n");
673 ok(res[0] == '\\', "first character is not a backslash\n");
674 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
675 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
678 static void test_chsize( void )
681 long cur, pos, count;
682 char temptext[] = "012345678";
683 char *tempfile = _tempnam( ".", "tst" );
685 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
687 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
688 ok( fd > 0, "Couldn't open test file\n" );
690 count = _write( fd, temptext, sizeof(temptext) );
691 ok( count > 0, "Couldn't write to test file\n" );
693 /* get current file pointer */
694 cur = _lseek( fd, 0, SEEK_CUR );
696 /* make the file smaller */
697 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
699 pos = _lseek( fd, 0, SEEK_CUR );
700 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
701 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
703 /* enlarge the file */
704 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
706 pos = _lseek( fd, 0, SEEK_CUR );
707 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
708 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
714 static void test_fopen_fclose_fcloseall( void )
716 char fname1[] = "empty1";
717 char fname2[] = "empty2";
718 char fname3[] = "empty3";
719 FILE *stream1, *stream2, *stream3, *stream4;
722 /* testing fopen() */
723 stream1 = fopen(fname1, "w+");
724 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
725 stream2 = fopen(fname2, "w ");
726 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
728 stream3 = fopen(fname3, "r");
729 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
730 stream3 = fopen(fname3, "w+");
731 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
733 stream4 = fopen("", "w+");
734 ok(stream4 == NULL && errno == ENOENT,
735 "filename is empty, errno = %d (expected 2)\n", errno);
737 stream4 = fopen(NULL, "w+");
738 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
739 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
741 /* testing fclose() */
742 ret = fclose(stream2);
743 ok(ret == 0, "The file '%s' was not closed\n", fname2);
744 ret = fclose(stream3);
745 ok(ret == 0, "The file '%s' was not closed\n", fname3);
746 ret = fclose(stream2);
747 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
748 ret = fclose(stream3);
749 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
751 /* testing fcloseall() */
752 numclosed = _fcloseall();
753 /* fname1 should be closed here */
754 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
755 numclosed = _fcloseall();
756 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
758 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
759 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
760 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
763 static void test_get_osfhandle(void)
766 char fname[] = "t_get_osfhanle";
770 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
771 handle = (HANDLE)_get_osfhandle(fd);
772 WriteFile(handle, "bar", 3, &bytes_written, NULL);
774 fd = _open(fname, _O_RDONLY, 0);
775 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
786 arg_c = winetest_get_mainargs( &arg_v );
788 /* testing low-level I/O */
791 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
792 else test_file_inherit_child_no(arg_v[2]);
795 test_file_inherit(arg_v[0]);
796 test_file_write_read();
799 /* testing stream I/O */
801 test_fopen_fclose_fcloseall();
803 test_readmode(FALSE); /* binary mode */
804 test_readmode(TRUE); /* ascii mode */
810 test_get_osfhandle();