push 6b90daee4ad260d418fbcb69f08db2ce800b82e2
[wine/hacks.git] / dlls / msvcrt / tests / file.c
blob36fcc8001b8607124c44dbe529feeb109864a946
1 /*
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"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <share.h>
28 #include <sys/stat.h>
29 #include <io.h>
30 #include <direct.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winnls.h>
34 #include <process.h>
35 #include <errno.h>
37 static HANDLE proc_handles[2];
39 static void test_fdopen( void )
41 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
42 char ibuf[10];
43 int fd;
44 FILE *file;
46 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
47 write (fd, buffer, sizeof (buffer));
48 close (fd);
50 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
51 lseek (fd, 5, SEEK_SET);
52 file = fdopen (fd, "rb");
53 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
54 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
55 fclose (file);
56 unlink ("fdopen.tst");
59 static void test_fileops( void )
61 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
62 char buffer[256];
63 WCHAR wbuffer[256];
64 int fd;
65 FILE *file;
66 fpos_t pos;
67 int i, c;
69 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
70 write (fd, outbuffer, sizeof (outbuffer));
71 close (fd);
73 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
74 file = fdopen (fd, "rb");
75 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
76 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
77 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
78 ok(feof(file) !=0,"feof doesn't signal EOF\n");
79 rewind(file);
80 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
81 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size\n");
82 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
83 ok(strlen(buffer) == 1,"fgets dropped chars\n");
84 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
86 rewind(file);
87 for (i = 0, c = EOF; i < sizeof(outbuffer); i++)
89 ok((c = fgetc(file)) == outbuffer[i], "fgetc returned wrong data\n");
91 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
92 ok(feof(file), "feof did not return EOF\n");
93 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF\n");
94 ok(feof(file), "feof after ungetc(EOF) did not return EOF\n");
95 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
96 c = outbuffer[sizeof(outbuffer) - 1];
97 ok(ungetc(c, file) == c, "ungetc did not return its input\n");
98 ok(!feof(file), "feof after ungetc returned EOF\n");
99 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF\n");
100 ok(c == outbuffer[sizeof(outbuffer) - 1],
101 "getc did not return ungetc'd data\n");
102 ok(!feof(file), "feof after getc returned EOF prematurely\n");
103 ok((c = fgetc(file)) == EOF, "getc did not return EOF\n");
104 ok(feof(file), "feof after getc did not return EOF\n");
106 rewind(file);
107 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
108 ok(pos == 0, "Unexpected result of fgetpos 0x%Lx\n", pos);
109 pos = (ULONGLONG)sizeof (outbuffer);
110 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected\n");
111 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected\n");
112 ok(pos == (ULONGLONG)sizeof (outbuffer), "Unexpected result of fgetpos 0x%Lx\n", pos);
114 fclose (file);
115 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
116 file = fdopen (fd, "rt"); /* open in TEXT mode */
117 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
118 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
119 ok(feof(file) !=0,"feof doesn't signal EOF\n");
120 rewind(file);
121 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
122 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
123 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
124 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
125 fclose (file);
127 file = fopen("fdopen.tst", "rb");
128 ok( file != NULL, "fopen failed\n");
129 /* sizeof(buffer) > content of file */
130 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
131 /* feof should be set now */
132 ok(feof(file), "feof after fread failed\n");
133 fclose (file);
135 unlink ("fdopen.tst");
138 #define IOMODE (ao?"ascii mode":"binary mode")
139 static void test_readmode( BOOL ascii_mode )
141 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";
142 static const char padbuffer[] = "ghjghjghjghj";
143 static const char nlbuffer[] = "\r\n";
144 char buffer[2*BUFSIZ+256];
145 const char *optr;
146 int fd;
147 FILE *file;
148 const int *ip;
149 int i, j, m, ao, pl;
150 unsigned int fp;
151 long l;
153 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
154 /* an internal buffer of BUFSIZ is maintained, so make a file big
155 * enough to test operations that cross the buffer boundary
157 j = (2*BUFSIZ-4)/strlen(padbuffer);
158 for (i=0; i<j; i++)
159 write (fd, padbuffer, strlen(padbuffer));
160 j = (2*BUFSIZ-4)%strlen(padbuffer);
161 for (i=0; i<j; i++)
162 write (fd, &padbuffer[i], 1);
163 write (fd, nlbuffer, strlen(nlbuffer));
164 write (fd, outbuffer, sizeof (outbuffer));
165 close (fd);
167 if (ascii_mode) {
168 /* Open file in ascii mode */
169 fd = open ("fdopen.tst", O_RDONLY);
170 file = fdopen (fd, "r");
171 ao = -1; /* on offset to account for carriage returns */
173 else {
174 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
175 file = fdopen (fd, "rb");
176 ao = 0;
179 /* first is a test of fgets, ftell, fseek */
180 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
181 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
182 l = ftell(file);
183 pl = 2*BUFSIZ-2;
184 ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE);
185 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
186 lstrlenA(buffer), pl+ao, IOMODE);
187 for (fp=0; fp<strlen(outbuffer); fp++)
188 if (outbuffer[fp] == '\n') break;
189 fp++;
190 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
191 l = ftell(file);
192 ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
193 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
194 lstrlenA(buffer), fp+ao, IOMODE);
195 /* test a seek back across the buffer boundary */
196 l = pl;
197 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
198 l = ftell(file);
199 ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE);
200 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
201 l = ftell(file);
202 ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
203 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
204 lstrlenA(buffer), fp+ao, IOMODE);
205 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
206 fp += 2;
207 l = ftell(file);
208 ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE);
209 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
210 lstrlenA(buffer), 2+ao, IOMODE);
212 /* test fread across buffer boundary */
213 rewind(file);
214 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
215 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
216 j=strlen(outbuffer);
217 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
218 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
219 l = ftell(file);
220 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);
221 for (m=0; m<3; m++)
222 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
223 m+=BUFSIZ+2+ao;
224 optr = outbuffer;
225 for (; m<i; m++) {
226 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
227 optr++;
228 if (ao && (*optr == '\r'))
229 optr++;
231 /* fread should return the requested number of bytes if available */
232 rewind(file);
233 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
234 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
235 j = fp+10;
236 i=fread(buffer,1,j,file);
237 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
238 /* test fread eof */
239 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
240 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
241 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
242 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
243 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
244 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
245 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
246 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
247 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
248 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
250 /* test some additional functions */
251 rewind(file);
252 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
253 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
254 i = _getw(file);
255 ip = (const int *)outbuffer;
256 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
257 for (fp=0; fp<strlen(outbuffer); fp++)
258 if (outbuffer[fp] == '\n') break;
259 fp++;
260 /* this will cause the next _getw to cross carriage return characters */
261 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
262 for (i=0, j=0; i<6; i++) {
263 if (ao==0 || outbuffer[fp-3+i] != '\r')
264 buffer[j++] = outbuffer[fp-3+i];
266 i = _getw(file);
267 ip = (int *)buffer;
268 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
270 fclose (file);
271 unlink ("fdopen.tst");
274 static void test_asciimode(void)
276 FILE *fp;
277 char buf[64];
279 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
280 fp = fopen("ascii.tst", "wb");
281 fputs("\r\r\n", fp);
282 fclose(fp);
283 fp = fopen("ascii.tst", "rt");
284 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
285 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
286 rewind(fp);
287 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
288 fclose(fp);
289 unlink("ascii.tst");
291 /* Simple test of foo ^Z [more than one block] bar handling */
292 fp = fopen("ascii.tst", "wb");
293 fputs("foo\032", fp); /* foo, logical EOF, ... */
294 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
295 fputs("bar", fp); /* ... bar */
296 fclose(fp);
297 fp = fopen("ascii.tst", "rt");
298 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
299 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
300 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
301 rewind(fp);
302 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
303 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
304 fclose(fp);
306 unlink("ascii.tst");
309 static WCHAR* AtoW( const char* p )
311 WCHAR* buffer;
312 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
313 buffer = malloc( len * sizeof(WCHAR) );
314 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
315 return buffer;
318 static void test_fgetc( void )
320 char* tempf;
321 FILE *tempfh;
322 int ich=0xe0, ret;
324 tempf=_tempnam(".","wne");
325 tempfh = fopen(tempf,"w+");
326 fputc(ich, tempfh);
327 fputc(ich, tempfh);
328 rewind(tempfh);
329 ret = fgetc(tempfh);
330 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
331 ret = fgetc(tempfh);
332 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
333 fclose(tempfh);
334 unlink(tempf);
337 static void test_fputc( void )
339 char* tempf;
340 FILE *tempfh;
341 int ret;
343 tempf=_tempnam(".","wne");
344 tempfh = fopen(tempf,"wb");
345 ret = fputc(0,tempfh);
346 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
347 ret = fputc(0xff,tempfh);
348 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
349 ret = fputc(0xffffffff,tempfh);
350 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
351 fclose(tempfh);
353 tempfh = fopen(tempf,"rb");
354 ret = fputc(0,tempfh);
355 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
356 fclose(tempfh);
358 unlink(tempf);
361 static void test_flsbuf( void )
363 char* tempf;
364 FILE *tempfh;
365 int ret;
366 int bufmode;
367 int bufmodes[] = {_IOFBF,_IONBF};
369 tempf=_tempnam(".","wne");
370 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
372 tempfh = fopen(tempf,"wb");
373 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
374 ret = _flsbuf(0,tempfh);
375 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
376 bufmodes[bufmode], 0, ret);
377 ret = _flsbuf(0xff,tempfh);
378 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
379 bufmodes[bufmode], 0, ret);
380 ret = _flsbuf(0xffffffff,tempfh);
381 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
382 bufmodes[bufmode], 0, ret);
383 fclose(tempfh);
386 tempfh = fopen(tempf,"rb");
387 ret = _flsbuf(0,tempfh);
388 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
389 fclose(tempfh);
391 unlink(tempf);
394 static void test_fgetwc( void )
396 #define LLEN 512
398 char* tempf;
399 FILE *tempfh;
400 static const char mytext[]= "This is test_fgetwc\r\n";
401 WCHAR wtextW[BUFSIZ+LLEN+1];
402 WCHAR *mytextW = NULL, *aptr, *wptr;
403 BOOL diff_found = FALSE;
404 int j;
405 unsigned int i;
406 long l;
408 tempf=_tempnam(".","wne");
409 tempfh = fopen(tempf,"wb");
410 j = 'a';
411 /* pad to almost the length of the internal buffer */
412 for (i=0; i<BUFSIZ-4; i++)
413 fputc(j,tempfh);
414 j = '\r';
415 fputc(j,tempfh);
416 j = '\n';
417 fputc(j,tempfh);
418 fputs(mytext,tempfh);
419 fclose(tempfh);
420 /* in text mode, getws/c expects multibyte characters */
421 /*currently Wine only supports plain ascii, and that is all that is tested here */
422 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
423 fgetws(wtextW,LLEN,tempfh);
424 l=ftell(tempfh);
425 ok(l==BUFSIZ-2, "ftell expected %d got %ld\n", BUFSIZ-2, l);
426 fgetws(wtextW,LLEN,tempfh);
427 l=ftell(tempfh);
428 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n",
429 BUFSIZ-2+strlen(mytext), l);
430 mytextW = AtoW (mytext);
431 aptr = mytextW;
432 wptr = wtextW;
433 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
435 diff_found |= (*aptr != *wptr);
437 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
438 ok(*wptr == '\n', "Carriage return was not skipped\n");
439 fclose(tempfh);
440 unlink(tempf);
442 tempfh = fopen(tempf,"wb");
443 j = 'a';
444 /* pad to almost the length of the internal buffer. Use an odd number of bytes
445 to test that we can read wchars that are split across the internal buffer
446 boundary */
447 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
448 fputc(j,tempfh);
449 j = '\r';
450 fputwc(j,tempfh);
451 j = '\n';
452 fputwc(j,tempfh);
453 fputws(wtextW,tempfh);
454 fputws(wtextW,tempfh);
455 fclose(tempfh);
456 /* in binary mode, getws/c expects wide characters */
457 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
458 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
459 fgetws(wtextW,j,tempfh);
460 l=ftell(tempfh);
461 j=(j-1)*sizeof(WCHAR);
462 ok(l==j, "ftell expected %d got %ld\n", j, l);
463 i=fgetc(tempfh);
464 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
465 l=ftell(tempfh);
466 j++;
467 ok(l==j, "ftell expected %d got %ld\n", j, l);
468 fgetws(wtextW,3,tempfh);
469 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
470 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
471 l=ftell(tempfh);
472 j += 4;
473 ok(l==j, "ftell expected %d got %ld\n", j, l);
474 for(i=0; i<strlen(mytext); i++)
475 wtextW[i] = 0;
476 /* the first time we get the string, it should be entirely within the local buffer */
477 fgetws(wtextW,LLEN,tempfh);
478 l=ftell(tempfh);
479 j += (strlen(mytext)-1)*sizeof(WCHAR);
480 ok(l==j, "ftell expected %d got %ld\n", j, l);
481 diff_found = FALSE;
482 aptr = mytextW;
483 wptr = wtextW;
484 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
486 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
487 diff_found |= (*aptr != *wptr);
489 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
490 ok(*wptr == '\n', "Should get newline\n");
491 for(i=0; i<strlen(mytext); i++)
492 wtextW[i] = 0;
493 /* the second time we get the string, it should cross the local buffer boundary.
494 One of the wchars should be split across the boundary */
495 fgetws(wtextW,LLEN,tempfh);
496 diff_found = FALSE;
497 aptr = mytextW;
498 wptr = wtextW;
499 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
501 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
502 diff_found |= (*aptr != *wptr);
504 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
505 ok(*wptr == '\n', "Should get newline\n");
507 free(mytextW);
508 fclose(tempfh);
509 unlink(tempf);
512 static void test_ctrlz( void )
514 char* tempf;
515 FILE *tempfh;
516 static const char mytext[]= "This is test_ctrlz";
517 char buffer[256];
518 int i, j;
519 long l;
521 tempf=_tempnam(".","wne");
522 tempfh = fopen(tempf,"wb");
523 fputs(mytext,tempfh);
524 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
525 fputc(j,tempfh);
526 j = '\r';
527 fputc(j,tempfh);
528 j = '\n';
529 fputc(j,tempfh);
530 j = 'a';
531 fputc(j,tempfh);
532 fclose(tempfh);
533 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
534 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
535 i=strlen(buffer);
536 j=strlen(mytext);
537 ok(i==j, "returned string length expected %d got %d\n", j, i);
538 j+=4; /* ftell should indicate the true end of file */
539 l=ftell(tempfh);
540 ok(l==j, "ftell expected %d got %ld\n", j, l);
541 ok(feof(tempfh), "did not get EOF\n");
542 fclose(tempfh);
544 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
545 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
546 i=strlen(buffer);
547 j=strlen(mytext)+3; /* should get through newline */
548 ok(i==j, "returned string length expected %d got %d\n", j, i);
549 l=ftell(tempfh);
550 ok(l==j, "ftell expected %d got %ld\n", j, l);
551 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
552 i=strlen(buffer);
553 ok(i==1, "returned string length expected %d got %d\n", 1, i);
554 ok(feof(tempfh), "did not get EOF\n");
555 fclose(tempfh);
556 unlink(tempf);
559 static void test_file_put_get( void )
561 char* tempf;
562 FILE *tempfh;
563 static const char mytext[]= "This is a test_file_put_get\n";
564 static const char dostext[]= "This is a test_file_put_get\r\n";
565 char btext[LLEN];
566 WCHAR wtextW[LLEN+1];
567 WCHAR *mytextW = NULL, *aptr, *wptr;
568 BOOL diff_found = FALSE;
569 unsigned int i;
571 tempf=_tempnam(".","wne");
572 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
573 fputs(mytext,tempfh);
574 fclose(tempfh);
575 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
576 fgets(btext,LLEN,tempfh);
577 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
578 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
579 fclose(tempfh);
580 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
581 fputs(dostext,tempfh);
582 fclose(tempfh);
583 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
584 fgets(btext,LLEN,tempfh);
585 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
586 fclose(tempfh);
587 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
588 fgets(btext,LLEN,tempfh);
589 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
591 fclose(tempfh);
592 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
593 fgetws(wtextW,LLEN,tempfh);
594 mytextW = AtoW (mytext);
595 aptr = mytextW;
596 wptr = wtextW;
598 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
600 diff_found |= (*aptr != *wptr);
602 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
603 free(mytextW);
604 fclose(tempfh);
605 unlink(tempf);
608 static void test_file_write_read( void )
610 char* tempf;
611 int tempfd;
612 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
613 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
614 char btext[LLEN];
615 int ret, i;
617 tempf=_tempnam(".","wne");
618 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
619 _S_IREAD | _S_IWRITE);
620 ok( tempfd != -1,
621 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
622 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
623 "_write _O_BINARY bad return value\n");
624 _close(tempfd);
625 i = lstrlenA(mytext);
626 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
627 ok(_read(tempfd,btext,i) == i,
628 "_read _O_BINARY got bad length\n");
629 ok( memcmp(dostext,btext,i) == 0,
630 "problems with _O_BINARY _write / _read\n");
631 _close(tempfd);
632 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
633 ok(_read(tempfd,btext,i) == i-1,
634 "_read _O_TEXT got bad length\n");
635 ok( memcmp(mytext,btext,i-1) == 0,
636 "problems with _O_BINARY _write / _O_TEXT _read\n");
637 _close(tempfd);
638 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
639 _S_IREAD | _S_IWRITE);
640 ok( tempfd != -1,
641 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
642 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
643 "_write _O_TEXT bad return value\n");
644 _close(tempfd);
645 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
646 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
647 "_read _O_BINARY got bad length\n");
648 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
649 "problems with _O_TEXT _write / _O_BINARY _read\n");
650 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
651 _close(tempfd);
652 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
653 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
654 "_read _O_TEXT got bad length\n");
655 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
656 "problems with _O_TEXT _write / _read\n");
657 _close(tempfd);
659 memset(btext, 0, LLEN);
660 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
661 ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd));
662 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
663 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
664 _close(tempfd);
666 /* Test reading only \n or \r */
667 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
668 _lseek(tempfd, -1, FILE_END);
669 ret = _read(tempfd,btext,LLEN);
670 ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
671 _lseek(tempfd, -2, FILE_END);
672 ret = _read(tempfd,btext,LLEN);
673 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
674 _lseek(tempfd, -3, FILE_END);
675 ret = _read(tempfd,btext,2);
676 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
677 ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd));
678 _close(tempfd);
680 ret = unlink(tempf);
681 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
683 tempf=_tempnam(".","wne");
684 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
685 ok( tempfd != -1,
686 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
687 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
688 "_write _O_BINARY bad return value\n");
689 _close(tempfd);
690 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
691 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
692 "_read _O_BINARY got bad length\n");
693 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
694 "problems with _O_BINARY _write / _read\n");
695 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
696 _close(tempfd);
697 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
698 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
699 "_read _O_TEXT got bad length\n");
700 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
701 "problems with _O_BINARY _write / _O_TEXT _read\n");
702 _close(tempfd);
704 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
705 ok( ret == 0,
706 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
707 ret = unlink(tempf);
708 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
711 static void test_file_inherit_child(const char* fd_s)
713 int fd = atoi(fd_s);
714 char buffer[32];
715 int ret;
717 ret =write(fd, "Success", 8);
718 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
719 lseek(fd, 0, SEEK_SET);
720 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
721 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
724 static void test_file_inherit_child_no(const char* fd_s)
726 int fd = atoi(fd_s);
727 int ret;
729 ret = write(fd, "Success", 8);
730 ok( ret == -1 && errno == EBADF,
731 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
734 static void test_file_inherit( const char* selfname )
736 int fd;
737 const char* arg_v[5];
738 char buffer[16];
740 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
741 ok(fd != -1, "Couldn't create test file\n");
742 arg_v[0] = selfname;
743 arg_v[1] = "tests/file.c";
744 arg_v[2] = "inherit";
745 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
746 arg_v[4] = 0;
747 _spawnvp(_P_WAIT, selfname, arg_v);
748 ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
749 lseek(fd, 0, SEEK_SET);
750 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
751 close (fd);
752 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
754 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
755 ok(fd != -1, "Couldn't create test file\n");
756 arg_v[0] = selfname;
757 arg_v[1] = "tests/file.c";
758 arg_v[2] = "inherit_no";
759 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
760 arg_v[4] = 0;
761 _spawnvp(_P_WAIT, selfname, arg_v);
762 ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
763 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
764 close (fd);
765 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
768 static void test_tmpnam( void )
770 char name[MAX_PATH] = "abc";
771 char *res;
773 res = tmpnam(NULL);
774 ok(res != NULL, "tmpnam returned NULL\n");
775 ok(res[0] == '\\', "first character is not a backslash\n");
776 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
777 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
779 res = tmpnam(name);
780 ok(res != NULL, "tmpnam returned NULL\n");
781 ok(res == name, "supplied buffer was not used\n");
782 ok(res[0] == '\\', "first character is not a backslash\n");
783 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
784 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
787 static void test_chsize( void )
789 int fd;
790 long cur, pos, count;
791 char temptext[] = "012345678";
792 char *tempfile = _tempnam( ".", "tst" );
794 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
796 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
797 ok( fd > 0, "Couldn't open test file\n" );
799 count = _write( fd, temptext, sizeof(temptext) );
800 ok( count > 0, "Couldn't write to test file\n" );
802 /* get current file pointer */
803 cur = _lseek( fd, 0, SEEK_CUR );
805 /* make the file smaller */
806 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
808 pos = _lseek( fd, 0, SEEK_CUR );
809 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
810 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
812 /* enlarge the file */
813 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
815 pos = _lseek( fd, 0, SEEK_CUR );
816 ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos );
817 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
819 _close( fd );
820 _unlink( tempfile );
823 static void test_fopen_fclose_fcloseall( void )
825 char fname1[] = "empty1";
826 char fname2[] = "empty2";
827 char fname3[] = "empty3";
828 FILE *stream1, *stream2, *stream3, *stream4;
829 int ret, numclosed;
831 /* testing fopen() */
832 stream1 = fopen(fname1, "w+");
833 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
834 stream2 = fopen(fname2, "w ");
835 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
836 _unlink(fname3);
837 stream3 = fopen(fname3, "r");
838 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
839 stream3 = fopen(fname3, "w+");
840 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
841 errno = 0xfaceabad;
842 stream4 = fopen("", "w+");
843 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
844 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
845 errno = 0xfaceabad;
846 stream4 = fopen(NULL, "w+");
847 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
848 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
850 /* testing fclose() */
851 ret = fclose(stream2);
852 ok(ret == 0, "The file '%s' was not closed\n", fname2);
853 ret = fclose(stream3);
854 ok(ret == 0, "The file '%s' was not closed\n", fname3);
855 ret = fclose(stream2);
856 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
857 ret = fclose(stream3);
858 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
860 /* testing fcloseall() */
861 numclosed = _fcloseall();
862 /* fname1 should be closed here */
863 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
864 numclosed = _fcloseall();
865 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
867 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
868 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
869 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
872 static void test_get_osfhandle(void)
874 int fd;
875 char fname[] = "t_get_osfhanle";
876 DWORD bytes_written;
877 HANDLE handle;
879 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
880 handle = (HANDLE)_get_osfhandle(fd);
881 WriteFile(handle, "bar", 3, &bytes_written, NULL);
882 _close(fd);
883 fd = _open(fname, _O_RDONLY, 0);
884 ok(fd != -1, "Coudn't open '%s' after _get_osfhanle()\n", fname);
886 _close(fd);
887 _unlink(fname);
890 static void test_setmaxstdio(void)
892 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
893 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
896 static void test_stat(void)
898 int fd;
899 int pipes[2];
900 struct stat buf;
902 /* Tests for a file */
903 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
904 if (fd >= 0)
906 if (fstat(fd, &buf) == 0)
908 if ((buf.st_mode & _S_IFMT) == _S_IFREG)
910 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
911 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n",
912 buf.st_dev, buf.st_rdev);
913 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n",
914 buf.st_nlink);
915 ok(buf.st_size == 0, "st_size is %d, expected 0\n",
916 buf.st_size);
918 else
919 skip("file is not a file?\n");
921 else
922 skip("fstat failed, errno %d\n", errno);
923 close(fd);
924 remove("stat.tst");
926 else
927 skip("open failed with errno %d\n", errno);
929 /* Tests for a char device */
930 if (_dup2(0, 10) == 0)
932 if (fstat(10, &buf) == 0)
934 if (buf.st_mode == _S_IFCHR)
936 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
937 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
938 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
940 else
941 skip("stdin is not a char device?\n");
943 else
944 skip("fstat failed with errno %d\n", errno);
945 close(10);
947 else
948 skip("_dup2 failed with errno %d\n", errno);
950 /* Tests for pipes */
951 if (_pipe(pipes, 1024, O_BINARY) == 0)
953 if (fstat(pipes[0], &buf) == 0)
955 if (buf.st_mode == _S_IFIFO)
957 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n",
958 buf.st_dev, pipes[0]);
959 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n",
960 buf.st_rdev, pipes[0]);
961 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n",
962 buf.st_nlink);
964 else
965 skip("pipe() didn't make a pipe?\n");
967 else
968 skip("fstat failed with errno %d\n", errno);
969 close(pipes[0]);
970 close(pipes[1]);
972 else
973 skip("pipe failed with errno %d\n", errno);
976 static const char* pipe_string="Hello world";
978 /* How many messages to transfer over the pipe */
979 #define N_TEST_MESSAGES 3
981 static void test_pipes_child(int argc, char** args)
983 int fd;
984 int nwritten;
985 int i;
987 if (argc < 5)
989 ok(0, "not enough parameters: %d\n", argc);
990 return;
993 fd=atoi(args[3]);
994 ok(close(fd) == 0, "unable to close %d: %d\n", fd, errno);
996 fd=atoi(args[4]);
998 for (i=0; i<N_TEST_MESSAGES; i++) {
999 nwritten=write(fd, pipe_string, strlen(pipe_string));
1000 ok(nwritten == strlen(pipe_string), "i %d, expected to write %d bytes, wrote %d\n", i, strlen(pipe_string), nwritten);
1001 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1002 if (i < N_TEST_MESSAGES-1)
1003 Sleep(100);
1006 ok(close(fd) == 0, "unable to close %d: %d\n", fd, errno);
1009 static void test_pipes(const char* selfname)
1011 int pipes[2];
1012 char str_fdr[12], str_fdw[12];
1013 FILE* file;
1014 const char* arg_v[6];
1015 char buf[4096];
1016 char expected[4096];
1017 int r;
1018 int i;
1020 /* Test reading from a pipe with read() */
1021 if (_pipe(pipes, 1024, O_BINARY) < 0)
1023 ok(0, "pipe failed with errno %d\n", errno);
1024 return;
1027 arg_v[0] = selfname;
1028 arg_v[1] = "tests/file.c";
1029 arg_v[2] = "pipes";
1030 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1031 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1032 arg_v[5] = NULL;
1033 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1034 ok(close(pipes[1]) == 0, "unable to close %d: %d\n", pipes[1], errno);
1036 for (i=0; i<N_TEST_MESSAGES; i++) {
1037 r=read(pipes[0], buf, sizeof(buf)-1);
1038 ok(r == strlen(pipe_string), "i %d, expected to read %d bytes, got %d\n", i, strlen(pipe_string)+1, r);
1039 if (r > 0)
1040 buf[r]='\0';
1041 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1044 r=read(pipes[0], buf, sizeof(buf)-1);
1045 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1046 ok(close(pipes[0]) == 0, "unable to close %d: %d\n", pipes[0], errno);
1048 /* Test reading from a pipe with fread() */
1049 if (_pipe(pipes, 1024, O_BINARY) < 0)
1051 ok(0, "pipe failed with errno %d\n", errno);
1052 return;
1055 arg_v[0] = selfname;
1056 arg_v[1] = "tests/file.c";
1057 arg_v[2] = "pipes";
1058 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1059 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1060 arg_v[5] = NULL;
1061 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1062 ok(close(pipes[1]) == 0, "unable to close %d: %d\n", pipes[1], errno);
1063 file=fdopen(pipes[0], "r");
1065 /* In blocking mode, fread will keep calling read() until it gets
1066 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1067 * in cooked mode instead of a pipe, it would also stop on EOL.)
1069 expected[0] = 0;
1070 for (i=0; i<N_TEST_MESSAGES; i++)
1071 strcat(expected, pipe_string);
1072 r=fread(buf, 1, sizeof(buf)-1, file);
1073 ok(r == strlen(expected), "fread() returned %d instead of %d: ferror=%d\n", r, strlen(expected), ferror(file));
1074 if (r > 0)
1075 buf[r]='\0';
1076 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1078 /* Let child close the file before we read, so we can sense EOF reliably */
1079 Sleep(100);
1080 r=fread(buf, 1, sizeof(buf)-1, file);
1081 ok(r == 0, "fread() returned %d instead of 0\n", r);
1082 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1083 ok(feof(file), "feof() is false!\n");
1085 ok(fclose(file) == 0, "unable to close the pipe: %d\n", errno);
1088 static void test_unlink(void)
1090 FILE* file;
1091 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1092 file = fopen("test_unlink\\empty", "w");
1093 ok(file != NULL, "unable to create test file\n");
1094 if(file)
1095 fclose(file);
1096 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1097 unlink("test_unlink\\empty");
1098 rmdir("test_unlink");
1101 START_TEST(file)
1103 int arg_c;
1104 char** arg_v;
1106 arg_c = winetest_get_mainargs( &arg_v );
1108 /* testing low-level I/O */
1109 if (arg_c >= 3)
1111 if (strcmp(arg_v[2], "inherit") == 0)
1112 test_file_inherit_child(arg_v[3]);
1113 else if (strcmp(arg_v[2], "inherit_no") == 0)
1114 test_file_inherit_child_no(arg_v[3]);
1115 else if (strcmp(arg_v[2], "pipes") == 0)
1116 test_pipes_child(arg_c, arg_v);
1117 else
1118 ok(0, "invalid argument '%s'\n", arg_v[2]);
1119 return;
1121 test_file_inherit(arg_v[0]);
1122 test_file_write_read();
1123 test_chsize();
1124 test_stat();
1125 test_unlink();
1127 /* testing stream I/O */
1128 test_fdopen();
1129 test_fopen_fclose_fcloseall();
1130 test_fileops();
1131 test_asciimode();
1132 test_readmode(FALSE); /* binary mode */
1133 test_readmode(TRUE); /* ascii mode */
1134 test_fgetc();
1135 test_fputc();
1136 test_flsbuf();
1137 test_fgetwc();
1138 test_ctrlz();
1139 test_file_put_get();
1140 test_tmpnam();
1141 test_get_osfhandle();
1142 test_setmaxstdio();
1143 test_pipes(arg_v[0]);
1145 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1146 * file contains lines in the correct order
1148 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);