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"
38 #define MSVCRT_FD_BLOCK_SIZE 32
44 CRITICAL_SECTION crit
;
46 static ioinfo
**__pioinfo
;
48 static HANDLE proc_handles
[2];
50 static int (__cdecl
*p_fopen_s
)(FILE**, const char*, const char*);
51 static int (__cdecl
*p__wfopen_s
)(FILE**, const wchar_t*, const wchar_t*);
53 static const char* get_base_name(const char *path
)
55 const char *ret
= path
+strlen(path
)-1;
58 if(*ret
=='\\' || *ret
=='/')
65 static void init(void)
67 HMODULE hmod
= GetModuleHandleA("msvcrt.dll");
69 setlocale(LC_CTYPE
, "C");
71 p_fopen_s
= (void*)GetProcAddress(hmod
, "fopen_s");
72 p__wfopen_s
= (void*)GetProcAddress(hmod
, "_wfopen_s");
73 __pioinfo
= (void*)GetProcAddress(hmod
, "__pioinfo");
76 static void test_filbuf( void )
82 fp
= fopen("filbuf.tst", "wb");
83 fwrite("\n\n\n\n", 1, 4, fp
);
86 fp
= fopen("filbuf.tst", "rt");
88 ok(c
== '\n', "read wrong byte\n");
89 /* See bug 16970 for why we care about _filbuf.
90 * ftell returns screwy values on files with lots
91 * of bare LFs in ascii mode because it assumes
92 * that ascii files contain only CRLFs, removes
93 * the CR's early in _filbuf, and adjusts the return
94 * value of ftell to compensate.
95 * native _filbuf will read the whole file, then consume and return
96 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
97 * pointing to a buffer of three bare LFs, so
98 * ftell will return 4 - 3 - 3 = -2.
100 ok(ftell(fp
) == -2, "ascii crlf removal does not match native\n");
101 ok(fgetpos(fp
, &pos
) == 0, "fgetpos fail\n");
102 ok(pos
== -2, "ftell does not match fgetpos\n");
104 unlink("filbuf.tst");
107 static void test_fdopen( void )
109 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
114 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
115 write (fd
, buffer
, sizeof (buffer
));
118 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
119 lseek (fd
, 5, SEEK_SET
);
120 file
= fdopen (fd
, "rb");
121 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
122 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
124 unlink ("fdopen.tst");
127 static void test_fileops( void )
129 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
136 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
138 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
139 write (fd
, outbuffer
, sizeof (outbuffer
));
142 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
144 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
145 file
= fdopen (fd
, "rb");
146 setvbuf(file
,NULL
,bufmodes
[bufmode
],2048);
147 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes
[bufmode
]);
148 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
149 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
150 ok(feof(file
) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
152 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
153 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes
[bufmode
]);
154 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
155 ok(strlen(buffer
) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes
[bufmode
]);
156 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes
[bufmode
]);
159 for (i
= 0; i
< sizeof(outbuffer
); i
++)
161 ok(fgetc(file
) == outbuffer
[i
], "fgetc returned wrong data for bufmode=%x\n", bufmodes
[bufmode
]);
163 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
164 ok(feof(file
), "feof did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
165 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
166 ok(feof(file
), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
167 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
168 c
= outbuffer
[sizeof(outbuffer
) - 1];
169 ok(ungetc(c
, file
) == c
, "ungetc did not return its input for bufmode=%x\n", bufmodes
[bufmode
]);
170 ok(!feof(file
), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
171 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
172 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
173 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes
[bufmode
]);
174 ok(!feof(file
), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes
[bufmode
]);
175 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
176 ok(feof(file
), "feof after getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
179 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
180 ok(pos
== 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
, bufmodes
[bufmode
]);
181 pos
= sizeof (outbuffer
);
182 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
183 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
184 ok(pos
== sizeof (outbuffer
), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
, bufmodes
[bufmode
]);
188 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
189 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
190 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) !=0,"fgetws failed unexpected\n");
191 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) ==0,"fgetws didn't signal EOF\n");
192 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
194 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
195 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
196 ok(fgetws(wbuffer
,sizeof(outbuffer
)/sizeof(outbuffer
[0]),file
) !=0,"fgets failed unexpected\n");
197 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
200 file
= fopen("fdopen.tst", "rb");
201 ok( file
!= NULL
, "fopen failed\n");
202 /* sizeof(buffer) > content of file */
203 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
204 /* feof should be set now */
205 ok(feof(file
), "feof after fread failed\n");
208 unlink ("fdopen.tst");
211 #define IOMODE (ao?"ascii mode":"binary mode")
212 static void test_readmode( BOOL ascii_mode
)
214 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";
215 static const char padbuffer
[] = "ghjghjghjghj";
216 static const char nlbuffer
[] = "\r\n";
217 char buffer
[2*BUFSIZ
+256];
226 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
227 /* an internal buffer of BUFSIZ is maintained, so make a file big
228 * enough to test operations that cross the buffer boundary
230 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
232 write (fd
, padbuffer
, strlen(padbuffer
));
233 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
235 write (fd
, &padbuffer
[i
], 1);
236 write (fd
, nlbuffer
, strlen(nlbuffer
));
237 write (fd
, outbuffer
, sizeof (outbuffer
));
241 /* Open file in ascii mode */
242 fd
= open ("fdopen.tst", O_RDONLY
);
243 file
= fdopen (fd
, "r");
244 ao
= -1; /* on offset to account for carriage returns */
247 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
248 file
= fdopen (fd
, "rb");
252 /* first is a test of fgets, ftell, fseek */
253 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
254 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
257 ok(l
== pl
,"padding line ftell got %d should be %d in %s\n", l
, pl
, IOMODE
);
258 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
259 lstrlenA(buffer
), pl
+ao
, IOMODE
);
260 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
261 if (outbuffer
[fp
] == '\n') break;
263 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
265 ok(l
== pl
+fp
,"line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
266 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
267 lstrlenA(buffer
), fp
+ao
, IOMODE
);
268 /* test a seek back across the buffer boundary */
270 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
272 ok(l
== pl
,"ftell after seek got %d should be %d in %s\n", l
, pl
, IOMODE
);
273 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
275 ok(l
== pl
+fp
,"second read of line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
276 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
277 lstrlenA(buffer
), fp
+ao
, IOMODE
);
278 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
281 ok(l
== pl
+fp
,"line 2 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
282 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
283 lstrlenA(buffer
), 2+ao
, IOMODE
);
285 /* test fread across buffer boundary */
287 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
288 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
290 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
291 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
293 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
);
295 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
299 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
301 if (ao
&& (*optr
== '\r'))
304 /* fread should return the requested number of bytes if available */
306 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
307 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
309 i
=fread(buffer
,1,j
,file
);
310 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
312 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
313 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
314 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
315 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
316 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
317 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
318 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
319 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
320 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
321 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
323 /* test some additional functions */
325 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
326 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
328 ip
= (const int *)outbuffer
;
329 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
330 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
331 if (outbuffer
[fp
] == '\n') break;
333 /* this will cause the next _getw to cross carriage return characters */
334 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
335 for (i
=0, j
=0; i
<6; i
++) {
336 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
337 buffer
[j
++] = outbuffer
[fp
-3+i
];
341 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
344 unlink ("fdopen.tst");
347 static void test_asciimode(void)
353 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
354 fp
= fopen("ascii.tst", "wb");
357 fp
= fopen("ascii.tst", "rt");
358 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets\n");
359 ok(0 == strcmp(buf
, "\r\n"), "CR CR LF not read as CR LF\n");
361 ok((fread(buf
, 1, sizeof(buf
), fp
) == 2) && (0 == strcmp(buf
, "\r\n")), "CR CR LF not read as CR LF\n");
365 /* Simple test of foo ^Z [more than one block] bar handling */
366 fp
= fopen("ascii.tst", "wb");
367 fputs("foo\032", fp
); /* foo, logical EOF, ... */
368 fseek(fp
, 65536L, SEEK_SET
); /* ... more than MSVCRT_BUFSIZ, ... */
369 fputs("bar", fp
); /* ... bar */
371 fp
= fopen("ascii.tst", "rt");
372 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets foo\n");
373 ok(0 == strcmp(buf
, "foo"), "foo ^Z not read as foo by fgets\n");
374 ok(fgets(buf
, sizeof(buf
), fp
) == NULL
, "fgets after logical EOF\n");
376 ok((fread(buf
, 1, sizeof(buf
), fp
) == 3) && (0 == strcmp(buf
, "foo")), "foo ^Z not read as foo by fread\n");
377 ok((fread(buf
, 1, sizeof(buf
), fp
) == 0), "fread after logical EOF\n");
380 /* Show ASCII mode handling*/
381 fp
= fopen("ascii.tst","wb");
382 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp
);
385 fp
= fopen("ascii.tst", "r");
387 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
389 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
390 fseek(fp
,0,SEEK_CUR
);
391 for(i
=1; i
<10; i
++) {
392 ok((j
= ftell(fp
)) == i
*3, "ftell fails in TEXT mode\n");
393 fseek(fp
,0,SEEK_CUR
);
394 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek failed in line %d\n", i
);
396 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
398 /* Show that fseek doesn't skip \\r !*/
401 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
402 fseek(fp
, 2 ,SEEK_CUR
);
403 for(i
=1; i
<10; i
++) {
404 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with pos Offset failed in line %d\n", i
);
405 fseek(fp
, 2 ,SEEK_CUR
);
407 fseek(fp
, 9*3 ,SEEK_SET
);
409 ok(c
== '9', "fgetc failed, expected '9', got '%c'\n", c
);
410 fseek(fp
, -4 ,SEEK_CUR
);
411 for(i
= 8; i
>=0; i
--) {
412 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with neg Offset failed in line %d\n", i
);
413 fseek(fp
, -4 ,SEEK_CUR
);
415 /* Show what happens if fseek positions filepointer on \\r */
417 fp
= fopen("ascii.tst", "r");
418 fseek(fp
, 3 ,SEEK_SET
);
419 ok((c
= fgetc(fp
)) == '1', "fgetc fails to read next char when positioned on \\r\n");
425 static void test_asciimode2(void)
427 /* Error sequence from one app was getchar followed by small fread
428 * with one \r removed had last byte of buffer filled with
429 * next byte of *unbuffered* data rather than next byte from buffer
430 * Test case is a short string of one byte followed by a newline
431 * followed by filler to fill out the sector, then a sector of
432 * some different byte.
438 static const char obuf
[] =
440 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
441 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
442 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
443 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
444 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
445 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
446 "000000000000000000\n"
447 "1111111111111111111";
449 fp
= fopen("ascii2.tst", "wt");
450 fwrite(obuf
, 1, sizeof(obuf
), fp
);
453 fp
= fopen("ascii2.tst", "rt");
454 ok(getc(fp
) == '0', "first char not 0\n");
455 memset(ibuf
, 0, sizeof(ibuf
));
456 i
= fread(ibuf
, 1, sizeof(ibuf
), fp
);
457 ok(i
== sizeof(ibuf
), "fread i %d != sizeof(ibuf)\n", i
);
458 ok(0 == strncmp(ibuf
, obuf
+1, sizeof(ibuf
)), "ibuf != obuf\n");
460 unlink("ascii2.tst");
463 static void test_filemodeT(void)
465 char DATA
[] = {26, 't', 'e', 's' ,'t'};
467 char temppath
[MAX_PATH
];
468 char tempfile
[MAX_PATH
];
472 WIN32_FIND_DATAA findData
;
475 GetTempPathA(MAX_PATH
, temppath
);
476 GetTempFileNameA(temppath
, "", 0, tempfile
);
478 f
= fopen(tempfile
, "w+bDT");
479 bytesWritten
= fwrite(DATA
, 1, sizeof(DATA
), f
);
481 bytesRead
= fread(DATA2
, 1, sizeof(DATA2
), f
);
484 ok (bytesRead
== bytesWritten
&& bytesRead
== sizeof(DATA
),
485 "fopen file mode 'T' wrongly interpreted as 't'\n" );
487 h
= FindFirstFileA(tempfile
, &findData
);
489 ok (h
== INVALID_HANDLE_VALUE
, "file wasn't deleted when closed.\n" );
491 if (h
!= INVALID_HANDLE_VALUE
) FindClose(h
);
494 static WCHAR
* AtoW( const char* p
)
497 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
498 buffer
= malloc( len
* sizeof(WCHAR
) );
499 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
503 /* Test reading in text mode when the 512'th character read is \r*/
504 static void test_readboundary(void)
507 char buf
[513], rbuf
[513];
509 for (i
= 0; i
< 511; i
++)
511 j
= (i
%('~' - ' ')+ ' ');
516 fp
= fopen("boundary.tst", "wt");
517 fwrite(buf
, 512,1,fp
);
519 fp
= fopen("boundary.tst", "rt");
522 fseek(fp
,0 , SEEK_CUR
);
527 unlink("boundary.tst");
529 ok(strcmp(buf
, rbuf
) == 0,"CRLF on buffer boundary failure\n");
532 static void test_fgetc( void )
538 tempf
=_tempnam(".","wne");
539 tempfh
= fopen(tempf
,"w+");
544 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
546 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
548 tempfh
= fopen(tempf
,"wt");
551 tempfh
= fopen(tempf
,"wt");
552 setbuf(tempfh
, NULL
);
554 ok(ret
== -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
560 static void test_fputc( void )
566 tempf
=_tempnam(".","wne");
567 tempfh
= fopen(tempf
,"wb");
568 ret
= fputc(0,tempfh
);
569 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
570 ret
= fputc(0xff,tempfh
);
571 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
572 ret
= fputc(0xffffffff,tempfh
);
573 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
576 tempfh
= fopen(tempf
,"rb");
577 ret
= fputc(0,tempfh
);
578 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
585 static void test_flsbuf( void )
592 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
594 tempf
=_tempnam(".","wne");
595 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
597 tempfh
= fopen(tempf
,"wb");
598 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
599 ret
= _flsbuf(0,tempfh
);
600 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
601 bufmodes
[bufmode
], 0, ret
);
602 ret
= _flsbuf(0xff,tempfh
);
603 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
604 bufmodes
[bufmode
], 0xff, ret
);
605 ret
= _flsbuf(0xffffffff,tempfh
);
606 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
607 bufmodes
[bufmode
], 0xff, ret
);
611 tempfh
->_base
[1] = 'a';
612 ret
= _flsbuf(0xab,tempfh
);
613 ok(ret
== 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
614 bufmodes
[bufmode
], ret
);
615 ok(tempfh
->_base
[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
622 tempfh
= fopen(tempf
,"rb");
623 ret
= _flsbuf(0,tempfh
);
624 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
627 /* See bug 17123, exposed by WinAVR's make */
628 tempfh
= fopen(tempf
,"w");
629 ok(tempfh
->_cnt
== 0, "_cnt on freshly opened file was %d\n", tempfh
->_cnt
);
630 setbuf(tempfh
, NULL
);
631 ok(tempfh
->_cnt
== 0, "_cnt on unbuffered file was %d\n", tempfh
->_cnt
);
632 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
634 ret
= _flsbuf('Q',tempfh
);
635 ok('Q' == ret
, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret
);
636 /* ... and reset it to zero */
637 ok(tempfh
->_cnt
== 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh
->_cnt
);
639 /* And just for grins, make sure the file is correct */
640 tempfh
= fopen(tempf
,"r");
642 ok(c
== 'Q', "first byte should be 'Q'\n");
644 ok(c
== EOF
, "there should only be one byte\n");
651 static void test_fflush( void )
653 static const char obuf
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
654 char buf1
[16], buf2
[24];
659 tempf
=_tempnam(".","wne");
661 /* Prepare the file. */
662 tempfh
= fopen(tempf
,"wb");
663 ok(tempfh
!= NULL
, "Can't open test file.\n");
664 fwrite(obuf
, 1, sizeof(obuf
), tempfh
);
667 /* Open the file for input. */
668 tempfh
= fopen(tempf
,"rb");
669 ok(tempfh
!= NULL
, "Can't open test file.\n");
670 fread(buf1
, 1, sizeof(buf1
), tempfh
);
672 /* Using fflush() on input stream is undefined in ANSI.
673 * But MSDN says that it clears input buffer. */
674 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
675 ret
= fflush(tempfh
);
676 ok(ret
== 0, "expected 0, got %d\n", ret
);
677 memset(buf2
, '?', sizeof(buf2
));
678 fread(buf2
, 1, sizeof(buf2
), tempfh
);
679 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) == 0, "Got unexpected data (%c)\n", buf2
[0]);
681 /* fflush(NULL) doesn't clear input buffer. */
682 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
684 ok(ret
== 0, "expected 0, got %d\n", ret
);
685 memset(buf2
, '?', sizeof(buf2
));
686 fread(buf2
, 1, sizeof(buf2
), tempfh
);
687 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) != 0, "Got unexpected data (%c)\n", buf2
[0]);
689 /* _flushall() clears input buffer. */
690 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
692 ok(ret
>= 0, "unexpected ret %d\n", ret
);
693 memset(buf2
, '?', sizeof(buf2
));
694 fread(buf2
, 1, sizeof(buf2
), tempfh
);
695 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) == 0, "Got unexpected data (%c)\n", buf2
[0]);
703 static void test_fgetwc( void )
709 static const char mytext
[]= "This is test_fgetwc\r\n";
710 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
711 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
712 BOOL diff_found
= FALSE
;
717 tempf
=_tempnam(".","wne");
718 tempfh
= fopen(tempf
,"wb");
720 /* pad to almost the length of the internal buffer */
721 for (i
=0; i
<BUFSIZ
-4; i
++)
727 fputs(mytext
,tempfh
);
729 /* in text mode, getws/c expects multibyte characters */
730 /*currently Wine only supports plain ascii, and that is all that is tested here */
731 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
732 fgetws(wtextW
,LLEN
,tempfh
);
734 ok(l
==BUFSIZ
-2, "ftell expected %d got %d\n", BUFSIZ
-2, l
);
735 fgetws(wtextW
,LLEN
,tempfh
);
737 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %d\n", BUFSIZ
-2+lstrlenA(mytext
), l
);
738 mytextW
= AtoW (mytext
);
741 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
743 diff_found
|= (*aptr
!= *wptr
);
745 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
746 ok(*wptr
== '\n', "Carriage return was not skipped\n");
750 tempfh
= fopen(tempf
,"wb");
752 /* pad to almost the length of the internal buffer. Use an odd number of bytes
753 to test that we can read wchars that are split across the internal buffer
755 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
761 fputws(wtextW
,tempfh
);
762 fputws(wtextW
,tempfh
);
764 /* in binary mode, getws/c expects wide characters */
765 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
766 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
767 fgetws(wtextW
,j
,tempfh
);
769 j
=(j
-1)*sizeof(WCHAR
);
770 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
772 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
775 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
776 fgetws(wtextW
,3,tempfh
);
777 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
778 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
781 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
782 for(i
=0; i
<strlen(mytext
); i
++)
784 /* the first time we get the string, it should be entirely within the local buffer */
785 fgetws(wtextW
,LLEN
,tempfh
);
787 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
788 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
792 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
794 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
795 diff_found
|= (*aptr
!= *wptr
);
797 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
798 ok(*wptr
== '\n', "Should get newline\n");
799 for(i
=0; i
<strlen(mytext
); i
++)
801 /* the second time we get the string, it should cross the local buffer boundary.
802 One of the wchars should be split across the boundary */
803 fgetws(wtextW
,LLEN
,tempfh
);
807 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
809 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
810 diff_found
|= (*aptr
!= *wptr
);
812 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
813 ok(*wptr
== '\n', "Should get newline\n");
821 static void test_fgetwc_locale(const char* text
, const char* locale
, int codepage
)
823 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
825 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
826 WCHAR wtextW
[BUFSIZ
];
830 if (!setlocale(LC_CTYPE
, locale
))
832 win_skip("%s locale not available\n", locale
);
836 GetTempPathA(MAX_PATH
, temppath
);
837 GetTempFileNameA(temppath
, "", 0, tempfile
);
839 tempfh
= fopen(tempfile
, "wb");
840 ok(tempfh
!= NULL
, "can't open tempfile\n");
841 fwrite(text
, 1, strlen(text
), tempfh
);
846 /* mbstowcs rejects invalid multibyte sequence,
847 so we use MultiByteToWideChar here. */
848 ret
= MultiByteToWideChar(codepage
, 0, text
, -1,
849 wtextW
, sizeof(wtextW
)/sizeof(wtextW
[0]));
850 ok(ret
> 0, "MultiByteToWideChar failed\n");
856 for (p
= text
; *p
!= '\0'; p
++)
857 wtextW
[ret
++] = (unsigned char)*p
;
861 tempfh
= fopen(tempfile
, "rt");
862 ok(tempfh
!= NULL
, "can't open tempfile\n");
864 for (i
= 0; i
< ret
-1; i
++)
867 ok(ch
== wtextW
[i
], "got %04hx, expected %04hx (cp%d[%d])\n", ch
, wtextW
[i
], codepage
, i
);
870 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
873 tempfh
= fopen(tempfile
, "wb");
874 ok(tempfh
!= NULL
, "can't open tempfile\n");
875 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
878 tempfh
= fopen(tempfile
, "rb");
879 ok(tempfh
!= NULL
, "can't open tempfile\n");
880 for (i
= 0; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
883 ok(ch
== wchar_text
[i
], "got %04hx, expected %04x (cp%d[%d])\n", ch
, wchar_text
[i
], codepage
, i
);
886 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
891 static void test_fgetwc_unicode(void)
893 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
895 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
896 char utf8_text
[BUFSIZ
];
900 GetTempPathA(MAX_PATH
, temppath
);
901 GetTempFileNameA(temppath
, "", 0, tempfile
);
905 win_skip("fopen_s not available\n");
909 tempfh
= fopen(tempfile
, "wb");
910 ok(tempfh
!= NULL
, "can't open tempfile\n");
911 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
914 tempfh
= fopen(tempfile
, "rt,ccs=unicode");
915 ok(tempfh
!= NULL
, "can't open tempfile\n");
916 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
919 ok(ch
== wchar_text
[i
],
920 "got %04hx, expected %04x (unicode[%d])\n", ch
, wchar_text
[i
], i
-1);
923 ok(ch
== WEOF
, "got %04hx, expected WEOF (unicode)\n", ch
);
926 tempfh
= fopen(tempfile
, "wb");
927 ok(tempfh
!= NULL
, "can't open tempfile\n");
928 ret
= WideCharToMultiByte(CP_UTF8
, 0, wchar_text
, sizeof(wchar_text
)/sizeof(wchar_text
[0]),
929 utf8_text
, sizeof(utf8_text
), NULL
, NULL
);
930 ok(ret
> 0, "utf-8 conversion failed\n");
931 fwrite(utf8_text
, sizeof(char), ret
, tempfh
);
934 tempfh
= fopen(tempfile
, "rt, ccs=UTF-8");
935 ok(tempfh
!= NULL
, "can't open tempfile\n");
936 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
939 ok(ch
== wchar_text
[i
],
940 "got %04hx, expected %04x (utf8[%d])\n", ch
, wchar_text
[i
], i
-1);
943 ok(ch
== WEOF
, "got %04hx, expected WEOF (utf8)\n", ch
);
948 static void test_fputwc(void)
950 char temppath
[MAX_PATH
];
951 char tempfile
[MAX_PATH
];
956 GetTempPathA(MAX_PATH
, temppath
);
957 GetTempFileNameA(temppath
, "", 0, tempfile
);
959 f
= fopen(tempfile
, "w");
960 ret
= fputwc('a', f
);
961 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
962 ret
= fputwc('\n', f
);
963 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
966 f
= fopen(tempfile
, "rb");
967 ret
= fread(buf
, 1, sizeof(buf
), f
);
968 ok(ret
== 3, "fread returned %d, expected 3\n", ret
);
969 ok(!memcmp(buf
, "a\r\n", 3), "incorrect file data\n");
973 f
= fopen(tempfile
, "w,ccs=unicode");
974 ret
= fputwc('a', f
);
975 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
976 ret
= fputwc('\n', f
);
977 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
980 f
= fopen(tempfile
, "rb");
981 ret
= fread(buf
, 1, sizeof(buf
), f
);
982 ok(ret
== 8, "fread returned %d, expected 8\n", ret
);
983 ok(!memcmp(buf
, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
986 f
= fopen(tempfile
, "w,ccs=utf-8");
987 ret
= fputwc('a', f
);
988 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
989 ret
= fputwc('\n', f
);
990 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
993 f
= fopen(tempfile
, "rb");
994 ret
= fread(buf
, 1, sizeof(buf
), f
);
995 ok(ret
== 6, "fread returned %d, expected 6\n", ret
);
996 ok(!memcmp(buf
, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
999 win_skip("fputwc tests on unicode files\n");
1005 static void test_ctrlz( void )
1009 static const char mytext
[]= "This is test_ctrlz";
1014 tempf
=_tempnam(".","wne");
1015 tempfh
= fopen(tempf
,"wb");
1016 fputs(mytext
,tempfh
);
1017 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
1026 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1027 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1030 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1031 j
+=4; /* ftell should indicate the true end of file */
1033 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1034 ok(feof(tempfh
), "did not get EOF\n");
1037 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
1038 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1040 j
=strlen(mytext
)+3; /* should get through newline */
1041 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1043 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1044 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1046 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
1047 ok(feof(tempfh
), "did not get EOF\n");
1053 static void test_file_put_get( void )
1057 static const char mytext
[]= "This is a test_file_put_get\n";
1058 static const char dostext
[]= "This is a test_file_put_get\r\n";
1060 WCHAR wtextW
[LLEN
+1];
1061 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
1062 BOOL diff_found
= FALSE
;
1065 tempf
=_tempnam(".","wne");
1066 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
1067 fputs(mytext
,tempfh
);
1069 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1070 fgets(btext
,LLEN
,tempfh
);
1071 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
1072 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
1074 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
1075 fputs(dostext
,tempfh
);
1077 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1078 fgets(btext
,LLEN
,tempfh
);
1079 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
1081 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1082 fgets(btext
,LLEN
,tempfh
);
1083 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
1086 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1087 fgetws(wtextW
,LLEN
,tempfh
);
1088 mytextW
= AtoW (mytext
);
1092 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
1094 diff_found
|= (*aptr
!= *wptr
);
1096 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
1103 static void test_file_write_read( void )
1107 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
1108 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
1112 tempf
=_tempnam(".","wne");
1113 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
1114 _S_IREAD
| _S_IWRITE
);
1116 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1117 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1118 "_write _O_BINARY bad return value\n");
1120 i
= lstrlenA(mytext
);
1121 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1122 ok(_read(tempfd
,btext
,i
) == i
,
1123 "_read _O_BINARY got bad length\n");
1124 ok( memcmp(dostext
,btext
,i
) == 0,
1125 "problems with _O_BINARY _write / _read\n");
1127 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1128 ok(_read(tempfd
,btext
,i
) == i
-1,
1129 "_read _O_TEXT got bad length\n");
1130 ok( memcmp(mytext
,btext
,i
-1) == 0,
1131 "problems with _O_BINARY _write / _O_TEXT _read\n");
1133 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
1134 _S_IREAD
| _S_IWRITE
);
1136 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
1137 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
1138 "_write _O_TEXT bad return value\n");
1140 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1141 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1142 "_read _O_BINARY got bad length\n");
1143 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1144 "problems with _O_TEXT _write / _O_BINARY _read\n");
1145 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1147 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1148 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1149 "_read _O_TEXT got bad length\n");
1150 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1151 "problems with _O_TEXT _write / _read\n");
1154 memset(btext
, 0, LLEN
);
1155 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
1156 ok(tell(tempfd
) == 0, "bad position %u expecting 0\n", tell(tempfd
));
1157 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
1158 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
1161 /* Test reading only \n or \r */
1162 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1163 _lseek(tempfd
, -1, FILE_END
);
1164 ret
= _read(tempfd
,btext
,LLEN
);
1165 ok(ret
== 1 && *btext
== '\n', "_read expected 1 got bad length: %d\n", ret
);
1166 _lseek(tempfd
, -2, FILE_END
);
1167 ret
= _read(tempfd
,btext
,LLEN
);
1168 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
1169 _lseek(tempfd
, -2, FILE_END
);
1170 ret
= _read(tempfd
,btext
,1);
1171 ok(ret
== 1 && *btext
== '\n', "_read returned %d, buf: %d\n", ret
, *btext
);
1172 ret
= read(tempfd
,btext
,1);
1173 ok(ret
== 0, "_read returned %d, expected 0\n", ret
);
1174 _lseek(tempfd
, -3, FILE_END
);
1175 ret
= _read(tempfd
,btext
,1);
1176 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1177 ok(tell(tempfd
) == 41, "bad position %u expecting 41\n", tell(tempfd
));
1178 _lseek(tempfd
, -3, FILE_END
);
1179 ret
= _read(tempfd
,btext
,2);
1180 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1181 ok(tell(tempfd
) == 42, "bad position %u expecting 42\n", tell(tempfd
));
1182 _lseek(tempfd
, -3, FILE_END
);
1183 ret
= _read(tempfd
,btext
,3);
1184 ok(ret
== 2 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1185 ok(tell(tempfd
) == 43, "bad position %u expecting 43\n", tell(tempfd
));
1188 ret
= unlink(tempf
);
1189 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1192 tempf
=_tempnam(".","wne");
1193 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
, _S_IWRITE
);
1195 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1196 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1197 "_write _O_BINARY bad return value\n");
1199 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1200 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1201 "_read _O_BINARY got bad length\n");
1202 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1203 "problems with _O_BINARY _write / _read\n");
1204 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1206 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1207 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1208 "_read _O_TEXT got bad length\n");
1209 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1210 "problems with _O_BINARY _write / _O_TEXT _read\n");
1213 /* test _read with single bytes. CR should be skipped and LF pulled in */
1214 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1215 for (i
=0; i
<strlen(mytext
); i
++) /* */
1217 _read(tempfd
,btext
, 1);
1218 ok(btext
[0] == mytext
[i
],"_read failed at pos %d 0x%02x vs 0x%02x\n", i
, btext
[0], mytext
[i
]);
1220 while (_read(tempfd
,btext
, 1));
1223 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1224 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1225 i
= _read(tempfd
,btext
, strlen(mytext
));
1226 ok(i
== strlen(mytext
)-1, "_read_i %d\n", i
);
1229 /* test read/write in unicode mode */
1232 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_WTEXT
, _S_IWRITE
);
1233 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1234 ret
= _write(tempfd
, "a", 1);
1235 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1236 ret
= _write(tempfd
, "a\x00\n\x00\xff\xff", 6);
1237 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1240 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1241 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1242 ret
= _read(tempfd
, btext
, sizeof(btext
));
1243 ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1244 ok(!memcmp(btext
, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1247 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1248 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1250 ret
= _read(tempfd
, btext
, 3);
1251 ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1252 ok(errno
== 22, "errno = %d\n", errno
);
1253 ret
= _read(tempfd
, btext
, sizeof(btext
));
1254 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1255 ok(!memcmp(btext
, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1258 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_U8TEXT
, _S_IWRITE
);
1259 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1261 ret
= _write(tempfd
, "a", 1);
1262 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1263 ok(errno
== 22, "errno = %d\n", errno
);
1264 ret
= _write(tempfd
, "a\x00\n\x00\x62\x00", 6);
1265 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1268 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1269 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1270 ret
= _read(tempfd
, btext
, sizeof(btext
));
1271 ok(ret
== 7, "_read returned %d, expected 7\n", ret
);
1272 ok(!memcmp(btext
, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1275 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1276 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1277 ret
= _read(tempfd
, btext
, sizeof(btext
));
1278 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1279 ok(!memcmp(btext
, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1281 /* when buffer is small read sometimes fails in native implementation */
1282 lseek(tempfd
, 3 /* skip bom */, SEEK_SET
);
1283 ret
= _read(tempfd
, btext
, 4);
1284 todo_wine
ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1286 lseek(tempfd
, 6, SEEK_SET
);
1287 ret
= _read(tempfd
, btext
, 2);
1288 ok(ret
== 2, "_read returned %d, expected 2\n", ret
);
1289 ok(!memcmp(btext
, "\x62\x00", 2), "btext is incorrect\n");
1292 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_BINARY
, _S_IWRITE
);
1293 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1294 ret
= _write(tempfd
, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1295 ok(ret
== 12, "_write returned %d, expected 9\n", ret
);
1298 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1299 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1300 ret
= _read(tempfd
, btext
, sizeof(btext
));
1301 ok(ret
== 12, "_read returned %d, expected 12\n", ret
);
1302 ok(!memcmp(btext
, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1304 /* test invalid utf8 sequence */
1305 lseek(tempfd
, 5, SEEK_SET
);
1306 ret
= _read(tempfd
, btext
, sizeof(btext
));
1307 todo_wine
ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1308 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1309 todo_wine
ok(!memcmp(btext
, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1310 ok(!memcmp(btext
+ret
-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1315 win_skip("unicode mode tests on file\n");
1318 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
1320 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
1321 ret
= unlink(tempf
);
1322 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1326 static void test_file_inherit_child(const char* fd_s
)
1328 int fd
= atoi(fd_s
);
1332 ret
=write(fd
, "Success", 8);
1333 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
1334 lseek(fd
, 0, SEEK_SET
);
1335 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
1336 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1339 static void test_file_inherit_child_no(const char* fd_s
)
1341 int fd
= atoi(fd_s
);
1344 ret
= write(fd
, "Success", 8);
1345 ok( ret
== -1 && errno
== EBADF
,
1346 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
1349 static void create_io_inherit_block( STARTUPINFOA
*startup
, unsigned int count
, const HANDLE
*handles
)
1351 static BYTE block
[1024];
1356 startup
->lpReserved2
= block
;
1357 startup
->cbReserved2
= sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE
)) * count
;
1358 wxflag_ptr
= block
+ sizeof(unsigned);
1359 handle_ptr
= (HANDLE
*)(wxflag_ptr
+ count
);
1361 *(unsigned*)block
= count
;
1362 for (i
= 0; i
< count
; i
++)
1364 wxflag_ptr
[i
] = 0x81;
1365 handle_ptr
[i
] = handles
[i
];
1369 static const char *read_file( HANDLE file
)
1371 static char buffer
[128];
1373 SetFilePointer( file
, 0, NULL
, FILE_BEGIN
);
1374 if (!ReadFile( file
, buffer
, sizeof(buffer
) - 1, &ret
, NULL
)) ret
= 0;
1379 static void test_stdout_handle( STARTUPINFOA
*startup
, char *cmdline
, HANDLE hstdout
, BOOL expect_stdout
,
1384 SECURITY_ATTRIBUTES sa
;
1385 PROCESS_INFORMATION proc
;
1387 /* make file handle inheritable */
1388 sa
.nLength
= sizeof(sa
);
1389 sa
.lpSecurityDescriptor
= NULL
;
1390 sa
.bInheritHandle
= TRUE
;
1392 hErrorFile
= CreateFileA( "fdopen.err", GENERIC_READ
|GENERIC_WRITE
,
1393 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1394 startup
->dwFlags
= STARTF_USESTDHANDLES
;
1395 startup
->hStdInput
= GetStdHandle( STD_INPUT_HANDLE
);
1396 startup
->hStdOutput
= hErrorFile
;
1397 startup
->hStdError
= GetStdHandle( STD_ERROR_HANDLE
);
1399 CreateProcessA( NULL
, cmdline
, NULL
, NULL
, TRUE
,
1400 CREATE_DEFAULT_ERROR_MODE
| NORMAL_PRIORITY_CLASS
, NULL
, NULL
, startup
, &proc
);
1401 winetest_wait_child_process( proc
.hProcess
);
1403 data
= read_file( hErrorFile
);
1405 ok( strcmp( data
, "Success" ), "%s: Error file shouldn't contain data\n", descr
);
1407 ok( !strcmp( data
, "Success" ), "%s: Wrong error data (%s)\n", descr
, data
);
1411 data
= read_file( hstdout
);
1413 ok( !strcmp( data
, "Success" ), "%s: Wrong stdout data (%s)\n", descr
, data
);
1415 ok( strcmp( data
, "Success" ), "%s: Stdout file shouldn't contain data\n", descr
);
1418 CloseHandle( hErrorFile
);
1419 DeleteFileA( "fdopen.err" );
1422 static void test_file_inherit( const char* selfname
)
1425 const char* arg_v
[5];
1427 char cmdline
[MAX_PATH
];
1428 STARTUPINFOA startup
;
1429 SECURITY_ATTRIBUTES sa
;
1432 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1433 ok(fd
!= -1, "Couldn't create test file\n");
1434 arg_v
[0] = get_base_name(selfname
);
1435 arg_v
[1] = "tests/file.c";
1436 arg_v
[2] = "inherit";
1437 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1439 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1440 ok(tell(fd
) == 8, "bad position %u expecting 8\n", tell(fd
));
1441 lseek(fd
, 0, SEEK_SET
);
1442 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1444 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1446 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
1447 ok(fd
!= -1, "Couldn't create test file\n");
1448 arg_v
[1] = "tests/file.c";
1449 arg_v
[2] = "inherit_no";
1450 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1452 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1453 ok(tell(fd
) == 0, "bad position %u expecting 0\n", tell(fd
));
1454 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
1456 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1458 /* make file handle inheritable */
1459 sa
.nLength
= sizeof(sa
);
1460 sa
.lpSecurityDescriptor
= NULL
;
1461 sa
.bInheritHandle
= TRUE
;
1462 sprintf(cmdline
, "%s file inherit 1", selfname
);
1464 /* init an empty Reserved2, which should not be recognized as inherit-block */
1465 ZeroMemory(&startup
, sizeof(startup
));
1466 startup
.cb
= sizeof(startup
);
1467 create_io_inherit_block( &startup
, 0, NULL
);
1468 test_stdout_handle( &startup
, cmdline
, 0, FALSE
, "empty block" );
1470 /* test with valid inheritblock */
1471 handles
[0] = GetStdHandle( STD_INPUT_HANDLE
);
1472 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1473 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1474 handles
[2] = GetStdHandle( STD_ERROR_HANDLE
);
1475 create_io_inherit_block( &startup
, 3, handles
);
1476 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "valid block" );
1477 CloseHandle( handles
[1] );
1478 DeleteFileA("fdopen.tst");
1480 /* test inherit block starting with unsigned zero */
1481 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1482 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1483 create_io_inherit_block( &startup
, 3, handles
);
1484 *(unsigned int *)startup
.lpReserved2
= 0;
1485 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "zero count block" );
1486 CloseHandle( handles
[1] );
1487 DeleteFileA("fdopen.tst");
1489 /* test inherit block with smaller size */
1490 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1491 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1492 create_io_inherit_block( &startup
, 3, handles
);
1493 startup
.cbReserved2
-= 3;
1494 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "small size block" );
1495 CloseHandle( handles
[1] );
1496 DeleteFileA("fdopen.tst");
1498 /* test inherit block with even smaller size */
1499 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1500 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1501 create_io_inherit_block( &startup
, 3, handles
);
1502 startup
.cbReserved2
= sizeof(unsigned int) + sizeof(HANDLE
) + sizeof(char);
1503 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "smaller size block" );
1504 CloseHandle( handles
[1] );
1505 DeleteFileA("fdopen.tst");
1507 /* test inherit block with larger size */
1508 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1509 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1510 create_io_inherit_block( &startup
, 3, handles
);
1511 startup
.cbReserved2
+= 7;
1512 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "large size block" );
1513 CloseHandle( handles
[1] );
1514 DeleteFileA("fdopen.tst");
1517 static void test_tmpnam( void )
1519 char name
[MAX_PATH
] = "abc";
1523 ok(res
!= NULL
, "tmpnam returned NULL\n");
1524 ok(res
[0] == '\\', "first character is not a backslash\n");
1525 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1526 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
1529 ok(res
!= NULL
, "tmpnam returned NULL\n");
1530 ok(res
== name
, "supplied buffer was not used\n");
1531 ok(res
[0] == '\\', "first character is not a backslash\n");
1532 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1533 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
1536 static void test_chsize( void )
1539 LONG cur
, pos
, count
;
1540 char temptext
[] = "012345678";
1541 char *tempfile
= _tempnam( ".", "tst" );
1543 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
1545 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
1546 ok( fd
> 0, "Couldn't open test file\n" );
1548 count
= _write( fd
, temptext
, sizeof(temptext
) );
1549 ok( count
> 0, "Couldn't write to test file\n" );
1551 /* get current file pointer */
1552 cur
= _lseek( fd
, 0, SEEK_CUR
);
1554 /* make the file smaller */
1555 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
1557 pos
= _lseek( fd
, 0, SEEK_CUR
);
1558 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1559 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
1561 /* enlarge the file */
1562 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
1564 pos
= _lseek( fd
, 0, SEEK_CUR
);
1565 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1566 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
1569 _unlink( tempfile
);
1573 static void test_fopen_fclose_fcloseall( void )
1575 char fname1
[] = "empty1";
1576 char fname2
[] = "empty2";
1577 char fname3
[] = "empty3";
1578 FILE *stream1
, *stream2
, *stream3
, *stream4
;
1581 /* testing fopen() */
1582 stream1
= fopen(fname1
, "w+");
1583 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
1584 stream2
= fopen(fname2
, "w ");
1585 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
1587 stream3
= fopen(fname3
, "r");
1588 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
1589 stream3
= fopen(fname3
, "w+");
1590 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
1592 stream4
= fopen("", "w+");
1593 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1594 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
1596 stream4
= fopen(NULL
, "w+");
1597 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1598 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
1600 /* testing fclose() */
1601 ret
= fclose(stream2
);
1602 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
1603 ret
= fclose(stream3
);
1604 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
1605 ret
= fclose(stream2
);
1606 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
1607 ret
= fclose(stream3
);
1608 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
1610 /* testing fcloseall() */
1611 numclosed
= _fcloseall();
1612 /* fname1 should be closed here */
1613 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
1614 numclosed
= _fcloseall();
1615 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
1617 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
1618 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
1619 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
1622 static void test_fopen_s( void )
1624 const char name
[] = "empty1";
1626 unsigned char *ubuff
= (unsigned char*)buff
;
1633 win_skip("Skipping fopen_s test\n");
1636 /* testing fopen_s */
1637 ret
= p_fopen_s(&file
, name
, "w");
1638 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1639 ok(file
!= 0, "fopen_s failed to return value\n");
1640 fwrite(name
, sizeof(name
), 1, file
);
1643 ok(ret
!= EOF
, "File failed to close\n");
1645 file
= fopen(name
, "r");
1646 ok(file
!= 0, "fopen failed\n");
1647 len
= fread(buff
, 1, sizeof(name
), file
);
1648 ok(len
== sizeof(name
), "File length is %d\n", len
);
1649 buff
[sizeof(name
)] = '\0';
1650 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1653 ok(ret
!= EOF
, "File failed to close\n");
1655 ret
= p_fopen_s(&file
, name
, "w, ccs=UNIcode");
1656 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1657 ret
= fwrite("a", 1, 2, file
);
1658 ok(ret
== 2, "fwrite returned %d\n", ret
);
1661 ret
= p_fopen_s(&file
, name
, "r");
1662 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1663 len
= fread(buff
, 1, 2, file
);
1664 ok(len
== 2, "len = %d\n", len
);
1665 ok(ubuff
[0]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1666 ubuff
[0], ubuff
[1]);
1669 ret
= p_fopen_s(&file
, name
, "r,ccs=unicode");
1670 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1671 len
= fread(buff
, 1, 2, file
);
1672 ok(len
== 2, "len = %d\n", len
);
1673 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1674 ubuff
[0], ubuff
[1]);
1677 ret
= p_fopen_s(&file
, name
, "r,ccs=utf-16le");
1678 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1679 len
= fread(buff
, 1, 2, file
);
1680 ok(len
== 2, "len = %d\n", len
);
1681 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1682 ubuff
[0], ubuff
[1]);
1685 ret
= p_fopen_s(&file
, name
, "r,ccs=utf-8");
1686 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1687 len
= fread(buff
, 1, 2, file
);
1688 ok(len
== 2, "len = %d\n", len
);
1689 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1690 ubuff
[0], ubuff
[1]);
1693 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-16le");
1694 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1697 ret
= p_fopen_s(&file
, name
, "r");
1698 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1699 len
= fread(buff
, 1, 3, file
);
1700 ok(len
== 2, "len = %d\n", len
);
1701 ok(ubuff
[0]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1702 ubuff
[0], ubuff
[1]);
1705 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-8");
1706 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1709 ret
= p_fopen_s(&file
, name
, "r");
1710 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1711 len
= fread(buff
, 1, 4, file
);
1712 ok(len
== 3, "len = %d\n", len
);
1713 ok(ubuff
[0]==0xef && ubuff
[1]==0xbb && ubuff
[2]==0xbf,
1714 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1715 ubuff
[0], ubuff
[1], ubuff
[2]);
1718 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1721 static void test__wfopen_s( void )
1723 const char name
[] = "empty1";
1724 const WCHAR wname
[] = {
1725 'e','m','p','t','y','1',0
1727 const WCHAR wmode
[] = {
1737 win_skip("Skipping _wfopen_s test\n");
1740 /* testing _wfopen_s */
1741 ret
= p__wfopen_s(&file
, wname
, wmode
);
1742 ok(ret
== 0, "_wfopen_s failed with %d\n", ret
);
1743 ok(file
!= 0, "_wfopen_s failed to return value\n");
1744 fwrite(name
, sizeof(name
), 1, file
);
1747 ok(ret
!= EOF
, "File failed to close\n");
1749 file
= fopen(name
, "r");
1750 ok(file
!= 0, "fopen failed\n");
1751 len
= fread(buff
, 1, sizeof(name
), file
);
1752 ok(len
== sizeof(name
), "File length is %d\n", len
);
1753 buff
[sizeof(name
)] = '\0';
1754 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1757 ok(ret
!= EOF
, "File failed to close\n");
1759 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1762 static void test_setmode(void)
1764 const char name
[] = "empty1";
1768 win_skip("unicode file modes are not available, skipping setmode tests\n");
1772 fd
= _open(name
, _O_CREAT
|_O_WRONLY
, _S_IWRITE
);
1773 ok(fd
!= -1, "failed to open file\n");
1776 ret
= _setmode(fd
, 0xffffffff);
1777 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1778 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1781 ret
= _setmode(fd
, 0);
1782 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1783 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1786 ret
= _setmode(fd
, _O_BINARY
|_O_TEXT
);
1787 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1788 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1791 ret
= _setmode(fd
, _O_WTEXT
|_O_U16TEXT
);
1792 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1793 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1795 ret
= _setmode(fd
, _O_BINARY
);
1796 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1798 ret
= _setmode(fd
, _O_WTEXT
);
1799 ok(ret
== _O_BINARY
, "_setmode returned %x, expected _O_BINARY\n", ret
);
1801 ret
= _setmode(fd
, _O_TEXT
);
1802 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1804 ret
= _setmode(fd
, _O_U16TEXT
);
1805 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1807 ret
= _setmode(fd
, _O_U8TEXT
);
1808 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1810 ret
= _setmode(fd
, _O_TEXT
);
1811 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1817 static void test_get_osfhandle(void)
1820 char fname
[] = "t_get_osfhanle";
1821 DWORD bytes_written
;
1824 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
1825 handle
= (HANDLE
)_get_osfhandle(fd
);
1826 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
1828 fd
= _open(fname
, _O_RDONLY
, 0);
1829 ok(fd
!= -1, "Couldn't open '%s' after _get_osfhandle()\n", fname
);
1835 static void test_setmaxstdio(void)
1837 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1838 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1841 static void test_stat(void)
1848 /* Tests for a file */
1849 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1852 ret
= fstat(fd
, &buf
);
1853 ok(!ret
, "fstat failed: errno=%d\n", errno
);
1854 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1855 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1856 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
1857 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1858 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1859 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1861 ret
= stat("stat.tst", &buf
);
1862 ok(!ret
, "stat failed: errno=%d\n", errno
);
1863 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1864 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1865 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1866 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1867 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1870 ret
= stat("stat.tst\\", &buf
);
1871 ok(ret
== -1, "stat returned %d\n", ret
);
1872 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1878 skip("open failed with errno %d\n", errno
);
1880 /* Tests for a char device */
1881 if (_dup2(0, 10) == 0)
1883 ret
= fstat(10, &buf
);
1884 ok(!ret
, "fstat(stdin) failed: errno=%d\n", errno
);
1885 if ((buf
.st_mode
& _S_IFMT
) == _S_IFCHR
)
1887 ok(buf
.st_mode
== _S_IFCHR
, "bad st_mode=%06o\n", buf
.st_mode
);
1888 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
1889 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
1890 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1893 skip("stdin is not a char device? st_mode=%06o\n", buf
.st_mode
);
1897 skip("_dup2 failed with errno %d\n", errno
);
1899 /* Tests for pipes */
1900 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
1902 ret
= fstat(pipes
[0], &buf
);
1903 ok(!ret
, "fstat(pipe) failed: errno=%d\n", errno
);
1904 ok(buf
.st_mode
== _S_IFIFO
, "bad st_mode=%06o\n", buf
.st_mode
);
1905 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n", buf
.st_dev
, pipes
[0]);
1906 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n", buf
.st_rdev
, pipes
[0]);
1907 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1912 skip("pipe failed with errno %d\n", errno
);
1914 /* Tests for directory */
1915 if(mkdir("stat.tst") == 0)
1917 ret
= stat("stat.tst ", &buf
);
1918 ok(!ret
, "stat(directory) failed: errno=%d\n", errno
);
1919 ok((buf
.st_mode
& _S_IFMT
) == _S_IFDIR
, "bad format = %06o\n", buf
.st_mode
);
1920 ok((buf
.st_mode
& 0777) == 0777, "bad st_mode = %06o\n", buf
.st_mode
);
1921 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1922 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1925 ret
= stat("stat.tst\\ ", &buf
);
1926 ok(ret
== -1, "stat returned %d\n", ret
);
1927 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1928 rmdir( "stat.tst" );
1931 skip("mkdir failed with errno %d\n", errno
);
1934 ret
= stat("c:", &buf
);
1935 ok(ret
== -1, "stat returned %d\n", ret
);
1936 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1938 ret
= stat("c:/", &buf
);
1939 ok(!ret
, "stat returned %d\n", ret
);
1940 ok(buf
.st_dev
== 2, "st_dev = %d\n", buf
.st_dev
);
1941 ok(buf
.st_rdev
== 2, "st_rdev = %d\n", buf
.st_rdev
);
1944 static const char* pipe_string
="Hello world";
1946 /* How many messages to transfer over the pipe */
1947 #define N_TEST_MESSAGES 3
1949 static void test_pipes_child(int argc
, char** args
)
1957 ok(0, "not enough parameters: %d\n", argc
);
1963 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
1967 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
1968 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
1969 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write '%s' wrote %d\n", i
, pipe_string
, nwritten
);
1970 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
1971 if (i
< N_TEST_MESSAGES
-1)
1976 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
1979 static void test_pipes(const char* selfname
)
1982 char str_fdr
[12], str_fdw
[12];
1984 const char* arg_v
[6];
1986 char expected
[4096];
1990 /* Test reading from a pipe with read() */
1991 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
1993 ok(0, "pipe failed with errno %d\n", errno
);
1997 arg_v
[0] = get_base_name(selfname
);
1998 arg_v
[1] = "tests/file.c";
2000 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2001 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2003 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2005 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2007 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
2008 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2009 ok(r
== strlen(pipe_string
), "i %d, got %d\n", i
, r
);
2012 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
2015 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2016 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
2018 ok(!i
, "unable to close %d: %d\n", pipes
[0], errno
);
2020 /* Test reading from a pipe with fread() */
2021 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2023 ok(0, "pipe failed with errno %d\n", errno
);
2027 arg_v
[1] = "tests/file.c";
2029 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2030 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2032 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2034 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2035 file
=fdopen(pipes
[0], "r");
2037 /* In blocking mode, fread will keep calling read() until it gets
2038 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2039 * in cooked mode instead of a pipe, it would also stop on EOL.)
2042 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
2043 strcat(expected
, pipe_string
);
2044 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2045 ok(r
== strlen(expected
), "fread() returned %d: ferror=%d\n", r
, ferror(file
));
2048 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
2050 /* Let child close the file before we read, so we can sense EOF reliably */
2052 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2053 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
2054 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
2055 ok(feof(file
), "feof() is false!\n");
2058 ok(!i
, "unable to close the pipe: %d\n", errno
);
2060 /* test \r handling when it's the last character read */
2061 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2063 ok(0, "pipe failed with errno %d\n", errno
);
2066 r
= write(pipes
[1], "\r\n\rab\r\n", 7);
2067 ok(r
== 7, "write returned %d, errno = %d\n", r
, errno
);
2068 setmode(pipes
[0], O_TEXT
);
2069 r
= read(pipes
[0], buf
, 1);
2070 ok(r
== 1, "read returned %d, expected 1\n", r
);
2071 ok(buf
[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf
[0]);
2072 r
= read(pipes
[0], buf
, 1);
2073 ok(r
== 1, "read returned %d, expected 1\n", r
);
2074 ok(buf
[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf
[0]);
2075 r
= read(pipes
[0], buf
, 1);
2076 ok(r
== 1, "read returned %d, expected 1\n", r
);
2077 ok(buf
[0] == 'a', "buf[0] = %x, expected 'a'\n", buf
[0]);
2078 r
= read(pipes
[0], buf
, 2);
2079 ok(r
== 2, "read returned %d, expected 1\n", r
);
2080 ok(buf
[0] == 'b', "buf[0] = %x, expected 'b'\n", buf
[0]);
2081 ok(buf
[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf
[1]);
2085 /* test utf16 read with insufficient data */
2086 r
= write(pipes
[1], "a\0b", 3);
2087 ok(r
== 3, "write returned %d, errno = %d\n", r
, errno
);
2090 setmode(pipes
[0], _O_WTEXT
);
2091 r
= read(pipes
[0], buf
, 4);
2092 ok(r
== 2, "read returned %d, expected 2\n", r
);
2093 ok(!memcmp(buf
, "a\0bz", 4), "read returned incorrect data\n");
2094 r
= write(pipes
[1], "\0", 1);
2095 ok(r
== 1, "write returned %d, errno = %d\n", r
, errno
);
2098 r
= read(pipes
[0], buf
, 2);
2099 ok(r
== 0, "read returned %d, expected 0\n", r
);
2100 ok(!memcmp(buf
, "\0z", 2), "read returned incorrect data\n");
2104 win_skip("unicode mode tests on pipe\n");
2111 static void test_unlink(void)
2114 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2115 file
= fopen("test_unlink\\empty", "w");
2116 ok(file
!= NULL
, "unable to create test file\n");
2119 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2120 unlink("test_unlink\\empty");
2121 rmdir("test_unlink");
2124 static void test_dup2(void)
2126 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2129 static void test_stdin(void)
2131 HANDLE stdinh
= GetStdHandle(STD_INPUT_HANDLE
);
2136 stdin_dup
= _dup(STDIN_FILENO
);
2137 ok(stdin_dup
!= -1, "_dup(STDIN_FILENO) failed\n");
2139 ok(stdinh
== (HANDLE
)_get_osfhandle(STDIN_FILENO
),
2140 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2142 r
= SetStdHandle(STD_INPUT_HANDLE
, INVALID_HANDLE_VALUE
);
2143 ok(r
== TRUE
, "SetStdHandle returned %x, expected TRUE\n", r
);
2144 h
= GetStdHandle(STD_INPUT_HANDLE
);
2145 ok(h
== INVALID_HANDLE_VALUE
, "h = %p\n", h
);
2147 close(STDIN_FILENO
);
2148 h
= GetStdHandle(STD_INPUT_HANDLE
);
2149 ok(h
== NULL
, "h != NULL\n");
2151 fd
= open("stdin.tst", O_WRONLY
| O_CREAT
, _S_IREAD
|_S_IWRITE
);
2152 ok(fd
!= -1, "open failed\n");
2153 ok(fd
== STDIN_FILENO
, "fd = %d, expected STDIN_FILENO\n", fd
);
2154 h
= GetStdHandle(STD_INPUT_HANDLE
);
2155 ok(h
!= NULL
, "h == NULL\n");
2157 unlink("stdin.tst");
2159 r
= _dup2(stdin_dup
, STDIN_FILENO
);
2160 ok(r
!= -1, "_dup2 failed\n");
2161 h
= GetStdHandle(STD_INPUT_HANDLE
);
2162 ok(h
!= NULL
, "h == NULL\n");
2165 static void test_mktemp(void)
2170 ok(!_mktemp(buf
), "_mktemp(\"a\") != NULL\n");
2172 strcpy(buf
, "testXXXXX");
2173 ok(!_mktemp(buf
), "_mktemp(\"testXXXXX\") != NULL\n");
2175 strcpy(buf
, "testXXXXXX");
2176 ok(_mktemp(buf
) != NULL
, "_mktemp(\"testXXXXXX\") == NULL\n");
2178 strcpy(buf
, "testXXXXXXa");
2179 ok(!_mktemp(buf
), "_mktemp(\"testXXXXXXa\") != NULL\n");
2181 strcpy(buf
, "**XXXXXX");
2182 ok(_mktemp(buf
) != NULL
, "_mktemp(\"**XXXXXX\") == NULL\n");
2185 static void test__open_osfhandle(void)
2192 fd
= _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE
, 0);
2193 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2194 ok(errno
== EBADF
, "errno = %d\n", errno
);
2196 h
= CreateFileA("open_osfhandle.tst", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
2197 fd
= _open_osfhandle((intptr_t)h
, 0);
2198 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2199 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2200 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2201 ok(info
->wxflag
== 1, "info->wxflag = %x, expected 1\n", info
->wxflag
);
2203 ok(info
->handle
== INVALID_HANDLE_VALUE
, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info
->handle
);
2204 ok(info
->wxflag
== 0, "info->wxflag = %x, expected 0\n", info
->wxflag
);
2205 DeleteFileA("open_osfhandle.tst");
2208 fd
= _open_osfhandle((intptr_t)h
, 0);
2209 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2210 ok(errno
== EBADF
, "errno = %d\n", errno
);
2212 ok(CreatePipe(&h
, &tmp
, NULL
, 0), "CreatePipe failed\n");
2213 fd
= _open_osfhandle((intptr_t)h
, 0);
2214 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2215 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2216 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2217 ok(info
->wxflag
== 9, "info->wxflag = %x, expected 9\n", info
->wxflag
);
2222 static void test_write_flush_size(FILE *file
, int bufsize
)
2229 inbuffer
= calloc(bufsize
+ 1, 1);
2230 outbuffer
= calloc(bufsize
+ 1, 1);
2231 _snprintf(outbuffer
, bufsize
+ 1, "0,1,2,3,4,5,6,7,8,9");
2233 for (size
= bufsize
+ 1; size
>= bufsize
- 1; size
--) {
2235 fwrite(outbuffer
, 1, size
, file
);
2236 /* lseek() below intentionally redirects the write in fflush() to detect
2237 * if fwrite() has already flushed the whole buffer or not.
2239 lseek(fd
, 1, SEEK_SET
);
2241 fseek(file
, 0, SEEK_SET
);
2242 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2243 if (size
== bufsize
)
2244 todo_wine
ok(memcmp(outbuffer
, inbuffer
, bufsize
) == 0, "missing flush by %d byte write\n", size
);
2246 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d byte write\n", size
);
2249 fwrite(outbuffer
, 1, bufsize
/ 2, file
);
2250 fwrite(outbuffer
+ bufsize
/ 2, 1, bufsize
/ 2, file
);
2251 lseek(fd
, 1, SEEK_SET
);
2253 fseek(file
, 0, SEEK_SET
);
2254 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2255 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d/2 byte double write\n", bufsize
);
2260 static void test_write_flush(void)
2266 tempf
= _tempnam(".","wne");
2267 file
= fopen(tempf
, "wb+");
2268 ok(file
!= NULL
, "unable to create test file\n");
2270 fwrite(iobuf
, 1, 1, file
); /* needed for wine to init _bufsiz */
2271 ok(file
->_bufsiz
== 4096, "incorrect default buffer size: %d", file
->_bufsiz
);
2272 test_write_flush_size(file
, file
->_bufsiz
);
2273 setvbuf(file
, iobuf
, _IOFBF
, sizeof(iobuf
));
2274 test_write_flush_size(file
, sizeof(iobuf
));
2287 arg_c
= winetest_get_mainargs( &arg_v
);
2289 /* testing low-level I/O */
2292 if (strcmp(arg_v
[2], "inherit") == 0)
2293 test_file_inherit_child(arg_v
[3]);
2294 else if (strcmp(arg_v
[2], "inherit_no") == 0)
2295 test_file_inherit_child_no(arg_v
[3]);
2296 else if (strcmp(arg_v
[2], "pipes") == 0)
2297 test_pipes_child(arg_c
, arg_v
);
2299 ok(0, "invalid argument '%s'\n", arg_v
[2]);
2303 test_file_inherit(arg_v
[0]);
2304 test_file_write_read();
2309 /* testing stream I/O */
2312 test_fopen_fclose_fcloseall();
2320 test_readmode(FALSE
); /* binary mode */
2321 test_readmode(TRUE
); /* ascii mode */
2322 test_readboundary();
2328 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2329 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2330 /* \x83 is U+0192 */
2331 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2332 /* \x83 is U+0083 */
2333 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2334 test_fgetwc_unicode();
2337 test_file_put_get();
2339 test_get_osfhandle();
2341 test_pipes(arg_v
[0]);
2344 test__open_osfhandle();
2347 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2348 * file contains lines in the correct order
2350 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);