setupapi: Print the debug string and not the pointer to it.
[wine.git] / dlls / msvcrt / tests / file.c
blob0f94083c996d1332993f6bae692aaf66a1b2ea61
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_fflush( void )
596 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
597 char buf1[16], buf2[24];
598 char *tempf;
599 FILE *tempfh;
600 int ret;
602 tempf=_tempnam(".","wne");
604 /* Prepare the file. */
605 tempfh = fopen(tempf,"wb");
606 ok(tempfh != NULL, "Can't open test file.\n");
607 fwrite(obuf, 1, sizeof(obuf), tempfh);
608 fclose(tempfh);
610 /* Open the file for input. */
611 tempfh = fopen(tempf,"rb");
612 ok(tempfh != NULL, "Can't open test file.\n");
613 fread(buf1, 1, sizeof(buf1), tempfh);
615 /* Using fflush() on input stream is undefined in ANSI.
616 * But MSDN says that it clears input buffer. */
617 _lseek(_fileno(tempfh), 0, SEEK_SET);
618 ret = fflush(tempfh);
619 ok(ret == 0, "expected 0, got %d\n", ret);
620 memset(buf2, '?', sizeof(buf2));
621 fread(buf2, 1, sizeof(buf2), tempfh);
622 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
624 /* fflush(NULL) doesn't clear input buffer. */
625 _lseek(_fileno(tempfh), 0, SEEK_SET);
626 ret = fflush(NULL);
627 ok(ret == 0, "expected 0, got %d\n", ret);
628 memset(buf2, '?', sizeof(buf2));
629 fread(buf2, 1, sizeof(buf2), tempfh);
630 ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]);
632 /* _flushall() clears input buffer. */
633 _lseek(_fileno(tempfh), 0, SEEK_SET);
634 ret = _flushall();
635 ok(ret >= 0, "unexpected ret %d\n", ret);
636 memset(buf2, '?', sizeof(buf2));
637 fread(buf2, 1, sizeof(buf2), tempfh);
638 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
640 fclose(tempfh);
642 unlink(tempf);
643 free(tempf);
646 static void test_fgetwc( void )
648 #define LLEN 512
650 char* tempf;
651 FILE *tempfh;
652 static const char mytext[]= "This is test_fgetwc\r\n";
653 WCHAR wtextW[BUFSIZ+LLEN+1];
654 WCHAR *mytextW = NULL, *aptr, *wptr;
655 BOOL diff_found = FALSE;
656 int j;
657 unsigned int i;
658 LONG l;
660 tempf=_tempnam(".","wne");
661 tempfh = fopen(tempf,"wb");
662 j = 'a';
663 /* pad to almost the length of the internal buffer */
664 for (i=0; i<BUFSIZ-4; i++)
665 fputc(j,tempfh);
666 j = '\r';
667 fputc(j,tempfh);
668 j = '\n';
669 fputc(j,tempfh);
670 fputs(mytext,tempfh);
671 fclose(tempfh);
672 /* in text mode, getws/c expects multibyte characters */
673 /*currently Wine only supports plain ascii, and that is all that is tested here */
674 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
675 fgetws(wtextW,LLEN,tempfh);
676 l=ftell(tempfh);
677 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l);
678 fgetws(wtextW,LLEN,tempfh);
679 l=ftell(tempfh);
680 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlen(mytext), l);
681 mytextW = AtoW (mytext);
682 aptr = mytextW;
683 wptr = wtextW;
684 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
686 diff_found |= (*aptr != *wptr);
688 ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
689 ok(*wptr == '\n', "Carriage return was not skipped\n");
690 fclose(tempfh);
691 unlink(tempf);
693 tempfh = fopen(tempf,"wb");
694 j = 'a';
695 /* pad to almost the length of the internal buffer. Use an odd number of bytes
696 to test that we can read wchars that are split across the internal buffer
697 boundary */
698 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++)
699 fputc(j,tempfh);
700 j = '\r';
701 fputwc(j,tempfh);
702 j = '\n';
703 fputwc(j,tempfh);
704 fputws(wtextW,tempfh);
705 fputws(wtextW,tempfh);
706 fclose(tempfh);
707 /* in binary mode, getws/c expects wide characters */
708 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
709 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext);
710 fgetws(wtextW,j,tempfh);
711 l=ftell(tempfh);
712 j=(j-1)*sizeof(WCHAR);
713 ok(l==j, "ftell expected %d got %d\n", j, l);
714 i=fgetc(tempfh);
715 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i);
716 l=ftell(tempfh);
717 j++;
718 ok(l==j, "ftell expected %d got %d\n", j, l);
719 fgetws(wtextW,3,tempfh);
720 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]);
721 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]);
722 l=ftell(tempfh);
723 j += 4;
724 ok(l==j, "ftell expected %d got %d\n", j, l);
725 for(i=0; i<strlen(mytext); i++)
726 wtextW[i] = 0;
727 /* the first time we get the string, it should be entirely within the local buffer */
728 fgetws(wtextW,LLEN,tempfh);
729 l=ftell(tempfh);
730 j += (strlen(mytext)-1)*sizeof(WCHAR);
731 ok(l==j, "ftell expected %d got %d\n", j, l);
732 diff_found = FALSE;
733 aptr = mytextW;
734 wptr = wtextW;
735 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
737 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
738 diff_found |= (*aptr != *wptr);
740 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
741 ok(*wptr == '\n', "Should get newline\n");
742 for(i=0; i<strlen(mytext); i++)
743 wtextW[i] = 0;
744 /* the second time we get the string, it should cross the local buffer boundary.
745 One of the wchars should be split across the boundary */
746 fgetws(wtextW,LLEN,tempfh);
747 diff_found = FALSE;
748 aptr = mytextW;
749 wptr = wtextW;
750 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++)
752 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr);
753 diff_found |= (*aptr != *wptr);
755 ok(!(diff_found), "fgetwc difference found in BINARY mode\n");
756 ok(*wptr == '\n', "Should get newline\n");
758 free(mytextW);
759 fclose(tempfh);
760 unlink(tempf);
761 free(tempf);
764 static void test_ctrlz( void )
766 char* tempf;
767 FILE *tempfh;
768 static const char mytext[]= "This is test_ctrlz";
769 char buffer[256];
770 int i, j;
771 LONG l;
773 tempf=_tempnam(".","wne");
774 tempfh = fopen(tempf,"wb");
775 fputs(mytext,tempfh);
776 j = 0x1a; /* a ctrl-z character signals EOF in text mode */
777 fputc(j,tempfh);
778 j = '\r';
779 fputc(j,tempfh);
780 j = '\n';
781 fputc(j,tempfh);
782 j = 'a';
783 fputc(j,tempfh);
784 fclose(tempfh);
785 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
786 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
787 i=strlen(buffer);
788 j=strlen(mytext);
789 ok(i==j, "returned string length expected %d got %d\n", j, i);
790 j+=4; /* ftell should indicate the true end of file */
791 l=ftell(tempfh);
792 ok(l==j, "ftell expected %d got %d\n", j, l);
793 ok(feof(tempfh), "did not get EOF\n");
794 fclose(tempfh);
796 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */
797 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
798 i=strlen(buffer);
799 j=strlen(mytext)+3; /* should get through newline */
800 ok(i==j, "returned string length expected %d got %d\n", j, i);
801 l=ftell(tempfh);
802 ok(l==j, "ftell expected %d got %d\n", j, l);
803 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n");
804 i=strlen(buffer);
805 ok(i==1, "returned string length expected %d got %d\n", 1, i);
806 ok(feof(tempfh), "did not get EOF\n");
807 fclose(tempfh);
808 unlink(tempf);
809 free(tempf);
812 static void test_file_put_get( void )
814 char* tempf;
815 FILE *tempfh;
816 static const char mytext[]= "This is a test_file_put_get\n";
817 static const char dostext[]= "This is a test_file_put_get\r\n";
818 char btext[LLEN];
819 WCHAR wtextW[LLEN+1];
820 WCHAR *mytextW = NULL, *aptr, *wptr;
821 BOOL diff_found = FALSE;
822 unsigned int i;
824 tempf=_tempnam(".","wne");
825 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
826 fputs(mytext,tempfh);
827 fclose(tempfh);
828 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
829 fgets(btext,LLEN,tempfh);
830 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
831 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
832 fclose(tempfh);
833 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
834 fputs(dostext,tempfh);
835 fclose(tempfh);
836 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
837 fgets(btext,LLEN,tempfh);
838 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
839 fclose(tempfh);
840 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
841 fgets(btext,LLEN,tempfh);
842 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
844 fclose(tempfh);
845 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
846 fgetws(wtextW,LLEN,tempfh);
847 mytextW = AtoW (mytext);
848 aptr = mytextW;
849 wptr = wtextW;
851 for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
853 diff_found |= (*aptr != *wptr);
855 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
856 free(mytextW);
857 fclose(tempfh);
858 unlink(tempf);
859 free(tempf);
862 static void test_file_write_read( void )
864 char* tempf;
865 int tempfd;
866 static const char mytext[]= "This is test_file_write_read\nsecond line\n";
867 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
868 char btext[LLEN];
869 int ret, i;
871 tempf=_tempnam(".","wne");
872 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,
873 _S_IREAD | _S_IWRITE);
874 ok( tempfd != -1,
875 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
876 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
877 "_write _O_BINARY bad return value\n");
878 _close(tempfd);
879 i = lstrlenA(mytext);
880 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
881 ok(_read(tempfd,btext,i) == i,
882 "_read _O_BINARY got bad length\n");
883 ok( memcmp(dostext,btext,i) == 0,
884 "problems with _O_BINARY _write / _read\n");
885 _close(tempfd);
886 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
887 ok(_read(tempfd,btext,i) == i-1,
888 "_read _O_TEXT got bad length\n");
889 ok( memcmp(mytext,btext,i-1) == 0,
890 "problems with _O_BINARY _write / _O_TEXT _read\n");
891 _close(tempfd);
892 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
893 _S_IREAD | _S_IWRITE);
894 ok( tempfd != -1,
895 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
896 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
897 "_write _O_TEXT bad return value\n");
898 _close(tempfd);
899 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
900 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
901 "_read _O_BINARY got bad length\n");
902 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
903 "problems with _O_TEXT _write / _O_BINARY _read\n");
904 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
905 _close(tempfd);
906 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
907 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
908 "_read _O_TEXT got bad length\n");
909 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
910 "problems with _O_TEXT _write / _read\n");
911 _close(tempfd);
913 memset(btext, 0, LLEN);
914 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */
915 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd));
916 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n");
917 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n");
918 _close(tempfd);
920 /* Test reading only \n or \r */
921 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
922 _lseek(tempfd, -1, FILE_END);
923 ret = _read(tempfd,btext,LLEN);
924 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
925 _lseek(tempfd, -2, FILE_END);
926 ret = _read(tempfd,btext,LLEN);
927 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
928 _lseek(tempfd, -3, FILE_END);
929 ret = _read(tempfd,btext,1);
930 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
931 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
932 _lseek(tempfd, -3, FILE_END);
933 ret = _read(tempfd,btext,2);
934 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
935 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
936 _lseek(tempfd, -3, FILE_END);
937 ret = _read(tempfd,btext,3);
938 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
939 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
940 _close(tempfd);
942 ret = unlink(tempf);
943 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
944 free(tempf);
946 tempf=_tempnam(".","wne");
947 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0);
948 ok( tempfd != -1,
949 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
950 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
951 "_write _O_BINARY bad return value\n");
952 _close(tempfd);
953 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
954 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
955 "_read _O_BINARY got bad length\n");
956 ok( memcmp(dostext,btext,strlen(dostext)) == 0,
957 "problems with _O_BINARY _write / _read\n");
958 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
959 _close(tempfd);
960 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
961 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
962 "_read _O_TEXT got bad length\n");
963 ok( memcmp(mytext,btext,strlen(mytext)) == 0,
964 "problems with _O_BINARY _write / _O_TEXT _read\n");
965 _close(tempfd);
967 /* test _read with single bytes. CR should be skipped and LF pulled in */
968 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
969 for (i=0; i<strlen(mytext); i++) /* */
971 _read(tempfd,btext, 1);
972 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]);
974 while (_read(tempfd,btext, 1));
975 _close(tempfd);
977 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
978 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
979 i = _read(tempfd,btext, strlen(mytext));
980 ok(i == strlen(mytext)-1, "_read_i %d\n", i);
981 _close(tempfd);
983 ret =_chmod (tempf, _S_IREAD | _S_IWRITE);
984 ok( ret == 0,
985 "Can't chmod '%s' to read-write: %d\n", tempf, errno);
986 ret = unlink(tempf);
987 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
988 free(tempf);
991 static void test_file_inherit_child(const char* fd_s)
993 int fd = atoi(fd_s);
994 char buffer[32];
995 int ret;
997 ret =write(fd, "Success", 8);
998 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
999 lseek(fd, 0, SEEK_SET);
1000 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
1001 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1004 static void test_file_inherit_child_no(const char* fd_s)
1006 int fd = atoi(fd_s);
1007 int ret;
1009 ret = write(fd, "Success", 8);
1010 ok( ret == -1 && errno == EBADF,
1011 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
1014 static void create_io_inherit_block( STARTUPINFO *startup, unsigned int count, const HANDLE *handles )
1016 static BYTE block[1024];
1017 BYTE *wxflag_ptr;
1018 HANDLE *handle_ptr;
1019 unsigned int i;
1021 startup->lpReserved2 = block;
1022 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count;
1023 wxflag_ptr = block + sizeof(unsigned);
1024 handle_ptr = (HANDLE *)(wxflag_ptr + count);
1026 *(unsigned*)block = count;
1027 for (i = 0; i < count; i++)
1029 wxflag_ptr[i] = 0x81;
1030 handle_ptr[i] = handles[i];
1034 static const char *read_file( HANDLE file )
1036 static char buffer[128];
1037 DWORD ret;
1038 SetFilePointer( file, 0, NULL, FILE_BEGIN );
1039 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0;
1040 buffer[ret] = 0;
1041 return buffer;
1044 static void test_stdout_handle( STARTUPINFO *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout,
1045 const char *descr )
1047 const char *data;
1048 HANDLE hErrorFile;
1049 SECURITY_ATTRIBUTES sa;
1050 PROCESS_INFORMATION proc;
1052 /* make file handle inheritable */
1053 sa.nLength = sizeof(sa);
1054 sa.lpSecurityDescriptor = NULL;
1055 sa.bInheritHandle = TRUE;
1057 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE,
1058 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1059 startup->dwFlags = STARTF_USESTDHANDLES;
1060 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
1061 startup->hStdOutput = hErrorFile;
1062 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE );
1064 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE,
1065 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc );
1066 winetest_wait_child_process( proc.hProcess );
1068 data = read_file( hErrorFile );
1069 if (expect_stdout)
1070 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr );
1071 else
1072 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data );
1074 if (hstdout)
1076 data = read_file( hstdout );
1077 if (expect_stdout)
1078 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data );
1079 else
1080 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr );
1083 CloseHandle( hErrorFile );
1084 DeleteFile( "fdopen.err" );
1087 static void test_file_inherit( const char* selfname )
1089 int fd;
1090 const char* arg_v[5];
1091 char buffer[16];
1092 char cmdline[MAX_PATH];
1093 STARTUPINFO startup;
1094 SECURITY_ATTRIBUTES sa;
1095 HANDLE handles[3];
1097 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
1098 ok(fd != -1, "Couldn't create test file\n");
1099 arg_v[0] = selfname;
1100 arg_v[1] = "tests/file.c";
1101 arg_v[2] = "inherit";
1102 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1103 arg_v[4] = 0;
1104 _spawnvp(_P_WAIT, selfname, arg_v);
1105 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd));
1106 lseek(fd, 0, SEEK_SET);
1107 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
1108 close (fd);
1109 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1111 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
1112 ok(fd != -1, "Couldn't create test file\n");
1113 arg_v[0] = selfname;
1114 arg_v[1] = "tests/file.c";
1115 arg_v[2] = "inherit_no";
1116 arg_v[3] = buffer; sprintf(buffer, "%d", fd);
1117 arg_v[4] = 0;
1118 _spawnvp(_P_WAIT, selfname, arg_v);
1119 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd));
1120 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
1121 close (fd);
1122 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1124 /* make file handle inheritable */
1125 sa.nLength = sizeof(sa);
1126 sa.lpSecurityDescriptor = NULL;
1127 sa.bInheritHandle = TRUE;
1128 sprintf(cmdline, "%s file inherit 1", selfname);
1130 /* init an empty Reserved2, which should not be recognized as inherit-block */
1131 ZeroMemory(&startup, sizeof(STARTUPINFO));
1132 startup.cb = sizeof(startup);
1133 create_io_inherit_block( &startup, 0, NULL );
1134 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" );
1136 /* test with valid inheritblock */
1137 handles[0] = GetStdHandle( STD_INPUT_HANDLE );
1138 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1139 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1140 handles[2] = GetStdHandle( STD_ERROR_HANDLE );
1141 create_io_inherit_block( &startup, 3, handles );
1142 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" );
1143 CloseHandle( handles[1] );
1144 DeleteFile("fdopen.tst");
1146 /* test inherit block starting with unsigned zero */
1147 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1148 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1149 create_io_inherit_block( &startup, 3, handles );
1150 *(unsigned int *)startup.lpReserved2 = 0;
1151 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" );
1152 CloseHandle( handles[1] );
1153 DeleteFile("fdopen.tst");
1155 /* test inherit block with smaller size */
1156 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1157 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1158 create_io_inherit_block( &startup, 3, handles );
1159 startup.cbReserved2 -= 3;
1160 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" );
1161 CloseHandle( handles[1] );
1162 DeleteFile("fdopen.tst");
1164 /* test inherit block with even smaller size */
1165 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1166 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1167 create_io_inherit_block( &startup, 3, handles );
1168 startup.cbReserved2 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char);
1169 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" );
1170 CloseHandle( handles[1] );
1171 DeleteFile("fdopen.tst");
1173 /* test inherit block with larger size */
1174 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
1175 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
1176 create_io_inherit_block( &startup, 3, handles );
1177 startup.cbReserved2 += 7;
1178 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
1179 CloseHandle( handles[1] );
1180 DeleteFile("fdopen.tst");
1183 static void test_tmpnam( void )
1185 char name[MAX_PATH] = "abc";
1186 char *res;
1188 res = tmpnam(NULL);
1189 ok(res != NULL, "tmpnam returned NULL\n");
1190 ok(res[0] == '\\', "first character is not a backslash\n");
1191 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1192 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
1194 res = tmpnam(name);
1195 ok(res != NULL, "tmpnam returned NULL\n");
1196 ok(res == name, "supplied buffer was not used\n");
1197 ok(res[0] == '\\', "first character is not a backslash\n");
1198 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
1199 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
1202 static void test_chsize( void )
1204 int fd;
1205 LONG cur, pos, count;
1206 char temptext[] = "012345678";
1207 char *tempfile = _tempnam( ".", "tst" );
1209 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
1211 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
1212 ok( fd > 0, "Couldn't open test file\n" );
1214 count = _write( fd, temptext, sizeof(temptext) );
1215 ok( count > 0, "Couldn't write to test file\n" );
1217 /* get current file pointer */
1218 cur = _lseek( fd, 0, SEEK_CUR );
1220 /* make the file smaller */
1221 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
1223 pos = _lseek( fd, 0, SEEK_CUR );
1224 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1225 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
1227 /* enlarge the file */
1228 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
1230 pos = _lseek( fd, 0, SEEK_CUR );
1231 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
1232 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
1234 _close( fd );
1235 _unlink( tempfile );
1236 free( tempfile );
1239 static void test_fopen_fclose_fcloseall( void )
1241 char fname1[] = "empty1";
1242 char fname2[] = "empty2";
1243 char fname3[] = "empty3";
1244 FILE *stream1, *stream2, *stream3, *stream4;
1245 int ret, numclosed;
1247 /* testing fopen() */
1248 stream1 = fopen(fname1, "w+");
1249 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1);
1250 stream2 = fopen(fname2, "w ");
1251 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 );
1252 _unlink(fname3);
1253 stream3 = fopen(fname3, "r");
1254 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 );
1255 stream3 = fopen(fname3, "w+");
1256 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 );
1257 errno = 0xfaceabad;
1258 stream4 = fopen("", "w+");
1259 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1260 "filename is empty, errno = %d (expected 2 or 22)\n", errno);
1261 errno = 0xfaceabad;
1262 stream4 = fopen(NULL, "w+");
1263 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT),
1264 "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
1266 /* testing fclose() */
1267 ret = fclose(stream2);
1268 ok(ret == 0, "The file '%s' was not closed\n", fname2);
1269 ret = fclose(stream3);
1270 ok(ret == 0, "The file '%s' was not closed\n", fname3);
1271 ret = fclose(stream2);
1272 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret);
1273 ret = fclose(stream3);
1274 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret);
1276 /* testing fcloseall() */
1277 numclosed = _fcloseall();
1278 /* fname1 should be closed here */
1279 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed);
1280 numclosed = _fcloseall();
1281 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed);
1283 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1);
1284 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2);
1285 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3);
1288 static void test_fopen_s( void )
1290 const char name[] = "empty1";
1291 char buff[16];
1292 FILE *file;
1293 int ret;
1294 int len;
1296 if (!p_fopen_s)
1298 win_skip("Skipping fopen_s test\n");
1299 return;
1301 /* testing fopen_s */
1302 ret = p_fopen_s(&file, name, "w");
1303 ok(ret == 0, "fopen_s failed with %d\n", ret);
1304 ok(file != 0, "fopen_s failed to return value\n");
1305 fwrite(name, sizeof(name), 1, file);
1307 ret = fclose(file);
1308 ok(ret != EOF, "File failed to close\n");
1310 file = fopen(name, "r");
1311 ok(file != 0, "fopen failed\n");
1312 len = fread(buff, 1, sizeof(name), file);
1313 ok(len == sizeof(name), "File length is %d\n", len);
1314 buff[sizeof(name)] = '\0';
1315 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1317 ret = fclose(file);
1318 ok(ret != EOF, "File failed to close\n");
1320 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1323 static void test__wfopen_s( void )
1325 const char name[] = "empty1";
1326 const WCHAR wname[] = {
1327 'e','m','p','t','y','1',0
1329 const WCHAR wmode[] = {
1330 'w',0
1332 char buff[16];
1333 FILE *file;
1334 int ret;
1335 int len;
1337 if (!p__wfopen_s)
1339 win_skip("Skipping _wfopen_s test\n");
1340 return;
1342 /* testing _wfopen_s */
1343 ret = p__wfopen_s(&file, wname, wmode);
1344 ok(ret == 0, "_wfopen_s failed with %d\n", ret);
1345 ok(file != 0, "_wfopen_s failed to return value\n");
1346 fwrite(name, sizeof(name), 1, file);
1348 ret = fclose(file);
1349 ok(ret != EOF, "File failed to close\n");
1351 file = fopen(name, "r");
1352 ok(file != 0, "fopen failed\n");
1353 len = fread(buff, 1, sizeof(name), file);
1354 ok(len == sizeof(name), "File length is %d\n", len);
1355 buff[sizeof(name)] = '\0';
1356 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name);
1358 ret = fclose(file);
1359 ok(ret != EOF, "File failed to close\n");
1361 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name);
1364 static void test_get_osfhandle(void)
1366 int fd;
1367 char fname[] = "t_get_osfhanle";
1368 DWORD bytes_written;
1369 HANDLE handle;
1371 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE);
1372 handle = (HANDLE)_get_osfhandle(fd);
1373 WriteFile(handle, "bar", 3, &bytes_written, NULL);
1374 _close(fd);
1375 fd = _open(fname, _O_RDONLY, 0);
1376 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname);
1378 _close(fd);
1379 _unlink(fname);
1382 static void test_setmaxstdio(void)
1384 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1385 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1388 static void test_stat(void)
1390 int fd;
1391 int pipes[2];
1392 int ret;
1393 struct stat buf;
1395 /* Tests for a file */
1396 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
1397 if (fd >= 0)
1399 ret = fstat(fd, &buf);
1400 ok(!ret, "fstat failed: errno=%d\n", errno);
1401 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1402 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1403 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev);
1404 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1405 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1406 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1408 ret = stat("stat.tst", &buf);
1409 ok(!ret, "stat failed: errno=%d\n", errno);
1410 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode);
1411 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode);
1412 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev);
1413 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1414 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size);
1416 close(fd);
1417 remove("stat.tst");
1419 else
1420 skip("open failed with errno %d\n", errno);
1422 /* Tests for a char device */
1423 if (_dup2(0, 10) == 0)
1425 ret = fstat(10, &buf);
1426 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno);
1427 if ((buf.st_mode & _S_IFMT) == _S_IFCHR)
1429 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode);
1430 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev);
1431 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev);
1432 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1434 else
1435 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode);
1436 close(10);
1438 else
1439 skip("_dup2 failed with errno %d\n", errno);
1441 /* Tests for pipes */
1442 if (_pipe(pipes, 1024, O_BINARY) == 0)
1444 ret = fstat(pipes[0], &buf);
1445 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno);
1446 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode);
1447 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]);
1448 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]);
1449 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink);
1450 close(pipes[0]);
1451 close(pipes[1]);
1453 else
1454 skip("pipe failed with errno %d\n", errno);
1457 static const char* pipe_string="Hello world";
1459 /* How many messages to transfer over the pipe */
1460 #define N_TEST_MESSAGES 3
1462 static void test_pipes_child(int argc, char** args)
1464 int fd;
1465 int nwritten;
1466 int i;
1468 if (argc < 5)
1470 ok(0, "not enough parameters: %d\n", argc);
1471 return;
1474 fd=atoi(args[3]);
1475 i=close(fd);
1476 ok(!i, "unable to close %d: %d\n", fd, errno);
1478 fd=atoi(args[4]);
1480 for (i=0; i<N_TEST_MESSAGES; i++) {
1481 nwritten=write(fd, pipe_string, strlen(pipe_string));
1482 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten);
1483 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1484 if (i < N_TEST_MESSAGES-1)
1485 Sleep(100);
1488 i=close(fd);
1489 ok(!i, "unable to close %d: %d\n", fd, errno);
1492 static void test_pipes(const char* selfname)
1494 int pipes[2];
1495 char str_fdr[12], str_fdw[12];
1496 FILE* file;
1497 const char* arg_v[6];
1498 char buf[4096];
1499 char expected[4096];
1500 int r;
1501 int i;
1503 /* Test reading from a pipe with read() */
1504 if (_pipe(pipes, 1024, O_BINARY) < 0)
1506 ok(0, "pipe failed with errno %d\n", errno);
1507 return;
1510 arg_v[0] = selfname;
1511 arg_v[1] = "tests/file.c";
1512 arg_v[2] = "pipes";
1513 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1514 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1515 arg_v[5] = NULL;
1516 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1517 i=close(pipes[1]);
1518 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1520 for (i=0; i<N_TEST_MESSAGES; i++) {
1521 r=read(pipes[0], buf, sizeof(buf)-1);
1522 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r);
1523 if (r > 0)
1524 buf[r]='\0';
1525 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf);
1528 r=read(pipes[0], buf, sizeof(buf)-1);
1529 ok(r == 0, "expected to read 0 bytes, got %d\n", r);
1530 i=close(pipes[0]);
1531 ok(!i, "unable to close %d: %d\n", pipes[0], errno);
1533 /* Test reading from a pipe with fread() */
1534 if (_pipe(pipes, 1024, O_BINARY) < 0)
1536 ok(0, "pipe failed with errno %d\n", errno);
1537 return;
1540 arg_v[0] = selfname;
1541 arg_v[1] = "tests/file.c";
1542 arg_v[2] = "pipes";
1543 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]);
1544 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]);
1545 arg_v[5] = NULL;
1546 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v);
1547 i=close(pipes[1]);
1548 ok(!i, "unable to close %d: %d\n", pipes[1], errno);
1549 file=fdopen(pipes[0], "r");
1551 /* In blocking mode, fread will keep calling read() until it gets
1552 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
1553 * in cooked mode instead of a pipe, it would also stop on EOL.)
1555 expected[0] = 0;
1556 for (i=0; i<N_TEST_MESSAGES; i++)
1557 strcat(expected, pipe_string);
1558 r=fread(buf, 1, sizeof(buf)-1, file);
1559 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file));
1560 if (r > 0)
1561 buf[r]='\0';
1562 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected);
1564 /* Let child close the file before we read, so we can sense EOF reliably */
1565 Sleep(100);
1566 r=fread(buf, 1, sizeof(buf)-1, file);
1567 ok(r == 0, "fread() returned %d instead of 0\n", r);
1568 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file));
1569 ok(feof(file), "feof() is false!\n");
1571 i=fclose(file);
1572 ok(!i, "unable to close the pipe: %d\n", errno);
1575 static void test_unlink(void)
1577 FILE* file;
1578 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
1579 file = fopen("test_unlink\\empty", "w");
1580 ok(file != NULL, "unable to create test file\n");
1581 if(file)
1582 fclose(file);
1583 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
1584 unlink("test_unlink\\empty");
1585 rmdir("test_unlink");
1588 static void test_dup2(void)
1590 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
1593 START_TEST(file)
1595 int arg_c;
1596 char** arg_v;
1598 init();
1600 arg_c = winetest_get_mainargs( &arg_v );
1602 /* testing low-level I/O */
1603 if (arg_c >= 3)
1605 if (strcmp(arg_v[2], "inherit") == 0)
1606 test_file_inherit_child(arg_v[3]);
1607 else if (strcmp(arg_v[2], "inherit_no") == 0)
1608 test_file_inherit_child_no(arg_v[3]);
1609 else if (strcmp(arg_v[2], "pipes") == 0)
1610 test_pipes_child(arg_c, arg_v);
1611 else
1612 ok(0, "invalid argument '%s'\n", arg_v[2]);
1613 return;
1615 test_dup2();
1616 test_file_inherit(arg_v[0]);
1617 test_file_write_read();
1618 test_chsize();
1619 test_stat();
1620 test_unlink();
1622 /* testing stream I/O */
1623 test_filbuf();
1624 test_fdopen();
1625 test_fopen_fclose_fcloseall();
1626 test_fopen_s();
1627 test__wfopen_s();
1628 test_fileops();
1629 test_asciimode();
1630 test_asciimode2();
1631 test_readmode(FALSE); /* binary mode */
1632 test_readmode(TRUE); /* ascii mode */
1633 test_readboundary();
1634 test_fgetc();
1635 test_fputc();
1636 test_flsbuf();
1637 test_fflush();
1638 test_fgetwc();
1639 test_ctrlz();
1640 test_file_put_get();
1641 test_tmpnam();
1642 test_get_osfhandle();
1643 test_setmaxstdio();
1644 test_pipes(arg_v[0]);
1646 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
1647 * file contains lines in the correct order
1649 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);