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];
147 int i, j, m, fp, ao, pl;
150 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
151 /* an internal buffer of BUFSIZ is maintained, so make a file big
152 * enough to test operations that cross the buffer boundary
154 j = (2*BUFSIZ-4)/strlen(padbuffer);
156 write (fd, padbuffer, strlen(padbuffer));
157 j = (2*BUFSIZ-4)%strlen(padbuffer);
159 write (fd, &padbuffer[i], 1);
160 write (fd, nlbuffer, strlen(nlbuffer));
161 write (fd, outbuffer, sizeof (outbuffer));
165 /* Open file in ascii mode */
166 fd = open ("fdopen.tst", O_RDONLY);
167 file = fdopen (fd, "r");
168 ao = -1; /* on offset to account for carriage returns */
171 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
172 file = fdopen (fd, "rb");
176 /* first is a test of fgets, ftell, fseek */
177 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
178 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
181 ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE);
182 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
183 lstrlenA(buffer), pl+ao, IOMODE);
184 for (fp=0; fp<strlen(outbuffer); fp++)
185 if (outbuffer[fp] == '\n') break;
187 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
189 ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
190 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
191 lstrlenA(buffer), fp+ao, IOMODE);
192 /* test a seek back across the buffer boundary */
194 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
196 ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE);
197 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
199 ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
200 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
201 lstrlenA(buffer), fp+ao, IOMODE);
202 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
205 ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
206 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
207 lstrlenA(buffer), 2+ao, IOMODE);
209 /* test fread across buffer boundary */
211 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
212 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
214 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
215 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
217 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);
219 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
223 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
225 if (ao && (*optr == '\r'))
228 /* fread should return the requested number of bytes if available */
230 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
231 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
233 i=fread(buffer,1,j,file);
234 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
236 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
237 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
238 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
239 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
240 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
241 todo_wine ok(feof(file)==0,"feof failure in %s\n", IOMODE);
242 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
243 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
244 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
245 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
247 /* test some additional functions */
249 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
250 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
252 ip = (const int *)outbuffer;
253 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
254 for (fp=0; fp<strlen(outbuffer); fp++)
255 if (outbuffer[fp] == '\n') break;
257 /* this will cause the next _getw to cross carriage return characters */
258 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
259 for (i=0, j=0; i<6; i++) {
260 if (ao==0 || outbuffer[fp-3+i] != '\r')
261 buffer[j++] = outbuffer[fp-3+i];
265 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
268 unlink ("fdopen.tst");
272 static WCHAR* AtoW( const char* p )
275 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
276 buffer = malloc( len * sizeof(WCHAR) );
277 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
281 static void test_fgetc( void )
287 tempf=_tempnam(".","wne");
288 tempfh = fopen(tempf,"w+");
293 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
295 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
300 static void test_fgetwc( void )
306 static const char mytext[]= "This is test_fgetwc\r\n";
307 WCHAR wtextW[BUFSIZ+LLEN+1];
308 WCHAR *mytextW = NULL, *aptr, *wptr;
309 BOOL diff_found = FALSE;
313 tempf=_tempnam(".","wne");
314 tempfh = fopen(tempf,"wb");
316 /* pad to almost the length of the internal buffer */
317 for (i=0; i<BUFSIZ-4; i++)
323 fputs(mytext,tempfh);
325 /* in text mode, getws/c expects multibyte characters */
326 /*currently Wine only supports plain ascii, and that is all that is tested here */
327 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
328 fgetws(wtextW,LLEN,tempfh);
330 ok(l==BUFSIZ-2, "ftell expected %d got %ld\n", BUFSIZ-2, l);
331 fgetws(wtextW,LLEN,tempfh);
333 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
334 BUFSIZ-2+strlen(mytext), l);
335 mytextW = AtoW (mytext);
338 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
340 diff_found |= (*aptr != *wptr);
342 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
343 ok(*wptr == '\n', "Carriage return was not skipped\n");
347 tempfh = fopen(tempf,"wb");
349 /* pad to almost the length of the internal buffer. Use an odd number of bytes
350 to test that we can read wchars that are split across the internal buffer
352 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
358 fputws(wtextW,tempfh);
359 fputws(wtextW,tempfh);
361 /* in binary mode, getws/c expects wide characters */
362 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
363 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
364 fgetws(wtextW,j,tempfh);
366 j=(j-1)*sizeof(WCHAR);
367 ok(l==j, "ftell expected %d got %ld\n", j, l);
369 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
372 ok(l==j, "ftell expected %d got %ld\n", j, l);
373 fgetws(wtextW,3,tempfh);
374 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
375 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
378 ok(l==j, "ftell expected %d got %ld\n", j, l);
379 for(i=0; i<strlen(mytext); i++)
381 /* the first time we get the string, it should be entirely within the local buffer */
382 fgetws(wtextW,LLEN,tempfh);
384 j += (strlen(mytext)-1)*sizeof(WCHAR);
385 ok(l==j, "ftell expected %d got %ld\n", j, l);
389 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
391 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
392 diff_found |= (*aptr != *wptr);
394 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
395 ok(*wptr == '\n', "Should get newline\n");
396 for(i=0; i<strlen(mytext); i++)
398 /* the second time we get the string, it should cross the local buffer boundary.
399 One of the wchars should be split across the boundary */
400 fgetws(wtextW,LLEN,tempfh);
404 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
406 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
407 diff_found |= (*aptr != *wptr);
409 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
410 ok(*wptr == '\n', "Should get newline\n");
417 static void test_ctrlz( void )
421 static const char mytext[]= "This is test_ctrlz";
426 tempf=_tempnam(".","wne");
427 tempfh = fopen(tempf,"wb");
428 fputs(mytext,tempfh);
429 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
438 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
439 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
442 ok(i==j, "returned string length expected %d got %d\n", j, i);
443 j+=4; /* ftell should indicate the true end of file */
445 ok(l==j, "ftell expected %d got %ld\n", j, l);
446 ok(feof(tempfh), "did not get EOF\n");
449 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
450 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
452 j=strlen(mytext)+3; /* should get through newline */
453 ok(i==j, "returned string length expected %d got %d\n", j, i);
455 ok(l==j, "ftell expected %d got %ld\n", j, l);
456 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
458 ok(i==1, "returned string length expected %d got %d\n", 1, i);
459 ok(feof(tempfh), "did not get EOF\n");
464 static void test_file_put_get( void )
468 static const char mytext[]= "This is a test_file_put_get\n";
469 static const char dostext[]= "This is a test_file_put_get\r\n";
471 WCHAR wtextW[LLEN+1];
472 WCHAR *mytextW = NULL, *aptr, *wptr;
473 BOOL diff_found = FALSE;
476 tempf=_tempnam(".","wne");
477 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
478 fputs(mytext,tempfh);
480 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
481 fgets(btext,LLEN,tempfh);
482 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
483 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
485 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
486 fputs(dostext,tempfh);
488 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
489 fgets(btext,LLEN,tempfh);
490 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
492 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
493 fgets(btext,LLEN,tempfh);
494 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
497 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
498 fgetws(wtextW,LLEN,tempfh);
499 mytextW = AtoW (mytext);
503 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
505 diff_found |= (*aptr != *wptr);
507 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
513 static void test_file_write_read( void )
517 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
518 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
522 tempf=_tempnam(".","wne");
523 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
524 _S_IREAD | _S_IWRITE);
526 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
527 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
528 "_write _O_BINARY bad return value\n");
530 i = lstrlenA(mytext);
531 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
532 ok(_read(tempfd,btext,i) == i,
533 "_read _O_BINARY got bad length\n");
534 ok( memcmp(dostext,btext,i) == 0,
535 "problems with _O_BINARY _write / _read\n");
537 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
538 ok(_read(tempfd,btext,i) == i-1,
539 "_read _O_TEXT got bad length\n");
540 ok( memcmp(mytext,btext,i-1) == 0,
541 "problems with _O_BINARY _write / _O_TEXT _read\n");
543 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
544 _S_IREAD | _S_IWRITE);
546 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
547 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
548 "_write _O_TEXT bad return value\n");
550 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
551 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
552 "_read _O_BINARY got bad length\n");
553 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
554 "problems with _O_TEXT _write / _O_BINARY _read\n");
555 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
557 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
558 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
559 "_read _O_TEXT got bad length\n");
560 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
561 "problems with _O_TEXT _write / _read\n");
564 memset(btext, 0, LLEN);
565 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
566 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
567 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
568 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
571 /* Test reading only \n or \r */
572 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
573 _lseek(tempfd, -1, FILE_END);
574 ret = _read(tempfd,btext,LLEN);
575 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
576 _lseek(tempfd, -2, FILE_END);
577 ret = _read(tempfd,btext,LLEN);
578 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
579 _lseek(tempfd, -3, FILE_END);
580 ret = _read(tempfd,btext,2);
581 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
582 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
586 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
588 tempf=_tempnam(".","wne");
589 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
591 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
592 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
593 "_write _O_BINARY bad return value\n");
595 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
596 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
597 "_read _O_BINARY got bad length\n");
598 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
599 "problems with _O_BINARY _write / _read\n");
600 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
602 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
603 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
604 "_read _O_TEXT got bad length\n");
605 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
606 "problems with _O_BINARY _write / _O_TEXT _read\n");
609 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
611 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
613 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
616 static void test_file_inherit_child(const char* fd_s)
622 ret =write(fd, "Success", 8);
623 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
624 lseek(fd, 0, SEEK_SET);
625 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
626 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
629 static void test_file_inherit_child_no(const char* fd_s)
634 ret = write(fd, "Success", 8);
635 ok( ret == -1 && errno == EBADF,
636 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
639 static void test_file_inherit( const char* selfname )
642 const char* arg_v[5];
645 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _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);
651 _spawnvp(_P_WAIT, selfname, arg_v);
652 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
653 lseek(fd, 0, SEEK_SET);
654 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
656 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
658 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
659 ok(fd != -1, "Couldn't create test file\n");
661 arg_v[1] = "tests/file.c";
662 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
665 _spawnvp(_P_WAIT, selfname, arg_v);
666 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
667 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
669 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
672 static void test_tmpnam( void )
674 char name[MAX_PATH] = "abc";
678 ok(res != NULL, "tmpnam returned NULL\n");
679 ok(res[0] == '\\', "first character is not a backslash\n");
680 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
681 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
684 ok(res != NULL, "tmpnam returned NULL\n");
685 ok(res == name, "supplied buffer was not used\n");
686 ok(res[0] == '\\', "first character is not a backslash\n");
687 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
688 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
691 static void test_chsize( void )
694 long cur, pos, count;
695 char temptext[] = "012345678";
696 char *tempfile = _tempnam( ".", "tst" );
698 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
700 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
701 ok( fd > 0, "Couldn't open test file\n" );
703 count = _write( fd, temptext, sizeof(temptext) );
704 ok( count > 0, "Couldn't write to test file\n" );
706 /* get current file pointer */
707 cur = _lseek( fd, 0, SEEK_CUR );
709 /* make the file smaller */
710 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
712 pos = _lseek( fd, 0, SEEK_CUR );
713 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
714 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
716 /* enlarge the file */
717 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
719 pos = _lseek( fd, 0, SEEK_CUR );
720 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
721 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
727 static void test_fopen_fclose_fcloseall( void )
729 char fname1[] = "empty1";
730 char fname2[] = "empty2";
731 char fname3[] = "empty3";
732 FILE *stream1, *stream2, *stream3, *stream4;
735 /* testing fopen() */
736 stream1 = fopen(fname1, "w+");
737 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
738 stream2 = fopen(fname2, "w ");
739 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
741 stream3 = fopen(fname3, "r");
742 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
743 stream3 = fopen(fname3, "w+");
744 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
746 stream4 = fopen("", "w+");
747 ok(stream4 == NULL && errno == ENOENT,
748 "filename is empty, errno = %d (expected 2)\n", errno);
750 stream4 = fopen(NULL, "w+");
751 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
752 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
754 /* testing fclose() */
755 ret = fclose(stream2);
756 ok(ret == 0, "The file '%s' was not closed\n", fname2);
757 ret = fclose(stream3);
758 ok(ret == 0, "The file '%s' was not closed\n", fname3);
759 ret = fclose(stream2);
760 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
761 ret = fclose(stream3);
762 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
764 /* testing fcloseall() */
765 numclosed = _fcloseall();
766 /* fname1 should be closed here */
767 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
768 numclosed = _fcloseall();
769 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
771 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
772 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
773 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
776 static void test_get_osfhandle(void)
779 char fname[] = "t_get_osfhanle";
783 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
784 handle = (HANDLE)_get_osfhandle(fd);
785 WriteFile(handle, "bar", 3, &bytes_written, NULL);
787 fd = _open(fname, _O_RDONLY, 0);
788 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
794 static void test_setmaxstdio(void)
796 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
797 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
800 static void test_stat(void)
806 /* Tests for a file */
807 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
810 if (fstat(fd, &buf) == 0)
812 if (S_ISREG(buf.st_mode))
814 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
815 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n",
816 buf.st_dev, buf.st_rdev);
817 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n",
819 ok(buf.st_size == 0, "st_size is %d, expected 0\n",
823 skip("file is not a file?\n");
826 skip("fstat failed, errno %d\n", errno);
831 skip("open failed with errno %d\n", errno);
833 /* Tests for a char device */
834 if (_dup2(0, 10) == 0)
836 if (fstat(10, &buf) == 0)
838 if (buf.st_mode == _S_IFCHR)
840 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
841 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
842 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
845 skip("stdin is not a char device?\n");
848 skip("fstat failed with errno %d\n", errno);
852 skip("_dup2 failed with errno %d\n", errno);
854 /* Tests for pipes */
855 if (_pipe(pipes, 1024, O_BINARY) == 0)
857 if (fstat(pipes[0], &buf) == 0)
859 if (buf.st_mode == _S_IFIFO)
861 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n",
862 buf.st_dev, pipes[0]);
863 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n",
864 buf.st_rdev, pipes[0]);
865 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n",
869 skip("pipe() didn't make a pipe?\n");
872 skip("fstat failed with errno %d\n", errno);
877 skip("pipe failed with errno %d\n", errno);
885 arg_c = winetest_get_mainargs( &arg_v );
887 /* testing low-level I/O */
890 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
891 else test_file_inherit_child_no(arg_v[2]);
894 test_file_inherit(arg_v[0]);
895 test_file_write_read();
899 /* testing stream I/O */
901 test_fopen_fclose_fcloseall();
903 test_readmode(FALSE); /* binary mode */
904 test_readmode(TRUE); /* ascii mode */
910 test_get_osfhandle();