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_fgetwc( void )
264 static const char mytext[]= "This is test_fgetwc\r\n";
265 WCHAR wtextW[MSVCRT_BUFSIZ+LLEN+1];
266 WCHAR *mytextW = NULL, *aptr, *wptr;
267 BOOL diff_found = FALSE;
271 tempf=_tempnam(".","wne");
272 tempfh = fopen(tempf,"wb");
274 /* pad to almost the length of the internal buffer */
275 for (i=0; i<MSVCRT_BUFSIZ-4; i++)
281 fputs(mytext,tempfh);
283 /* in text mode, getws/c expects multibyte characters */
284 /*currently Wine only supports plain ascii, and that is all that is tested here */
285 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
286 fgetws(wtextW,LLEN,tempfh);
288 ok(l==MSVCRT_BUFSIZ-2, "ftell expected %d got %ld\n", MSVCRT_BUFSIZ-2, l);
289 fgetws(wtextW,LLEN,tempfh);
291 ok(l==MSVCRT_BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
292 MSVCRT_BUFSIZ-2+strlen(mytext), l);
293 mytextW = AtoW ((char*)mytext);
296 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
298 diff_found |= (*aptr != *wptr);
300 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
301 ok(*wptr == '\n', "Carriage return was not skipped\n");
305 tempfh = fopen(tempf,"wb");
307 /* pad to almost the length of the internal buffer. Use an odd number of bytes
308 to test that we can read wchars that are split across the internal buffer
310 for (i=0; i<MSVCRT_BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
316 fputws(wtextW,tempfh);
317 fputws(wtextW,tempfh);
319 /* in binary mode, getws/c expects wide characters */
320 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
321 j=(MSVCRT_BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
322 fgetws(wtextW,j,tempfh);
324 j=(j-1)*sizeof(WCHAR);
325 ok(l==j, "ftell expected %d got %ld\n", j, l);
327 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
330 ok(l==j, "ftell expected %d got %ld\n", j, l);
331 fgetws(wtextW,3,tempfh);
332 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
333 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
336 ok(l==j, "ftell expected %d got %ld\n", j, l);
337 for(i=0; i<strlen(mytext); i++)
339 /* the first time we get the string, it should be entirely within the local buffer */
340 fgetws(wtextW,LLEN,tempfh);
342 j += (strlen(mytext)-1)*sizeof(WCHAR);
343 ok(l==j, "ftell expected %d got %ld\n", j, l);
347 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
349 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
350 diff_found |= (*aptr != *wptr);
352 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
353 ok(*wptr == '\n', "Should get newline\n");
354 for(i=0; i<strlen(mytext); i++)
356 /* the second time we get the string, it should cross the local buffer boundary.
357 One of the wchars should be split across the boundary */
358 fgetws(wtextW,LLEN,tempfh);
362 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
364 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
365 diff_found |= (*aptr != *wptr);
367 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
368 ok(*wptr == '\n', "Should get newline\n");
370 if(mytextW) free (mytextW);
375 static void test_ctrlz( void )
379 static const char mytext[]= "This is test_ctrlz";
384 tempf=_tempnam(".","wne");
385 tempfh = fopen(tempf,"wb");
386 fputs(mytext,tempfh);
387 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
396 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
397 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
400 ok(i==j, "returned string length expected %d got %d\n", j, i);
401 j+=4; /* ftell should indicate the true end of file */
403 ok(l==j, "ftell expected %d got %ld\n", j, l);
404 ok(feof(tempfh), "did not get EOF\n");
407 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
408 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
410 j=strlen(mytext)+3; /* should get through newline */
411 ok(i==j, "returned string length expected %d got %d\n", j, i);
413 ok(l==j, "ftell expected %d got %ld\n", j, l);
414 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
416 ok(i==1, "returned string length expected %d got %d\n", 1, i);
417 ok(feof(tempfh), "did not get EOF\n");
422 static void test_file_put_get( void )
426 static const char mytext[]= "This is a test_file_put_get\n";
427 static const char dostext[]= "This is a test_file_put_get\r\n";
429 WCHAR wtextW[LLEN+1];
430 WCHAR *mytextW = NULL, *aptr, *wptr;
431 BOOL diff_found = FALSE;
434 tempf=_tempnam(".","wne");
435 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
436 fputs(mytext,tempfh);
438 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
439 fgets(btext,LLEN,tempfh);
440 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
441 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
443 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
444 fputs(dostext,tempfh);
446 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
447 fgets(btext,LLEN,tempfh);
448 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
450 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
451 fgets(btext,LLEN,tempfh);
452 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
455 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
456 fgetws(wtextW,LLEN,tempfh);
457 mytextW = AtoW ((char*)mytext);
461 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
463 diff_found |= (*aptr != *wptr);
465 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
466 if(mytextW) free (mytextW);
471 static void test_file_write_read( void )
475 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
476 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
480 tempf=_tempnam(".","wne");
481 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
482 _S_IREAD | _S_IWRITE);
484 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
485 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
486 "_write _O_BINARY bad return value\n");
488 i = lstrlenA(mytext);
489 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
490 ok(_read(tempfd,btext,i) == i,
491 "_read _O_BINARY got bad length\n");
492 ok( memcmp(dostext,btext,i) == 0,
493 "problems with _O_BINARY _write / _read\n");
495 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
496 ok(_read(tempfd,btext,i) == i-1,
497 "_read _O_TEXT got bad length\n");
498 ok( memcmp(mytext,btext,i-1) == 0,
499 "problems with _O_BINARY _write / _O_TEXT _read\n");
501 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
502 _S_IREAD | _S_IWRITE);
504 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
505 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
506 "_write _O_TEXT bad return value\n");
508 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
509 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
510 "_read _O_BINARY got bad length\n");
511 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
512 "problems with _O_TEXT _write / _O_BINARY _read\n");
513 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
515 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
516 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
517 "_read _O_TEXT got bad length\n");
518 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
519 "problems with _O_TEXT _write / _read\n");
522 memset(btext, 0, LLEN);
523 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
524 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
525 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
526 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
529 /* Test reading only \n or \r */
530 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
531 _lseek(tempfd, -1, FILE_END);
532 ret = _read(tempfd,btext,LLEN);
533 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
534 _lseek(tempfd, -2, FILE_END);
535 ret = _read(tempfd,btext,LLEN);
536 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
537 _lseek(tempfd, -3, FILE_END);
538 ret = _read(tempfd,btext,2);
539 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
540 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
544 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
546 tempf=_tempnam(".","wne");
547 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
549 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
550 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
551 "_write _O_BINARY bad return value\n");
553 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
554 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
555 "_read _O_BINARY got bad length\n");
556 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
557 "problems with _O_BINARY _write / _read\n");
558 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
560 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
561 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
562 "_read _O_TEXT got bad length\n");
563 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
564 "problems with _O_BINARY _write / _O_TEXT _read\n");
567 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
569 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
571 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
574 static void test_file_inherit_child(const char* fd_s)
580 ret =write(fd, "Success", 8);
581 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
582 lseek(fd, 0, SEEK_SET);
583 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
584 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
587 static void test_file_inherit_child_no(const char* fd_s)
592 ret = write(fd, "Success", 8);
593 ok( ret == -1 && errno == EBADF,
594 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
597 static void test_file_inherit( const char* selfname )
600 const char* arg_v[5];
603 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
604 ok(fd != -1, "Couldn't create test file\n");
606 arg_v[1] = "tests/file.c";
607 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
609 _spawnvp(_P_WAIT, selfname, arg_v);
610 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
611 lseek(fd, 0, SEEK_SET);
612 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
614 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
616 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
617 ok(fd != -1, "Couldn't create test file\n");
619 arg_v[1] = "tests/file.c";
620 arg_v[2] = buffer; sprintf(buffer, "%d", fd);
623 _spawnvp(_P_WAIT, selfname, arg_v);
624 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
625 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
627 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
630 static void test_tmpnam( void )
632 char name[MAX_PATH] = "abc";
636 ok(res != NULL, "tmpnam returned NULL\n");
637 ok(res[0] == '\\', "first character is not a backslash\n");
638 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
639 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
642 ok(res != NULL, "tmpnam returned NULL\n");
643 ok(res == name, "supplied buffer was not used\n");
644 ok(res[0] == '\\', "first character is not a backslash\n");
645 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
646 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
649 static void test_chsize( void )
652 long cur, pos, count;
653 char temptext[] = "012345678";
654 char *tempfile = _tempnam( ".", "tst" );
656 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
658 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
659 ok( fd > 0, "Couldn't open test file\n" );
661 count = _write( fd, temptext, sizeof(temptext) );
662 ok( count > 0, "Couldn't write to test file\n" );
664 /* get current file pointer */
665 cur = _lseek( fd, 0, SEEK_CUR );
667 /* make the file smaller */
668 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
670 pos = _lseek( fd, 0, SEEK_CUR );
671 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
672 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
674 /* enlarge the file */
675 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
677 pos = _lseek( fd, 0, SEEK_CUR );
678 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
679 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
685 static void test_fopen_fclose_fcloseall( void )
687 char fname1[] = "empty1";
688 char fname2[] = "empty2";
689 char fname3[] = "empty3";
690 FILE *stream1, *stream2, *stream3, *stream4;
693 /* testing fopen() */
694 stream1 = fopen(fname1, "w+");
695 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
696 stream2 = fopen(fname2, "w ");
697 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
699 stream3 = fopen(fname3, "r");
700 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
701 stream3 = fopen(fname3, "w+");
702 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
704 stream4 = fopen("", "w+");
705 ok(stream4 == NULL && errno == ENOENT,
706 "filename is empty, errno = %d (expected 2)\n", errno);
708 stream4 = fopen(NULL, "w+");
709 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
710 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
712 /* testing fclose() */
713 ret = fclose(stream2);
714 ok(ret == 0, "The file '%s' was not closed\n", fname2);
715 ret = fclose(stream3);
716 ok(ret == 0, "The file '%s' was not closed\n", fname3);
717 ret = fclose(stream2);
718 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
719 ret = fclose(stream3);
720 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
722 /* testing fcloseall() */
723 numclosed = _fcloseall();
724 /* fname1 should be closed here */
725 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
726 numclosed = _fcloseall();
727 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
729 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
730 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
731 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
734 static void test_get_osfhandle(void)
737 char fname[] = "t_get_osfhanle";
741 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
742 handle = (HANDLE)_get_osfhandle(fd);
743 WriteFile(handle, "bar", 3, &bytes_written, NULL);
745 fd = _open(fname, _O_RDONLY, 0);
746 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
757 arg_c = winetest_get_mainargs( &arg_v );
759 /* testing low-level I/O */
762 if (arg_c == 3) test_file_inherit_child(arg_v[2]);
763 else test_file_inherit_child_no(arg_v[2]);
766 test_file_inherit(arg_v[0]);
767 test_file_write_read();
770 /* testing stream I/O */
772 test_fopen_fclose_fcloseall();
774 test_readmode(FALSE); /* binary mode */
775 test_readmode(TRUE); /* ascii mode */
780 test_get_osfhandle();