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);
298 static void test_fgetwc( void )
304 static const char mytext[]= "This is test_fgetwc\r\n";
305 WCHAR wtextW[MSVCRT_BUFSIZ+LLEN+1];
306 WCHAR *mytextW = NULL, *aptr, *wptr;
307 BOOL diff_found = FALSE;
311 tempf=_tempnam(".","wne");
312 tempfh = fopen(tempf,"wb");
314 /* pad to almost the length of the internal buffer */
315 for (i=0; i<MSVCRT_BUFSIZ-4; i++)
321 fputs(mytext,tempfh);
323 /* in text mode, getws/c expects multibyte characters */
324 /*currently Wine only supports plain ascii, and that is all that is tested here */
325 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
326 fgetws(wtextW,LLEN,tempfh);
328 ok(l==MSVCRT_BUFSIZ-2, "ftell expected %d got %ld\n", MSVCRT_BUFSIZ-2, l);
329 fgetws(wtextW,LLEN,tempfh);
331 ok(l==MSVCRT_BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
332 MSVCRT_BUFSIZ-2+strlen(mytext), l);
333 mytextW = AtoW ((char*)mytext);
336 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
338 diff_found |= (*aptr != *wptr);
340 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
341 ok(*wptr == '\n', "Carriage return was not skipped\n");
345 tempfh = fopen(tempf,"wb");
347 /* pad to almost the length of the internal buffer. Use an odd number of bytes
348 to test that we can read wchars that are split across the internal buffer
350 for (i=0; i<MSVCRT_BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
356 fputws(wtextW,tempfh);
357 fputws(wtextW,tempfh);
359 /* in binary mode, getws/c expects wide characters */
360 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
361 j=(MSVCRT_BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
362 fgetws(wtextW,j,tempfh);
364 j=(j-1)*sizeof(WCHAR);
365 ok(l==j, "ftell expected %d got %ld\n", j, l);
367 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
370 ok(l==j, "ftell expected %d got %ld\n", j, l);
371 fgetws(wtextW,3,tempfh);
372 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
373 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
376 ok(l==j, "ftell expected %d got %ld\n", j, l);
377 for(i=0; i<strlen(mytext); i++)
379 /* the first time we get the string, it should be entirely within the local buffer */
380 fgetws(wtextW,LLEN,tempfh);
382 j += (strlen(mytext)-1)*sizeof(WCHAR);
383 ok(l==j, "ftell expected %d got %ld\n", j, l);
387 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
389 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
390 diff_found |= (*aptr != *wptr);
392 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
393 ok(*wptr == '\n', "Should get newline\n");
394 for(i=0; i<strlen(mytext); i++)
396 /* the second time we get the string, it should cross the local buffer boundary.
397 One of the wchars should be split across the boundary */
398 fgetws(wtextW,LLEN,tempfh);
402 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
404 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
405 diff_found |= (*aptr != *wptr);
407 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
408 ok(*wptr == '\n', "Should get newline\n");
415 static void test_ctrlz( void )
419 static const char mytext[]= "This is test_ctrlz";
424 tempf=_tempnam(".","wne");
425 tempfh = fopen(tempf,"wb");
426 fputs(mytext,tempfh);
427 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
436 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
437 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
440 ok(i==j, "returned string length expected %d got %d\n", j, i);
441 j+=4; /* ftell should indicate the true end of file */
443 ok(l==j, "ftell expected %d got %ld\n", j, l);
444 ok(feof(tempfh), "did not get EOF\n");
447 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
448 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
450 j=strlen(mytext)+3; /* should get through newline */
451 ok(i==j, "returned string length expected %d got %d\n", j, i);
453 ok(l==j, "ftell expected %d got %ld\n", j, l);
454 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
456 ok(i==1, "returned string length expected %d got %d\n", 1, i);
457 ok(feof(tempfh), "did not get EOF\n");
462 static void test_file_put_get( void )
466 static const char mytext[]= "This is a test_file_put_get\n";
467 static const char dostext[]= "This is a test_file_put_get\r\n";
469 WCHAR wtextW[LLEN+1];
470 WCHAR *mytextW = NULL, *aptr, *wptr;
471 BOOL diff_found = FALSE;
474 tempf=_tempnam(".","wne");
475 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
476 fputs(mytext,tempfh);
478 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
479 fgets(btext,LLEN,tempfh);
480 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
481 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
483 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
484 fputs(dostext,tempfh);
486 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
487 fgets(btext,LLEN,tempfh);
488 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
490 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
491 fgets(btext,LLEN,tempfh);
492 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
495 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
496 fgetws(wtextW,LLEN,tempfh);
497 mytextW = AtoW ((char*)mytext);
501 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
503 diff_found |= (*aptr != *wptr);
505 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
511 static void test_file_write_read( void )
515 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
516 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
520 tempf=_tempnam(".","wne");
521 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
522 _S_IREAD | _S_IWRITE);
524 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
525 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
526 "_write _O_BINARY bad return value\n");
528 i = lstrlenA(mytext);
529 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
530 ok(_read(tempfd,btext,i) == i,
531 "_read _O_BINARY got bad length\n");
532 ok( memcmp(dostext,btext,i) == 0,
533 "problems with _O_BINARY _write / _read\n");
535 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
536 ok(_read(tempfd,btext,i) == i-1,
537 "_read _O_TEXT got bad length\n");
538 ok( memcmp(mytext,btext,i-1) == 0,
539 "problems with _O_BINARY _write / _O_TEXT _read\n");
541 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
542 _S_IREAD | _S_IWRITE);
544 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
545 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
546 "_write _O_TEXT bad return value\n");
548 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
549 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
550 "_read _O_BINARY got bad length\n");
551 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
552 "problems with _O_TEXT _write / _O_BINARY _read\n");
553 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
555 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
556 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
557 "_read _O_TEXT got bad length\n");
558 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
559 "problems with _O_TEXT _write / _read\n");
562 memset(btext, 0, LLEN);
563 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
564 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
565 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
566 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
569 /* Test reading only \n or \r */
570 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
571 _lseek(tempfd, -1, FILE_END);
572 ret = _read(tempfd,btext,LLEN);
573 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
574 _lseek(tempfd, -2, FILE_END);
575 ret = _read(tempfd,btext,LLEN);
576 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
577 _lseek(tempfd, -3, FILE_END);
578 ret = _read(tempfd,btext,2);
579 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
580 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
584 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
586 tempf=_tempnam(".","wne");
587 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
589 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
590 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
591 "_write _O_BINARY bad return value\n");
593 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
594 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
595 "_read _O_BINARY got bad length\n");
596 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
597 "problems with _O_BINARY _write / _read\n");
598 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
600 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
601 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
602 "_read _O_TEXT got bad length\n");
603 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
604 "problems with _O_BINARY _write / _O_TEXT _read\n");
607 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
609 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
611 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
614 static void test_file_inherit_child(const char* fd_s)
620 ret =write(fd, "Success", 8);
621 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
622 lseek(fd, 0, SEEK_SET);
623 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
624 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
627 static void test_file_inherit_child_no(const char* fd_s)
632 ret = write(fd, "Success", 8);
633 ok( ret == -1 && errno == EBADF,
634 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
637 static void test_file_inherit( const char* selfname )
640 const char* arg_v[5];
643 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
644 ok(fd != -1, "Couldn't create test file\n");
646 arg_v[1] = "tests/file.c";
647 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
649 _spawnvp(_P_WAIT, selfname, arg_v);
650 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
651 lseek(fd, 0, SEEK_SET);
652 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
654 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
656 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
657 ok(fd != -1, "Couldn't create test file\n");
659 arg_v[1] = "tests/file.c";
660 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
663 _spawnvp(_P_WAIT, selfname, arg_v);
664 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
665 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
667 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
670 static void test_tmpnam( void )
672 char name[MAX_PATH] = "abc";
676 ok(res != NULL, "tmpnam returned NULL\n");
677 ok(res[0] == '\\', "first character is not a backslash\n");
678 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
679 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
682 ok(res != NULL, "tmpnam returned NULL\n");
683 ok(res == name, "supplied buffer was not used\n");
684 ok(res[0] == '\\', "first character is not a backslash\n");
685 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
686 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
689 static void test_chsize( void )
692 long cur, pos, count;
693 char temptext[] = "012345678";
694 char *tempfile = _tempnam( ".", "tst" );
696 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
698 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
699 ok( fd > 0, "Couldn't open test file\n" );
701 count = _write( fd, temptext, sizeof(temptext) );
702 ok( count > 0, "Couldn't write to test file\n" );
704 /* get current file pointer */
705 cur = _lseek( fd, 0, SEEK_CUR );
707 /* make the file smaller */
708 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
710 pos = _lseek( fd, 0, SEEK_CUR );
711 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
712 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
714 /* enlarge the file */
715 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
717 pos = _lseek( fd, 0, SEEK_CUR );
718 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
719 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
725 static void test_fopen_fclose_fcloseall( void )
727 char fname1[] = "empty1";
728 char fname2[] = "empty2";
729 char fname3[] = "empty3";
730 FILE *stream1, *stream2, *stream3, *stream4;
733 /* testing fopen() */
734 stream1 = fopen(fname1, "w+");
735 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
736 stream2 = fopen(fname2, "w ");
737 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
739 stream3 = fopen(fname3, "r");
740 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
741 stream3 = fopen(fname3, "w+");
742 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
744 stream4 = fopen("", "w+");
745 ok(stream4 == NULL && errno == ENOENT,
746 "filename is empty, errno = %d (expected 2)\n", errno);
748 stream4 = fopen(NULL, "w+");
749 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
750 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
752 /* testing fclose() */
753 ret = fclose(stream2);
754 ok(ret == 0, "The file '%s' was not closed\n", fname2);
755 ret = fclose(stream3);
756 ok(ret == 0, "The file '%s' was not closed\n", fname3);
757 ret = fclose(stream2);
758 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
759 ret = fclose(stream3);
760 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
762 /* testing fcloseall() */
763 numclosed = _fcloseall();
764 /* fname1 should be closed here */
765 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
766 numclosed = _fcloseall();
767 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
769 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
770 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
771 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
774 static void test_get_osfhandle(void)
777 char fname[] = "t_get_osfhanle";
781 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
782 handle = (HANDLE)_get_osfhandle(fd);
783 WriteFile(handle, "bar", 3, &bytes_written, NULL);
785 fd = _open(fname, _O_RDONLY, 0);
786 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
792 static void test_setmaxstdio(void)
794 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
795 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
803 arg_c = winetest_get_mainargs( &arg_v );
805 /* testing low-level I/O */
808 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
809 else test_file_inherit_child_no(arg_v[2]);
812 test_file_inherit(arg_v[0]);
813 test_file_write_read();
816 /* testing stream I/O */
818 test_fopen_fclose_fcloseall();
820 test_readmode(FALSE); /* binary mode */
821 test_readmode(TRUE); /* ascii mode */
827 test_get_osfhandle();