msvcrt: Handle negative file->_cnt value in _flsbuf function.
[wine/multimedia.git] / dlls / msvcrt / tests / file.c
blobb9b904d611853ffc2d6cb99892986f532081381a
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 int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
40 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
42 static void init(void)
44 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
46 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
47 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
50 static void test_filbuf( void )
52 FILE *fp;
53 int c;
54 fpos_t pos;
56 fp = fopen("filbuf.tst", "wb");
57 fwrite("\n\n\n\n", 1, 4, fp);
58 fclose(fp);
60 fp = fopen("filbuf.tst", "rt");
61 c = _filbuf(fp);
62 ok(c == '\n', "read wrong byte\n");
63 /* See bug 16970 for why we care about _filbuf.
64 * ftell returns screwy values on files with lots
65 * of bare LFs in ascii mode because it assumes
66 * that ascii files contain only CRLFs, removes
67 * the CR's early in _filbuf, and adjusts the return
68 * value of ftell to compensate.
69 * native _filbuf will read the whole file, then consume and return
70 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
71 * pointing to a buffer of three bare LFs, so
72 * ftell will return 4 - 3 - 3 = -2.
74 ok(ftell(fp) == -2, "ascii crlf removal does not match native\n");
75 ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n");
76 ok(pos == -2, "ftell does not match fgetpos\n");
77 fclose(fp);
78 unlink("filbuf.tst");
81 static void test_fdopen( void )
83 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
84 char ibuf[10];
85 int fd;
86 FILE *file;
88 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
89 write (fd, buffer, sizeof (buffer));
90 close (fd);
92 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
93 lseek (fd, 5, SEEK_SET);
94 file = fdopen (fd, "rb");
95 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
96 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
97 fclose (file);
98 unlink ("fdopen.tst");
101 static void test_fileops( void )
103 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
104 char buffer[256];
105 WCHAR wbuffer[256];
106 int fd;
107 FILE *file;
108 fpos_t pos;
109 int i, c, bufmode;
110 static const int bufmodes[] = {_IOFBF,_IONBF};
112 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
113 write (fd, outbuffer, sizeof (outbuffer));
114 close (fd);
116 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
118 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
119 file = fdopen (fd, "rb");
120 setvbuf(file,NULL,bufmodes[bufmode],2048);
121 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
122 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
123 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
124 ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
125 rewind(file);
126 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
127 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]);
128 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
129 ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]);
130 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]);
132 rewind(file);
133 for (i = 0; i < sizeof(outbuffer); i++)
135 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]);
137 ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
138 ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
139 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
140 ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
141 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
142 c = outbuffer[sizeof(outbuffer) - 1];
143 ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]);
144 ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
145 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]);
146 ok(c == outbuffer[sizeof(outbuffer) - 1],
147 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]);
148 ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]);
149 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
150 ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]);
152 rewind(file);
153 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
154 ok(pos == 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
155 pos = sizeof (outbuffer);
156 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
157 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
158 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD)(pos >> 32), (DWORD)pos, bufmodes[bufmode]);
160 fclose (file);
162 fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
163 file = fdopen (fd, "rt"); /* open in TEXT mode */
164 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
165 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
166 ok(feof(file) !=0,"feof doesn't signal EOF\n");
167 rewind(file);
168 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
169 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
170 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
171 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
172 fclose (file);
174 file = fopen("fdopen.tst", "rb");
175 ok( file != NULL, "fopen failed\n");
176 /* sizeof(buffer) > content of file */
177 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n");
178 /* feof should be set now */
179 ok(feof(file), "feof after fread failed\n");
180 fclose (file);
182 unlink ("fdopen.tst");
185 #define IOMODE (ao?"ascii mode":"binary mode")
186 static void test_readmode( BOOL ascii_mode )
188 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";
189 static const char padbuffer[] = "ghjghjghjghj";
190 static const char nlbuffer[] = "\r\n";
191 char buffer[2*BUFSIZ+256];
192 const char *optr;
193 int fd;
194 FILE *file;
195 const int *ip;
196 int i, j, m, ao, pl;
197 unsigned int fp;
198 LONG l;
200 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
201 /* an internal buffer of BUFSIZ is maintained, so make a file big
202 * enough to test operations that cross the buffer boundary
204 j = (2*BUFSIZ-4)/strlen(padbuffer);
205 for (i=0; i<j; i++)
206 write (fd, padbuffer, strlen(padbuffer));
207 j = (2*BUFSIZ-4)%strlen(padbuffer);
208 for (i=0; i<j; i++)
209 write (fd, &padbuffer[i], 1);
210 write (fd, nlbuffer, strlen(nlbuffer));
211 write (fd, outbuffer, sizeof (outbuffer));
212 close (fd);
214 if (ascii_mode) {
215 /* Open file in ascii mode */
216 fd = open ("fdopen.tst", O_RDONLY);
217 file = fdopen (fd, "r");
218 ao = -1; /* on offset to account for carriage returns */
220 else {
221 fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
222 file = fdopen (fd, "rb");
223 ao = 0;
226 /* first is a test of fgets, ftell, fseek */
227 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
228 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
229 l = ftell(file);
230 pl = 2*BUFSIZ-2;
231 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE);
232 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n",
233 lstrlenA(buffer), pl+ao, IOMODE);
234 for (fp=0; fp<strlen(outbuffer); fp++)
235 if (outbuffer[fp] == '\n') break;
236 fp++;
237 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
238 l = ftell(file);
239 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
240 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n",
241 lstrlenA(buffer), fp+ao, IOMODE);
242 /* test a seek back across the buffer boundary */
243 l = pl;
244 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE);
245 l = ftell(file);
246 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE);
247 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE);
248 l = ftell(file);
249 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
250 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n",
251 lstrlenA(buffer), fp+ao, IOMODE);
252 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE);
253 fp += 2;
254 l = ftell(file);
255 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE);
256 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n",
257 lstrlenA(buffer), 2+ao, IOMODE);
259 /* test fread across buffer boundary */
260 rewind(file);
261 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
262 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
263 j=strlen(outbuffer);
264 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file);
265 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE);
266 l = ftell(file);
267 ok(l == pl+j-(ao*4)-5,"ftell after fread got %d should be %d in %s\n", l, pl+j-(ao*4)-5, IOMODE);
268 for (m=0; m<3; m++)
269 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]);
270 m+=BUFSIZ+2+ao;
271 optr = outbuffer;
272 for (; m<i; m++) {
273 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE);
274 optr++;
275 if (ao && (*optr == '\r'))
276 optr++;
278 /* fread should return the requested number of bytes if available */
279 rewind(file);
280 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
281 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
282 j = fp+10;
283 i=fread(buffer,1,j,file);
284 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE);
285 /* test fread eof */
286 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE);
287 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
288 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE);
289 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
290 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE);
291 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
292 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE);
293 ok(feof(file)==0,"feof failure in %s\n", IOMODE);
294 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE);
295 ok(feof(file)!=0,"feof failure in %s\n", IOMODE);
297 /* test some additional functions */
298 rewind(file);
299 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE);
300 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE);
301 i = _getw(file);
302 ip = (const int *)outbuffer;
303 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
304 for (fp=0; fp<strlen(outbuffer); fp++)
305 if (outbuffer[fp] == '\n') break;
306 fp++;
307 /* this will cause the next _getw to cross carriage return characters */
308 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE);
309 for (i=0, j=0; i<6; i++) {
310 if (ao==0 || outbuffer[fp-3+i] != '\r')
311 buffer[j++] = outbuffer[fp-3+i];
313 i = _getw(file);
314 ip = (int *)buffer;
315 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE);
317 fclose (file);
318 unlink ("fdopen.tst");
321 static void test_asciimode(void)
323 FILE *fp;
324 char buf[64];
325 int c, i, j;
327 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
328 fp = fopen("ascii.tst", "wb");
329 fputs("\r\r\n", fp);
330 fclose(fp);
331 fp = fopen("ascii.tst", "rt");
332 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n");
333 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n");
334 rewind(fp);
335 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n");
336 fclose(fp);
337 unlink("ascii.tst");
339 /* Simple test of foo ^Z [more than one block] bar handling */
340 fp = fopen("ascii.tst", "wb");
341 fputs("foo\032", fp); /* foo, logical EOF, ... */
342 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */
343 fputs("bar", fp); /* ... bar */
344 fclose(fp);
345 fp = fopen("ascii.tst", "rt");
346 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n");
347 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n");
348 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n");
349 rewind(fp);
350 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n");
351 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n");
352 fclose(fp);
354 /* Show ASCII mode handling*/
355 fp= fopen("ascii.tst","wb");
356 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp);
357 fclose(fp);
359 fp = fopen("ascii.tst", "r");
360 c= fgetc(fp);
361 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
362 c= fgetc(fp);
363 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
364 fseek(fp,0,SEEK_CUR);
365 for(i=1; i<10; i++) {
366 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n");
367 fseek(fp,0,SEEK_CUR);
368 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i);
369 c= fgetc(fp);
370 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c);
372 /* Show that fseek doesn't skip \\r !*/
373 rewind(fp);
374 c= fgetc(fp);
375 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c);
376 fseek(fp, 2 ,SEEK_CUR);
377 for(i=1; i<10; i++) {
378 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i);
379 fseek(fp, 2 ,SEEK_CUR);
381 fseek(fp, 9*3 ,SEEK_SET);
382 c = fgetc(fp);
383 ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c);
384 fseek(fp, -4 ,SEEK_CUR);
385 for(i= 8; i>=0; i--) {
386 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i);
387 fseek(fp, -4 ,SEEK_CUR);
389 /* Show what happens if fseek positions filepointer on \\r */
390 fclose(fp);
391 fp = fopen("ascii.tst", "r");
392 fseek(fp, 3 ,SEEK_SET);
393 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n");
394 fclose(fp);
396 unlink("ascii.tst");
399 static void test_asciimode2(void)
401 /* Error sequence from one app was getchar followed by small fread
402 * with one \r removed had last byte of buffer filled with
403 * next byte of *unbuffered* data rather than next byte from buffer
404 * Test case is a short string of one byte followed by a newline
405 * followed by filler to fill out the sector, then a sector of
406 * some different byte.
409 FILE *fp;
410 char ibuf[4];
411 int i;
412 static const char obuf[] =
413 "00\n"
414 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
415 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
416 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
417 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
418 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
419 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
420 "000000000000000000\n"
421 "1111111111111111111";
423 fp = fopen("ascii2.tst", "wt");
424 fwrite(obuf, 1, sizeof(obuf), fp);
425 fclose(fp);
427 fp = fopen("ascii2.tst", "rt");
428 ok(getc(fp) == '0', "first char not 0\n");
429 memset(ibuf, 0, sizeof(ibuf));
430 i = fread(ibuf, 1, sizeof(ibuf), fp);
431 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i);
432 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n");
433 fclose(fp);
434 unlink("ascii2.tst");
437 static WCHAR* AtoW( const char* p )
439 WCHAR* buffer;
440 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
441 buffer = malloc( len * sizeof(WCHAR) );
442 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
443 return buffer;
446 /* Test reading in text mode when the 512'th character read is \r*/
447 static void test_readboundary(void)
449 FILE *fp;
450 char buf[513], rbuf[513];
451 int i, j;
452 for (i = 0; i < 511; i++)
454 j = (i%('~' - ' ')+ ' ');
455 buf[i] = j;
457 buf[511] = '\n';
458 buf[512] =0;
459 fp = fopen("boundary.tst", "wt");
460 fwrite(buf, 512,1,fp);
461 fclose(fp);
462 fp = fopen("boundary.tst", "rt");
463 for(i=0; i<512; i++)
465 fseek(fp,0 , SEEK_CUR);
466 rbuf[i] = fgetc(fp);
468 rbuf[512] =0;
469 fclose(fp);
470 unlink("boundary.tst");
472 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
475 static void test_fgetc( void )
477 char* tempf;
478 FILE *tempfh;
479 int ich=0xe0, ret;
481 tempf=_tempnam(".","wne");
482 tempfh = fopen(tempf,"w+");
483 fputc(ich, tempfh);
484 fputc(ich, tempfh);
485 rewind(tempfh);
486 ret = fgetc(tempfh);
487 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret);
488 ret = fgetc(tempfh);
489 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret);
490 fclose(tempfh);
491 tempfh = fopen(tempf,"wt");
492 fputc('\n', tempfh);
493 fclose(tempfh);
494 tempfh = fopen(tempf,"wt");
495 setbuf(tempfh, NULL);
496 ret = fgetc(tempfh);
497 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
498 fclose(tempfh);
499 unlink(tempf);
500 free(tempf);
503 static void test_fputc( void )
505 char* tempf;
506 FILE *tempfh;
507 int ret;
509 tempf=_tempnam(".","wne");
510 tempfh = fopen(tempf,"wb");
511 ret = fputc(0,tempfh);
512 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret);
513 ret = fputc(0xff,tempfh);
514 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret);
515 ret = fputc(0xffffffff,tempfh);
516 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret);
517 fclose(tempfh);
519 tempfh = fopen(tempf,"rb");
520 ret = fputc(0,tempfh);
521 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
522 fclose(tempfh);
524 unlink(tempf);
525 free(tempf);
528 static void test_flsbuf( void )
530 char* tempf;
531 FILE *tempfh;
532 int c;
533 int ret;
534 int bufmode;
535 static const int bufmodes[] = {_IOFBF,_IONBF};
537 tempf=_tempnam(".","wne");
538 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
540 tempfh = fopen(tempf,"wb");
541 setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
542 ret = _flsbuf(0,tempfh);
543 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
544 bufmodes[bufmode], 0, ret);
545 ret = _flsbuf(0xff,tempfh);
546 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
547 bufmodes[bufmode], 0xff, ret);
548 ret = _flsbuf(0xffffffff,tempfh);
549 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
550 bufmodes[bufmode], 0xff, ret);
551 if(tempfh->_base) {
552 fputc('x', tempfh);
553 tempfh->_cnt = -1;
554 tempfh->_base[1] = 'a';
555 ret = _flsbuf(0xab,tempfh);
556 ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
557 bufmodes[bufmode], ret);
558 ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
559 tempfh->_base[1]);
562 fclose(tempfh);
565 tempfh = fopen(tempf,"rb");
566 ret = _flsbuf(0,tempfh);
567 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret);
568 fclose(tempfh);
570 /* See bug 17123, exposed by WinAVR's make */
571 tempfh = fopen(tempf,"w");
572 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
573 setbuf(tempfh, NULL);
574 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
575 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
576 tempfh->_cnt = 1234;
577 ret = _flsbuf('Q',tempfh);
578 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret);
579 /* ... and reset it to zero */
580 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt);
581 fclose(tempfh);
582 /* And just for grins, make sure the file is correct */
583 tempfh = fopen(tempf,"r");
584 c = fgetc(tempfh);
585 ok(c == 'Q', "first byte should be 'Q'\n");
586 c = fgetc(tempfh);
587 ok(c == EOF, "there should only be one byte\n");
588 fclose(tempfh);
590 unlink(tempf);
591 free(tempf);
594 static void test_fgetwc( void )
596 #define LLEN 512
598 char* tempf;
599 FILE *tempfh;
600 static const char mytext[]= "This is test_fgetwc\r\n";
601 WCHAR wtextW[BUFSIZ+LLEN+1];
602 WCHAR *mytextW = NULL, *aptr, *wptr;
603 BOOL diff_found = FALSE;
604 int j;
605 unsigned int i;
606 LONG l;
608 tempf=_tempnam(".","wne");
609 tempfh = fopen(tempf,"wb");
610 j = 'a';
611 /* pad to almost the length of the internal buffer */
612 for (i=0; i<BUFSIZ-4; i++)
613 fputc(j,tempfh);
614 j = '\r';
615 fputc(j,tempfh);
616 j = '\n';
617 fputc(j,tempfh);
618 fputs(mytext,tempfh);
619 fclose(tempfh);
620 /* in text mode, getws/c expects multibyte characters */
621 /*currently Wine only supports plain ascii, and that is all that is tested here */
622 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
623 fgetws(wtextW,LLEN,tempfh);
624 l=ftell(tempfh);
625 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
626 fgetws(wtextW,LLEN,tempfh);
627 l=ftell(tempfh);
628 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
629 mytextW = AtoW (mytext);
630 aptr = mytextW;
631 wptr = wtextW;
632 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
634 diff_found |= (*aptr != *wptr);
636 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
637 ok(*wptr == '\n', "Carriage return was not skipped\n");
638 fclose(tempfh);
639 unlink(tempf);
641 tempfh = fopen(tempf,"wb");
642 j = 'a';
643 /* pad to almost the length of the internal buffer. Use an odd number of bytes
644 to test that we can read wchars that are split across the internal buffer
645 boundary */
646 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
647 fputc(j,tempfh);
648 j = '\r';
649 fputwc(j,tempfh);
650 j = '\n';
651 fputwc(j,tempfh);
652 fputws(wtextW,tempfh);
653 fputws(wtextW,tempfh);
654 fclose(tempfh);
655 /* in binary mode, getws/c expects wide characters */
656 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
657 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
658 fgetws(wtextW,j,tempfh);
659 l=ftell(tempfh);
660 j=(j-1)*sizeof(WCHAR);
661 ok(l==j, "ftell expected %d got %d\n", j, l);
662 i=fgetc(tempfh);
663 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
664 l=ftell(tempfh);
665 j++;
666 ok(l==j, "ftell expected %d got %d\n", j, l);
667 fgetws(wtextW,3,tempfh);
668 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
669 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
670 l=ftell(tempfh);
671 j += 4;
672 ok(l==j, "ftell expected %d got %d\n", j, l);
673 for(i=0; i<strlen(mytext); i++)
674 wtextW[i] = 0;
675 /* the first time we get the string, it should be entirely within the local buffer */
676 fgetws(wtextW,LLEN,tempfh);
677 l=ftell(tempfh);
678 j += (strlen(mytext)-1)*sizeof(WCHAR);
679 ok(l==j, "ftell expected %d got %d\n", j, l);
680 diff_found = FALSE;
681 aptr = mytextW;
682 wptr = wtextW;
683 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
685 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
686 diff_found |= (*aptr != *wptr);
688 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
689 ok(*wptr == '\n', "Should get newline\n");
690 for(i=0; i<strlen(mytext); i++)
691 wtextW[i] = 0;
692 /* the second time we get the string, it should cross the local buffer boundary.
693 One of the wchars should be split across the boundary */
694 fgetws(wtextW,LLEN,tempfh);
695 diff_found = FALSE;
696 aptr = mytextW;
697 wptr = wtextW;
698 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
700 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
701 diff_found |= (*aptr != *wptr);
703 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
704 ok(*wptr == '\n', "Should get newline\n");
706 free(mytextW);
707 fclose(tempfh);
708 unlink(tempf);
709 free(tempf);
712 static void test_ctrlz( void )
714 char* tempf;
715 FILE *tempfh;
716 static const char mytext[]= "This is test_ctrlz";
717 char buffer[256];
718 int i, j;
719 LONG l;
721 tempf=_tempnam(".","wne");
722 tempfh = fopen(tempf,"wb");
723 fputs(mytext,tempfh);
724 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
725 fputc(j,tempfh);
726 j = '\r';
727 fputc(j,tempfh);
728 j = '\n';
729 fputc(j,tempfh);
730 j = 'a';
731 fputc(j,tempfh);
732 fclose(tempfh);
733 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
734 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
735 i=strlen(buffer);
736 j=strlen(mytext);
737 ok(i==j, "returned string length expected %d got %d\n", j, i);
738 j+=4; /* ftell should indicate the true end of file */
739 l=ftell(tempfh);
740 ok(l==j, "ftell expected %d got %d\n", j, l);
741 ok(feof(tempfh), "did not get EOF\n");
742 fclose(tempfh);
744 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
745 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
746 i=strlen(buffer);
747 j=strlen(mytext)+3; /* should get through newline */
748 ok(i==j, "returned string length expected %d got %d\n", j, i);
749 l=ftell(tempfh);
750 ok(l==j, "ftell expected %d got %d\n", j, l);
751 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
752 i=strlen(buffer);
753 ok(i==1, "returned string length expected %d got %d\n", 1, i);
754 ok(feof(tempfh), "did not get EOF\n");
755 fclose(tempfh);
756 unlink(tempf);
757 free(tempf);
760 static void test_file_put_get( void )
762 char* tempf;
763 FILE *tempfh;
764 static const char mytext[]= "This is a test_file_put_get\n";
765 static const char dostext[]= "This is a test_file_put_get\r\n";
766 char btext[LLEN];
767 WCHAR wtextW[LLEN+1];
768 WCHAR *mytextW = NULL, *aptr, *wptr;
769 BOOL diff_found = FALSE;
770 unsigned int i;
772 tempf=_tempnam(".","wne");
773 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
774 fputs(mytext,tempfh);
775 fclose(tempfh);
776 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
777 fgets(btext,LLEN,tempfh);
778 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
779 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
780 fclose(tempfh);
781 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
782 fputs(dostext,tempfh);
783 fclose(tempfh);
784 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
785 fgets(btext,LLEN,tempfh);
786 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
787 fclose(tempfh);
788 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
789 fgets(btext,LLEN,tempfh);
790 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
792 fclose(tempfh);
793 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
794 fgetws(wtextW,LLEN,tempfh);
795 mytextW = AtoW (mytext);
796 aptr = mytextW;
797 wptr = wtextW;
799 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
801 diff_found |= (*aptr != *wptr);
803 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
804 free(mytextW);
805 fclose(tempfh);
806 unlink(tempf);
807 free(tempf);
810 static void test_file_write_read( void )
812 char* tempf;
813 int tempfd;
814 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
815 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
816 char btext[LLEN];
817 int ret, i;
819 tempf=_tempnam(".","wne");
820 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
821 _S_IREAD | _S_IWRITE);
822 ok( tempfd != -1,
823 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
824 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
825 "_write _O_BINARY bad return value\n");
826 _close(tempfd);
827 i = lstrlenA(mytext);
828 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
829 ok(_read(tempfd,btext,i) == i,
830 "_read _O_BINARY got bad length\n");
831 ok( memcmp(dostext,btext,i) == 0,
832 "problems with _O_BINARY _write / _read\n");
833 _close(tempfd);
834 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
835 ok(_read(tempfd,btext,i) == i-1,
836 "_read _O_TEXT got bad length\n");
837 ok( memcmp(mytext,btext,i-1) == 0,
838 "problems with _O_BINARY _write / _O_TEXT _read\n");
839 _close(tempfd);
840 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
841 _S_IREAD | _S_IWRITE);
842 ok( tempfd != -1,
843 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
844 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
845 "_write _O_TEXT bad return value\n");
846 _close(tempfd);
847 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
848 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
849 "_read _O_BINARY got bad length\n");
850 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
851 "problems with _O_TEXT _write / _O_BINARY _read\n");
852 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
853 _close(tempfd);
854 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
855 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
856 "_read _O_TEXT got bad length\n");
857 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
858 "problems with _O_TEXT _write / _read\n");
859 _close(tempfd);
861 memset(btext, 0, LLEN);
862 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
863 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
864 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
865 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
866 _close(tempfd);
868 /* Test reading only \n or \r */
869 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
870 _lseek(tempfd, -1, FILE_END);
871 ret = _read(tempfd,btext,LLEN);
872 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
873 _lseek(tempfd, -2, FILE_END);
874 ret = _read(tempfd,btext,LLEN);
875 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
876 _lseek(tempfd, -3, FILE_END);
877 ret = _read(tempfd,btext,1);
878 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
879 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
880 _lseek(tempfd, -3, FILE_END);
881 ret = _read(tempfd,btext,2);
882 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
883 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
884 _lseek(tempfd, -3, FILE_END);
885 ret = _read(tempfd,btext,3);
886 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
887 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
888 _close(tempfd);
890 ret = unlink(tempf);
891 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
892 free(tempf);
894 tempf=_tempnam(".","wne");
895 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
896 ok( tempfd != -1,
897 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
898 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
899 "_write _O_BINARY bad return value\n");
900 _close(tempfd);
901 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
902 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
903 "_read _O_BINARY got bad length\n");
904 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
905 "problems with _O_BINARY _write / _read\n");
906 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
907 _close(tempfd);
908 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
909 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
910 "_read _O_TEXT got bad length\n");
911 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
912 "problems with _O_BINARY _write / _O_TEXT _read\n");
913 _close(tempfd);
915 /* test _read with single bytes. CR should be skipped and LF pulled in */
916 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
917 for (i=0; i<strlen(mytext); i++) /* */
919 _read(tempfd,btext, 1);
920 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
922 while (_read(tempfd,btext, 1));
923 _close(tempfd);
925 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
926 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
927 i = _read(tempfd,btext, strlen(mytext));
928 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
929 _close(tempfd);
931 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
932 ok( ret == 0,
933 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
934 ret = unlink(tempf);
935 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
936 free(tempf);
939 static void test_file_inherit_child(const char* fd_s)
941 int fd = atoi(fd_s);
942 char buffer[32];
943 int ret;
945 ret =write(fd, "Success", 8);
946 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
947 lseek(fd, 0, SEEK_SET);
948 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
949 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
952 static void test_file_inherit_child_no(const char* fd_s)
954 int fd = atoi(fd_s);
955 int ret;
957 ret = write(fd, "Success", 8);
958 ok( ret == -1 && errno == EBADF,
959 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
962 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
964 static BYTE block[1024];
965 BYTE *wxflag_ptr;
966 HANDLE *handle_ptr;
967 unsigned int i;
969 startup->lpReserved2 = block;
970 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
971 wxflag_ptr = block + sizeof(unsigned);
972 handle_ptr = (HANDLE *)(wxflag_ptr + count);
974 *(unsigned*)block = count;
975 for (i = 0; i < count; i++)
977 wxflag_ptr[i] = 0x81;
978 handle_ptr[i] = handles[i];
982 static const char *read_file( HANDLE file )
984 static char buffer[128];
985 DWORD ret;
986 SetFilePointer( file, 0, NULL, FILE_BEGIN );
987 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
988 buffer[ret] = 0;
989 return buffer;
992 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
993 const char *descr )
995 const char *data;
996 HANDLE hErrorFile;
997 SECURITY_ATTRIBUTES sa;
998 PROCESS_INFORMATION proc;
1000 /* make file handle inheritable */
1001 sa.nLength = sizeof(sa);
1002 sa.lpSecurityDescriptor = NULL;
1003 sa.bInheritHandle = TRUE;
1005 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1006 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1007 startup->dwFlags = STARTF_USESTDHANDLES;
1008 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1009 startup->hStdOutput = hErrorFile;
1010 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1012 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1013 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1014 winetest_wait_child_process( proc.hProcess );
1016 data = read_file( hErrorFile );
1017 if (expect_stdout)
1018 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1019 else
1020 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1022 if (hstdout)
1024 data = read_file( hstdout );
1025 if (expect_stdout)
1026 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1027 else
1028 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1031 CloseHandle( hErrorFile );
1032 DeleteFile( "fdopen.err" );
1035 static void test_file_inherit( const char* selfname )
1037 int fd;
1038 const char* arg_v[5];
1039 char buffer[16];
1040 char cmdline[MAX_PATH];
1041 STARTUPINFO startup;
1042 SECURITY_ATTRIBUTES sa;
1043 HANDLE handles[3];
1045 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1046 ok(fd != -1, "Couldn't create test file\n");
1047 arg_v[0] = selfname;
1048 arg_v[1] = "tests/file.c";
1049 arg_v[2] = "inherit";
1050 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1051 arg_v[4] = 0;
1052 _spawnvp(_P_WAIT, selfname, arg_v);
1053 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1054 lseek(fd, 0, SEEK_SET);
1055 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1056 close (fd);
1057 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1059 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1060 ok(fd != -1, "Couldn't create test file\n");
1061 arg_v[0] = selfname;
1062 arg_v[1] = "tests/file.c";
1063 arg_v[2] = "inherit_no";
1064 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1065 arg_v[4] = 0;
1066 _spawnvp(_P_WAIT, selfname, arg_v);
1067 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1068 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1069 close (fd);
1070 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1072 /* make file handle inheritable */
1073 sa.nLength = sizeof(sa);
1074 sa.lpSecurityDescriptor = NULL;
1075 sa.bInheritHandle = TRUE;
1076 sprintf(cmdline, "%s file inherit 1", selfname);
1078 /* init an empty Reserved2, which should not be recognized as inherit-block */
1079 ZeroMemory(&startup, sizeof(STARTUPINFO));
1080 startup.cb = sizeof(startup);
1081 create_io_inherit_block( &startup, 0, NULL );
1082 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1084 /* test with valid inheritblock */
1085 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1086 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1087 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1088 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1089 create_io_inherit_block( &startup, 3, handles );
1090 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1091 CloseHandle( handles[1] );
1092 DeleteFile("fdopen.tst");
1094 /* test inherit block starting with unsigned zero */
1095 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1096 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1097 create_io_inherit_block( &startup, 3, handles );
1098 *(unsigned int *)startup.lpReserved2 = 0;
1099 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1100 CloseHandle( handles[1] );
1101 DeleteFile("fdopen.tst");
1103 /* test inherit block with smaller size */
1104 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1105 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1106 create_io_inherit_block( &startup, 3, handles );
1107 startup.cbReserved2 -= 3;
1108 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1109 CloseHandle( handles[1] );
1110 DeleteFile("fdopen.tst");
1112 /* test inherit block with even smaller size */
1113 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1114 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1115 create_io_inherit_block( &startup, 3, handles );
1116 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1117 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1118 CloseHandle( handles[1] );
1119 DeleteFile("fdopen.tst");
1121 /* test inherit block with larger size */
1122 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1123 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1124 create_io_inherit_block( &startup, 3, handles );
1125 startup.cbReserved2 += 7;
1126 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1127 CloseHandle( handles[1] );
1128 DeleteFile("fdopen.tst");
1131 static void test_tmpnam( void )
1133 char name[MAX_PATH] = "abc";
1134 char *res;
1136 res = tmpnam(NULL);
1137 ok(res != NULL, "tmpnam returned NULL\n");
1138 ok(res[0] == '\\', "first character is not a backslash\n");
1139 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1140 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1142 res = tmpnam(name);
1143 ok(res != NULL, "tmpnam returned NULL\n");
1144 ok(res == name, "supplied buffer was not used\n");
1145 ok(res[0] == '\\', "first character is not a backslash\n");
1146 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1147 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1150 static void test_chsize( void )
1152 int fd;
1153 LONG cur, pos, count;
1154 char temptext[] = "012345678";
1155 char *tempfile = _tempnam( ".", "tst" );
1157 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1159 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1160 ok( fd > 0, "Couldn't open test file\n" );
1162 count = _write( fd, temptext, sizeof(temptext) );
1163 ok( count > 0, "Couldn't write to test file\n" );
1165 /* get current file pointer */
1166 cur = _lseek( fd, 0, SEEK_CUR );
1168 /* make the file smaller */
1169 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1171 pos = _lseek( fd, 0, SEEK_CUR );
1172 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1173 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1175 /* enlarge the file */
1176 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1178 pos = _lseek( fd, 0, SEEK_CUR );
1179 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1180 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1182 _close( fd );
1183 _unlink( tempfile );
1184 free( tempfile );
1187 static void test_fopen_fclose_fcloseall( void )
1189 char fname1[] = "empty1";
1190 char fname2[] = "empty2";
1191 char fname3[] = "empty3";
1192 FILE *stream1, *stream2, *stream3, *stream4;
1193 int ret, numclosed;
1195 /* testing fopen() */
1196 stream1 = fopen(fname1, "w+");
1197 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1198 stream2 = fopen(fname2, "w ");
1199 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1200 _unlink(fname3);
1201 stream3 = fopen(fname3, "r");
1202 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1203 stream3 = fopen(fname3, "w+");
1204 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1205 errno = 0xfaceabad;
1206 stream4 = fopen("", "w+");
1207 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1208 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1209 errno = 0xfaceabad;
1210 stream4 = fopen(NULL, "w+");
1211 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1212 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1214 /* testing fclose() */
1215 ret = fclose(stream2);
1216 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1217 ret = fclose(stream3);
1218 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1219 ret = fclose(stream2);
1220 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1221 ret = fclose(stream3);
1222 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1224 /* testing fcloseall() */
1225 numclosed = _fcloseall();
1226 /* fname1 should be closed here */
1227 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1228 numclosed = _fcloseall();
1229 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1231 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1232 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1233 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1236 static void test_fopen_s( void )
1238 const char name[] = "empty1";
1239 char buff[16];
1240 FILE *file;
1241 int ret;
1242 int len;
1244 if (!p_fopen_s)
1246 win_skip("Skipping fopen_s test\n");
1247 return;
1249 /* testing fopen_s */
1250 ret = p_fopen_s(&file, name, "w");
1251 ok(ret == 0, "fopen_s failed with %d\n", ret);
1252 ok(file != 0, "fopen_s failed to return value\n");
1253 fwrite(name, sizeof(name), 1, file);
1255 ret = fclose(file);
1256 ok(ret != EOF, "File failed to close\n");
1258 file = fopen(name, "r");
1259 ok(file != 0, "fopen failed\n");
1260 len = fread(buff, 1, sizeof(name), file);
1261 ok(len == sizeof(name), "File length is %d\n", len);
1262 buff[sizeof(name)] = '\0';
1263 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1265 ret = fclose(file);
1266 ok(ret != EOF, "File failed to close\n");
1268 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1271 static void test__wfopen_s( void )
1273 const char name[] = "empty1";
1274 const WCHAR wname[] = {
1275 'e','m','p','t','y','1',0
1277 const WCHAR wmode[] = {
1278 'w',0
1280 char buff[16];
1281 FILE *file;
1282 int ret;
1283 int len;
1285 if (!p__wfopen_s)
1287 win_skip("Skipping _wfopen_s test\n");
1288 return;
1290 /* testing _wfopen_s */
1291 ret = p__wfopen_s(&file, wname, wmode);
1292 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1293 ok(file != 0, "_wfopen_s failed to return value\n");
1294 fwrite(name, sizeof(name), 1, file);
1296 ret = fclose(file);
1297 ok(ret != EOF, "File failed to close\n");
1299 file = fopen(name, "r");
1300 ok(file != 0, "fopen failed\n");
1301 len = fread(buff, 1, sizeof(name), file);
1302 ok(len == sizeof(name), "File length is %d\n", len);
1303 buff[sizeof(name)] = '\0';
1304 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1306 ret = fclose(file);
1307 ok(ret != EOF, "File failed to close\n");
1309 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1312 static void test_get_osfhandle(void)
1314 int fd;
1315 char fname[] = "t_get_osfhanle";
1316 DWORD bytes_written;
1317 HANDLE handle;
1319 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1320 handle = (HANDLE)_get_osfhandle(fd);
1321 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1322 _close(fd);
1323 fd = _open(fname, _O_RDONLY, 0);
1324 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1326 _close(fd);
1327 _unlink(fname);
1330 static void test_setmaxstdio(void)
1332 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1333 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1336 static void test_stat(void)
1338 int fd;
1339 int pipes[2];
1340 int ret;
1341 struct stat buf;
1343 /* Tests for a file */
1344 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1345 if (fd >= 0)
1347 ret = fstat(fd, &buf);
1348 ok(!ret, "fstat failed: errno=%d\n", errno);
1349 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1350 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1351 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1352 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1353 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1354 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1356 ret = stat("stat.tst", &buf);
1357 ok(!ret, "stat failed: errno=%d\n", errno);
1358 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1359 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1360 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1361 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1362 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1364 close(fd);
1365 remove("stat.tst");
1367 else
1368 skip("open failed with errno %d\n", errno);
1370 /* Tests for a char device */
1371 if (_dup2(0, 10) == 0)
1373 ret = fstat(10, &buf);
1374 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1375 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1377 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1378 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1379 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1380 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1382 else
1383 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1384 close(10);
1386 else
1387 skip("_dup2 failed with errno %d\n", errno);
1389 /* Tests for pipes */
1390 if (_pipe(pipes, 1024, O_BINARY) == 0)
1392 ret = fstat(pipes[0], &buf);
1393 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1394 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1395 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1396 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1397 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1398 close(pipes[0]);
1399 close(pipes[1]);
1401 else
1402 skip("pipe failed with errno %d\n", errno);
1405 static const char* pipe_string="Hello world";
1407 /* How many messages to transfer over the pipe */
1408 #define N_TEST_MESSAGES 3
1410 static void test_pipes_child(int argc, char** args)
1412 int fd;
1413 int nwritten;
1414 int i;
1416 if (argc < 5)
1418 ok(0, "not enough parameters: %d\n", argc);
1419 return;
1422 fd=atoi(args[3]);
1423 i=close(fd);
1424 ok(!i, "unable to close %d: %d\n", fd, errno);
1426 fd=atoi(args[4]);
1428 for (i=0; i<N_TEST_MESSAGES; i++) {
1429 nwritten=write(fd, pipe_string, strlen(pipe_string));
1430 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1431 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1432 if (i < N_TEST_MESSAGES-1)
1433 Sleep(100);
1436 i=close(fd);
1437 ok(!i, "unable to close %d: %d\n", fd, errno);
1440 static void test_pipes(const char* selfname)
1442 int pipes[2];
1443 char str_fdr[12], str_fdw[12];
1444 FILE* file;
1445 const char* arg_v[6];
1446 char buf[4096];
1447 char expected[4096];
1448 int r;
1449 int i;
1451 /* Test reading from a pipe with read() */
1452 if (_pipe(pipes, 1024, O_BINARY) < 0)
1454 ok(0, "pipe failed with errno %d\n", errno);
1455 return;
1458 arg_v[0] = selfname;
1459 arg_v[1] = "tests/file.c";
1460 arg_v[2] = "pipes";
1461 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1462 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1463 arg_v[5] = NULL;
1464 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1465 i=close(pipes[1]);
1466 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1468 for (i=0; i<N_TEST_MESSAGES; i++) {
1469 r=read(pipes[0], buf, sizeof(buf)-1);
1470 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1471 if (r > 0)
1472 buf[r]='\0';
1473 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1476 r=read(pipes[0], buf, sizeof(buf)-1);
1477 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1478 i=close(pipes[0]);
1479 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1481 /* Test reading from a pipe with fread() */
1482 if (_pipe(pipes, 1024, O_BINARY) < 0)
1484 ok(0, "pipe failed with errno %d\n", errno);
1485 return;
1488 arg_v[0] = selfname;
1489 arg_v[1] = "tests/file.c";
1490 arg_v[2] = "pipes";
1491 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1492 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1493 arg_v[5] = NULL;
1494 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1495 i=close(pipes[1]);
1496 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1497 file=fdopen(pipes[0], "r");
1499 /* In blocking mode, fread will keep calling read() until it gets
1500 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1501 * in cooked mode instead of a pipe, it would also stop on EOL.)
1503 expected[0] = 0;
1504 for (i=0; i<N_TEST_MESSAGES; i++)
1505 strcat(expected, pipe_string);
1506 r=fread(buf, 1, sizeof(buf)-1, file);
1507 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1508 if (r > 0)
1509 buf[r]='\0';
1510 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1512 /* Let child close the file before we read, so we can sense EOF reliably */
1513 Sleep(100);
1514 r=fread(buf, 1, sizeof(buf)-1, file);
1515 ok(r == 0, "fread() returned %d instead of 0\n", r);
1516 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1517 ok(feof(file), "feof() is false!\n");
1519 i=fclose(file);
1520 ok(!i, "unable to close the pipe: %d\n", errno);
1523 static void test_unlink(void)
1525 FILE* file;
1526 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1527 file = fopen("test_unlink\\empty", "w");
1528 ok(file != NULL, "unable to create test file\n");
1529 if(file)
1530 fclose(file);
1531 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1532 unlink("test_unlink\\empty");
1533 rmdir("test_unlink");
1536 static void test_dup2(void)
1538 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1541 START_TEST(file)
1543 int arg_c;
1544 char** arg_v;
1546 init();
1548 arg_c = winetest_get_mainargs( &arg_v );
1550 /* testing low-level I/O */
1551 if (arg_c >= 3)
1553 if (strcmp(arg_v[2], "inherit") == 0)
1554 test_file_inherit_child(arg_v[3]);
1555 else if (strcmp(arg_v[2], "inherit_no") == 0)
1556 test_file_inherit_child_no(arg_v[3]);
1557 else if (strcmp(arg_v[2], "pipes") == 0)
1558 test_pipes_child(arg_c, arg_v);
1559 else
1560 ok(0, "invalid argument '%s'\n", arg_v[2]);
1561 return;
1563 test_dup2();
1564 test_file_inherit(arg_v[0]);
1565 test_file_write_read();
1566 test_chsize();
1567 test_stat();
1568 test_unlink();
1570 /* testing stream I/O */
1571 test_filbuf();
1572 test_fdopen();
1573 test_fopen_fclose_fcloseall();
1574 test_fopen_s();
1575 test__wfopen_s();
1576 test_fileops();
1577 test_asciimode();
1578 test_asciimode2();
1579 test_readmode(FALSE); /* binary mode */
1580 test_readmode(TRUE); /* ascii mode */
1581 test_readboundary();
1582 test_fgetc();
1583 test_fputc();
1584 test_flsbuf();
1585 test_fgetwc();
1586 test_ctrlz();
1587 test_file_put_get();
1588 test_tmpnam();
1589 test_get_osfhandle();
1590 test_setmaxstdio();
1591 test_pipes(arg_v[0]);
1593 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1594 * file contains lines in the correct order
1596 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);