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*MSVCRT_BUFSIZ+256], *optr;
145 int i, j, m, 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 = (2*MSVCRT_BUFSIZ-4)/strlen(padbuffer);
154 write (fd, padbuffer, strlen(padbuffer));
155 j = (2*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,2*MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
178 pl = 2*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,MSVCRT_BUFSIZ+strlen(outbuffer),file);
213 ok(i==MSVCRT_BUFSIZ+j,"fread failed, expected %d got %d in %s\n", MSVCRT_BUFSIZ+j, i, IOMODE);
215 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);
217 ok(buffer[m]==padbuffer[m+(MSVCRT_BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
218 m+=MSVCRT_BUFSIZ+2+ao;
219 optr = (char *)outbuffer;
221 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
223 if (ao && (*optr == '\r'))
226 /* fread should return the requested number of bytes if available */
228 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
229 ok(fgets(buffer,MSVCRT_BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
231 i=fread(buffer,1,j,file);
232 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
234 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
235 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
236 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
237 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
238 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
239 todo_wine ok(feof(file)==0,"feof failure in %s\n", IOMODE);
240 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
241 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
242 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
243 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
245 /* test some additional functions */
247 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
248 ok(fgets(buffer,2*MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
250 ip = (int *)outbuffer;
251 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
252 for (fp=0; fp<strlen(outbuffer); fp++)
253 if (outbuffer[fp] == '\n') break;
255 /* this will cause the next _getw to cross carriage return characters */
256 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
257 for (i=0, j=0; i<6; i++) {
258 if (ao==0 || outbuffer[fp-3+i] != '\r')
259 buffer[j++] = outbuffer[fp-3+i];
263 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
266 unlink ("fdopen.tst");
270 static WCHAR* AtoW( char* p )
273 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
274 buffer = malloc( len * sizeof(WCHAR) );
275 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
279 static void test_fgetc( void )
285 tempf=_tempnam(".","wne");
286 tempfh = fopen(tempf,"w+");
291 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
293 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
297 static void test_fgetwc( void )
303 static const char mytext[]= "This is test_fgetwc\r\n";
304 WCHAR wtextW[MSVCRT_BUFSIZ+LLEN+1];
305 WCHAR *mytextW = NULL, *aptr, *wptr;
306 BOOL diff_found = FALSE;
310 tempf=_tempnam(".","wne");
311 tempfh = fopen(tempf,"wb");
313 /* pad to almost the length of the internal buffer */
314 for (i=0; i<MSVCRT_BUFSIZ-4; i++)
320 fputs(mytext,tempfh);
322 /* in text mode, getws/c expects multibyte characters */
323 /*currently Wine only supports plain ascii, and that is all that is tested here */
324 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
325 fgetws(wtextW,LLEN,tempfh);
327 ok(l==MSVCRT_BUFSIZ-2, "ftell expected %d got %ld\n", MSVCRT_BUFSIZ-2, l);
328 fgetws(wtextW,LLEN,tempfh);
330 ok(l==MSVCRT_BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
331 MSVCRT_BUFSIZ-2+strlen(mytext), l);
332 mytextW = AtoW ((char*)mytext);
335 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
337 diff_found |= (*aptr != *wptr);
339 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
340 ok(*wptr == '\n', "Carriage return was not skipped\n");
344 tempfh = fopen(tempf,"wb");
346 /* pad to almost the length of the internal buffer. Use an odd number of bytes
347 to test that we can read wchars that are split across the internal buffer
349 for (i=0; i<MSVCRT_BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
355 fputws(wtextW,tempfh);
356 fputws(wtextW,tempfh);
358 /* in binary mode, getws/c expects wide characters */
359 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
360 j=(MSVCRT_BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
361 fgetws(wtextW,j,tempfh);
363 j=(j-1)*sizeof(WCHAR);
364 ok(l==j, "ftell expected %d got %ld\n", j, l);
366 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
369 ok(l==j, "ftell expected %d got %ld\n", j, l);
370 fgetws(wtextW,3,tempfh);
371 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
372 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
375 ok(l==j, "ftell expected %d got %ld\n", j, l);
376 for(i=0; i<strlen(mytext); i++)
378 /* the first time we get the string, it should be entirely within the local buffer */
379 fgetws(wtextW,LLEN,tempfh);
381 j += (strlen(mytext)-1)*sizeof(WCHAR);
382 ok(l==j, "ftell expected %d got %ld\n", j, l);
386 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
388 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
389 diff_found |= (*aptr != *wptr);
391 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
392 ok(*wptr == '\n', "Should get newline\n");
393 for(i=0; i<strlen(mytext); i++)
395 /* the second time we get the string, it should cross the local buffer boundary.
396 One of the wchars should be split across the boundary */
397 fgetws(wtextW,LLEN,tempfh);
401 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
403 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
404 diff_found |= (*aptr != *wptr);
406 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
407 ok(*wptr == '\n', "Should get newline\n");
414 static void test_ctrlz( void )
418 static const char mytext[]= "This is test_ctrlz";
423 tempf=_tempnam(".","wne");
424 tempfh = fopen(tempf,"wb");
425 fputs(mytext,tempfh);
426 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
435 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
436 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
439 ok(i==j, "returned string length expected %d got %d\n", j, i);
440 j+=4; /* ftell should indicate the true end of file */
442 ok(l==j, "ftell expected %d got %ld\n", j, l);
443 ok(feof(tempfh), "did not get EOF\n");
446 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
447 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
449 j=strlen(mytext)+3; /* should get through newline */
450 ok(i==j, "returned string length expected %d got %d\n", j, i);
452 ok(l==j, "ftell expected %d got %ld\n", j, l);
453 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
455 ok(i==1, "returned string length expected %d got %d\n", 1, i);
456 ok(feof(tempfh), "did not get EOF\n");
461 static void test_file_put_get( void )
465 static const char mytext[]= "This is a test_file_put_get\n";
466 static const char dostext[]= "This is a test_file_put_get\r\n";
468 WCHAR wtextW[LLEN+1];
469 WCHAR *mytextW = NULL, *aptr, *wptr;
470 BOOL diff_found = FALSE;
473 tempf=_tempnam(".","wne");
474 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
475 fputs(mytext,tempfh);
477 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
478 fgets(btext,LLEN,tempfh);
479 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
480 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
482 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
483 fputs(dostext,tempfh);
485 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
486 fgets(btext,LLEN,tempfh);
487 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
489 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
490 fgets(btext,LLEN,tempfh);
491 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
494 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
495 fgetws(wtextW,LLEN,tempfh);
496 mytextW = AtoW ((char*)mytext);
500 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
502 diff_found |= (*aptr != *wptr);
504 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
510 static void test_file_write_read( void )
514 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
515 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
519 tempf=_tempnam(".","wne");
520 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
521 _S_IREAD | _S_IWRITE);
523 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
524 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
525 "_write _O_BINARY bad return value\n");
527 i = lstrlenA(mytext);
528 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
529 ok(_read(tempfd,btext,i) == i,
530 "_read _O_BINARY got bad length\n");
531 ok( memcmp(dostext,btext,i) == 0,
532 "problems with _O_BINARY _write / _read\n");
534 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
535 ok(_read(tempfd,btext,i) == i-1,
536 "_read _O_TEXT got bad length\n");
537 ok( memcmp(mytext,btext,i-1) == 0,
538 "problems with _O_BINARY _write / _O_TEXT _read\n");
540 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
541 _S_IREAD | _S_IWRITE);
543 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
544 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
545 "_write _O_TEXT bad return value\n");
547 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
548 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
549 "_read _O_BINARY got bad length\n");
550 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
551 "problems with _O_TEXT _write / _O_BINARY _read\n");
552 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
554 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
555 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
556 "_read _O_TEXT got bad length\n");
557 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
558 "problems with _O_TEXT _write / _read\n");
561 memset(btext, 0, LLEN);
562 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
563 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
564 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
565 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
568 /* Test reading only \n or \r */
569 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
570 _lseek(tempfd, -1, FILE_END);
571 ret = _read(tempfd,btext,LLEN);
572 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
573 _lseek(tempfd, -2, FILE_END);
574 ret = _read(tempfd,btext,LLEN);
575 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
576 _lseek(tempfd, -3, FILE_END);
577 ret = _read(tempfd,btext,2);
578 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
579 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
583 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
585 tempf=_tempnam(".","wne");
586 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
588 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
589 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
590 "_write _O_BINARY bad return value\n");
592 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
593 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
594 "_read _O_BINARY got bad length\n");
595 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
596 "problems with _O_BINARY _write / _read\n");
597 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
599 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
600 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
601 "_read _O_TEXT got bad length\n");
602 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
603 "problems with _O_BINARY _write / _O_TEXT _read\n");
606 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
608 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
610 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
613 static void test_file_inherit_child(const char* fd_s)
619 ret =write(fd, "Success", 8);
620 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
621 lseek(fd, 0, SEEK_SET);
622 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
623 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
626 static void test_file_inherit_child_no(const char* fd_s)
631 ret = write(fd, "Success", 8);
632 ok( ret == -1 && errno == EBADF,
633 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
636 static void test_file_inherit( const char* selfname )
639 const char* arg_v[5];
642 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
643 ok(fd != -1, "Couldn't create test file\n");
645 arg_v[1] = "tests/file.c";
646 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
648 _spawnvp(_P_WAIT, selfname, arg_v);
649 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
650 lseek(fd, 0, SEEK_SET);
651 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
653 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
655 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
656 ok(fd != -1, "Couldn't create test file\n");
658 arg_v[1] = "tests/file.c";
659 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
662 _spawnvp(_P_WAIT, selfname, arg_v);
663 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
664 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
666 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
669 static void test_tmpnam( void )
671 char name[MAX_PATH] = "abc";
675 ok(res != NULL, "tmpnam returned NULL\n");
676 ok(res[0] == '\\', "first character is not a backslash\n");
677 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
678 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
681 ok(res != NULL, "tmpnam returned NULL\n");
682 ok(res == name, "supplied buffer was not used\n");
683 ok(res[0] == '\\', "first character is not a backslash\n");
684 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
685 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
688 static void test_chsize( void )
691 long cur, pos, count;
692 char temptext[] = "012345678";
693 char *tempfile = _tempnam( ".", "tst" );
695 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
697 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
698 ok( fd > 0, "Couldn't open test file\n" );
700 count = _write( fd, temptext, sizeof(temptext) );
701 ok( count > 0, "Couldn't write to test file\n" );
703 /* get current file pointer */
704 cur = _lseek( fd, 0, SEEK_CUR );
706 /* make the file smaller */
707 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
709 pos = _lseek( fd, 0, SEEK_CUR );
710 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
711 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
713 /* enlarge the file */
714 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
716 pos = _lseek( fd, 0, SEEK_CUR );
717 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
718 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
724 static void test_fopen_fclose_fcloseall( void )
726 char fname1[] = "empty1";
727 char fname2[] = "empty2";
728 char fname3[] = "empty3";
729 FILE *stream1, *stream2, *stream3, *stream4;
732 /* testing fopen() */
733 stream1 = fopen(fname1, "w+");
734 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
735 stream2 = fopen(fname2, "w ");
736 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
738 stream3 = fopen(fname3, "r");
739 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
740 stream3 = fopen(fname3, "w+");
741 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
743 stream4 = fopen("", "w+");
744 ok(stream4 == NULL && errno == ENOENT,
745 "filename is empty, errno = %d (expected 2)\n", errno);
747 stream4 = fopen(NULL, "w+");
748 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
749 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
751 /* testing fclose() */
752 ret = fclose(stream2);
753 ok(ret == 0, "The file '%s' was not closed\n", fname2);
754 ret = fclose(stream3);
755 ok(ret == 0, "The file '%s' was not closed\n", fname3);
756 ret = fclose(stream2);
757 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
758 ret = fclose(stream3);
759 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
761 /* testing fcloseall() */
762 numclosed = _fcloseall();
763 /* fname1 should be closed here */
764 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
765 numclosed = _fcloseall();
766 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
768 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
769 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
770 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
773 static void test_get_osfhandle(void)
776 char fname[] = "t_get_osfhanle";
780 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
781 handle = (HANDLE)_get_osfhandle(fd);
782 WriteFile(handle, "bar", 3, &bytes_written, NULL);
784 fd = _open(fname, _O_RDONLY, 0);
785 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
796 arg_c = winetest_get_mainargs( &arg_v );
798 /* testing low-level I/O */
801 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
802 else test_file_inherit_child_no(arg_v[2]);
805 test_file_inherit(arg_v[0]);
806 test_file_write_read();
809 /* testing stream I/O */
811 test_fopen_fclose_fcloseall();
813 test_readmode(FALSE); /* binary mode */
814 test_readmode(TRUE); /* ascii mode */
820 test_get_osfhandle();