2 * Unit test suite for file functions
4 * Copyright 2002 Bill Currie
5 * Copyright 2005 Paul Rupe
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
37 static void test_fdopen( void )
39 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
44 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
45 write (fd, buffer, sizeof (buffer));
48 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
49 lseek (fd, 5, SEEK_SET);
50 file = fdopen (fd, "rb");
51 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
52 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
54 unlink ("fdopen.tst");
57 static void test_fileops( void )
59 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
67 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
68 write (fd, outbuffer, sizeof (outbuffer));
71 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
72 file = fdopen (fd, "rb");
73 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
74 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
75 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
76 ok(feof(file) !=0,"feof doesn't signal EOF\n");
78 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
79 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size\n");
80 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
81 ok(strlen(buffer) == 1,"fgets dropped chars\n");
82 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
85 for (i = 0, c = EOF; i < sizeof(outbuffer); i++)
87 ok((c = fgetc(file)) == outbuffer[i], "fgetc returned wrong data\n");
89 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
90 ok(feof(file), "feof did not return EOF\n");
91 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF\n");
92 ok(feof(file), "feof after ungetc(EOF) did not return EOF\n");
93 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
94 c = outbuffer[sizeof(outbuffer) - 1];
95 ok(ungetc(c, file) == c, "ungetc did not return its input\n");
96 ok(!feof(file), "feof after ungetc returned EOF\n");
97 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF\n");
98 ok(c == outbuffer[sizeof(outbuffer) - 1],
99 "getc did not return ungetc'd data\n");
100 ok(!feof(file), "feof after getc returned EOF prematurely\n");
101 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
102 ok(feof(file), "feof after getc did not return EOF\n");
105 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
106 ok(pos == 0, "Unexpected result of fgetpos 0x%Lx\n", pos);
107 pos = (ULONGLONG)sizeof (outbuffer);
108 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected\n");
109 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
110 ok(pos == (ULONGLONG)sizeof (outbuffer), "Unexpected result of fgetpos 0x%Lx\n", pos);
113 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
114 file = fdopen (fd, "rt"); /* open in TEXT mode */
115 ok(fgetws(wbuffer,sizeof(wbuffer),file) !=0,"fgetws failed unexpected\n");
116 ok(fgetws(wbuffer,sizeof(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
117 ok(feof(file) !=0,"feof doesn't signal EOF\n");
119 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
120 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
121 ok(fgetws(wbuffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
122 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
125 file = fopen("fdopen.tst", "rb");
126 ok( file != NULL, "fopen failed\n");
127 /* sizeof(buffer) > content of file */
128 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
129 /* feof should be set now */
130 ok(feof(file), "feof after fread failed\n");
133 unlink ("fdopen.tst");
136 #define IOMODE (ao?"ascii mode":"binary mode")
137 static void test_readmode( BOOL ascii_mode )
139 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9\r\n\r\nA,B,C,D,E\r\nX,Y,Z";
140 static const char padbuffer[] = "ghjghjghjghj";
141 static const char nlbuffer[] = "\r\n";
142 char buffer[MSVCRT_BUFSIZ+256];
145 int i, j, fp, ao, *ip, pl;
148 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
149 /* an internal buffer of MSVCRT_BUFSIZ is maintained, so make a file big
150 * enough to test operations that cross the buffer boundary
152 j = (MSVCRT_BUFSIZ-4)/strlen(padbuffer);
154 write (fd, padbuffer, strlen(padbuffer));
155 j = (MSVCRT_BUFSIZ-4)%strlen(padbuffer);
157 write (fd, &padbuffer[i], 1);
158 write (fd, nlbuffer, strlen(nlbuffer));
159 write (fd, outbuffer, sizeof (outbuffer));
163 /* Open file in ascii mode */
164 fd = open ("fdopen.tst", O_RDONLY);
165 file = fdopen (fd, "r");
166 ao = -1; /* on offset to account for carriage returns */
169 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
170 file = fdopen (fd, "rb");
174 /* first is a test of fgets, ftell, fseek */
175 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
176 ok(fgets(buffer,MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
178 pl = MSVCRT_BUFSIZ-2;
179 ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE);
180 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
181 lstrlenA(buffer), pl+ao, IOMODE);
182 for (fp=0; fp<strlen(outbuffer); fp++)
183 if (outbuffer[fp] == '\n') break;
185 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
187 ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
188 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
189 lstrlenA(buffer), fp+ao, IOMODE);
190 /* test a seek back across the buffer boundary */
192 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
194 ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE);
195 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
197 ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
198 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
199 lstrlenA(buffer), fp+ao, IOMODE);
200 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
203 ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
204 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
205 lstrlenA(buffer), 2+ao, IOMODE);
207 /* test fread across buffer boundary */
209 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
210 ok(fgets(buffer,MSVCRT_BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
212 i=fread(buffer,1,256,file);
213 ok(i==j+6+ao*4,"fread failed, expected %d got %d in %s\n", j+6+ao*4, i, IOMODE);
215 ok(l == pl+j+1,"ftell after fread got %ld should be %d in %s\n", l, pl+j+1, IOMODE);
216 /* fread should return the requested number of bytes if available */
218 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
219 ok(fgets(buffer,MSVCRT_BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
221 i=fread(buffer,1,j,file);
222 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
224 /* test some additional functions */
226 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
227 ok(fgets(buffer,MSVCRT_BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
229 ip = (int *)outbuffer;
230 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
231 for (fp=0; fp<strlen(outbuffer); fp++)
232 if (outbuffer[fp] == '\n') break;
234 /* this will cause the next _getw to cross carriage return characters */
235 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
236 for (i=0, j=0; i<6; i++) {
237 if (ao==0 || outbuffer[fp-3+i] != '\r')
238 buffer[j++] = outbuffer[fp-3+i];
242 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
245 unlink ("fdopen.tst");
249 static WCHAR* AtoW( char* p )
252 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
253 buffer = malloc( len * sizeof(WCHAR) );
254 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
258 static void test_fgetc( void )
264 tempf=_tempnam(".","wne");
265 tempfh = fopen(tempf,"w+");
270 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
272 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
276 static void test_fgetwc( void )
282 static const char mytext[]= "This is test_fgetwc\r\n";
283 WCHAR wtextW[MSVCRT_BUFSIZ+LLEN+1];
284 WCHAR *mytextW = NULL, *aptr, *wptr;
285 BOOL diff_found = FALSE;
289 tempf=_tempnam(".","wne");
290 tempfh = fopen(tempf,"wb");
292 /* pad to almost the length of the internal buffer */
293 for (i=0; i<MSVCRT_BUFSIZ-4; i++)
299 fputs(mytext,tempfh);
301 /* in text mode, getws/c expects multibyte characters */
302 /*currently Wine only supports plain ascii, and that is all that is tested here */
303 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
304 fgetws(wtextW,LLEN,tempfh);
306 ok(l==MSVCRT_BUFSIZ-2, "ftell expected %d got %ld\n", MSVCRT_BUFSIZ-2, l);
307 fgetws(wtextW,LLEN,tempfh);
309 ok(l==MSVCRT_BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
310 MSVCRT_BUFSIZ-2+strlen(mytext), l);
311 mytextW = AtoW ((char*)mytext);
314 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
316 diff_found |= (*aptr != *wptr);
318 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
319 ok(*wptr == '\n', "Carriage return was not skipped\n");
323 tempfh = fopen(tempf,"wb");
325 /* pad to almost the length of the internal buffer. Use an odd number of bytes
326 to test that we can read wchars that are split across the internal buffer
328 for (i=0; i<MSVCRT_BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
334 fputws(wtextW,tempfh);
335 fputws(wtextW,tempfh);
337 /* in binary mode, getws/c expects wide characters */
338 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
339 j=(MSVCRT_BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
340 fgetws(wtextW,j,tempfh);
342 j=(j-1)*sizeof(WCHAR);
343 ok(l==j, "ftell expected %d got %ld\n", j, l);
345 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
348 ok(l==j, "ftell expected %d got %ld\n", j, l);
349 fgetws(wtextW,3,tempfh);
350 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
351 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
354 ok(l==j, "ftell expected %d got %ld\n", j, l);
355 for(i=0; i<strlen(mytext); i++)
357 /* the first time we get the string, it should be entirely within the local buffer */
358 fgetws(wtextW,LLEN,tempfh);
360 j += (strlen(mytext)-1)*sizeof(WCHAR);
361 ok(l==j, "ftell expected %d got %ld\n", j, l);
365 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
367 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
368 diff_found |= (*aptr != *wptr);
370 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
371 ok(*wptr == '\n', "Should get newline\n");
372 for(i=0; i<strlen(mytext); i++)
374 /* the second time we get the string, it should cross the local buffer boundary.
375 One of the wchars should be split across the boundary */
376 fgetws(wtextW,LLEN,tempfh);
380 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
382 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
383 diff_found |= (*aptr != *wptr);
385 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
386 ok(*wptr == '\n', "Should get newline\n");
393 static void test_ctrlz( void )
397 static const char mytext[]= "This is test_ctrlz";
402 tempf=_tempnam(".","wne");
403 tempfh = fopen(tempf,"wb");
404 fputs(mytext,tempfh);
405 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
414 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
415 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
418 ok(i==j, "returned string length expected %d got %d\n", j, i);
419 j+=4; /* ftell should indicate the true end of file */
421 ok(l==j, "ftell expected %d got %ld\n", j, l);
422 ok(feof(tempfh), "did not get EOF\n");
425 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
426 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
428 j=strlen(mytext)+3; /* should get through newline */
429 ok(i==j, "returned string length expected %d got %d\n", j, i);
431 ok(l==j, "ftell expected %d got %ld\n", j, l);
432 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
434 ok(i==1, "returned string length expected %d got %d\n", 1, i);
435 ok(feof(tempfh), "did not get EOF\n");
440 static void test_file_put_get( void )
444 static const char mytext[]= "This is a test_file_put_get\n";
445 static const char dostext[]= "This is a test_file_put_get\r\n";
447 WCHAR wtextW[LLEN+1];
448 WCHAR *mytextW = NULL, *aptr, *wptr;
449 BOOL diff_found = FALSE;
452 tempf=_tempnam(".","wne");
453 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
454 fputs(mytext,tempfh);
456 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
457 fgets(btext,LLEN,tempfh);
458 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
459 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
461 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
462 fputs(dostext,tempfh);
464 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
465 fgets(btext,LLEN,tempfh);
466 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
468 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
469 fgets(btext,LLEN,tempfh);
470 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
473 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
474 fgetws(wtextW,LLEN,tempfh);
475 mytextW = AtoW ((char*)mytext);
479 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
481 diff_found |= (*aptr != *wptr);
483 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
489 static void test_file_write_read( void )
493 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
494 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
498 tempf=_tempnam(".","wne");
499 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
500 _S_IREAD | _S_IWRITE);
502 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
503 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
504 "_write _O_BINARY bad return value\n");
506 i = lstrlenA(mytext);
507 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
508 ok(_read(tempfd,btext,i) == i,
509 "_read _O_BINARY got bad length\n");
510 ok( memcmp(dostext,btext,i) == 0,
511 "problems with _O_BINARY _write / _read\n");
513 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
514 ok(_read(tempfd,btext,i) == i-1,
515 "_read _O_TEXT got bad length\n");
516 ok( memcmp(mytext,btext,i-1) == 0,
517 "problems with _O_BINARY _write / _O_TEXT _read\n");
519 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
520 _S_IREAD | _S_IWRITE);
522 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
523 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
524 "_write _O_TEXT bad return value\n");
526 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
527 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
528 "_read _O_BINARY got bad length\n");
529 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
530 "problems with _O_TEXT _write / _O_BINARY _read\n");
531 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
533 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
534 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
535 "_read _O_TEXT got bad length\n");
536 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
537 "problems with _O_TEXT _write / _read\n");
540 memset(btext, 0, LLEN);
541 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
542 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
543 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
544 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
547 /* Test reading only \n or \r */
548 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
549 _lseek(tempfd, -1, FILE_END);
550 ret = _read(tempfd,btext,LLEN);
551 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
552 _lseek(tempfd, -2, FILE_END);
553 ret = _read(tempfd,btext,LLEN);
554 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
555 _lseek(tempfd, -3, FILE_END);
556 ret = _read(tempfd,btext,2);
557 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
558 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
562 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
564 tempf=_tempnam(".","wne");
565 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
567 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
568 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
569 "_write _O_BINARY bad return value\n");
571 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
572 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
573 "_read _O_BINARY got bad length\n");
574 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
575 "problems with _O_BINARY _write / _read\n");
576 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
578 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
579 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
580 "_read _O_TEXT got bad length\n");
581 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
582 "problems with _O_BINARY _write / _O_TEXT _read\n");
585 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
587 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
589 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
592 static void test_file_inherit_child(const char* fd_s)
598 ret =write(fd, "Success", 8);
599 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
600 lseek(fd, 0, SEEK_SET);
601 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
602 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
605 static void test_file_inherit_child_no(const char* fd_s)
610 ret = write(fd, "Success", 8);
611 ok( ret == -1 && errno == EBADF,
612 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
615 static void test_file_inherit( const char* selfname )
618 const char* arg_v[5];
621 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
622 ok(fd != -1, "Couldn't create test file\n");
624 arg_v[1] = "tests/file.c";
625 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
627 _spawnvp(_P_WAIT, selfname, arg_v);
628 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
629 lseek(fd, 0, SEEK_SET);
630 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
632 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
634 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
635 ok(fd != -1, "Couldn't create test file\n");
637 arg_v[1] = "tests/file.c";
638 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
641 _spawnvp(_P_WAIT, selfname, arg_v);
642 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
643 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
645 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
648 static void test_tmpnam( void )
650 char name[MAX_PATH] = "abc";
654 ok(res != NULL, "tmpnam returned NULL\n");
655 ok(res[0] == '\\', "first character is not a backslash\n");
656 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
657 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
660 ok(res != NULL, "tmpnam returned NULL\n");
661 ok(res == name, "supplied buffer was not used\n");
662 ok(res[0] == '\\', "first character is not a backslash\n");
663 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
664 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
667 static void test_chsize( void )
670 long cur, pos, count;
671 char temptext[] = "012345678";
672 char *tempfile = _tempnam( ".", "tst" );
674 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
676 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
677 ok( fd > 0, "Couldn't open test file\n" );
679 count = _write( fd, temptext, sizeof(temptext) );
680 ok( count > 0, "Couldn't write to test file\n" );
682 /* get current file pointer */
683 cur = _lseek( fd, 0, SEEK_CUR );
685 /* make the file smaller */
686 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
688 pos = _lseek( fd, 0, SEEK_CUR );
689 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
690 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
692 /* enlarge the file */
693 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
695 pos = _lseek( fd, 0, SEEK_CUR );
696 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
697 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
703 static void test_fopen_fclose_fcloseall( void )
705 char fname1[] = "empty1";
706 char fname2[] = "empty2";
707 char fname3[] = "empty3";
708 FILE *stream1, *stream2, *stream3, *stream4;
711 /* testing fopen() */
712 stream1 = fopen(fname1, "w+");
713 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
714 stream2 = fopen(fname2, "w ");
715 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
717 stream3 = fopen(fname3, "r");
718 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
719 stream3 = fopen(fname3, "w+");
720 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
722 stream4 = fopen("", "w+");
723 ok(stream4 == NULL && errno == ENOENT,
724 "filename is empty, errno = %d (expected 2)\n", errno);
726 stream4 = fopen(NULL, "w+");
727 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
728 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
730 /* testing fclose() */
731 ret = fclose(stream2);
732 ok(ret == 0, "The file '%s' was not closed\n", fname2);
733 ret = fclose(stream3);
734 ok(ret == 0, "The file '%s' was not closed\n", fname3);
735 ret = fclose(stream2);
736 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
737 ret = fclose(stream3);
738 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
740 /* testing fcloseall() */
741 numclosed = _fcloseall();
742 /* fname1 should be closed here */
743 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
744 numclosed = _fcloseall();
745 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
747 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
748 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
749 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
752 static void test_get_osfhandle(void)
755 char fname[] = "t_get_osfhanle";
759 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
760 handle = (HANDLE)_get_osfhandle(fd);
761 WriteFile(handle, "bar", 3, &bytes_written, NULL);
763 fd = _open(fname, _O_RDONLY, 0);
764 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
775 arg_c = winetest_get_mainargs( &arg_v );
777 /* testing low-level I/O */
780 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
781 else test_file_inherit_child_no(arg_v[2]);
784 test_file_inherit(arg_v[0]);
785 test_file_write_read();
788 /* testing stream I/O */
790 test_fopen_fclose_fcloseall();
792 test_readmode(FALSE); /* binary mode */
793 test_readmode(TRUE); /* ascii mode */
799 test_get_osfhandle();