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"
39 #define MSVCRT_FD_BLOCK_SIZE 32
45 CRITICAL_SECTION crit
;
47 static ioinfo
**__pioinfo
;
49 static HANDLE proc_handles
[2];
51 static int (__cdecl
*p_fopen_s
)(FILE**, const char*, const char*);
52 static int (__cdecl
*p__wfopen_s
)(FILE**, const wchar_t*, const wchar_t*);
53 static errno_t (__cdecl
*p__get_fmode
)(int*);
54 static errno_t (__cdecl
*p__set_fmode
)(int);
56 static const char* get_base_name(const char *path
)
58 const char *ret
= path
+strlen(path
)-1;
61 if(*ret
=='\\' || *ret
=='/')
68 static void init(void)
70 HMODULE hmod
= GetModuleHandleA("msvcrt.dll");
72 setlocale(LC_CTYPE
, "C");
74 p_fopen_s
= (void*)GetProcAddress(hmod
, "fopen_s");
75 p__wfopen_s
= (void*)GetProcAddress(hmod
, "_wfopen_s");
76 __pioinfo
= (void*)GetProcAddress(hmod
, "__pioinfo");
77 p__get_fmode
= (void*)GetProcAddress(hmod
, "_get_fmode");
78 p__set_fmode
= (void*)GetProcAddress(hmod
, "_set_fmode");
81 static void test_filbuf( void )
87 fp
= fopen("filbuf.tst", "wb");
88 fwrite("\n\n\n\n", 1, 4, fp
);
91 fp
= fopen("filbuf.tst", "rt");
93 ok(c
== '\n', "read wrong byte\n");
94 /* See bug 16970 for why we care about _filbuf.
95 * ftell returns screwy values on files with lots
96 * of bare LFs in ascii mode because it assumes
97 * that ascii files contain only CRLFs, removes
98 * the CR's early in _filbuf, and adjusts the return
99 * value of ftell to compensate.
100 * native _filbuf will read the whole file, then consume and return
101 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
102 * pointing to a buffer of three bare LFs, so
103 * ftell will return 4 - 3 - 3 = -2.
105 ok(ftell(fp
) == -2, "ascii crlf removal does not match native\n");
106 ok(fgetpos(fp
, &pos
) == 0, "fgetpos fail\n");
107 ok(pos
== -2, "ftell does not match fgetpos\n");
109 unlink("filbuf.tst");
112 static void test_fdopen( void )
114 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
119 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
120 write (fd
, buffer
, sizeof (buffer
));
123 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
124 lseek (fd
, 5, SEEK_SET
);
125 file
= fdopen (fd
, "rb");
126 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
127 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
129 unlink ("fdopen.tst");
132 static void test_fileops( void )
134 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
141 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
143 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
144 write (fd
, outbuffer
, sizeof (outbuffer
));
147 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
149 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
150 file
= fdopen (fd
, "rb");
151 setvbuf(file
,NULL
,bufmodes
[bufmode
],2048);
152 if(bufmodes
[bufmode
] == _IOFBF
)
153 ok(file
->_bufsiz
== 2048, "file->_bufsiz = %d\n", file
->_bufsiz
);
154 ok(file
->_base
!= NULL
, "file->_base = NULL\n");
155 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes
[bufmode
]);
156 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
157 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
158 ok(feof(file
) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
160 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
161 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes
[bufmode
]);
162 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
163 ok(strlen(buffer
) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes
[bufmode
]);
164 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes
[bufmode
]);
167 for (i
= 0; i
< sizeof(outbuffer
); i
++)
169 ok(fgetc(file
) == outbuffer
[i
], "fgetc returned wrong data for bufmode=%x\n", bufmodes
[bufmode
]);
171 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
172 ok(feof(file
), "feof did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
173 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
174 ok(feof(file
), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
175 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
176 c
= outbuffer
[sizeof(outbuffer
) - 1];
177 ok(ungetc(c
, file
) == c
, "ungetc did not return its input for bufmode=%x\n", bufmodes
[bufmode
]);
178 ok(!feof(file
), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
179 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
180 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
181 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes
[bufmode
]);
182 ok(!feof(file
), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes
[bufmode
]);
183 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
184 ok(feof(file
), "feof after getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
187 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
188 ok(pos
== 0, "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos
), bufmodes
[bufmode
]);
189 pos
= sizeof (outbuffer
);
190 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
191 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
192 ok(pos
== sizeof (outbuffer
), "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos
), bufmodes
[bufmode
]);
196 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
197 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
198 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) !=0,"fgetws failed unexpected\n");
199 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) ==0,"fgetws didn't signal EOF\n");
200 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
202 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
203 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
204 ok(fgetws(wbuffer
,sizeof(outbuffer
)/sizeof(outbuffer
[0]),file
) !=0,"fgets failed unexpected\n");
205 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
208 file
= fopen("fdopen.tst", "rb");
209 ok( file
!= NULL
, "fopen failed\n");
210 /* sizeof(buffer) > content of file */
211 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
212 /* feof should be set now */
213 ok(feof(file
), "feof after fread failed\n");
216 unlink ("fdopen.tst");
219 #define IOMODE (ao?"ascii mode":"binary mode")
220 static void test_readmode( BOOL ascii_mode
)
222 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";
223 static const char padbuffer
[] = "ghjghjghjghj";
224 static const char nlbuffer
[] = "\r\n";
225 static char buffer
[8192];
234 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
235 /* an internal buffer of BUFSIZ is maintained, so make a file big
236 * enough to test operations that cross the buffer boundary
238 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
240 write (fd
, padbuffer
, strlen(padbuffer
));
241 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
243 write (fd
, &padbuffer
[i
], 1);
244 write (fd
, nlbuffer
, strlen(nlbuffer
));
245 write (fd
, outbuffer
, sizeof (outbuffer
));
249 /* Open file in ascii mode */
250 fd
= open ("fdopen.tst", O_RDONLY
);
251 file
= fdopen (fd
, "r");
252 ao
= -1; /* on offset to account for carriage returns */
255 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
256 file
= fdopen (fd
, "rb");
260 /* first is a test of fgets, ftell, fseek */
261 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
262 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
265 ok(l
== pl
,"padding line ftell got %d should be %d in %s\n", l
, pl
, IOMODE
);
266 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
267 lstrlenA(buffer
), pl
+ao
, IOMODE
);
268 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
269 if (outbuffer
[fp
] == '\n') break;
271 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
273 ok(l
== pl
+fp
,"line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
274 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
275 lstrlenA(buffer
), fp
+ao
, IOMODE
);
276 /* test a seek back across the buffer boundary */
278 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
280 ok(l
== pl
,"ftell after seek got %d should be %d in %s\n", l
, pl
, IOMODE
);
281 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
283 ok(l
== pl
+fp
,"second read of line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
284 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
285 lstrlenA(buffer
), fp
+ao
, IOMODE
);
286 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
289 ok(l
== pl
+fp
,"line 2 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
290 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
291 lstrlenA(buffer
), 2+ao
, IOMODE
);
293 /* test fread across buffer boundary */
295 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
296 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
298 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
299 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
301 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
);
303 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
307 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
309 if (ao
&& (*optr
== '\r'))
312 /* fread should return the requested number of bytes if available */
314 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
315 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
317 i
=fread(buffer
,1,j
,file
);
318 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
320 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
321 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
322 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
323 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
324 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
325 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
326 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
327 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
328 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
329 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
331 /* test some additional functions */
333 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
334 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
336 ip
= (const int *)outbuffer
;
337 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
338 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
339 if (outbuffer
[fp
] == '\n') break;
341 /* this will cause the next _getw to cross carriage return characters */
342 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
343 for (i
=0, j
=0; i
<6; i
++) {
344 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
345 buffer
[j
++] = outbuffer
[fp
-3+i
];
349 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
352 unlink ("fdopen.tst");
354 /* test INTERNAL_BUFSIZ read containing 0x1a character (^Z) */
355 fd
= open("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
356 ok(fd
!= -1, "open failed\n");
357 memset(buffer
, 'a', sizeof(buffer
));
359 ok(write(fd
, buffer
, sizeof(buffer
)) == sizeof(buffer
), "write failed\n");
360 ok(close(fd
) != -1, "close failed\n");
362 fd
= open("fdopen.tst", O_RDONLY
);
363 ok(fd
!= -1, "open failed\n");
364 file
= fdopen(fd
, ascii_mode
? "r" : "rb");
365 ok(file
!= NULL
, "fdopen failed\n");
367 memset(buffer
, 0, sizeof(buffer
));
368 i
= fread(buffer
, 4096, 1, file
);
369 ok(!i
, "fread succeeded\n");
370 ok(file
->_bufsiz
== 4096, "file->_bufsiz = %d\n", file
->_bufsiz
);
371 for(i
=0; i
<4096; i
++)
372 if(buffer
[i
] != (i
==1 ? 0x1a : 'a')) break;
373 ok(i
==4096, "buffer[%d] = %d\n", i
, buffer
[i
]);
376 unlink("fdopen.tst");
379 static void test_asciimode(void)
385 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
386 fp
= fopen("ascii.tst", "wb");
389 fp
= fopen("ascii.tst", "rt");
390 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets\n");
391 ok(0 == strcmp(buf
, "\r\n"), "CR CR LF not read as CR LF\n");
393 ok((fread(buf
, 1, sizeof(buf
), fp
) == 2) && (0 == strcmp(buf
, "\r\n")), "CR CR LF not read as CR LF\n");
397 /* Simple test of foo ^Z [more than one block] bar handling */
398 fp
= fopen("ascii.tst", "wb");
399 fputs("foo\032", fp
); /* foo, logical EOF, ... */
400 fseek(fp
, 65536L, SEEK_SET
); /* ... more than MSVCRT_BUFSIZ, ... */
401 fputs("bar", fp
); /* ... bar */
403 fp
= fopen("ascii.tst", "rt");
404 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets foo\n");
405 ok(0 == strcmp(buf
, "foo"), "foo ^Z not read as foo by fgets\n");
406 ok(fgets(buf
, sizeof(buf
), fp
) == NULL
, "fgets after logical EOF\n");
408 ok((fread(buf
, 1, sizeof(buf
), fp
) == 3) && (0 == strcmp(buf
, "foo")), "foo ^Z not read as foo by fread\n");
409 ok((fread(buf
, 1, sizeof(buf
), fp
) == 0), "fread after logical EOF\n");
412 /* Show ASCII mode handling*/
413 fp
= fopen("ascii.tst","wb");
414 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp
);
417 fp
= fopen("ascii.tst", "r");
419 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
421 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
422 fseek(fp
,0,SEEK_CUR
);
423 for(i
=1; i
<10; i
++) {
424 ok((j
= ftell(fp
)) == i
*3, "ftell fails in TEXT mode\n");
425 fseek(fp
,0,SEEK_CUR
);
426 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek failed in line %d\n", i
);
428 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
430 /* Show that fseek doesn't skip \\r !*/
433 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
434 fseek(fp
, 2 ,SEEK_CUR
);
435 for(i
=1; i
<10; i
++) {
436 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with pos Offset failed in line %d\n", i
);
437 fseek(fp
, 2 ,SEEK_CUR
);
439 fseek(fp
, 9*3 ,SEEK_SET
);
441 ok(c
== '9', "fgetc failed, expected '9', got '%c'\n", c
);
442 fseek(fp
, -4 ,SEEK_CUR
);
443 for(i
= 8; i
>=0; i
--) {
444 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with neg Offset failed in line %d\n", i
);
445 fseek(fp
, -4 ,SEEK_CUR
);
447 /* Show what happens if fseek positions filepointer on \\r */
449 fp
= fopen("ascii.tst", "r");
450 fseek(fp
, 3 ,SEEK_SET
);
451 ok((c
= fgetc(fp
)) == '1', "fgetc fails to read next char when positioned on \\r\n");
457 static void test_asciimode2(void)
459 /* Error sequence from one app was getchar followed by small fread
460 * with one \r removed had last byte of buffer filled with
461 * next byte of *unbuffered* data rather than next byte from buffer
462 * Test case is a short string of one byte followed by a newline
463 * followed by filler to fill out the sector, then a sector of
464 * some different byte.
470 static const char obuf
[] =
472 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
473 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
474 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
475 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
476 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
477 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
478 "000000000000000000\n"
479 "1111111111111111111";
481 fp
= fopen("ascii2.tst", "wt");
482 fwrite(obuf
, 1, sizeof(obuf
), fp
);
485 fp
= fopen("ascii2.tst", "rt");
486 ok(getc(fp
) == '0', "first char not 0\n");
487 memset(ibuf
, 0, sizeof(ibuf
));
488 i
= fread(ibuf
, 1, sizeof(ibuf
), fp
);
489 ok(i
== sizeof(ibuf
), "fread i %d != sizeof(ibuf)\n", i
);
490 ok(0 == strncmp(ibuf
, obuf
+1, sizeof(ibuf
)), "ibuf != obuf\n");
492 unlink("ascii2.tst");
495 static void test_filemodeT(void)
497 char DATA
[] = {26, 't', 'e', 's' ,'t'};
499 char temppath
[MAX_PATH
];
500 char tempfile
[MAX_PATH
];
504 WIN32_FIND_DATAA findData
;
507 GetTempPathA(MAX_PATH
, temppath
);
508 GetTempFileNameA(temppath
, "", 0, tempfile
);
510 f
= fopen(tempfile
, "w+bDT");
511 bytesWritten
= fwrite(DATA
, 1, sizeof(DATA
), f
);
513 bytesRead
= fread(DATA2
, 1, sizeof(DATA2
), f
);
516 ok (bytesRead
== bytesWritten
&& bytesRead
== sizeof(DATA
),
517 "fopen file mode 'T' wrongly interpreted as 't'\n" );
519 h
= FindFirstFileA(tempfile
, &findData
);
521 ok (h
== INVALID_HANDLE_VALUE
, "file wasn't deleted when closed.\n" );
523 if (h
!= INVALID_HANDLE_VALUE
) FindClose(h
);
526 static WCHAR
* AtoW( const char* p
)
529 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
530 buffer
= malloc( len
* sizeof(WCHAR
) );
531 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
535 /* Test reading in text mode when the 512'th character read is \r*/
536 static void test_readboundary(void)
539 char buf
[513], rbuf
[513];
541 for (i
= 0; i
< 511; i
++)
543 j
= (i
%('~' - ' ')+ ' ');
548 fp
= fopen("boundary.tst", "wt");
549 fwrite(buf
, 512,1,fp
);
551 fp
= fopen("boundary.tst", "rt");
554 fseek(fp
,0 , SEEK_CUR
);
559 unlink("boundary.tst");
561 ok(strcmp(buf
, rbuf
) == 0,"CRLF on buffer boundary failure\n");
564 static void test_fgetc( void )
570 tempf
=_tempnam(".","wne");
571 tempfh
= fopen(tempf
,"w+");
576 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
578 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
580 tempfh
= fopen(tempf
,"wt");
583 tempfh
= fopen(tempf
,"wt");
584 setbuf(tempfh
, NULL
);
586 ok(ret
== -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
592 static void test_fputc( void )
598 tempf
=_tempnam(".","wne");
599 tempfh
= fopen(tempf
,"wb");
600 ret
= fputc(0,tempfh
);
601 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
602 ret
= fputc(0xff,tempfh
);
603 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
604 ret
= fputc(0xffffffff,tempfh
);
605 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
608 tempfh
= fopen(tempf
,"rb");
609 ret
= fputc(0,tempfh
);
610 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
617 static void test_flsbuf( void )
624 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
626 tempf
=_tempnam(".","wne");
627 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
629 tempfh
= fopen(tempf
,"wb");
630 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
631 ret
= _flsbuf(0,tempfh
);
632 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
633 bufmodes
[bufmode
], 0, ret
);
634 ret
= _flsbuf(0xff,tempfh
);
635 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
636 bufmodes
[bufmode
], 0xff, ret
);
637 ret
= _flsbuf(0xffffffff,tempfh
);
638 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
639 bufmodes
[bufmode
], 0xff, ret
);
643 tempfh
->_base
[1] = 'a';
644 ret
= _flsbuf(0xab,tempfh
);
645 ok(ret
== 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
646 bufmodes
[bufmode
], ret
);
647 ok(tempfh
->_base
[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
654 tempfh
= fopen(tempf
,"rb");
655 ret
= _flsbuf(0,tempfh
);
656 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
659 /* See bug 17123, exposed by WinAVR's make */
660 tempfh
= fopen(tempf
,"w");
661 ok(tempfh
->_cnt
== 0, "_cnt on freshly opened file was %d\n", tempfh
->_cnt
);
662 setbuf(tempfh
, NULL
);
663 ok(tempfh
->_cnt
== 0, "_cnt on unbuffered file was %d\n", tempfh
->_cnt
);
664 ok(tempfh
->_bufsiz
== 2, "_bufsiz = %d\n", tempfh
->_bufsiz
);
665 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
667 ret
= _flsbuf('Q',tempfh
);
668 ok('Q' == ret
, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret
);
669 /* ... and reset it to zero */
670 ok(tempfh
->_cnt
== 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh
->_cnt
);
672 /* And just for grins, make sure the file is correct */
673 tempfh
= fopen(tempf
,"r");
675 ok(c
== 'Q', "first byte should be 'Q'\n");
677 ok(c
== EOF
, "there should only be one byte\n");
684 static void test_fflush( void )
686 static const char obuf
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
687 char buf1
[16], buf2
[24];
692 tempf
=_tempnam(".","wne");
694 /* Prepare the file. */
695 tempfh
= fopen(tempf
,"wb");
696 ok(tempfh
!= NULL
, "Can't open test file.\n");
697 fwrite(obuf
, 1, sizeof(obuf
), tempfh
);
700 /* Open the file for input. */
701 tempfh
= fopen(tempf
,"rb");
702 ok(tempfh
!= NULL
, "Can't open test file.\n");
703 fread(buf1
, 1, sizeof(buf1
), tempfh
);
705 /* Using fflush() on input stream is undefined in ANSI.
706 * But MSDN says that it clears input buffer. */
707 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
708 ret
= fflush(tempfh
);
709 ok(ret
== 0, "expected 0, got %d\n", ret
);
710 memset(buf2
, '?', sizeof(buf2
));
711 fread(buf2
, 1, sizeof(buf2
), tempfh
);
712 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) == 0, "Got unexpected data (%c)\n", buf2
[0]);
714 /* fflush(NULL) doesn't clear input buffer. */
715 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
717 ok(ret
== 0, "expected 0, got %d\n", ret
);
718 memset(buf2
, '?', sizeof(buf2
));
719 fread(buf2
, 1, sizeof(buf2
), tempfh
);
720 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) != 0, "Got unexpected data (%c)\n", buf2
[0]);
722 /* _flushall() clears input buffer. */
723 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
725 ok(ret
>= 0, "unexpected ret %d\n", ret
);
726 memset(buf2
, '?', sizeof(buf2
));
727 fread(buf2
, 1, sizeof(buf2
), tempfh
);
728 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) == 0, "Got unexpected data (%c)\n", buf2
[0]);
736 static void test_fgetwc( void )
742 static const char mytext
[]= "This is test_fgetwc\r\n";
743 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
744 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
745 BOOL diff_found
= FALSE
;
750 tempf
=_tempnam(".","wne");
751 tempfh
= fopen(tempf
,"wb");
753 /* pad to almost the length of the internal buffer */
754 for (i
=0; i
<BUFSIZ
-4; i
++)
760 fputs(mytext
,tempfh
);
762 /* in text mode, getws/c expects multibyte characters */
763 /*currently Wine only supports plain ascii, and that is all that is tested here */
764 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
765 fgetws(wtextW
,LLEN
,tempfh
);
767 ok(l
==BUFSIZ
-2, "ftell expected %d got %d\n", BUFSIZ
-2, l
);
768 fgetws(wtextW
,LLEN
,tempfh
);
770 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %d\n", BUFSIZ
-2+lstrlenA(mytext
), l
);
771 mytextW
= AtoW (mytext
);
774 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
776 diff_found
|= (*aptr
!= *wptr
);
778 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
779 ok(*wptr
== '\n', "Carriage return was not skipped\n");
783 tempfh
= fopen(tempf
,"wb");
785 /* pad to almost the length of the internal buffer. Use an odd number of bytes
786 to test that we can read wchars that are split across the internal buffer
788 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
794 fputws(wtextW
,tempfh
);
795 fputws(wtextW
,tempfh
);
797 /* in binary mode, getws/c expects wide characters */
798 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
799 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
800 fgetws(wtextW
,j
,tempfh
);
802 j
=(j
-1)*sizeof(WCHAR
);
803 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
805 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
808 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
809 fgetws(wtextW
,3,tempfh
);
810 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
811 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
814 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
815 for(i
=0; i
<strlen(mytext
); i
++)
817 /* the first time we get the string, it should be entirely within the local buffer */
818 fgetws(wtextW
,LLEN
,tempfh
);
820 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
821 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
825 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
827 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
828 diff_found
|= (*aptr
!= *wptr
);
830 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
831 ok(*wptr
== '\n', "Should get newline\n");
832 for(i
=0; i
<strlen(mytext
); i
++)
834 /* the second time we get the string, it should cross the local buffer boundary.
835 One of the wchars should be split across the boundary */
836 fgetws(wtextW
,LLEN
,tempfh
);
840 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
842 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
843 diff_found
|= (*aptr
!= *wptr
);
845 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
846 ok(*wptr
== '\n', "Should get newline\n");
854 static void test_fgetwc_locale(const char* text
, const char* locale
, int codepage
)
856 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
858 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
859 WCHAR wtextW
[BUFSIZ
];
863 if (!setlocale(LC_CTYPE
, locale
))
865 win_skip("%s locale not available\n", locale
);
869 GetTempPathA(MAX_PATH
, temppath
);
870 GetTempFileNameA(temppath
, "", 0, tempfile
);
872 tempfh
= fopen(tempfile
, "wb");
873 ok(tempfh
!= NULL
, "can't open tempfile\n");
874 fwrite(text
, 1, strlen(text
), tempfh
);
879 /* mbstowcs rejects invalid multibyte sequence,
880 so we use MultiByteToWideChar here. */
881 ret
= MultiByteToWideChar(codepage
, 0, text
, -1,
882 wtextW
, sizeof(wtextW
)/sizeof(wtextW
[0]));
883 ok(ret
> 0, "MultiByteToWideChar failed\n");
889 for (p
= text
; *p
!= '\0'; p
++)
890 wtextW
[ret
++] = (unsigned char)*p
;
894 tempfh
= fopen(tempfile
, "rt");
895 ok(tempfh
!= NULL
, "can't open tempfile\n");
897 for (i
= 0; i
< ret
-1; i
++)
900 ok(ch
== wtextW
[i
], "got %04hx, expected %04hx (cp%d[%d])\n", ch
, wtextW
[i
], codepage
, i
);
903 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
906 tempfh
= fopen(tempfile
, "wb");
907 ok(tempfh
!= NULL
, "can't open tempfile\n");
908 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
911 tempfh
= fopen(tempfile
, "rb");
912 ok(tempfh
!= NULL
, "can't open tempfile\n");
913 for (i
= 0; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
916 ok(ch
== wchar_text
[i
], "got %04hx, expected %04x (cp%d[%d])\n", ch
, wchar_text
[i
], codepage
, i
);
919 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
924 static void test_fgetwc_unicode(void)
926 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
928 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
929 char utf8_text
[BUFSIZ
];
933 GetTempPathA(MAX_PATH
, temppath
);
934 GetTempFileNameA(temppath
, "", 0, tempfile
);
938 win_skip("fopen_s not available\n");
942 tempfh
= fopen(tempfile
, "wb");
943 ok(tempfh
!= NULL
, "can't open tempfile\n");
944 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
947 tempfh
= fopen(tempfile
, "rt,ccs=unicode");
948 ok(tempfh
!= NULL
, "can't open tempfile\n");
949 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
952 ok(ch
== wchar_text
[i
],
953 "got %04hx, expected %04x (unicode[%d])\n", ch
, wchar_text
[i
], i
-1);
956 ok(ch
== WEOF
, "got %04hx, expected WEOF (unicode)\n", ch
);
959 tempfh
= fopen(tempfile
, "wb");
960 ok(tempfh
!= NULL
, "can't open tempfile\n");
961 ret
= WideCharToMultiByte(CP_UTF8
, 0, wchar_text
, sizeof(wchar_text
)/sizeof(wchar_text
[0]),
962 utf8_text
, sizeof(utf8_text
), NULL
, NULL
);
963 ok(ret
> 0, "utf-8 conversion failed\n");
964 fwrite(utf8_text
, sizeof(char), ret
, tempfh
);
967 tempfh
= fopen(tempfile
, "rt, ccs=UTF-8");
968 ok(tempfh
!= NULL
, "can't open tempfile\n");
969 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
972 ok(ch
== wchar_text
[i
],
973 "got %04hx, expected %04x (utf8[%d])\n", ch
, wchar_text
[i
], i
-1);
976 ok(ch
== WEOF
, "got %04hx, expected WEOF (utf8)\n", ch
);
981 static void test_fputwc(void)
983 char temppath
[MAX_PATH
];
984 char tempfile
[MAX_PATH
];
989 GetTempPathA(MAX_PATH
, temppath
);
990 GetTempFileNameA(temppath
, "", 0, tempfile
);
992 f
= fopen(tempfile
, "w");
993 ret
= fputwc('a', f
);
994 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
995 ret
= fputwc('\n', f
);
996 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
999 f
= fopen(tempfile
, "rb");
1000 ret
= fread(buf
, 1, sizeof(buf
), f
);
1001 ok(ret
== 3, "fread returned %d, expected 3\n", ret
);
1002 ok(!memcmp(buf
, "a\r\n", 3), "incorrect file data\n");
1006 f
= fopen(tempfile
, "w,ccs=unicode");
1007 ret
= fputwc('a', f
);
1008 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
1009 ret
= fputwc('\n', f
);
1010 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
1013 f
= fopen(tempfile
, "rb");
1014 ret
= fread(buf
, 1, sizeof(buf
), f
);
1015 ok(ret
== 8, "fread returned %d, expected 8\n", ret
);
1016 ok(!memcmp(buf
, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
1019 f
= fopen(tempfile
, "w,ccs=utf-8");
1020 ret
= fputwc('a', f
);
1021 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
1022 ret
= fputwc('\n', f
);
1023 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
1026 f
= fopen(tempfile
, "rb");
1027 ret
= fread(buf
, 1, sizeof(buf
), f
);
1028 ok(ret
== 6, "fread returned %d, expected 6\n", ret
);
1029 ok(!memcmp(buf
, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
1032 win_skip("fputwc tests on unicode files\n");
1038 static void test_ctrlz( void )
1042 static const char mytext
[]= "This is test_ctrlz";
1047 tempf
=_tempnam(".","wne");
1048 tempfh
= fopen(tempf
,"wb");
1049 fputs(mytext
,tempfh
);
1050 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
1059 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1060 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1063 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1064 j
+=4; /* ftell should indicate the true end of file */
1066 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1067 ok(feof(tempfh
), "did not get EOF\n");
1070 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
1071 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1073 j
=strlen(mytext
)+3; /* should get through newline */
1074 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1076 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1077 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1079 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
1080 ok(feof(tempfh
), "did not get EOF\n");
1086 static void test_file_put_get( void )
1090 static const char mytext
[]= "This is a test_file_put_get\n";
1091 static const char dostext
[]= "This is a test_file_put_get\r\n";
1093 WCHAR wtextW
[LLEN
+1];
1094 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
1095 BOOL diff_found
= FALSE
;
1098 tempf
=_tempnam(".","wne");
1099 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
1100 fputs(mytext
,tempfh
);
1102 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1103 fgets(btext
,LLEN
,tempfh
);
1104 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
1105 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
1107 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
1108 fputs(dostext
,tempfh
);
1110 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1111 fgets(btext
,LLEN
,tempfh
);
1112 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
1114 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1115 fgets(btext
,LLEN
,tempfh
);
1116 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
1119 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1120 fgetws(wtextW
,LLEN
,tempfh
);
1121 mytextW
= AtoW (mytext
);
1125 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
1127 diff_found
|= (*aptr
!= *wptr
);
1129 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
1136 static void test_file_write_read( void )
1140 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
1141 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
1145 tempf
=_tempnam(".","wne");
1146 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
1147 _S_IREAD
| _S_IWRITE
);
1149 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1150 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1151 "_write _O_BINARY bad return value\n");
1153 i
= lstrlenA(mytext
);
1154 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1155 ok(_read(tempfd
,btext
,i
) == i
,
1156 "_read _O_BINARY got bad length\n");
1157 ok( memcmp(dostext
,btext
,i
) == 0,
1158 "problems with _O_BINARY _write / _read\n");
1160 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1161 ok(_read(tempfd
,btext
,i
) == i
-1,
1162 "_read _O_TEXT got bad length\n");
1163 ok( memcmp(mytext
,btext
,i
-1) == 0,
1164 "problems with _O_BINARY _write / _O_TEXT _read\n");
1166 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
1167 _S_IREAD
| _S_IWRITE
);
1169 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
1170 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
1171 "_write _O_TEXT bad return value\n");
1173 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1174 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1175 "_read _O_BINARY got bad length\n");
1176 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1177 "problems with _O_TEXT _write / _O_BINARY _read\n");
1178 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1180 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1181 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1182 "_read _O_TEXT got bad length\n");
1183 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1184 "problems with _O_TEXT _write / _read\n");
1187 memset(btext
, 0, LLEN
);
1188 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
1189 ok(tell(tempfd
) == 0, "bad position %u expecting 0\n", tell(tempfd
));
1190 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
1191 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
1194 /* Test reading only \n or \r */
1195 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1196 _lseek(tempfd
, -1, FILE_END
);
1197 ret
= _read(tempfd
,btext
,LLEN
);
1198 ok(ret
== 1 && *btext
== '\n', "_read expected 1 got bad length: %d\n", ret
);
1199 _lseek(tempfd
, -2, FILE_END
);
1200 ret
= _read(tempfd
,btext
,LLEN
);
1201 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
1202 _lseek(tempfd
, -2, FILE_END
);
1203 ret
= _read(tempfd
,btext
,1);
1204 ok(ret
== 1 && *btext
== '\n', "_read returned %d, buf: %d\n", ret
, *btext
);
1205 ret
= read(tempfd
,btext
,1);
1206 ok(ret
== 0, "_read returned %d, expected 0\n", ret
);
1207 _lseek(tempfd
, -3, FILE_END
);
1208 ret
= _read(tempfd
,btext
,1);
1209 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1210 ok(tell(tempfd
) == 41, "bad position %u expecting 41\n", tell(tempfd
));
1211 _lseek(tempfd
, -3, FILE_END
);
1212 ret
= _read(tempfd
,btext
,2);
1213 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1214 ok(tell(tempfd
) == 42, "bad position %u expecting 42\n", tell(tempfd
));
1215 _lseek(tempfd
, -3, FILE_END
);
1216 ret
= _read(tempfd
,btext
,3);
1217 ok(ret
== 2 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1218 ok(tell(tempfd
) == 43, "bad position %u expecting 43\n", tell(tempfd
));
1221 ret
= unlink(tempf
);
1222 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1225 tempf
=_tempnam(".","wne");
1226 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
, _S_IWRITE
);
1228 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1229 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1230 "_write _O_BINARY bad return value\n");
1232 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1233 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1234 "_read _O_BINARY got bad length\n");
1235 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1236 "problems with _O_BINARY _write / _read\n");
1237 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1239 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1240 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1241 "_read _O_TEXT got bad length\n");
1242 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1243 "problems with _O_BINARY _write / _O_TEXT _read\n");
1246 /* test _read with single bytes. CR should be skipped and LF pulled in */
1247 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1248 for (i
=0; i
<strlen(mytext
); i
++) /* */
1250 _read(tempfd
,btext
, 1);
1251 ok(btext
[0] == mytext
[i
],"_read failed at pos %d 0x%02x vs 0x%02x\n", i
, btext
[0], mytext
[i
]);
1253 while (_read(tempfd
,btext
, 1));
1256 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1257 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1258 i
= _read(tempfd
,btext
, strlen(mytext
));
1259 ok(i
== strlen(mytext
)-1, "_read_i %d\n", i
);
1262 /* test read/write in unicode mode */
1265 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_WTEXT
, _S_IWRITE
);
1266 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1267 ret
= _write(tempfd
, "a", 1);
1268 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1269 ret
= _write(tempfd
, "a\x00\n\x00\xff\xff", 6);
1270 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1273 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1274 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1275 ret
= _read(tempfd
, btext
, sizeof(btext
));
1276 ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1277 ok(!memcmp(btext
, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1280 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1281 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1283 ret
= _read(tempfd
, btext
, 3);
1284 ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1285 ok(errno
== 22, "errno = %d\n", errno
);
1286 ret
= _read(tempfd
, btext
, sizeof(btext
));
1287 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1288 ok(!memcmp(btext
, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1291 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_U8TEXT
, _S_IWRITE
);
1292 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1294 ret
= _write(tempfd
, "a", 1);
1295 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1296 ok(errno
== 22, "errno = %d\n", errno
);
1297 ret
= _write(tempfd
, "a\x00\n\x00\x62\x00", 6);
1298 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1301 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1302 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1303 ret
= _read(tempfd
, btext
, sizeof(btext
));
1304 ok(ret
== 7, "_read returned %d, expected 7\n", ret
);
1305 ok(!memcmp(btext
, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1308 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1309 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1310 ret
= _read(tempfd
, btext
, sizeof(btext
));
1311 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1312 ok(!memcmp(btext
, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1314 /* when buffer is small read sometimes fails in native implementation */
1315 lseek(tempfd
, 3 /* skip bom */, SEEK_SET
);
1316 ret
= _read(tempfd
, btext
, 4);
1317 todo_wine
ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1319 lseek(tempfd
, 6, SEEK_SET
);
1320 ret
= _read(tempfd
, btext
, 2);
1321 ok(ret
== 2, "_read returned %d, expected 2\n", ret
);
1322 ok(!memcmp(btext
, "\x62\x00", 2), "btext is incorrect\n");
1325 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_BINARY
, _S_IWRITE
);
1326 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1327 ret
= _write(tempfd
, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1328 ok(ret
== 12, "_write returned %d, expected 9\n", ret
);
1331 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1332 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1333 ret
= _read(tempfd
, btext
, sizeof(btext
));
1334 ok(ret
== 12, "_read returned %d, expected 12\n", ret
);
1335 ok(!memcmp(btext
, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1337 /* test invalid utf8 sequence */
1338 lseek(tempfd
, 5, SEEK_SET
);
1339 ret
= _read(tempfd
, btext
, sizeof(btext
));
1340 todo_wine
ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1341 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1342 todo_wine
ok(!memcmp(btext
, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1343 ok(!memcmp(btext
+ret
-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1348 win_skip("unicode mode tests on file\n");
1351 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
1353 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
1354 ret
= unlink(tempf
);
1355 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1359 static void test_file_inherit_child(const char* fd_s
)
1361 int fd
= atoi(fd_s
);
1365 ret
=write(fd
, "Success", 8);
1366 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
1367 lseek(fd
, 0, SEEK_SET
);
1368 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
1369 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1372 static void test_file_inherit_child_no(const char* fd_s
)
1374 int fd
= atoi(fd_s
);
1377 ret
= write(fd
, "Success", 8);
1378 ok( ret
== -1 && errno
== EBADF
,
1379 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
1382 static void create_io_inherit_block( STARTUPINFOA
*startup
, unsigned int count
, const HANDLE
*handles
)
1384 static BYTE block
[1024];
1389 startup
->lpReserved2
= block
;
1390 startup
->cbReserved2
= sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE
)) * count
;
1391 wxflag_ptr
= block
+ sizeof(unsigned);
1392 handle_ptr
= (HANDLE
*)(wxflag_ptr
+ count
);
1394 *(unsigned*)block
= count
;
1395 for (i
= 0; i
< count
; i
++)
1397 wxflag_ptr
[i
] = 0x81;
1398 handle_ptr
[i
] = handles
[i
];
1402 static const char *read_file( HANDLE file
)
1404 static char buffer
[128];
1406 SetFilePointer( file
, 0, NULL
, FILE_BEGIN
);
1407 if (!ReadFile( file
, buffer
, sizeof(buffer
) - 1, &ret
, NULL
)) ret
= 0;
1412 static void test_stdout_handle( STARTUPINFOA
*startup
, char *cmdline
, HANDLE hstdout
, BOOL expect_stdout
,
1417 SECURITY_ATTRIBUTES sa
;
1418 PROCESS_INFORMATION proc
;
1420 /* make file handle inheritable */
1421 sa
.nLength
= sizeof(sa
);
1422 sa
.lpSecurityDescriptor
= NULL
;
1423 sa
.bInheritHandle
= TRUE
;
1425 hErrorFile
= CreateFileA( "fdopen.err", GENERIC_READ
|GENERIC_WRITE
,
1426 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1427 startup
->dwFlags
= STARTF_USESTDHANDLES
;
1428 startup
->hStdInput
= GetStdHandle( STD_INPUT_HANDLE
);
1429 startup
->hStdOutput
= hErrorFile
;
1430 startup
->hStdError
= GetStdHandle( STD_ERROR_HANDLE
);
1432 CreateProcessA( NULL
, cmdline
, NULL
, NULL
, TRUE
,
1433 CREATE_DEFAULT_ERROR_MODE
| NORMAL_PRIORITY_CLASS
, NULL
, NULL
, startup
, &proc
);
1434 winetest_wait_child_process( proc
.hProcess
);
1436 data
= read_file( hErrorFile
);
1438 ok( strcmp( data
, "Success" ), "%s: Error file shouldn't contain data\n", descr
);
1440 ok( !strcmp( data
, "Success" ), "%s: Wrong error data (%s)\n", descr
, data
);
1444 data
= read_file( hstdout
);
1446 ok( !strcmp( data
, "Success" ), "%s: Wrong stdout data (%s)\n", descr
, data
);
1448 ok( strcmp( data
, "Success" ), "%s: Stdout file shouldn't contain data\n", descr
);
1451 CloseHandle( hErrorFile
);
1452 DeleteFileA( "fdopen.err" );
1455 static void test_file_inherit( const char* selfname
)
1458 const char* arg_v
[5];
1460 char cmdline
[MAX_PATH
];
1461 STARTUPINFOA startup
;
1462 SECURITY_ATTRIBUTES sa
;
1465 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1466 ok(fd
!= -1, "Couldn't create test file\n");
1467 arg_v
[0] = get_base_name(selfname
);
1468 arg_v
[1] = "tests/file.c";
1469 arg_v
[2] = "inherit";
1470 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1472 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1473 ok(tell(fd
) == 8, "bad position %u expecting 8\n", tell(fd
));
1474 lseek(fd
, 0, SEEK_SET
);
1475 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1477 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1479 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
1480 ok(fd
!= -1, "Couldn't create test file\n");
1481 arg_v
[1] = "tests/file.c";
1482 arg_v
[2] = "inherit_no";
1483 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1485 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1486 ok(tell(fd
) == 0, "bad position %u expecting 0\n", tell(fd
));
1487 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
1489 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1491 /* make file handle inheritable */
1492 sa
.nLength
= sizeof(sa
);
1493 sa
.lpSecurityDescriptor
= NULL
;
1494 sa
.bInheritHandle
= TRUE
;
1495 sprintf(cmdline
, "%s file inherit 1", selfname
);
1497 /* init an empty Reserved2, which should not be recognized as inherit-block */
1498 ZeroMemory(&startup
, sizeof(startup
));
1499 startup
.cb
= sizeof(startup
);
1500 create_io_inherit_block( &startup
, 0, NULL
);
1501 test_stdout_handle( &startup
, cmdline
, 0, FALSE
, "empty block" );
1503 /* test with valid inheritblock */
1504 handles
[0] = GetStdHandle( STD_INPUT_HANDLE
);
1505 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1506 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1507 handles
[2] = GetStdHandle( STD_ERROR_HANDLE
);
1508 create_io_inherit_block( &startup
, 3, handles
);
1509 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "valid block" );
1510 CloseHandle( handles
[1] );
1511 DeleteFileA("fdopen.tst");
1513 /* test inherit block starting with unsigned zero */
1514 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1515 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1516 create_io_inherit_block( &startup
, 3, handles
);
1517 *(unsigned int *)startup
.lpReserved2
= 0;
1518 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "zero count block" );
1519 CloseHandle( handles
[1] );
1520 DeleteFileA("fdopen.tst");
1522 /* test inherit block with smaller size */
1523 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1524 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1525 create_io_inherit_block( &startup
, 3, handles
);
1526 startup
.cbReserved2
-= 3;
1527 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "small size block" );
1528 CloseHandle( handles
[1] );
1529 DeleteFileA("fdopen.tst");
1531 /* test inherit block with even smaller size */
1532 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1533 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1534 create_io_inherit_block( &startup
, 3, handles
);
1535 startup
.cbReserved2
= sizeof(unsigned int) + sizeof(HANDLE
) + sizeof(char);
1536 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "smaller size block" );
1537 CloseHandle( handles
[1] );
1538 DeleteFileA("fdopen.tst");
1540 /* test inherit block with larger size */
1541 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1542 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1543 create_io_inherit_block( &startup
, 3, handles
);
1544 startup
.cbReserved2
+= 7;
1545 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "large size block" );
1546 CloseHandle( handles
[1] );
1547 DeleteFileA("fdopen.tst");
1550 static void test_invalid_stdin_child( void )
1558 handle
= (HANDLE
)_get_osfhandle(STDIN_FILENO
);
1559 ok(handle
== (HANDLE
)-2, "handle = %p\n", handle
);
1560 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1562 info
= &__pioinfo
[STDIN_FILENO
/MSVCRT_FD_BLOCK_SIZE
][STDIN_FILENO
%MSVCRT_FD_BLOCK_SIZE
];
1563 ok(info
->handle
== (HANDLE
)-2, "info->handle = %p\n", info
->handle
);
1564 ok(info
->wxflag
== 0xc1, "info->wxflag = %x\n", info
->wxflag
);
1566 ok(stdin
->_file
== -2, "stdin->_file = %d\n", stdin
->_file
);
1569 ret
= fread(&c
, 1, 1, stdin
);
1570 ok(!ret
, "fread(stdin) returned %d\n", ret
);
1571 ok(errno
== EBADF
, "errno = %d\n", errno
);
1574 ret
= read(-2, &c
, 1);
1575 ok(ret
== -1, "read(-2) returned %d\n", ret
);
1576 ok(errno
== EBADF
, "errno = %d\n", errno
);
1579 ret
= read(STDIN_FILENO
, &c
, 1);
1580 ok(ret
== -1, "read(STDIN_FILENO) returned %d\n", ret
);
1581 ok(errno
== EBADF
, "errno = %d\n", errno
);
1584 ret
= _flsbuf('a', stdin
);
1585 ok(ret
== EOF
, "_flsbuf(stdin) returned %d\n", ret
);
1586 ok(errno
== EBADF
, "errno = %d\n", errno
);
1589 ret
= fwrite(&c
, 1, 1, stdin
);
1590 ok(!ret
, "fwrite(stdin) returned %d\n", ret
);
1591 ok(errno
== EBADF
, "errno = %d\n", errno
);
1594 ret
= write(-2, &c
, 1);
1595 ok(ret
== -1, "write(-2) returned %d\n", ret
);
1596 ok(errno
== EBADF
, "errno = %d\n", errno
);
1599 ret
= write(STDIN_FILENO
, &c
, 1);
1600 ok(ret
== -1, "write(STDIN_FILENO) returned %d\n", ret
);
1601 ok(errno
== EBADF
, "errno = %d\n", errno
);
1604 ret
= fclose(stdin
);
1605 ok(ret
== -1, "fclose(stdin) returned %d\n", ret
);
1606 ok(errno
== EBADF
, "errno = %d\n", errno
);
1610 ok(ret
== -1, "close(-2) returned %d\n", ret
);
1611 ok(errno
== EBADF
, "errno = %d\n", errno
);
1614 ret
= close(STDIN_FILENO
);
1615 ok(ret
==-1 || !ret
, "close(STDIN_FILENO) returned %d\n", ret
);
1616 ok((ret
==-1 && errno
==EBADF
) || (!ret
&& errno
==0xdeadbeef), "errno = %d\n", errno
);
1619 static void test_invalid_stdin( const char* selfname
)
1621 char cmdline
[MAX_PATH
];
1622 PROCESS_INFORMATION proc
;
1623 SECURITY_ATTRIBUTES sa
;
1624 STARTUPINFOA startup
;
1629 /* Behaviour of the dll has changed in newer version */
1630 win_skip("skipping invalid stdin tests\n");
1634 ret
= RegOpenCurrentUser(KEY_READ
, &key
);
1635 ok(!ret
, "RegOpenCurrentUser failed: %x\n", ret
);
1637 sa
.nLength
= sizeof(sa
);
1638 sa
.lpSecurityDescriptor
= NULL
;
1639 sa
.bInheritHandle
= TRUE
;
1641 memset(&startup
, 0, sizeof(startup
));
1642 startup
.cb
= sizeof(startup
);
1643 startup
.dwFlags
= STARTF_USESTDHANDLES
;
1644 startup
.hStdInput
= key
;
1645 startup
.hStdOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
1646 startup
.hStdError
= GetStdHandle(STD_ERROR_HANDLE
);
1648 sprintf(cmdline
, "%s file stdin", selfname
);
1649 CreateProcessA(NULL
, cmdline
, NULL
, NULL
, TRUE
,
1650 CREATE_DEFAULT_ERROR_MODE
|NORMAL_PRIORITY_CLASS
, NULL
, NULL
, &startup
, &proc
);
1651 winetest_wait_child_process(proc
.hProcess
);
1653 ret
= RegCloseKey(key
);
1654 ok(!ret
, "RegCloseKey failed: %x\n", ret
);
1657 static void test_tmpnam( void )
1659 char name
[MAX_PATH
] = "abc";
1663 ok(res
!= NULL
, "tmpnam returned NULL\n");
1664 ok(res
[0] == '\\', "first character is not a backslash\n");
1665 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1666 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
1669 ok(res
!= NULL
, "tmpnam returned NULL\n");
1670 ok(res
== name
, "supplied buffer was not used\n");
1671 ok(res
[0] == '\\', "first character is not a backslash\n");
1672 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1673 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
1676 static void test_chsize( void )
1679 LONG cur
, pos
, count
;
1680 char temptext
[] = "012345678";
1681 char *tempfile
= _tempnam( ".", "tst" );
1683 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
1685 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
1686 ok( fd
> 0, "Couldn't open test file\n" );
1688 count
= _write( fd
, temptext
, sizeof(temptext
) );
1689 ok( count
> 0, "Couldn't write to test file\n" );
1691 /* get current file pointer */
1692 cur
= _lseek( fd
, 0, SEEK_CUR
);
1694 /* make the file smaller */
1695 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
1697 pos
= _lseek( fd
, 0, SEEK_CUR
);
1698 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1699 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
1701 /* enlarge the file */
1702 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
1704 pos
= _lseek( fd
, 0, SEEK_CUR
);
1705 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1706 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
1709 _unlink( tempfile
);
1713 static void test_fopen_fclose_fcloseall( void )
1715 char fname1
[] = "empty1";
1716 char fname2
[] = "empty2";
1717 char fname3
[] = "empty3";
1718 FILE *stream1
, *stream2
, *stream3
, *stream4
;
1721 /* testing fopen() */
1722 stream1
= fopen(fname1
, "w+");
1723 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
1724 stream2
= fopen(fname2
, "w ");
1725 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
1727 stream3
= fopen(fname3
, "r");
1728 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
1729 stream3
= fopen(fname3
, "w+");
1730 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
1732 stream4
= fopen("", "w+");
1733 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1734 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
1736 stream4
= fopen(NULL
, "w+");
1737 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1738 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
1740 /* testing fclose() */
1741 ret
= fclose(stream2
);
1742 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
1743 ret
= fclose(stream3
);
1744 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
1746 ret
= fclose(stream2
);
1747 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
1748 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1749 ret
= fclose(stream3
);
1750 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
1751 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
1753 /* testing fcloseall() */
1754 numclosed
= _fcloseall();
1755 /* fname1 should be closed here */
1756 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
1757 numclosed
= _fcloseall();
1758 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
1760 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
1761 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
1762 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
1765 static void test_fopen_s( void )
1767 const char name
[] = "empty1";
1769 unsigned char *ubuff
= (unsigned char*)buff
;
1776 win_skip("Skipping fopen_s test\n");
1779 /* testing fopen_s */
1780 ret
= p_fopen_s(&file
, name
, "w");
1781 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1782 ok(file
!= 0, "fopen_s failed to return value\n");
1783 fwrite(name
, sizeof(name
), 1, file
);
1786 ok(ret
!= EOF
, "File failed to close\n");
1788 file
= fopen(name
, "r");
1789 ok(file
!= 0, "fopen failed\n");
1790 len
= fread(buff
, 1, sizeof(name
), file
);
1791 ok(len
== sizeof(name
), "File length is %d\n", len
);
1792 buff
[sizeof(name
)] = '\0';
1793 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1796 ok(ret
!= EOF
, "File failed to close\n");
1798 ret
= p_fopen_s(&file
, name
, "w, ccs=UNIcode");
1799 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1800 ret
= fwrite("a", 1, 2, file
);
1801 ok(ret
== 2, "fwrite returned %d\n", ret
);
1804 ret
= p_fopen_s(&file
, name
, "r");
1805 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1806 len
= fread(buff
, 1, 2, file
);
1807 ok(len
== 2, "len = %d\n", len
);
1808 ok(ubuff
[0]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1809 ubuff
[0], ubuff
[1]);
1812 ret
= p_fopen_s(&file
, name
, "r,ccs=unicode");
1813 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1814 len
= fread(buff
, 1, 2, file
);
1815 ok(len
== 2, "len = %d\n", len
);
1816 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1817 ubuff
[0], ubuff
[1]);
1820 ret
= p_fopen_s(&file
, name
, "r,ccs=utf-16le");
1821 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1822 len
= fread(buff
, 1, 2, file
);
1823 ok(len
== 2, "len = %d\n", len
);
1824 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1825 ubuff
[0], ubuff
[1]);
1828 ret
= p_fopen_s(&file
, name
, "r,ccs=utf-8");
1829 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1830 len
= fread(buff
, 1, 2, file
);
1831 ok(len
== 2, "len = %d\n", len
);
1832 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1833 ubuff
[0], ubuff
[1]);
1836 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-16le");
1837 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1840 ret
= p_fopen_s(&file
, name
, "r");
1841 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1842 len
= fread(buff
, 1, 3, file
);
1843 ok(len
== 2, "len = %d\n", len
);
1844 ok(ubuff
[0]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1845 ubuff
[0], ubuff
[1]);
1848 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-8");
1849 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1852 ret
= p_fopen_s(&file
, name
, "r");
1853 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1854 len
= fread(buff
, 1, 4, file
);
1855 ok(len
== 3, "len = %d\n", len
);
1856 ok(ubuff
[0]==0xef && ubuff
[1]==0xbb && ubuff
[2]==0xbf,
1857 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1858 ubuff
[0], ubuff
[1], ubuff
[2]);
1861 /* test initial FILE values */
1862 memset(file
, 0xfe, sizeof(*file
));
1864 ret
= p_fopen_s(&file2
, name
, "r");
1865 ok(!ret
, "fopen_s failed with %d\n", ret
);
1866 ok(file
== file2
, "file != file2 %p %p\n", file
, file2
);
1867 ok(!file
->_ptr
, "file->_ptr != NULL\n");
1868 ok(!file
->_cnt
, "file->_cnt != 0\n");
1869 ok(!file
->_base
, "file->_base != NULL\n");
1870 ok(file
->_flag
== 1, "file->_flag = %x\n", file
->_flag
);
1871 ok(file
->_file
, "file->_file == 0\n");
1872 ok(file
->_charbuf
== 0xfefefefe, "file->_charbuf = %x\n", file
->_charbuf
);
1873 ok(file
->_bufsiz
== 0xfefefefe, "file->_bufsiz = %x\n", file
->_bufsiz
);
1874 ok(!file
->_tmpfname
, "file->_tmpfname != NULL\n");
1877 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1880 static void test__wfopen_s( void )
1882 const char name
[] = "empty1";
1883 const WCHAR wname
[] = {
1884 'e','m','p','t','y','1',0
1886 const WCHAR wmode
[] = {
1896 win_skip("Skipping _wfopen_s test\n");
1899 /* testing _wfopen_s */
1900 ret
= p__wfopen_s(&file
, wname
, wmode
);
1901 ok(ret
== 0, "_wfopen_s failed with %d\n", ret
);
1902 ok(file
!= 0, "_wfopen_s failed to return value\n");
1903 fwrite(name
, sizeof(name
), 1, file
);
1906 ok(ret
!= EOF
, "File failed to close\n");
1908 file
= fopen(name
, "r");
1909 ok(file
!= 0, "fopen failed\n");
1910 len
= fread(buff
, 1, sizeof(name
), file
);
1911 ok(len
== sizeof(name
), "File length is %d\n", len
);
1912 buff
[sizeof(name
)] = '\0';
1913 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1916 ok(ret
!= EOF
, "File failed to close\n");
1918 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1921 static void test_setmode(void)
1923 const char name
[] = "empty1";
1927 win_skip("unicode file modes are not available, skipping setmode tests\n");
1932 ret
= _setmode(-2, 0);
1933 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1934 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1937 ret
= _setmode(-2, _O_TEXT
);
1938 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1939 ok(errno
== EBADF
, "errno = %d\n", errno
);
1941 fd
= _open(name
, _O_CREAT
|_O_WRONLY
, _S_IWRITE
);
1942 ok(fd
!= -1, "failed to open file\n");
1945 ret
= _setmode(fd
, 0xffffffff);
1946 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1947 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1950 ret
= _setmode(fd
, 0);
1951 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1952 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1955 ret
= _setmode(fd
, _O_BINARY
|_O_TEXT
);
1956 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1957 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1960 ret
= _setmode(fd
, _O_WTEXT
|_O_U16TEXT
);
1961 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1962 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1964 ret
= _setmode(fd
, _O_BINARY
);
1965 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1967 ret
= _setmode(fd
, _O_WTEXT
);
1968 ok(ret
== _O_BINARY
, "_setmode returned %x, expected _O_BINARY\n", ret
);
1970 ret
= _setmode(fd
, _O_TEXT
);
1971 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1973 ret
= _setmode(fd
, _O_U16TEXT
);
1974 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1976 ret
= _setmode(fd
, _O_U8TEXT
);
1977 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1979 ret
= _setmode(fd
, _O_TEXT
);
1980 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1986 static void test_get_osfhandle(void)
1989 char fname
[] = "t_get_osfhanle";
1990 DWORD bytes_written
;
1993 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
1994 handle
= (HANDLE
)_get_osfhandle(fd
);
1995 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
1997 fd
= _open(fname
, _O_RDONLY
, 0);
1998 ok(fd
!= -1, "Couldn't open '%s' after _get_osfhandle()\n", fname
);
2004 handle
= (HANDLE
)_get_osfhandle(fd
);
2005 ok(handle
== INVALID_HANDLE_VALUE
, "_get_osfhandle returned %p\n", handle
);
2006 ok(errno
== EBADF
, "errno = %d\n", errno
);
2009 static void test_setmaxstdio(void)
2011 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
2012 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
2015 static void test_stat(void)
2022 /* Tests for a file */
2023 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
2026 ret
= fstat(fd
, &buf
);
2027 ok(!ret
, "fstat failed: errno=%d\n", errno
);
2028 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
2029 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
2030 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
2031 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
2032 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
2033 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
2035 ret
= stat("stat.tst", &buf
);
2036 ok(!ret
, "stat failed: errno=%d\n", errno
);
2037 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
2038 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
2039 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
2040 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
2041 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
2044 ret
= stat("stat.tst\\", &buf
);
2045 ok(ret
== -1, "stat returned %d\n", ret
);
2046 ok(errno
== ENOENT
, "errno = %d\n", errno
);
2052 skip("open failed with errno %d\n", errno
);
2054 /* Tests for a char device */
2055 if (_dup2(0, 10) == 0)
2057 ret
= fstat(10, &buf
);
2058 ok(!ret
, "fstat(stdin) failed: errno=%d\n", errno
);
2059 if ((buf
.st_mode
& _S_IFMT
) == _S_IFCHR
)
2061 ok(buf
.st_mode
== _S_IFCHR
, "bad st_mode=%06o\n", buf
.st_mode
);
2062 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
2063 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
2064 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
2067 skip("stdin is not a char device? st_mode=%06o\n", buf
.st_mode
);
2071 skip("_dup2 failed with errno %d\n", errno
);
2073 /* Tests for pipes */
2074 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
2076 ret
= fstat(pipes
[0], &buf
);
2077 ok(!ret
, "fstat(pipe) failed: errno=%d\n", errno
);
2078 ok(buf
.st_mode
== _S_IFIFO
, "bad st_mode=%06o\n", buf
.st_mode
);
2079 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n", buf
.st_dev
, pipes
[0]);
2080 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n", buf
.st_rdev
, pipes
[0]);
2081 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
2086 skip("pipe failed with errno %d\n", errno
);
2088 /* Tests for directory */
2089 if(mkdir("stat.tst") == 0)
2091 ret
= stat("stat.tst ", &buf
);
2092 ok(!ret
, "stat(directory) failed: errno=%d\n", errno
);
2093 ok((buf
.st_mode
& _S_IFMT
) == _S_IFDIR
, "bad format = %06o\n", buf
.st_mode
);
2094 ok((buf
.st_mode
& 0777) == 0777, "bad st_mode = %06o\n", buf
.st_mode
);
2095 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
2096 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
2099 ret
= stat("stat.tst\\ ", &buf
);
2100 ok(ret
== -1, "stat returned %d\n", ret
);
2101 ok(errno
== ENOENT
, "errno = %d\n", errno
);
2102 rmdir( "stat.tst" );
2105 skip("mkdir failed with errno %d\n", errno
);
2108 ret
= stat("c:", &buf
);
2109 ok(ret
== -1, "stat returned %d\n", ret
);
2110 ok(errno
== ENOENT
, "errno = %d\n", errno
);
2112 ret
= stat("c:/", &buf
);
2113 ok(!ret
, "stat returned %d\n", ret
);
2114 ok(buf
.st_dev
== 2, "st_dev = %d\n", buf
.st_dev
);
2115 ok(buf
.st_rdev
== 2, "st_rdev = %d\n", buf
.st_rdev
);
2118 static const char* pipe_string
="Hello world";
2120 /* How many messages to transfer over the pipe */
2121 #define N_TEST_MESSAGES 3
2123 static void test_pipes_child(int argc
, char** args
)
2131 ok(0, "not enough parameters: %d\n", argc
);
2137 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
2141 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
2142 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
2143 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write '%s' wrote %d\n", i
, pipe_string
, nwritten
);
2144 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
2145 if (i
< N_TEST_MESSAGES
-1)
2150 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
2153 static void test_pipes(const char* selfname
)
2156 char str_fdr
[12], str_fdw
[12];
2158 const char* arg_v
[6];
2160 char expected
[4096];
2164 /* Test reading from a pipe with read() */
2165 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2167 ok(0, "pipe failed with errno %d\n", errno
);
2171 arg_v
[0] = get_base_name(selfname
);
2172 arg_v
[1] = "tests/file.c";
2174 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2175 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2177 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2179 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2181 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
2182 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2183 ok(r
== strlen(pipe_string
), "i %d, got %d\n", i
, r
);
2186 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
2189 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2190 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
2192 ok(!i
, "unable to close %d: %d\n", pipes
[0], errno
);
2194 /* Test reading from a pipe with fread() */
2195 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2197 ok(0, "pipe failed with errno %d\n", errno
);
2201 arg_v
[1] = "tests/file.c";
2203 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2204 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2206 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2208 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2209 file
=fdopen(pipes
[0], "r");
2211 /* In blocking mode, fread will keep calling read() until it gets
2212 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2213 * in cooked mode instead of a pipe, it would also stop on EOL.)
2216 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
2217 strcat(expected
, pipe_string
);
2218 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2219 ok(r
== strlen(expected
), "fread() returned %d: ferror=%d\n", r
, ferror(file
));
2222 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
2224 /* Let child close the file before we read, so we can sense EOF reliably */
2226 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2227 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
2228 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
2229 ok(feof(file
), "feof() is false!\n");
2232 ok(!i
, "unable to close the pipe: %d\n", errno
);
2234 /* test \r handling when it's the last character read */
2235 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2237 ok(0, "pipe failed with errno %d\n", errno
);
2240 r
= write(pipes
[1], "\r\n\rab\r\n", 7);
2241 ok(r
== 7, "write returned %d, errno = %d\n", r
, errno
);
2242 setmode(pipes
[0], O_TEXT
);
2243 r
= read(pipes
[0], buf
, 1);
2244 ok(r
== 1, "read returned %d, expected 1\n", r
);
2245 ok(buf
[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf
[0]);
2246 r
= read(pipes
[0], buf
, 1);
2247 ok(r
== 1, "read returned %d, expected 1\n", r
);
2248 ok(buf
[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf
[0]);
2249 r
= read(pipes
[0], buf
, 1);
2250 ok(r
== 1, "read returned %d, expected 1\n", r
);
2251 ok(buf
[0] == 'a', "buf[0] = %x, expected 'a'\n", buf
[0]);
2252 r
= read(pipes
[0], buf
, 2);
2253 ok(r
== 2, "read returned %d, expected 1\n", r
);
2254 ok(buf
[0] == 'b', "buf[0] = %x, expected 'b'\n", buf
[0]);
2255 ok(buf
[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf
[1]);
2259 /* test utf16 read with insufficient data */
2260 r
= write(pipes
[1], "a\0b", 3);
2261 ok(r
== 3, "write returned %d, errno = %d\n", r
, errno
);
2264 setmode(pipes
[0], _O_WTEXT
);
2265 r
= read(pipes
[0], buf
, 4);
2266 ok(r
== 2, "read returned %d, expected 2\n", r
);
2267 ok(!memcmp(buf
, "a\0bz", 4), "read returned incorrect data\n");
2268 r
= write(pipes
[1], "\0", 1);
2269 ok(r
== 1, "write returned %d, errno = %d\n", r
, errno
);
2272 r
= read(pipes
[0], buf
, 2);
2273 ok(r
== 0, "read returned %d, expected 0\n", r
);
2274 ok(!memcmp(buf
, "\0z", 2), "read returned incorrect data\n");
2278 win_skip("unicode mode tests on pipe\n");
2285 static void test_unlink(void)
2288 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2289 file
= fopen("test_unlink\\empty", "w");
2290 ok(file
!= NULL
, "unable to create test file\n");
2293 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2294 unlink("test_unlink\\empty");
2295 rmdir("test_unlink");
2298 static void test_dup2(void)
2300 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2303 static void test_stdin(void)
2305 HANDLE stdinh
= GetStdHandle(STD_INPUT_HANDLE
);
2310 stdin_dup
= _dup(STDIN_FILENO
);
2311 ok(stdin_dup
!= -1, "_dup(STDIN_FILENO) failed\n");
2313 ok(stdinh
== (HANDLE
)_get_osfhandle(STDIN_FILENO
),
2314 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2316 r
= SetStdHandle(STD_INPUT_HANDLE
, INVALID_HANDLE_VALUE
);
2317 ok(r
== TRUE
, "SetStdHandle returned %x, expected TRUE\n", r
);
2318 h
= GetStdHandle(STD_INPUT_HANDLE
);
2319 ok(h
== INVALID_HANDLE_VALUE
, "h = %p\n", h
);
2321 close(STDIN_FILENO
);
2322 h
= GetStdHandle(STD_INPUT_HANDLE
);
2323 ok(h
== NULL
, "h != NULL\n");
2325 fd
= open("stdin.tst", O_WRONLY
| O_CREAT
, _S_IREAD
|_S_IWRITE
);
2326 ok(fd
!= -1, "open failed\n");
2327 ok(fd
== STDIN_FILENO
, "fd = %d, expected STDIN_FILENO\n", fd
);
2328 h
= GetStdHandle(STD_INPUT_HANDLE
);
2329 ok(h
!= NULL
, "h == NULL\n");
2331 unlink("stdin.tst");
2333 r
= _dup2(stdin_dup
, STDIN_FILENO
);
2334 ok(r
!= -1, "_dup2 failed\n");
2335 h
= GetStdHandle(STD_INPUT_HANDLE
);
2336 ok(h
!= NULL
, "h == NULL\n");
2339 static void test_mktemp(void)
2344 ok(!_mktemp(buf
), "_mktemp(\"a\") != NULL\n");
2346 strcpy(buf
, "testXXXXX");
2347 ok(!_mktemp(buf
), "_mktemp(\"testXXXXX\") != NULL\n");
2349 strcpy(buf
, "testXXXXXX");
2350 ok(_mktemp(buf
) != NULL
, "_mktemp(\"testXXXXXX\") == NULL\n");
2352 strcpy(buf
, "testXXXXXXa");
2353 ok(!_mktemp(buf
), "_mktemp(\"testXXXXXXa\") != NULL\n");
2355 strcpy(buf
, "**XXXXXX");
2356 ok(_mktemp(buf
) != NULL
, "_mktemp(\"**XXXXXX\") == NULL\n");
2359 static void test__open_osfhandle(void)
2366 fd
= _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE
, 0);
2367 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2368 ok(errno
== EBADF
, "errno = %d\n", errno
);
2370 h
= CreateFileA("open_osfhandle.tst", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
2371 fd
= _open_osfhandle((intptr_t)h
, 0);
2372 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2373 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2374 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2375 ok(info
->wxflag
== 1, "info->wxflag = %x, expected 1\n", info
->wxflag
);
2377 ok(info
->handle
== INVALID_HANDLE_VALUE
, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info
->handle
);
2378 ok(info
->wxflag
== 0, "info->wxflag = %x, expected 0\n", info
->wxflag
);
2379 DeleteFileA("open_osfhandle.tst");
2382 fd
= _open_osfhandle((intptr_t)h
, 0);
2383 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2384 ok(errno
== EBADF
, "errno = %d\n", errno
);
2386 ok(CreatePipe(&h
, &tmp
, NULL
, 0), "CreatePipe failed\n");
2387 fd
= _open_osfhandle((intptr_t)h
, 0);
2388 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2389 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2390 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2391 ok(info
->wxflag
== 9, "info->wxflag = %x, expected 9\n", info
->wxflag
);
2396 static void test_write_flush_size(FILE *file
, int bufsize
)
2404 inbuffer
= calloc(1, bufsize
+ 1);
2405 outbuffer
= calloc(1, bufsize
+ 1);
2406 _snprintf(outbuffer
, bufsize
+ 1, "0,1,2,3,4,5,6,7,8,9");
2408 for (size
= bufsize
+ 1; size
>= bufsize
- 1; size
--) {
2410 ok(file
->_cnt
== 0, "_cnt should be 0 after rewind, but is %d\n", file
->_cnt
);
2411 fwrite(outbuffer
, 1, size
, file
);
2412 /* lseek() below intentionally redirects the write in fflush() to detect
2413 * if fwrite() has already flushed the whole buffer or not.
2415 lseek(fd
, 1, SEEK_SET
);
2417 ok(file
->_cnt
== 0, "_cnt should be 0 after fflush, but is %d\n", file
->_cnt
);
2418 fseek(file
, 0, SEEK_SET
);
2419 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2420 if (size
== bufsize
)
2421 ok(memcmp(outbuffer
, inbuffer
, bufsize
) == 0, "missing flush by %d byte write\n", size
);
2423 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d byte write\n", size
);
2426 fwrite(outbuffer
, 1, bufsize
/ 2, file
);
2427 fwrite(outbuffer
+ bufsize
/ 2, 1, bufsize
/ 2, file
);
2428 lseek(fd
, 1, SEEK_SET
);
2430 fseek(file
, 0, SEEK_SET
);
2431 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2432 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d/2 byte double write\n", bufsize
);
2434 ok(!fseek(file
, -1, SEEK_END
), "fseek failed\n");
2435 ok(!fgetpos(file
, &pos
), "fgetpos failed\n");
2436 ok(fread(inbuffer
, 1, 1, file
) == 1, "fread failed\n");
2437 ok(file
->_flag
& _IOREAD
, "file->_flag = %x\n", file
->_flag
);
2438 ok(!file
->_cnt
, "file->_cnt = %d\n", file
->_cnt
);
2439 ok(file
->_ptr
!= file
->_base
, "file->_ptr == file->_base\n");
2440 ok(fwrite(outbuffer
, 1, bufsize
, file
), "fwrite failed\n");
2441 ok(file
->_flag
& _IOREAD
, "file->_flag = %x\n", file
->_flag
);
2442 ok(!file
->_cnt
, "file->_cnt = %d\n", file
->_cnt
);
2443 ok(file
->_ptr
== file
->_base
, "file->_ptr == file->_base\n");
2444 ok(!fgetpos(file
, &pos2
), "fgetpos failed\n");
2445 ok(pos
+bufsize
+1 == pos2
, "pos = %d (%d)\n", (int)pos
, (int)pos2
);
2450 static void test_write_flush(void)
2456 tempf
= _tempnam(".","wne");
2457 file
= fopen(tempf
, "wb+");
2458 ok(file
!= NULL
, "unable to create test file\n");
2460 ok(file
->_bufsiz
== 4096, "incorrect default buffer size: %d\n", file
->_bufsiz
);
2461 test_write_flush_size(file
, file
->_bufsiz
);
2462 setvbuf(file
, iobuf
, _IOFBF
, sizeof(iobuf
));
2463 test_write_flush_size(file
, sizeof(iobuf
));
2469 static void test_close(void)
2471 ioinfo
*stdout_info
, stdout_copy
, *stderr_info
, stderr_copy
;
2472 int fd1
, fd2
, ret1
, ret2
, ret3
, ret4
;
2476 /* test close on fds that use the same handle */
2477 h
= CreateFileA("fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
2478 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2479 ok(h
!= INVALID_HANDLE_VALUE
, "error opening fdopen.tst file\n");
2481 fd1
= _open_osfhandle((intptr_t)h
, 0);
2482 ok(fd1
!= -1, "_open_osfhandle failed (%d)\n", errno
);
2483 fd2
= _open_osfhandle((intptr_t)h
, 0);
2484 ok(fd2
!= -1, "_open_osfhandle failed (%d)\n", errno
);
2485 ok(fd1
!= fd2
, "fd1 == fd2\n");
2487 ok((HANDLE
)_get_osfhandle(fd1
) == h
, "handles mismatch (%p != %p)\n",
2488 (HANDLE
)_get_osfhandle(fd1
), h
);
2489 ok((HANDLE
)_get_osfhandle(fd2
) == h
, "handles mismatch (%p != %p)\n",
2490 (HANDLE
)_get_osfhandle(fd2
), h
);
2492 ok(!ret1
, "close(fd1) failed (%d)\n", errno
);
2493 ok(!GetHandleInformation(h
, &flags
), "GetHandleInformation succeeded\n");
2494 ok(close(fd2
), "close(fd2) succeeded\n");
2496 /* test close on already closed fd */
2499 ok(ret1
== -1, "close(fd1) succeeded\n");
2500 ok(errno
== 9, "errno = %d\n", errno
);
2502 /* test close on stdout and stderr that use the same handle */
2503 h
= CreateFileA("fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
2504 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2505 ok(h
!= INVALID_HANDLE_VALUE
, "error opening fdopen.tst file\n");
2507 /* tests output will not be visible from now on */
2508 stdout_info
= &__pioinfo
[STDOUT_FILENO
/MSVCRT_FD_BLOCK_SIZE
][STDOUT_FILENO
%MSVCRT_FD_BLOCK_SIZE
];
2509 stderr_info
= &__pioinfo
[STDERR_FILENO
/MSVCRT_FD_BLOCK_SIZE
][STDERR_FILENO
%MSVCRT_FD_BLOCK_SIZE
];
2510 stdout_copy
= *stdout_info
;
2511 stderr_copy
= *stderr_info
;
2512 stdout_info
->handle
= h
;
2513 stderr_info
->handle
= h
;
2515 ret1
= close(STDOUT_FILENO
);
2516 ret2
= GetHandleInformation(h
, &flags
);
2517 ret3
= close(STDERR_FILENO
);
2518 ret4
= GetHandleInformation(h
, &flags
);
2520 *stdout_info
= stdout_copy
;
2521 *stderr_info
= stderr_copy
;
2522 SetStdHandle(STD_OUTPUT_HANDLE
, stdout_info
->handle
);
2523 SetStdHandle(STD_ERROR_HANDLE
, stderr_info
->handle
);
2524 /* stdout and stderr restored */
2526 ok(!ret1
, "close(STDOUT_FILENO) failed\n");
2527 ok(ret2
, "GetHandleInformation failed\n");
2528 ok(!ret3
, "close(STDERR_FILENO) failed\n");
2529 ok(!ret4
, "GetHandleInformation succeeded\n");
2531 DeleteFileA( "fdopen.tst" );
2534 static void test__creat(void)
2536 int fd
, pos
, count
, readonly
, old_fmode
= 0, have_fmode
;
2537 char buf
[6], testdata
[4] = {'a', '\n', 'b', '\n'};
2539 have_fmode
= p__get_fmode
&& p__set_fmode
&& !p__get_fmode(&old_fmode
);
2541 win_skip("_fmode can't be set, skipping mode tests\n");
2544 p__set_fmode(_O_TEXT
);
2545 fd
= _creat("_creat.tst", 0);
2546 ok(fd
> 0, "_creat failed\n");
2547 _write(fd
, testdata
, 4);
2550 ok(pos
== 6, "expected pos 6 (text mode), got %d\n", pos
);
2552 ok(_lseek(fd
, SEEK_SET
, 0) == 0, "_lseek failed\n");
2553 count
= _read(fd
, buf
, 6);
2554 ok(count
== 4, "_read returned %d, expected 4\n", count
);
2555 count
= count
> 0 ? count
> 4 ? 4 : count
: 0;
2556 ok(memcmp(buf
, testdata
, count
) == 0, "_read returned wrong contents\n");
2558 readonly
= GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY
;
2559 ok(readonly
, "expected read-only file\n");
2560 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL
);
2561 DeleteFileA("_creat.tst");
2564 p__set_fmode(_O_BINARY
);
2565 fd
= _creat("_creat.tst", _S_IREAD
| _S_IWRITE
);
2566 ok(fd
> 0, "_creat failed\n");
2567 _write(fd
, testdata
, 4);
2570 ok(pos
== 4, "expected pos 4 (binary mode), got %d\n", pos
);
2572 ok(_lseek(fd
, SEEK_SET
, 0) == 0, "_lseek failed\n");
2573 count
= _read(fd
, buf
, 6);
2574 ok(count
== 4, "_read returned %d, expected 4\n", count
);
2575 count
= count
> 0 ? count
> 4 ? 4 : count
: 0;
2576 ok(memcmp(buf
, testdata
, count
) == 0, "_read returned wrong contents\n");
2578 readonly
= GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY
;
2579 ok(!readonly
, "expected rw file\n");
2580 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL
);
2581 DeleteFileA("_creat.tst");
2584 p__set_fmode(old_fmode
);
2594 arg_c
= winetest_get_mainargs( &arg_v
);
2596 /* testing low-level I/O */
2599 if (strcmp(arg_v
[2], "inherit") == 0)
2600 test_file_inherit_child(arg_v
[3]);
2601 else if (strcmp(arg_v
[2], "inherit_no") == 0)
2602 test_file_inherit_child_no(arg_v
[3]);
2603 else if (strcmp(arg_v
[2], "pipes") == 0)
2604 test_pipes_child(arg_c
, arg_v
);
2605 else if (strcmp(arg_v
[2], "stdin") == 0)
2606 test_invalid_stdin_child();
2608 ok(0, "invalid argument '%s'\n", arg_v
[2]);
2612 test_file_inherit(arg_v
[0]);
2613 test_invalid_stdin(arg_v
[0]);
2614 test_file_write_read();
2619 /* testing stream I/O */
2622 test_fopen_fclose_fcloseall();
2630 test_readmode(FALSE
); /* binary mode */
2631 test_readmode(TRUE
); /* ascii mode */
2632 test_readboundary();
2638 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2639 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2640 /* \x83 is U+0192 */
2641 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2642 /* \x83 is U+0083 */
2643 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2644 test_fgetwc_unicode();
2647 test_file_put_get();
2649 test_get_osfhandle();
2651 test_pipes(arg_v
[0]);
2654 test__open_osfhandle();
2659 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2660 * file contains lines in the correct order
2662 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);