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"
36 static void test_fdopen( void )
38 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
43 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
44 write (fd, buffer, sizeof (buffer));
47 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
48 lseek (fd, 5, SEEK_SET);
49 file = fdopen (fd, "rb");
50 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
51 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
53 unlink ("fdopen.tst");
56 static void test_fileops( void )
58 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
66 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
67 write (fd, outbuffer, sizeof (outbuffer));
70 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
71 file = fdopen (fd, "rb");
72 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
73 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
74 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
75 ok(feof(file) !=0,"feof doesn't signal EOF\n");
77 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
78 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size\n");
79 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
80 ok(strlen(buffer) == 1,"fgets dropped chars\n");
81 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
84 for (i = 0, c = EOF; i < sizeof(outbuffer); i++)
86 ok((c = fgetc(file)) == outbuffer[i], "fgetc returned wrong data\n");
88 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
89 ok(feof(file), "feof did not return EOF\n");
90 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF\n");
91 ok(feof(file), "feof after ungetc(EOF) did not return EOF\n");
92 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
93 c = outbuffer[sizeof(outbuffer) - 1];
94 ok(ungetc(c, file) == c, "ungetc did not return its input\n");
95 ok(!feof(file), "feof after ungetc returned EOF\n");
96 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF\n");
97 ok(c == outbuffer[sizeof(outbuffer) - 1],
98 "getc did not return ungetc'd data\n");
99 ok(!feof(file), "feof after getc returned EOF prematurely\n");
100 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
101 ok(feof(file), "feof after getc did not return EOF\n");
104 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
105 ok(pos == 0, "Unexpected result of fgetpos 0x%Lx\n", pos);
106 pos = (ULONGLONG)sizeof (outbuffer);
107 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected\n");
108 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
109 ok(pos == (ULONGLONG)sizeof (outbuffer), "Unexpected result of fgetpos 0x%Lx\n", pos);
112 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
113 file = fdopen (fd, "rt"); /* open in TEXT mode */
114 ok(fgetws(wbuffer,sizeof(wbuffer),file) !=0,"fgetws failed unexpected\n");
115 ok(fgetws(wbuffer,sizeof(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
116 ok(feof(file) !=0,"feof doesn't signal EOF\n");
118 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
119 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
120 ok(fgetws(wbuffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
121 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
124 file = fopen("fdopen.tst", "rb");
125 ok( file != NULL, "fopen failed\n");
126 /* sizeof(buffer) > content of file */
127 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
128 /* feof should be set now */
129 ok(feof(file), "feof after fread failed\n");
132 unlink ("fdopen.tst");
135 #define IOMODE (ao?"ascii mode":"binary mode")
136 static void test_readmode( BOOL ascii_mode )
138 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";
139 static const char padbuffer[] = "ghjghjghjghj";
140 static const char nlbuffer[] = "\r\n";
141 char buffer[2*BUFSIZ+256];
146 int i, j, m, fp, ao, pl;
149 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
150 /* an internal buffer of BUFSIZ is maintained, so make a file big
151 * enough to test operations that cross the buffer boundary
153 j = (2*BUFSIZ-4)/strlen(padbuffer);
155 write (fd, padbuffer, strlen(padbuffer));
156 j = (2*BUFSIZ-4)%strlen(padbuffer);
158 write (fd, &padbuffer[i], 1);
159 write (fd, nlbuffer, strlen(nlbuffer));
160 write (fd, outbuffer, sizeof (outbuffer));
164 /* Open file in ascii mode */
165 fd = open ("fdopen.tst", O_RDONLY);
166 file = fdopen (fd, "r");
167 ao = -1; /* on offset to account for carriage returns */
170 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
171 file = fdopen (fd, "rb");
175 /* first is a test of fgets, ftell, fseek */
176 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
177 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
180 ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE);
181 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
182 lstrlenA(buffer), pl+ao, IOMODE);
183 for (fp=0; fp<strlen(outbuffer); fp++)
184 if (outbuffer[fp] == '\n') break;
186 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
188 ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
189 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
190 lstrlenA(buffer), fp+ao, IOMODE);
191 /* test a seek back across the buffer boundary */
193 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
195 ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE);
196 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
198 ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
199 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
200 lstrlenA(buffer), fp+ao, IOMODE);
201 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
204 ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
205 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
206 lstrlenA(buffer), 2+ao, IOMODE);
208 /* test fread across buffer boundary */
210 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
211 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
213 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
214 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
216 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);
218 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
222 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
224 if (ao && (*optr == '\r'))
227 /* fread should return the requested number of bytes if available */
229 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
230 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
232 i=fread(buffer,1,j,file);
233 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
235 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
236 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
237 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
238 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
239 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
240 todo_wine ok(feof(file)==0,"feof failure in %s\n", IOMODE);
241 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
242 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
243 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
244 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
246 /* test some additional functions */
248 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
249 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
251 ip = (const int *)outbuffer;
252 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
253 for (fp=0; fp<strlen(outbuffer); fp++)
254 if (outbuffer[fp] == '\n') break;
256 /* this will cause the next _getw to cross carriage return characters */
257 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
258 for (i=0, j=0; i<6; i++) {
259 if (ao==0 || outbuffer[fp-3+i] != '\r')
260 buffer[j++] = outbuffer[fp-3+i];
264 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
267 unlink ("fdopen.tst");
271 static WCHAR* AtoW( const char* p )
274 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
275 buffer = malloc( len * sizeof(WCHAR) );
276 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
280 static void test_fgetc( void )
286 tempf=_tempnam(".","wne");
287 tempfh = fopen(tempf,"w+");
292 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
294 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
299 static void test_fgetwc( void )
305 static const char mytext[]= "This is test_fgetwc\r\n";
306 WCHAR wtextW[BUFSIZ+LLEN+1];
307 WCHAR *mytextW = NULL, *aptr, *wptr;
308 BOOL diff_found = FALSE;
312 tempf=_tempnam(".","wne");
313 tempfh = fopen(tempf,"wb");
315 /* pad to almost the length of the internal buffer */
316 for (i=0; i<BUFSIZ-4; i++)
322 fputs(mytext,tempfh);
324 /* in text mode, getws/c expects multibyte characters */
325 /*currently Wine only supports plain ascii, and that is all that is tested here */
326 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
327 fgetws(wtextW,LLEN,tempfh);
329 ok(l==BUFSIZ-2, "ftell expected %d got %ld\n", BUFSIZ-2, l);
330 fgetws(wtextW,LLEN,tempfh);
332 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
333 BUFSIZ-2+strlen(mytext), l);
334 mytextW = AtoW (mytext);
337 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
339 diff_found |= (*aptr != *wptr);
341 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
342 ok(*wptr == '\n', "Carriage return was not skipped\n");
346 tempfh = fopen(tempf,"wb");
348 /* pad to almost the length of the internal buffer. Use an odd number of bytes
349 to test that we can read wchars that are split across the internal buffer
351 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
357 fputws(wtextW,tempfh);
358 fputws(wtextW,tempfh);
360 /* in binary mode, getws/c expects wide characters */
361 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
362 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
363 fgetws(wtextW,j,tempfh);
365 j=(j-1)*sizeof(WCHAR);
366 ok(l==j, "ftell expected %d got %ld\n", j, l);
368 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
371 ok(l==j, "ftell expected %d got %ld\n", j, l);
372 fgetws(wtextW,3,tempfh);
373 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
374 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
377 ok(l==j, "ftell expected %d got %ld\n", j, l);
378 for(i=0; i<strlen(mytext); i++)
380 /* the first time we get the string, it should be entirely within the local buffer */
381 fgetws(wtextW,LLEN,tempfh);
383 j += (strlen(mytext)-1)*sizeof(WCHAR);
384 ok(l==j, "ftell expected %d got %ld\n", j, l);
388 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
390 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
391 diff_found |= (*aptr != *wptr);
393 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
394 ok(*wptr == '\n', "Should get newline\n");
395 for(i=0; i<strlen(mytext); i++)
397 /* the second time we get the string, it should cross the local buffer boundary.
398 One of the wchars should be split across the boundary */
399 fgetws(wtextW,LLEN,tempfh);
403 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
405 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
406 diff_found |= (*aptr != *wptr);
408 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
409 ok(*wptr == '\n', "Should get newline\n");
416 static void test_ctrlz( void )
420 static const char mytext[]= "This is test_ctrlz";
425 tempf=_tempnam(".","wne");
426 tempfh = fopen(tempf,"wb");
427 fputs(mytext,tempfh);
428 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
437 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
438 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
441 ok(i==j, "returned string length expected %d got %d\n", j, i);
442 j+=4; /* ftell should indicate the true end of file */
444 ok(l==j, "ftell expected %d got %ld\n", j, l);
445 ok(feof(tempfh), "did not get EOF\n");
448 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
449 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
451 j=strlen(mytext)+3; /* should get through newline */
452 ok(i==j, "returned string length expected %d got %d\n", j, i);
454 ok(l==j, "ftell expected %d got %ld\n", j, l);
455 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
457 ok(i==1, "returned string length expected %d got %d\n", 1, i);
458 ok(feof(tempfh), "did not get EOF\n");
463 static void test_file_put_get( void )
467 static const char mytext[]= "This is a test_file_put_get\n";
468 static const char dostext[]= "This is a test_file_put_get\r\n";
470 WCHAR wtextW[LLEN+1];
471 WCHAR *mytextW = NULL, *aptr, *wptr;
472 BOOL diff_found = FALSE;
475 tempf=_tempnam(".","wne");
476 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
477 fputs(mytext,tempfh);
479 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
480 fgets(btext,LLEN,tempfh);
481 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
482 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
484 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
485 fputs(dostext,tempfh);
487 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
488 fgets(btext,LLEN,tempfh);
489 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
491 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
492 fgets(btext,LLEN,tempfh);
493 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
496 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
497 fgetws(wtextW,LLEN,tempfh);
498 mytextW = AtoW (mytext);
502 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
504 diff_found |= (*aptr != *wptr);
506 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
512 static void test_file_write_read( void )
516 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
517 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
521 tempf=_tempnam(".","wne");
522 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
523 _S_IREAD | _S_IWRITE);
525 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
526 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
527 "_write _O_BINARY bad return value\n");
529 i = lstrlenA(mytext);
530 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
531 ok(_read(tempfd,btext,i) == i,
532 "_read _O_BINARY got bad length\n");
533 ok( memcmp(dostext,btext,i) == 0,
534 "problems with _O_BINARY _write / _read\n");
536 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
537 ok(_read(tempfd,btext,i) == i-1,
538 "_read _O_TEXT got bad length\n");
539 ok( memcmp(mytext,btext,i-1) == 0,
540 "problems with _O_BINARY _write / _O_TEXT _read\n");
542 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
543 _S_IREAD | _S_IWRITE);
545 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
546 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
547 "_write _O_TEXT bad return value\n");
549 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
550 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
551 "_read _O_BINARY got bad length\n");
552 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
553 "problems with _O_TEXT _write / _O_BINARY _read\n");
554 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
556 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
557 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
558 "_read _O_TEXT got bad length\n");
559 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
560 "problems with _O_TEXT _write / _read\n");
563 memset(btext, 0, LLEN);
564 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
565 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
566 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
567 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
570 /* Test reading only \n or \r */
571 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
572 _lseek(tempfd, -1, FILE_END);
573 ret = _read(tempfd,btext,LLEN);
574 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
575 _lseek(tempfd, -2, FILE_END);
576 ret = _read(tempfd,btext,LLEN);
577 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
578 _lseek(tempfd, -3, FILE_END);
579 ret = _read(tempfd,btext,2);
580 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
581 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
585 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
587 tempf=_tempnam(".","wne");
588 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
590 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
591 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
592 "_write _O_BINARY bad return value\n");
594 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
595 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
596 "_read _O_BINARY got bad length\n");
597 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
598 "problems with _O_BINARY _write / _read\n");
599 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
601 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
602 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
603 "_read _O_TEXT got bad length\n");
604 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
605 "problems with _O_BINARY _write / _O_TEXT _read\n");
608 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
610 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
612 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
615 static void test_file_inherit_child(const char* fd_s)
621 ret =write(fd, "Success", 8);
622 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
623 lseek(fd, 0, SEEK_SET);
624 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
625 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
628 static void test_file_inherit_child_no(const char* fd_s)
633 ret = write(fd, "Success", 8);
634 ok( ret == -1 && errno == EBADF,
635 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
638 static void test_file_inherit( const char* selfname )
641 const char* arg_v[5];
644 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
645 ok(fd != -1, "Couldn't create test file\n");
647 arg_v[1] = "tests/file.c";
648 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
650 _spawnvp(_P_WAIT, selfname, arg_v);
651 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
652 lseek(fd, 0, SEEK_SET);
653 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
655 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
657 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
658 ok(fd != -1, "Couldn't create test file\n");
660 arg_v[1] = "tests/file.c";
661 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
664 _spawnvp(_P_WAIT, selfname, arg_v);
665 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
666 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
668 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
671 static void test_tmpnam( void )
673 char name[MAX_PATH] = "abc";
677 ok(res != NULL, "tmpnam returned NULL\n");
678 ok(res[0] == '\\', "first character is not a backslash\n");
679 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
680 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
683 ok(res != NULL, "tmpnam returned NULL\n");
684 ok(res == name, "supplied buffer was not used\n");
685 ok(res[0] == '\\', "first character is not a backslash\n");
686 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
687 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
690 static void test_chsize( void )
693 long cur, pos, count;
694 char temptext[] = "012345678";
695 char *tempfile = _tempnam( ".", "tst" );
697 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
699 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
700 ok( fd > 0, "Couldn't open test file\n" );
702 count = _write( fd, temptext, sizeof(temptext) );
703 ok( count > 0, "Couldn't write to test file\n" );
705 /* get current file pointer */
706 cur = _lseek( fd, 0, SEEK_CUR );
708 /* make the file smaller */
709 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
711 pos = _lseek( fd, 0, SEEK_CUR );
712 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
713 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
715 /* enlarge the file */
716 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
718 pos = _lseek( fd, 0, SEEK_CUR );
719 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
720 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
726 static void test_fopen_fclose_fcloseall( void )
728 char fname1[] = "empty1";
729 char fname2[] = "empty2";
730 char fname3[] = "empty3";
731 FILE *stream1, *stream2, *stream3, *stream4;
734 /* testing fopen() */
735 stream1 = fopen(fname1, "w+");
736 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
737 stream2 = fopen(fname2, "w ");
738 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
740 stream3 = fopen(fname3, "r");
741 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
742 stream3 = fopen(fname3, "w+");
743 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
745 stream4 = fopen("", "w+");
746 ok(stream4 == NULL && errno == ENOENT,
747 "filename is empty, errno = %d (expected 2)\n", errno);
749 stream4 = fopen(NULL, "w+");
750 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
751 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
753 /* testing fclose() */
754 ret = fclose(stream2);
755 ok(ret == 0, "The file '%s' was not closed\n", fname2);
756 ret = fclose(stream3);
757 ok(ret == 0, "The file '%s' was not closed\n", fname3);
758 ret = fclose(stream2);
759 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
760 ret = fclose(stream3);
761 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
763 /* testing fcloseall() */
764 numclosed = _fcloseall();
765 /* fname1 should be closed here */
766 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
767 numclosed = _fcloseall();
768 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
770 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
771 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
772 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
775 static void test_get_osfhandle(void)
778 char fname[] = "t_get_osfhanle";
782 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
783 handle = (HANDLE)_get_osfhandle(fd);
784 WriteFile(handle, "bar", 3, &bytes_written, NULL);
786 fd = _open(fname, _O_RDONLY, 0);
787 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
793 static void test_setmaxstdio(void)
795 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
796 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
804 arg_c = winetest_get_mainargs( &arg_v );
806 /* testing low-level I/O */
809 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
810 else test_file_inherit_child_no(arg_v[2]);
813 test_file_inherit(arg_v[0]);
814 test_file_write_read();
817 /* testing stream I/O */
819 test_fopen_fclose_fcloseall();
821 test_readmode(FALSE); /* binary mode */
822 test_readmode(TRUE); /* ascii mode */
828 test_get_osfhandle();