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*);
52 static errno_t (__cdecl
*p__get_fmode
)(int*);
53 static errno_t (__cdecl
*p__set_fmode
)(int);
55 static const char* get_base_name(const char *path
)
57 const char *ret
= path
+strlen(path
)-1;
60 if(*ret
=='\\' || *ret
=='/')
67 static void init(void)
69 HMODULE hmod
= GetModuleHandleA("msvcrt.dll");
71 setlocale(LC_CTYPE
, "C");
73 p_fopen_s
= (void*)GetProcAddress(hmod
, "fopen_s");
74 p__wfopen_s
= (void*)GetProcAddress(hmod
, "_wfopen_s");
75 __pioinfo
= (void*)GetProcAddress(hmod
, "__pioinfo");
76 p__get_fmode
= (void*)GetProcAddress(hmod
, "_get_fmode");
77 p__set_fmode
= (void*)GetProcAddress(hmod
, "_set_fmode");
80 static void test_filbuf( void )
86 fp
= fopen("filbuf.tst", "wb");
87 fwrite("\n\n\n\n", 1, 4, fp
);
90 fp
= fopen("filbuf.tst", "rt");
92 ok(c
== '\n', "read wrong byte\n");
93 /* See bug 16970 for why we care about _filbuf.
94 * ftell returns screwy values on files with lots
95 * of bare LFs in ascii mode because it assumes
96 * that ascii files contain only CRLFs, removes
97 * the CR's early in _filbuf, and adjusts the return
98 * value of ftell to compensate.
99 * native _filbuf will read the whole file, then consume and return
100 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr
101 * pointing to a buffer of three bare LFs, so
102 * ftell will return 4 - 3 - 3 = -2.
104 ok(ftell(fp
) == -2, "ascii crlf removal does not match native\n");
105 ok(fgetpos(fp
, &pos
) == 0, "fgetpos fail\n");
106 ok(pos
== -2, "ftell does not match fgetpos\n");
108 unlink("filbuf.tst");
111 static void test_fdopen( void )
113 static const char buffer
[] = {0,1,2,3,4,5,6,7,8,9};
118 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
119 write (fd
, buffer
, sizeof (buffer
));
122 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
123 lseek (fd
, 5, SEEK_SET
);
124 file
= fdopen (fd
, "rb");
125 ok (fread (ibuf
, 1, sizeof (buffer
), file
) == 5, "read wrong byte count\n");
126 ok (memcmp (ibuf
, buffer
+ 5, 5) == 0, "read wrong bytes\n");
128 unlink ("fdopen.tst");
131 static void test_fileops( void )
133 static const char outbuffer
[] = "0,1,2,3,4,5,6,7,8,9";
140 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
142 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
143 write (fd
, outbuffer
, sizeof (outbuffer
));
146 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
148 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
149 file
= fdopen (fd
, "rb");
150 setvbuf(file
,NULL
,bufmodes
[bufmode
],2048);
151 if(bufmodes
[bufmode
] == _IOFBF
)
152 ok(file
->_bufsiz
== 2048, "file->_bufsiz = %d\n", file
->_bufsiz
);
153 ok(file
->_base
!= NULL
, "file->_base = NULL\n");
154 ok(strlen(outbuffer
) == (sizeof(outbuffer
)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes
[bufmode
]);
155 ok(fgets(buffer
,sizeof(buffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
156 ok(fgets(buffer
,sizeof(buffer
),file
) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
157 ok(feof(file
) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes
[bufmode
]);
159 ok(fgets(buffer
,strlen(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
160 ok(lstrlenA(buffer
) == lstrlenA(outbuffer
) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes
[bufmode
]);
161 ok(fgets(buffer
,sizeof(outbuffer
),file
) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
162 ok(strlen(buffer
) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes
[bufmode
]);
163 ok(buffer
[0] == outbuffer
[strlen(outbuffer
)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes
[bufmode
]);
166 for (i
= 0; i
< sizeof(outbuffer
); i
++)
168 ok(fgetc(file
) == outbuffer
[i
], "fgetc returned wrong data for bufmode=%x\n", bufmodes
[bufmode
]);
170 ok((c
= fgetc(file
)) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
171 ok(feof(file
), "feof did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
172 ok(ungetc(c
, file
) == EOF
, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
173 ok(feof(file
), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
174 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
175 c
= outbuffer
[sizeof(outbuffer
) - 1];
176 ok(ungetc(c
, file
) == c
, "ungetc did not return its input for bufmode=%x\n", bufmodes
[bufmode
]);
177 ok(!feof(file
), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
178 ok((c
= fgetc(file
)) != EOF
, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes
[bufmode
]);
179 ok(c
== outbuffer
[sizeof(outbuffer
) - 1],
180 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes
[bufmode
]);
181 ok(!feof(file
), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes
[bufmode
]);
182 ok(fgetc(file
) == EOF
, "getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
183 ok(feof(file
), "feof after getc did not return EOF for bufmode=%x\n", bufmodes
[bufmode
]);
186 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
187 ok(pos
== 0, "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
, bufmodes
[bufmode
]);
188 pos
= sizeof (outbuffer
);
189 ok(fsetpos(file
, &pos
) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
190 ok(fgetpos(file
,&pos
) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes
[bufmode
]);
191 ok(pos
== sizeof (outbuffer
), "Unexpected result of fgetpos %x%08x for bufmode=%x\n", (DWORD
)(pos
>> 32), (DWORD
)pos
, bufmodes
[bufmode
]);
195 fd
= open ("fdopen.tst", O_RDONLY
| O_TEXT
);
196 file
= fdopen (fd
, "rt"); /* open in TEXT mode */
197 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) !=0,"fgetws failed unexpected\n");
198 ok(fgetws(wbuffer
,sizeof(wbuffer
)/sizeof(wbuffer
[0]),file
) ==0,"fgetws didn't signal EOF\n");
199 ok(feof(file
) !=0,"feof doesn't signal EOF\n");
201 ok(fgetws(wbuffer
,strlen(outbuffer
),file
) !=0,"fgetws failed unexpected\n");
202 ok(lstrlenW(wbuffer
) == (lstrlenA(outbuffer
) -1),"fgetws didn't read right size\n");
203 ok(fgetws(wbuffer
,sizeof(outbuffer
)/sizeof(outbuffer
[0]),file
) !=0,"fgets failed unexpected\n");
204 ok(lstrlenW(wbuffer
) == 1,"fgets dropped chars\n");
207 file
= fopen("fdopen.tst", "rb");
208 ok( file
!= NULL
, "fopen failed\n");
209 /* sizeof(buffer) > content of file */
210 ok(fread(buffer
, sizeof(buffer
), 1, file
) == 0, "fread test failed\n");
211 /* feof should be set now */
212 ok(feof(file
), "feof after fread failed\n");
215 unlink ("fdopen.tst");
218 #define IOMODE (ao?"ascii mode":"binary mode")
219 static void test_readmode( BOOL ascii_mode
)
221 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";
222 static const char padbuffer
[] = "ghjghjghjghj";
223 static const char nlbuffer
[] = "\r\n";
224 char buffer
[2*BUFSIZ
+256];
233 fd
= open ("fdopen.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
234 /* an internal buffer of BUFSIZ is maintained, so make a file big
235 * enough to test operations that cross the buffer boundary
237 j
= (2*BUFSIZ
-4)/strlen(padbuffer
);
239 write (fd
, padbuffer
, strlen(padbuffer
));
240 j
= (2*BUFSIZ
-4)%strlen(padbuffer
);
242 write (fd
, &padbuffer
[i
], 1);
243 write (fd
, nlbuffer
, strlen(nlbuffer
));
244 write (fd
, outbuffer
, sizeof (outbuffer
));
248 /* Open file in ascii mode */
249 fd
= open ("fdopen.tst", O_RDONLY
);
250 file
= fdopen (fd
, "r");
251 ao
= -1; /* on offset to account for carriage returns */
254 fd
= open ("fdopen.tst", O_RDONLY
| O_BINARY
);
255 file
= fdopen (fd
, "rb");
259 /* first is a test of fgets, ftell, fseek */
260 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
261 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
264 ok(l
== pl
,"padding line ftell got %d should be %d in %s\n", l
, pl
, IOMODE
);
265 ok(lstrlenA(buffer
) == pl
+ao
,"padding line fgets got size %d should be %d in %s\n",
266 lstrlenA(buffer
), pl
+ao
, IOMODE
);
267 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
268 if (outbuffer
[fp
] == '\n') break;
270 ok(fgets(buffer
,256,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
272 ok(l
== pl
+fp
,"line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
273 ok(lstrlenA(buffer
) == fp
+ao
,"line 1 fgets got size %d should be %d in %s\n",
274 lstrlenA(buffer
), fp
+ao
, IOMODE
);
275 /* test a seek back across the buffer boundary */
277 ok(fseek(file
,l
,SEEK_SET
)==0,"seek failure in %s\n", IOMODE
);
279 ok(l
== pl
,"ftell after seek got %d should be %d in %s\n", l
, pl
, IOMODE
);
280 ok(fgets(buffer
,256,file
) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE
);
282 ok(l
== pl
+fp
,"second read of line 1 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
283 ok(lstrlenA(buffer
) == fp
+ao
,"second read of line 1 fgets got size %d should be %d in %s\n",
284 lstrlenA(buffer
), fp
+ao
, IOMODE
);
285 ok(fgets(buffer
,256,file
) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE
);
288 ok(l
== pl
+fp
,"line 2 ftell got %d should be %d in %s\n", l
, pl
+fp
, IOMODE
);
289 ok(lstrlenA(buffer
) == 2+ao
,"line 2 fgets got size %d should be %d in %s\n",
290 lstrlenA(buffer
), 2+ao
, IOMODE
);
292 /* test fread across buffer boundary */
294 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
295 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
297 i
=fread(buffer
,1,BUFSIZ
+strlen(outbuffer
),file
);
298 ok(i
==BUFSIZ
+j
,"fread failed, expected %d got %d in %s\n", BUFSIZ
+j
, i
, IOMODE
);
300 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
);
302 ok(buffer
[m
]==padbuffer
[m
+(BUFSIZ
-4)%strlen(padbuffer
)],"expected %c got %c\n", padbuffer
[m
], buffer
[m
]);
306 ok(buffer
[m
]==*optr
,"char %d expected %c got %c in %s\n", m
, *optr
, buffer
[m
], IOMODE
);
308 if (ao
&& (*optr
== '\r'))
311 /* fread should return the requested number of bytes if available */
313 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
314 ok(fgets(buffer
,BUFSIZ
-6,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
316 i
=fread(buffer
,1,j
,file
);
317 ok(i
==j
,"fread failed, expected %d got %d in %s\n", j
, i
, IOMODE
);
319 ok(fseek(file
,0,SEEK_END
)==0,"seek failure in %s\n", IOMODE
);
320 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
321 ok(fread(buffer
,1,1,file
)==0,"fread failure in %s\n", IOMODE
);
322 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
323 ok(fseek(file
,-3,SEEK_CUR
)==0,"seek failure in %s\n", IOMODE
);
324 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
325 ok(fread(buffer
,2,1,file
)==1,"fread failed in %s\n", IOMODE
);
326 ok(feof(file
)==0,"feof failure in %s\n", IOMODE
);
327 ok(fread(buffer
,2,1,file
)==0,"fread failure in %s\n",IOMODE
);
328 ok(feof(file
)!=0,"feof failure in %s\n", IOMODE
);
330 /* test some additional functions */
332 ok(ftell(file
) == 0,"Did not start at beginning of file in %s\n", IOMODE
);
333 ok(fgets(buffer
,2*BUFSIZ
+256,file
) !=0,"padding line fgets failed unexpected in %s\n", IOMODE
);
335 ip
= (const int *)outbuffer
;
336 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
337 for (fp
=0; fp
<strlen(outbuffer
); fp
++)
338 if (outbuffer
[fp
] == '\n') break;
340 /* this will cause the next _getw to cross carriage return characters */
341 ok(fgets(buffer
,fp
-6,file
) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE
);
342 for (i
=0, j
=0; i
<6; i
++) {
343 if (ao
==0 || outbuffer
[fp
-3+i
] != '\r')
344 buffer
[j
++] = outbuffer
[fp
-3+i
];
348 ok(i
== *ip
,"_getw failed, expected %08x got %08x in %s\n", *ip
, i
, IOMODE
);
351 unlink ("fdopen.tst");
354 static void test_asciimode(void)
360 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */
361 fp
= fopen("ascii.tst", "wb");
364 fp
= fopen("ascii.tst", "rt");
365 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets\n");
366 ok(0 == strcmp(buf
, "\r\n"), "CR CR LF not read as CR LF\n");
368 ok((fread(buf
, 1, sizeof(buf
), fp
) == 2) && (0 == strcmp(buf
, "\r\n")), "CR CR LF not read as CR LF\n");
372 /* Simple test of foo ^Z [more than one block] bar handling */
373 fp
= fopen("ascii.tst", "wb");
374 fputs("foo\032", fp
); /* foo, logical EOF, ... */
375 fseek(fp
, 65536L, SEEK_SET
); /* ... more than MSVCRT_BUFSIZ, ... */
376 fputs("bar", fp
); /* ... bar */
378 fp
= fopen("ascii.tst", "rt");
379 ok(fgets(buf
, sizeof(buf
), fp
) != NULL
, "fgets foo\n");
380 ok(0 == strcmp(buf
, "foo"), "foo ^Z not read as foo by fgets\n");
381 ok(fgets(buf
, sizeof(buf
), fp
) == NULL
, "fgets after logical EOF\n");
383 ok((fread(buf
, 1, sizeof(buf
), fp
) == 3) && (0 == strcmp(buf
, "foo")), "foo ^Z not read as foo by fread\n");
384 ok((fread(buf
, 1, sizeof(buf
), fp
) == 0), "fread after logical EOF\n");
387 /* Show ASCII mode handling*/
388 fp
= fopen("ascii.tst","wb");
389 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp
);
392 fp
= fopen("ascii.tst", "r");
394 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
396 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
397 fseek(fp
,0,SEEK_CUR
);
398 for(i
=1; i
<10; i
++) {
399 ok((j
= ftell(fp
)) == i
*3, "ftell fails in TEXT mode\n");
400 fseek(fp
,0,SEEK_CUR
);
401 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek failed in line %d\n", i
);
403 ok(c
== '\n', "fgetc failed, expected '\\n', got '%c'\n", c
);
405 /* Show that fseek doesn't skip \\r !*/
408 ok(c
== '0', "fgetc failed, expected '0', got '%c'\n", c
);
409 fseek(fp
, 2 ,SEEK_CUR
);
410 for(i
=1; i
<10; i
++) {
411 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with pos Offset failed in line %d\n", i
);
412 fseek(fp
, 2 ,SEEK_CUR
);
414 fseek(fp
, 9*3 ,SEEK_SET
);
416 ok(c
== '9', "fgetc failed, expected '9', got '%c'\n", c
);
417 fseek(fp
, -4 ,SEEK_CUR
);
418 for(i
= 8; i
>=0; i
--) {
419 ok((c
= fgetc(fp
)) == '0'+ i
, "fgetc after fseek with neg Offset failed in line %d\n", i
);
420 fseek(fp
, -4 ,SEEK_CUR
);
422 /* Show what happens if fseek positions filepointer on \\r */
424 fp
= fopen("ascii.tst", "r");
425 fseek(fp
, 3 ,SEEK_SET
);
426 ok((c
= fgetc(fp
)) == '1', "fgetc fails to read next char when positioned on \\r\n");
432 static void test_asciimode2(void)
434 /* Error sequence from one app was getchar followed by small fread
435 * with one \r removed had last byte of buffer filled with
436 * next byte of *unbuffered* data rather than next byte from buffer
437 * Test case is a short string of one byte followed by a newline
438 * followed by filler to fill out the sector, then a sector of
439 * some different byte.
445 static const char obuf
[] =
447 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
448 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
449 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
450 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
451 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
452 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
453 "000000000000000000\n"
454 "1111111111111111111";
456 fp
= fopen("ascii2.tst", "wt");
457 fwrite(obuf
, 1, sizeof(obuf
), fp
);
460 fp
= fopen("ascii2.tst", "rt");
461 ok(getc(fp
) == '0', "first char not 0\n");
462 memset(ibuf
, 0, sizeof(ibuf
));
463 i
= fread(ibuf
, 1, sizeof(ibuf
), fp
);
464 ok(i
== sizeof(ibuf
), "fread i %d != sizeof(ibuf)\n", i
);
465 ok(0 == strncmp(ibuf
, obuf
+1, sizeof(ibuf
)), "ibuf != obuf\n");
467 unlink("ascii2.tst");
470 static void test_filemodeT(void)
472 char DATA
[] = {26, 't', 'e', 's' ,'t'};
474 char temppath
[MAX_PATH
];
475 char tempfile
[MAX_PATH
];
479 WIN32_FIND_DATAA findData
;
482 GetTempPathA(MAX_PATH
, temppath
);
483 GetTempFileNameA(temppath
, "", 0, tempfile
);
485 f
= fopen(tempfile
, "w+bDT");
486 bytesWritten
= fwrite(DATA
, 1, sizeof(DATA
), f
);
488 bytesRead
= fread(DATA2
, 1, sizeof(DATA2
), f
);
491 ok (bytesRead
== bytesWritten
&& bytesRead
== sizeof(DATA
),
492 "fopen file mode 'T' wrongly interpreted as 't'\n" );
494 h
= FindFirstFileA(tempfile
, &findData
);
496 ok (h
== INVALID_HANDLE_VALUE
, "file wasn't deleted when closed.\n" );
498 if (h
!= INVALID_HANDLE_VALUE
) FindClose(h
);
501 static WCHAR
* AtoW( const char* p
)
504 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
505 buffer
= malloc( len
* sizeof(WCHAR
) );
506 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
510 /* Test reading in text mode when the 512'th character read is \r*/
511 static void test_readboundary(void)
514 char buf
[513], rbuf
[513];
516 for (i
= 0; i
< 511; i
++)
518 j
= (i
%('~' - ' ')+ ' ');
523 fp
= fopen("boundary.tst", "wt");
524 fwrite(buf
, 512,1,fp
);
526 fp
= fopen("boundary.tst", "rt");
529 fseek(fp
,0 , SEEK_CUR
);
534 unlink("boundary.tst");
536 ok(strcmp(buf
, rbuf
) == 0,"CRLF on buffer boundary failure\n");
539 static void test_fgetc( void )
545 tempf
=_tempnam(".","wne");
546 tempfh
= fopen(tempf
,"w+");
551 ok(ich
== ret
, "First fgetc expected %x got %x\n", ich
, ret
);
553 ok(ich
== ret
, "Second fgetc expected %x got %x\n", ich
, ret
);
555 tempfh
= fopen(tempf
,"wt");
558 tempfh
= fopen(tempf
,"wt");
559 setbuf(tempfh
, NULL
);
561 ok(ret
== -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n");
567 static void test_fputc( void )
573 tempf
=_tempnam(".","wne");
574 tempfh
= fopen(tempf
,"wb");
575 ret
= fputc(0,tempfh
);
576 ok(0 == ret
, "fputc(0,tempfh) expected %x got %x\n", 0, ret
);
577 ret
= fputc(0xff,tempfh
);
578 ok(0xff == ret
, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret
);
579 ret
= fputc(0xffffffff,tempfh
);
580 ok(0xff == ret
, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret
);
583 tempfh
= fopen(tempf
,"rb");
584 ret
= fputc(0,tempfh
);
585 ok(EOF
== ret
, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
592 static void test_flsbuf( void )
599 static const int bufmodes
[] = {_IOFBF
,_IONBF
};
601 tempf
=_tempnam(".","wne");
602 for (bufmode
=0; bufmode
< sizeof(bufmodes
)/sizeof(bufmodes
[0]); bufmode
++)
604 tempfh
= fopen(tempf
,"wb");
605 setvbuf(tempfh
,NULL
,bufmodes
[bufmode
],2048);
606 ret
= _flsbuf(0,tempfh
);
607 ok(0 == ret
, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n",
608 bufmodes
[bufmode
], 0, ret
);
609 ret
= _flsbuf(0xff,tempfh
);
610 ok(0xff == ret
, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n",
611 bufmodes
[bufmode
], 0xff, ret
);
612 ret
= _flsbuf(0xffffffff,tempfh
);
613 ok(0xff == ret
, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n",
614 bufmodes
[bufmode
], 0xff, ret
);
618 tempfh
->_base
[1] = 'a';
619 ret
= _flsbuf(0xab,tempfh
);
620 ok(ret
== 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n",
621 bufmodes
[bufmode
], ret
);
622 ok(tempfh
->_base
[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n",
629 tempfh
= fopen(tempf
,"rb");
630 ret
= _flsbuf(0,tempfh
);
631 ok(EOF
== ret
, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF
, ret
);
634 /* See bug 17123, exposed by WinAVR's make */
635 tempfh
= fopen(tempf
,"w");
636 ok(tempfh
->_cnt
== 0, "_cnt on freshly opened file was %d\n", tempfh
->_cnt
);
637 setbuf(tempfh
, NULL
);
638 ok(tempfh
->_cnt
== 0, "_cnt on unbuffered file was %d\n", tempfh
->_cnt
);
639 ok(tempfh
->_bufsiz
== 2, "_bufsiz = %d\n", tempfh
->_bufsiz
);
640 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
642 ret
= _flsbuf('Q',tempfh
);
643 ok('Q' == ret
, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret
);
644 /* ... and reset it to zero */
645 ok(tempfh
->_cnt
== 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh
->_cnt
);
647 /* And just for grins, make sure the file is correct */
648 tempfh
= fopen(tempf
,"r");
650 ok(c
== 'Q', "first byte should be 'Q'\n");
652 ok(c
== EOF
, "there should only be one byte\n");
659 static void test_fflush( void )
661 static const char obuf
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
662 char buf1
[16], buf2
[24];
667 tempf
=_tempnam(".","wne");
669 /* Prepare the file. */
670 tempfh
= fopen(tempf
,"wb");
671 ok(tempfh
!= NULL
, "Can't open test file.\n");
672 fwrite(obuf
, 1, sizeof(obuf
), tempfh
);
675 /* Open the file for input. */
676 tempfh
= fopen(tempf
,"rb");
677 ok(tempfh
!= NULL
, "Can't open test file.\n");
678 fread(buf1
, 1, sizeof(buf1
), tempfh
);
680 /* Using fflush() on input stream is undefined in ANSI.
681 * But MSDN says that it clears input buffer. */
682 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
683 ret
= fflush(tempfh
);
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 /* fflush(NULL) doesn't clear input buffer. */
690 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
692 ok(ret
== 0, "expected 0, got %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]);
697 /* _flushall() clears input buffer. */
698 _lseek(_fileno(tempfh
), 0, SEEK_SET
);
700 ok(ret
>= 0, "unexpected ret %d\n", ret
);
701 memset(buf2
, '?', sizeof(buf2
));
702 fread(buf2
, 1, sizeof(buf2
), tempfh
);
703 ok(memcmp(buf1
, buf2
, sizeof(buf1
)) == 0, "Got unexpected data (%c)\n", buf2
[0]);
711 static void test_fgetwc( void )
717 static const char mytext
[]= "This is test_fgetwc\r\n";
718 WCHAR wtextW
[BUFSIZ
+LLEN
+1];
719 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
720 BOOL diff_found
= FALSE
;
725 tempf
=_tempnam(".","wne");
726 tempfh
= fopen(tempf
,"wb");
728 /* pad to almost the length of the internal buffer */
729 for (i
=0; i
<BUFSIZ
-4; i
++)
735 fputs(mytext
,tempfh
);
737 /* in text mode, getws/c expects multibyte characters */
738 /*currently Wine only supports plain ascii, and that is all that is tested here */
739 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
740 fgetws(wtextW
,LLEN
,tempfh
);
742 ok(l
==BUFSIZ
-2, "ftell expected %d got %d\n", BUFSIZ
-2, l
);
743 fgetws(wtextW
,LLEN
,tempfh
);
745 ok(l
==BUFSIZ
-2+strlen(mytext
), "ftell expected %d got %d\n", BUFSIZ
-2+lstrlenA(mytext
), l
);
746 mytextW
= AtoW (mytext
);
749 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
751 diff_found
|= (*aptr
!= *wptr
);
753 ok(!(diff_found
), "fgetwc difference found in TEXT mode\n");
754 ok(*wptr
== '\n', "Carriage return was not skipped\n");
758 tempfh
= fopen(tempf
,"wb");
760 /* pad to almost the length of the internal buffer. Use an odd number of bytes
761 to test that we can read wchars that are split across the internal buffer
763 for (i
=0; i
<BUFSIZ
-3-strlen(mytext
)*sizeof(WCHAR
); i
++)
769 fputws(wtextW
,tempfh
);
770 fputws(wtextW
,tempfh
);
772 /* in binary mode, getws/c expects wide characters */
773 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
774 j
=(BUFSIZ
-2)/sizeof(WCHAR
)-strlen(mytext
);
775 fgetws(wtextW
,j
,tempfh
);
777 j
=(j
-1)*sizeof(WCHAR
);
778 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
780 ok(i
=='a', "fgetc expected %d got %d\n", 0x61, i
);
783 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
784 fgetws(wtextW
,3,tempfh
);
785 ok(wtextW
[0]=='\r',"expected carriage return got %04hx\n", wtextW
[0]);
786 ok(wtextW
[1]=='\n',"expected newline got %04hx\n", wtextW
[1]);
789 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
790 for(i
=0; i
<strlen(mytext
); i
++)
792 /* the first time we get the string, it should be entirely within the local buffer */
793 fgetws(wtextW
,LLEN
,tempfh
);
795 j
+= (strlen(mytext
)-1)*sizeof(WCHAR
);
796 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
800 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
802 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
803 diff_found
|= (*aptr
!= *wptr
);
805 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
806 ok(*wptr
== '\n', "Should get newline\n");
807 for(i
=0; i
<strlen(mytext
); i
++)
809 /* the second time we get the string, it should cross the local buffer boundary.
810 One of the wchars should be split across the boundary */
811 fgetws(wtextW
,LLEN
,tempfh
);
815 for (i
=0; i
<strlen(mytext
)-2; i
++, aptr
++, wptr
++)
817 ok(*aptr
== *wptr
, "Char %d expected %04hx got %04hx\n", i
, *aptr
, *wptr
);
818 diff_found
|= (*aptr
!= *wptr
);
820 ok(!(diff_found
), "fgetwc difference found in BINARY mode\n");
821 ok(*wptr
== '\n', "Should get newline\n");
829 static void test_fgetwc_locale(const char* text
, const char* locale
, int codepage
)
831 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
833 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
834 WCHAR wtextW
[BUFSIZ
];
838 if (!setlocale(LC_CTYPE
, locale
))
840 win_skip("%s locale not available\n", locale
);
844 GetTempPathA(MAX_PATH
, temppath
);
845 GetTempFileNameA(temppath
, "", 0, tempfile
);
847 tempfh
= fopen(tempfile
, "wb");
848 ok(tempfh
!= NULL
, "can't open tempfile\n");
849 fwrite(text
, 1, strlen(text
), tempfh
);
854 /* mbstowcs rejects invalid multibyte sequence,
855 so we use MultiByteToWideChar here. */
856 ret
= MultiByteToWideChar(codepage
, 0, text
, -1,
857 wtextW
, sizeof(wtextW
)/sizeof(wtextW
[0]));
858 ok(ret
> 0, "MultiByteToWideChar failed\n");
864 for (p
= text
; *p
!= '\0'; p
++)
865 wtextW
[ret
++] = (unsigned char)*p
;
869 tempfh
= fopen(tempfile
, "rt");
870 ok(tempfh
!= NULL
, "can't open tempfile\n");
872 for (i
= 0; i
< ret
-1; i
++)
875 ok(ch
== wtextW
[i
], "got %04hx, expected %04hx (cp%d[%d])\n", ch
, wtextW
[i
], codepage
, i
);
878 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
881 tempfh
= fopen(tempfile
, "wb");
882 ok(tempfh
!= NULL
, "can't open tempfile\n");
883 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
886 tempfh
= fopen(tempfile
, "rb");
887 ok(tempfh
!= NULL
, "can't open tempfile\n");
888 for (i
= 0; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
891 ok(ch
== wchar_text
[i
], "got %04hx, expected %04x (cp%d[%d])\n", ch
, wchar_text
[i
], codepage
, i
);
894 ok(ch
== WEOF
, "got %04hx, expected WEOF (cp%d)\n", ch
, codepage
);
899 static void test_fgetwc_unicode(void)
901 char temppath
[MAX_PATH
], tempfile
[MAX_PATH
];
903 static const WCHAR wchar_text
[] = { 0xfeff, 0xff1f, '!' };
904 char utf8_text
[BUFSIZ
];
908 GetTempPathA(MAX_PATH
, temppath
);
909 GetTempFileNameA(temppath
, "", 0, tempfile
);
913 win_skip("fopen_s not available\n");
917 tempfh
= fopen(tempfile
, "wb");
918 ok(tempfh
!= NULL
, "can't open tempfile\n");
919 fwrite(wchar_text
, 1, sizeof(wchar_text
), tempfh
);
922 tempfh
= fopen(tempfile
, "rt,ccs=unicode");
923 ok(tempfh
!= NULL
, "can't open tempfile\n");
924 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
927 ok(ch
== wchar_text
[i
],
928 "got %04hx, expected %04x (unicode[%d])\n", ch
, wchar_text
[i
], i
-1);
931 ok(ch
== WEOF
, "got %04hx, expected WEOF (unicode)\n", ch
);
934 tempfh
= fopen(tempfile
, "wb");
935 ok(tempfh
!= NULL
, "can't open tempfile\n");
936 ret
= WideCharToMultiByte(CP_UTF8
, 0, wchar_text
, sizeof(wchar_text
)/sizeof(wchar_text
[0]),
937 utf8_text
, sizeof(utf8_text
), NULL
, NULL
);
938 ok(ret
> 0, "utf-8 conversion failed\n");
939 fwrite(utf8_text
, sizeof(char), ret
, tempfh
);
942 tempfh
= fopen(tempfile
, "rt, ccs=UTF-8");
943 ok(tempfh
!= NULL
, "can't open tempfile\n");
944 for (i
= 1; i
< sizeof(wchar_text
)/sizeof(wchar_text
[0]); i
++)
947 ok(ch
== wchar_text
[i
],
948 "got %04hx, expected %04x (utf8[%d])\n", ch
, wchar_text
[i
], i
-1);
951 ok(ch
== WEOF
, "got %04hx, expected WEOF (utf8)\n", ch
);
956 static void test_fputwc(void)
958 char temppath
[MAX_PATH
];
959 char tempfile
[MAX_PATH
];
964 GetTempPathA(MAX_PATH
, temppath
);
965 GetTempFileNameA(temppath
, "", 0, tempfile
);
967 f
= fopen(tempfile
, "w");
968 ret
= fputwc('a', f
);
969 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
970 ret
= fputwc('\n', f
);
971 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
974 f
= fopen(tempfile
, "rb");
975 ret
= fread(buf
, 1, sizeof(buf
), f
);
976 ok(ret
== 3, "fread returned %d, expected 3\n", ret
);
977 ok(!memcmp(buf
, "a\r\n", 3), "incorrect file data\n");
981 f
= fopen(tempfile
, "w,ccs=unicode");
982 ret
= fputwc('a', f
);
983 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
984 ret
= fputwc('\n', f
);
985 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
988 f
= fopen(tempfile
, "rb");
989 ret
= fread(buf
, 1, sizeof(buf
), f
);
990 ok(ret
== 8, "fread returned %d, expected 8\n", ret
);
991 ok(!memcmp(buf
, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n");
994 f
= fopen(tempfile
, "w,ccs=utf-8");
995 ret
= fputwc('a', f
);
996 ok(ret
== 'a', "fputwc returned %x, expected 'a'\n", ret
);
997 ret
= fputwc('\n', f
);
998 ok(ret
== '\n', "fputwc returned %x, expected '\\n'\n", ret
);
1001 f
= fopen(tempfile
, "rb");
1002 ret
= fread(buf
, 1, sizeof(buf
), f
);
1003 ok(ret
== 6, "fread returned %d, expected 6\n", ret
);
1004 ok(!memcmp(buf
, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n");
1007 win_skip("fputwc tests on unicode files\n");
1013 static void test_ctrlz( void )
1017 static const char mytext
[]= "This is test_ctrlz";
1022 tempf
=_tempnam(".","wne");
1023 tempfh
= fopen(tempf
,"wb");
1024 fputs(mytext
,tempfh
);
1025 j
= 0x1a; /* a ctrl-z character signals EOF in text mode */
1034 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1035 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1038 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1039 j
+=4; /* ftell should indicate the true end of file */
1041 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1042 ok(feof(tempfh
), "did not get EOF\n");
1045 tempfh
= fopen(tempf
,"rb"); /* open in BINARY mode */
1046 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1048 j
=strlen(mytext
)+3; /* should get through newline */
1049 ok(i
==j
, "returned string length expected %d got %d\n", j
, i
);
1051 ok(l
==j
, "ftell expected %d got %d\n", j
, l
);
1052 ok(fgets(buffer
,256,tempfh
) != 0,"fgets failed unexpected\n");
1054 ok(i
==1, "returned string length expected %d got %d\n", 1, i
);
1055 ok(feof(tempfh
), "did not get EOF\n");
1061 static void test_file_put_get( void )
1065 static const char mytext
[]= "This is a test_file_put_get\n";
1066 static const char dostext
[]= "This is a test_file_put_get\r\n";
1068 WCHAR wtextW
[LLEN
+1];
1069 WCHAR
*mytextW
= NULL
, *aptr
, *wptr
;
1070 BOOL diff_found
= FALSE
;
1073 tempf
=_tempnam(".","wne");
1074 tempfh
= fopen(tempf
,"wt"); /* open in TEXT mode */
1075 fputs(mytext
,tempfh
);
1077 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1078 fgets(btext
,LLEN
,tempfh
);
1079 ok( strlen(mytext
) + 1 == strlen(btext
),"TEXT/BINARY mode not handled for write\n");
1080 ok( btext
[strlen(mytext
)-1] == '\r', "CR not written\n");
1082 tempfh
= fopen(tempf
,"wb"); /* open in BINARY mode */
1083 fputs(dostext
,tempfh
);
1085 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1086 fgets(btext
,LLEN
,tempfh
);
1087 ok(strcmp(btext
, mytext
) == 0,"_O_TEXT read doesn't strip CR\n");
1089 tempfh
= fopen(tempf
,"rb"); /* open in TEXT mode */
1090 fgets(btext
,LLEN
,tempfh
);
1091 ok(strcmp(btext
, dostext
) == 0,"_O_BINARY read doesn't preserve CR\n");
1094 tempfh
= fopen(tempf
,"rt"); /* open in TEXT mode */
1095 fgetws(wtextW
,LLEN
,tempfh
);
1096 mytextW
= AtoW (mytext
);
1100 for (i
=0; i
<strlen(mytext
); i
++, aptr
++, wptr
++)
1102 diff_found
|= (*aptr
!= *wptr
);
1104 ok(!(diff_found
), "fgetwc doesn't strip CR in TEXT mode\n");
1111 static void test_file_write_read( void )
1115 static const char mytext
[]= "This is test_file_write_read\nsecond line\n";
1116 static const char dostext
[]= "This is test_file_write_read\r\nsecond line\r\n";
1120 tempf
=_tempnam(".","wne");
1121 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
,
1122 _S_IREAD
| _S_IWRITE
);
1124 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1125 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1126 "_write _O_BINARY bad return value\n");
1128 i
= lstrlenA(mytext
);
1129 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1130 ok(_read(tempfd
,btext
,i
) == i
,
1131 "_read _O_BINARY got bad length\n");
1132 ok( memcmp(dostext
,btext
,i
) == 0,
1133 "problems with _O_BINARY _write / _read\n");
1135 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1136 ok(_read(tempfd
,btext
,i
) == i
-1,
1137 "_read _O_TEXT got bad length\n");
1138 ok( memcmp(mytext
,btext
,i
-1) == 0,
1139 "problems with _O_BINARY _write / _O_TEXT _read\n");
1141 tempfd
= _open(tempf
,_O_CREAT
|_O_TRUNC
|_O_TEXT
|_O_RDWR
,
1142 _S_IREAD
| _S_IWRITE
);
1144 "Can't open '%s': %d\n", tempf
, errno
); /* open in TEXT mode */
1145 ok(_write(tempfd
,mytext
,strlen(mytext
)) == lstrlenA(mytext
),
1146 "_write _O_TEXT bad return value\n");
1148 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1149 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1150 "_read _O_BINARY got bad length\n");
1151 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1152 "problems with _O_TEXT _write / _O_BINARY _read\n");
1153 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1155 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1156 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1157 "_read _O_TEXT got bad length\n");
1158 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1159 "problems with _O_TEXT _write / _read\n");
1162 memset(btext
, 0, LLEN
);
1163 tempfd
= _open(tempf
,_O_APPEND
|_O_RDWR
); /* open for APPEND in default mode */
1164 ok(tell(tempfd
) == 0, "bad position %u expecting 0\n", tell(tempfd
));
1165 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
), "_read _O_APPEND got bad length\n");
1166 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0, "problems with _O_APPEND _read\n");
1169 /* Test reading only \n or \r */
1170 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1171 _lseek(tempfd
, -1, FILE_END
);
1172 ret
= _read(tempfd
,btext
,LLEN
);
1173 ok(ret
== 1 && *btext
== '\n', "_read expected 1 got bad length: %d\n", ret
);
1174 _lseek(tempfd
, -2, FILE_END
);
1175 ret
= _read(tempfd
,btext
,LLEN
);
1176 ok(ret
== 1 && *btext
== '\n', "_read expected '\\n' got bad length: %d\n", ret
);
1177 _lseek(tempfd
, -2, FILE_END
);
1178 ret
= _read(tempfd
,btext
,1);
1179 ok(ret
== 1 && *btext
== '\n', "_read returned %d, buf: %d\n", ret
, *btext
);
1180 ret
= read(tempfd
,btext
,1);
1181 ok(ret
== 0, "_read returned %d, expected 0\n", ret
);
1182 _lseek(tempfd
, -3, FILE_END
);
1183 ret
= _read(tempfd
,btext
,1);
1184 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1185 ok(tell(tempfd
) == 41, "bad position %u expecting 41\n", tell(tempfd
));
1186 _lseek(tempfd
, -3, FILE_END
);
1187 ret
= _read(tempfd
,btext
,2);
1188 ok(ret
== 1 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1189 ok(tell(tempfd
) == 42, "bad position %u expecting 42\n", tell(tempfd
));
1190 _lseek(tempfd
, -3, FILE_END
);
1191 ret
= _read(tempfd
,btext
,3);
1192 ok(ret
== 2 && *btext
== 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret
, btext
, ret
);
1193 ok(tell(tempfd
) == 43, "bad position %u expecting 43\n", tell(tempfd
));
1196 ret
= unlink(tempf
);
1197 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1200 tempf
=_tempnam(".","wne");
1201 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_BINARY
|_O_RDWR
, _S_IWRITE
);
1203 "Can't open '%s': %d\n", tempf
, errno
); /* open in BINARY mode */
1204 ok(_write(tempfd
,dostext
,strlen(dostext
)) == lstrlenA(dostext
),
1205 "_write _O_BINARY bad return value\n");
1207 tempfd
= _open(tempf
,_O_RDONLY
|_O_BINARY
,0); /* open in BINARY mode */
1208 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(dostext
),
1209 "_read _O_BINARY got bad length\n");
1210 ok( memcmp(dostext
,btext
,strlen(dostext
)) == 0,
1211 "problems with _O_BINARY _write / _read\n");
1212 ok( btext
[strlen(dostext
)-2] == '\r', "CR not written or read\n");
1214 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1215 ok(_read(tempfd
,btext
,LLEN
) == lstrlenA(mytext
),
1216 "_read _O_TEXT got bad length\n");
1217 ok( memcmp(mytext
,btext
,strlen(mytext
)) == 0,
1218 "problems with _O_BINARY _write / _O_TEXT _read\n");
1221 /* test _read with single bytes. CR should be skipped and LF pulled in */
1222 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1223 for (i
=0; i
<strlen(mytext
); i
++) /* */
1225 _read(tempfd
,btext
, 1);
1226 ok(btext
[0] == mytext
[i
],"_read failed at pos %d 0x%02x vs 0x%02x\n", i
, btext
[0], mytext
[i
]);
1228 while (_read(tempfd
,btext
, 1));
1231 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */
1232 tempfd
= _open(tempf
,_O_RDONLY
|_O_TEXT
); /* open in TEXT mode */
1233 i
= _read(tempfd
,btext
, strlen(mytext
));
1234 ok(i
== strlen(mytext
)-1, "_read_i %d\n", i
);
1237 /* test read/write in unicode mode */
1240 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_WTEXT
, _S_IWRITE
);
1241 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1242 ret
= _write(tempfd
, "a", 1);
1243 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1244 ret
= _write(tempfd
, "a\x00\n\x00\xff\xff", 6);
1245 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1248 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1249 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1250 ret
= _read(tempfd
, btext
, sizeof(btext
));
1251 ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1252 ok(!memcmp(btext
, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n");
1255 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1256 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1258 ret
= _read(tempfd
, btext
, 3);
1259 ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1260 ok(errno
== 22, "errno = %d\n", errno
);
1261 ret
= _read(tempfd
, btext
, sizeof(btext
));
1262 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1263 ok(!memcmp(btext
, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n");
1266 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_U8TEXT
, _S_IWRITE
);
1267 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1269 ret
= _write(tempfd
, "a", 1);
1270 ok(ret
== -1, "_write returned %d, expected -1\n", ret
);
1271 ok(errno
== 22, "errno = %d\n", errno
);
1272 ret
= _write(tempfd
, "a\x00\n\x00\x62\x00", 6);
1273 ok(ret
== 6, "_write returned %d, expected 6\n", ret
);
1276 tempfd
= _open(tempf
, _O_RDONLY
|_O_BINARY
, 0);
1277 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1278 ret
= _read(tempfd
, btext
, sizeof(btext
));
1279 ok(ret
== 7, "_read returned %d, expected 7\n", ret
);
1280 ok(!memcmp(btext
, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n");
1283 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1284 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1285 ret
= _read(tempfd
, btext
, sizeof(btext
));
1286 ok(ret
== 6, "_read returned %d, expected 6\n", ret
);
1287 ok(!memcmp(btext
, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n");
1289 /* when buffer is small read sometimes fails in native implementation */
1290 lseek(tempfd
, 3 /* skip bom */, SEEK_SET
);
1291 ret
= _read(tempfd
, btext
, 4);
1292 todo_wine
ok(ret
== -1, "_read returned %d, expected -1\n", ret
);
1294 lseek(tempfd
, 6, SEEK_SET
);
1295 ret
= _read(tempfd
, btext
, 2);
1296 ok(ret
== 2, "_read returned %d, expected 2\n", ret
);
1297 ok(!memcmp(btext
, "\x62\x00", 2), "btext is incorrect\n");
1300 tempfd
= _open(tempf
, _O_CREAT
|_O_TRUNC
|_O_WRONLY
|_O_BINARY
, _S_IWRITE
);
1301 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1302 ret
= _write(tempfd
, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12);
1303 ok(ret
== 12, "_write returned %d, expected 9\n", ret
);
1306 tempfd
= _open(tempf
, _O_RDONLY
|_O_WTEXT
, 0);
1307 ok(tempfd
!= -1, "_open failed with error: %d\n", errno
);
1308 ret
= _read(tempfd
, btext
, sizeof(btext
));
1309 ok(ret
== 12, "_read returned %d, expected 12\n", ret
);
1310 ok(!memcmp(btext
, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n");
1312 /* test invalid utf8 sequence */
1313 lseek(tempfd
, 5, SEEK_SET
);
1314 ret
= _read(tempfd
, btext
, sizeof(btext
));
1315 todo_wine
ok(ret
== 10, "_read returned %d, expected 10\n", ret
);
1316 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */
1317 todo_wine
ok(!memcmp(btext
, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n");
1318 ok(!memcmp(btext
+ret
-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n");
1323 win_skip("unicode mode tests on file\n");
1326 ret
=_chmod (tempf
, _S_IREAD
| _S_IWRITE
);
1328 "Can't chmod '%s' to read-write: %d\n", tempf
, errno
);
1329 ret
= unlink(tempf
);
1330 ok( ret
== 0 ,"Can't unlink '%s': %d\n", tempf
, errno
);
1334 static void test_file_inherit_child(const char* fd_s
)
1336 int fd
= atoi(fd_s
);
1340 ret
=write(fd
, "Success", 8);
1341 ok( ret
== 8, "Couldn't write in child process on %d (%s)\n", fd
, strerror(errno
));
1342 lseek(fd
, 0, SEEK_SET
);
1343 ok(read(fd
, buffer
, sizeof (buffer
)) == 8, "Couldn't read back the data\n");
1344 ok(memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1347 static void test_file_inherit_child_no(const char* fd_s
)
1349 int fd
= atoi(fd_s
);
1352 ret
= write(fd
, "Success", 8);
1353 ok( ret
== -1 && errno
== EBADF
,
1354 "Wrong write result in child process on %d (%s)\n", fd
, strerror(errno
));
1357 static void create_io_inherit_block( STARTUPINFOA
*startup
, unsigned int count
, const HANDLE
*handles
)
1359 static BYTE block
[1024];
1364 startup
->lpReserved2
= block
;
1365 startup
->cbReserved2
= sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE
)) * count
;
1366 wxflag_ptr
= block
+ sizeof(unsigned);
1367 handle_ptr
= (HANDLE
*)(wxflag_ptr
+ count
);
1369 *(unsigned*)block
= count
;
1370 for (i
= 0; i
< count
; i
++)
1372 wxflag_ptr
[i
] = 0x81;
1373 handle_ptr
[i
] = handles
[i
];
1377 static const char *read_file( HANDLE file
)
1379 static char buffer
[128];
1381 SetFilePointer( file
, 0, NULL
, FILE_BEGIN
);
1382 if (!ReadFile( file
, buffer
, sizeof(buffer
) - 1, &ret
, NULL
)) ret
= 0;
1387 static void test_stdout_handle( STARTUPINFOA
*startup
, char *cmdline
, HANDLE hstdout
, BOOL expect_stdout
,
1392 SECURITY_ATTRIBUTES sa
;
1393 PROCESS_INFORMATION proc
;
1395 /* make file handle inheritable */
1396 sa
.nLength
= sizeof(sa
);
1397 sa
.lpSecurityDescriptor
= NULL
;
1398 sa
.bInheritHandle
= TRUE
;
1400 hErrorFile
= CreateFileA( "fdopen.err", GENERIC_READ
|GENERIC_WRITE
,
1401 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1402 startup
->dwFlags
= STARTF_USESTDHANDLES
;
1403 startup
->hStdInput
= GetStdHandle( STD_INPUT_HANDLE
);
1404 startup
->hStdOutput
= hErrorFile
;
1405 startup
->hStdError
= GetStdHandle( STD_ERROR_HANDLE
);
1407 CreateProcessA( NULL
, cmdline
, NULL
, NULL
, TRUE
,
1408 CREATE_DEFAULT_ERROR_MODE
| NORMAL_PRIORITY_CLASS
, NULL
, NULL
, startup
, &proc
);
1409 winetest_wait_child_process( proc
.hProcess
);
1411 data
= read_file( hErrorFile
);
1413 ok( strcmp( data
, "Success" ), "%s: Error file shouldn't contain data\n", descr
);
1415 ok( !strcmp( data
, "Success" ), "%s: Wrong error data (%s)\n", descr
, data
);
1419 data
= read_file( hstdout
);
1421 ok( !strcmp( data
, "Success" ), "%s: Wrong stdout data (%s)\n", descr
, data
);
1423 ok( strcmp( data
, "Success" ), "%s: Stdout file shouldn't contain data\n", descr
);
1426 CloseHandle( hErrorFile
);
1427 DeleteFileA( "fdopen.err" );
1430 static void test_file_inherit( const char* selfname
)
1433 const char* arg_v
[5];
1435 char cmdline
[MAX_PATH
];
1436 STARTUPINFOA startup
;
1437 SECURITY_ATTRIBUTES sa
;
1440 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1441 ok(fd
!= -1, "Couldn't create test file\n");
1442 arg_v
[0] = get_base_name(selfname
);
1443 arg_v
[1] = "tests/file.c";
1444 arg_v
[2] = "inherit";
1445 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1447 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1448 ok(tell(fd
) == 8, "bad position %u expecting 8\n", tell(fd
));
1449 lseek(fd
, 0, SEEK_SET
);
1450 ok(read(fd
, buffer
, sizeof (buffer
)) == 8 && memcmp(buffer
, "Success", 8) == 0, "Couldn't read back the data\n");
1452 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1454 fd
= open ("fdopen.tst", O_CREAT
| O_RDWR
| O_BINARY
| O_NOINHERIT
, _S_IREAD
|_S_IWRITE
);
1455 ok(fd
!= -1, "Couldn't create test file\n");
1456 arg_v
[1] = "tests/file.c";
1457 arg_v
[2] = "inherit_no";
1458 arg_v
[3] = buffer
; sprintf(buffer
, "%d", fd
);
1460 _spawnvp(_P_WAIT
, selfname
, arg_v
);
1461 ok(tell(fd
) == 0, "bad position %u expecting 0\n", tell(fd
));
1462 ok(read(fd
, buffer
, sizeof (buffer
)) == 0, "Found unexpected data (%s)\n", buffer
);
1464 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
1466 /* make file handle inheritable */
1467 sa
.nLength
= sizeof(sa
);
1468 sa
.lpSecurityDescriptor
= NULL
;
1469 sa
.bInheritHandle
= TRUE
;
1470 sprintf(cmdline
, "%s file inherit 1", selfname
);
1472 /* init an empty Reserved2, which should not be recognized as inherit-block */
1473 ZeroMemory(&startup
, sizeof(startup
));
1474 startup
.cb
= sizeof(startup
);
1475 create_io_inherit_block( &startup
, 0, NULL
);
1476 test_stdout_handle( &startup
, cmdline
, 0, FALSE
, "empty block" );
1478 /* test with valid inheritblock */
1479 handles
[0] = GetStdHandle( STD_INPUT_HANDLE
);
1480 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1481 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1482 handles
[2] = GetStdHandle( STD_ERROR_HANDLE
);
1483 create_io_inherit_block( &startup
, 3, handles
);
1484 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "valid block" );
1485 CloseHandle( handles
[1] );
1486 DeleteFileA("fdopen.tst");
1488 /* test inherit block starting with unsigned zero */
1489 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1490 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1491 create_io_inherit_block( &startup
, 3, handles
);
1492 *(unsigned int *)startup
.lpReserved2
= 0;
1493 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "zero count block" );
1494 CloseHandle( handles
[1] );
1495 DeleteFileA("fdopen.tst");
1497 /* test inherit block with smaller size */
1498 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1499 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1500 create_io_inherit_block( &startup
, 3, handles
);
1501 startup
.cbReserved2
-= 3;
1502 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "small size block" );
1503 CloseHandle( handles
[1] );
1504 DeleteFileA("fdopen.tst");
1506 /* test inherit block with even smaller size */
1507 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1508 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1509 create_io_inherit_block( &startup
, 3, handles
);
1510 startup
.cbReserved2
= sizeof(unsigned int) + sizeof(HANDLE
) + sizeof(char);
1511 test_stdout_handle( &startup
, cmdline
, handles
[1], FALSE
, "smaller size block" );
1512 CloseHandle( handles
[1] );
1513 DeleteFileA("fdopen.tst");
1515 /* test inherit block with larger size */
1516 handles
[1] = CreateFileA( "fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
1517 FILE_SHARE_READ
| FILE_SHARE_WRITE
, &sa
, CREATE_ALWAYS
, 0, NULL
);
1518 create_io_inherit_block( &startup
, 3, handles
);
1519 startup
.cbReserved2
+= 7;
1520 test_stdout_handle( &startup
, cmdline
, handles
[1], TRUE
, "large size block" );
1521 CloseHandle( handles
[1] );
1522 DeleteFileA("fdopen.tst");
1525 static void test_tmpnam( void )
1527 char name
[MAX_PATH
] = "abc";
1531 ok(res
!= NULL
, "tmpnam returned NULL\n");
1532 ok(res
[0] == '\\', "first character is not a backslash\n");
1533 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1534 ok(res
[strlen(res
)-1] == '.', "first call - last character is not a dot\n");
1537 ok(res
!= NULL
, "tmpnam returned NULL\n");
1538 ok(res
== name
, "supplied buffer was not used\n");
1539 ok(res
[0] == '\\', "first character is not a backslash\n");
1540 ok(strchr(res
+1, '\\') == 0, "file not in the root directory\n");
1541 ok(res
[strlen(res
)-1] != '.', "second call - last character is a dot\n");
1544 static void test_chsize( void )
1547 LONG cur
, pos
, count
;
1548 char temptext
[] = "012345678";
1549 char *tempfile
= _tempnam( ".", "tst" );
1551 ok( tempfile
!= NULL
, "Couldn't create test file: %s\n", tempfile
);
1553 fd
= _open( tempfile
, _O_CREAT
|_O_TRUNC
|_O_RDWR
, _S_IREAD
|_S_IWRITE
);
1554 ok( fd
> 0, "Couldn't open test file\n" );
1556 count
= _write( fd
, temptext
, sizeof(temptext
) );
1557 ok( count
> 0, "Couldn't write to test file\n" );
1559 /* get current file pointer */
1560 cur
= _lseek( fd
, 0, SEEK_CUR
);
1562 /* make the file smaller */
1563 ok( _chsize( fd
, sizeof(temptext
) / 2 ) == 0, "_chsize() failed\n" );
1565 pos
= _lseek( fd
, 0, SEEK_CUR
);
1566 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1567 ok( _filelength( fd
) == sizeof(temptext
) / 2, "Wrong file size\n" );
1569 /* enlarge the file */
1570 ok( _chsize( fd
, sizeof(temptext
) * 2 ) == 0, "_chsize() failed\n" );
1572 pos
= _lseek( fd
, 0, SEEK_CUR
);
1573 ok( cur
== pos
, "File pointer changed from: %d to: %d\n", cur
, pos
);
1574 ok( _filelength( fd
) == sizeof(temptext
) * 2, "Wrong file size\n" );
1577 _unlink( tempfile
);
1581 static void test_fopen_fclose_fcloseall( void )
1583 char fname1
[] = "empty1";
1584 char fname2
[] = "empty2";
1585 char fname3
[] = "empty3";
1586 FILE *stream1
, *stream2
, *stream3
, *stream4
;
1589 /* testing fopen() */
1590 stream1
= fopen(fname1
, "w+");
1591 ok(stream1
!= NULL
, "The file '%s' was not opened\n", fname1
);
1592 stream2
= fopen(fname2
, "w ");
1593 ok(stream2
!= NULL
, "The file '%s' was not opened\n", fname2
);
1595 stream3
= fopen(fname3
, "r");
1596 ok(stream3
== NULL
, "The file '%s' shouldn't exist before\n", fname3
);
1597 stream3
= fopen(fname3
, "w+");
1598 ok(stream3
!= NULL
, "The file '%s' should be opened now\n", fname3
);
1600 stream4
= fopen("", "w+");
1601 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1602 "filename is empty, errno = %d (expected 2 or 22)\n", errno
);
1604 stream4
= fopen(NULL
, "w+");
1605 ok(stream4
== NULL
&& (errno
== EINVAL
|| errno
== ENOENT
),
1606 "filename is NULL, errno = %d (expected 2 or 22)\n", errno
);
1608 /* testing fclose() */
1609 ret
= fclose(stream2
);
1610 ok(ret
== 0, "The file '%s' was not closed\n", fname2
);
1611 ret
= fclose(stream3
);
1612 ok(ret
== 0, "The file '%s' was not closed\n", fname3
);
1613 ret
= fclose(stream2
);
1614 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname2
, ret
);
1615 ret
= fclose(stream3
);
1616 ok(ret
== EOF
, "Closing file '%s' returned %d\n", fname3
, ret
);
1618 /* testing fcloseall() */
1619 numclosed
= _fcloseall();
1620 /* fname1 should be closed here */
1621 ok(numclosed
== 1, "Number of files closed by fcloseall(): %u\n", numclosed
);
1622 numclosed
= _fcloseall();
1623 ok(numclosed
== 0, "Number of files closed by fcloseall(): %u\n", numclosed
);
1625 ok(_unlink(fname1
) == 0, "Couldn't unlink file named '%s'\n", fname1
);
1626 ok(_unlink(fname2
) == 0, "Couldn't unlink file named '%s'\n", fname2
);
1627 ok(_unlink(fname3
) == 0, "Couldn't unlink file named '%s'\n", fname3
);
1630 static void test_fopen_s( void )
1632 const char name
[] = "empty1";
1634 unsigned char *ubuff
= (unsigned char*)buff
;
1641 win_skip("Skipping fopen_s test\n");
1644 /* testing fopen_s */
1645 ret
= p_fopen_s(&file
, name
, "w");
1646 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1647 ok(file
!= 0, "fopen_s failed to return value\n");
1648 fwrite(name
, sizeof(name
), 1, file
);
1651 ok(ret
!= EOF
, "File failed to close\n");
1653 file
= fopen(name
, "r");
1654 ok(file
!= 0, "fopen failed\n");
1655 len
= fread(buff
, 1, sizeof(name
), file
);
1656 ok(len
== sizeof(name
), "File length is %d\n", len
);
1657 buff
[sizeof(name
)] = '\0';
1658 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1661 ok(ret
!= EOF
, "File failed to close\n");
1663 ret
= p_fopen_s(&file
, name
, "w, ccs=UNIcode");
1664 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1665 ret
= fwrite("a", 1, 2, file
);
1666 ok(ret
== 2, "fwrite returned %d\n", ret
);
1669 ret
= p_fopen_s(&file
, name
, "r");
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]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1674 ubuff
[0], ubuff
[1]);
1677 ret
= p_fopen_s(&file
, name
, "r,ccs=unicode");
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-16le");
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
, "r,ccs=utf-8");
1694 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1695 len
= fread(buff
, 1, 2, file
);
1696 ok(len
== 2, "len = %d\n", len
);
1697 ok(ubuff
[0]=='a' && ubuff
[1]==0, "buff[0]=%02x, buff[1]=%02x\n",
1698 ubuff
[0], ubuff
[1]);
1701 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-16le");
1702 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1705 ret
= p_fopen_s(&file
, name
, "r");
1706 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1707 len
= fread(buff
, 1, 3, file
);
1708 ok(len
== 2, "len = %d\n", len
);
1709 ok(ubuff
[0]==0xff && ubuff
[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n",
1710 ubuff
[0], ubuff
[1]);
1713 ret
= p_fopen_s(&file
, name
, "w,ccs=utf-8");
1714 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1717 ret
= p_fopen_s(&file
, name
, "r");
1718 ok(ret
== 0, "fopen_s failed with %d\n", ret
);
1719 len
= fread(buff
, 1, 4, file
);
1720 ok(len
== 3, "len = %d\n", len
);
1721 ok(ubuff
[0]==0xef && ubuff
[1]==0xbb && ubuff
[2]==0xbf,
1722 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n",
1723 ubuff
[0], ubuff
[1], ubuff
[2]);
1726 /* test initial FILE values */
1727 memset(file
, 0xfe, sizeof(*file
));
1729 ret
= p_fopen_s(&file2
, name
, "r");
1730 ok(!ret
, "fopen_s failed with %d\n", ret
);
1731 ok(file
== file2
, "file != file2 %p %p\n", file
, file2
);
1732 ok(!file
->_ptr
, "file->_ptr != NULL\n");
1733 ok(!file
->_cnt
, "file->_cnt != 0\n");
1734 ok(!file
->_base
, "file->_base != NULL\n");
1735 ok(file
->_flag
== 1, "file->_flag = %x\n", file
->_flag
);
1736 ok(file
->_file
, "file->_file == 0\n");
1737 ok(file
->_charbuf
== 0xfefefefe, "file->_charbuf = %x\n", file
->_charbuf
);
1738 ok(file
->_bufsiz
== 0xfefefefe, "file->_bufsiz = %x\n", file
->_bufsiz
);
1739 ok(!file
->_tmpfname
, "file->_tmpfname != NULL\n");
1742 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1745 static void test__wfopen_s( void )
1747 const char name
[] = "empty1";
1748 const WCHAR wname
[] = {
1749 'e','m','p','t','y','1',0
1751 const WCHAR wmode
[] = {
1761 win_skip("Skipping _wfopen_s test\n");
1764 /* testing _wfopen_s */
1765 ret
= p__wfopen_s(&file
, wname
, wmode
);
1766 ok(ret
== 0, "_wfopen_s failed with %d\n", ret
);
1767 ok(file
!= 0, "_wfopen_s failed to return value\n");
1768 fwrite(name
, sizeof(name
), 1, file
);
1771 ok(ret
!= EOF
, "File failed to close\n");
1773 file
= fopen(name
, "r");
1774 ok(file
!= 0, "fopen failed\n");
1775 len
= fread(buff
, 1, sizeof(name
), file
);
1776 ok(len
== sizeof(name
), "File length is %d\n", len
);
1777 buff
[sizeof(name
)] = '\0';
1778 ok(strcmp(name
, buff
) == 0, "File content mismatch! Got %s, expected %s\n", buff
, name
);
1781 ok(ret
!= EOF
, "File failed to close\n");
1783 ok(_unlink(name
) == 0, "Couldn't unlink file named '%s'\n", name
);
1786 static void test_setmode(void)
1788 const char name
[] = "empty1";
1792 win_skip("unicode file modes are not available, skipping setmode tests\n");
1797 ret
= _setmode(-2, 0);
1798 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1799 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1802 ret
= _setmode(-2, _O_TEXT
);
1803 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1804 ok(errno
== EBADF
, "errno = %d\n", errno
);
1806 fd
= _open(name
, _O_CREAT
|_O_WRONLY
, _S_IWRITE
);
1807 ok(fd
!= -1, "failed to open file\n");
1810 ret
= _setmode(fd
, 0xffffffff);
1811 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1812 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1815 ret
= _setmode(fd
, 0);
1816 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1817 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1820 ret
= _setmode(fd
, _O_BINARY
|_O_TEXT
);
1821 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1822 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1825 ret
= _setmode(fd
, _O_WTEXT
|_O_U16TEXT
);
1826 ok(ret
== -1, "_setmode returned %x, expected -1\n", ret
);
1827 ok(errno
== EINVAL
, "errno = %d\n", errno
);
1829 ret
= _setmode(fd
, _O_BINARY
);
1830 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1832 ret
= _setmode(fd
, _O_WTEXT
);
1833 ok(ret
== _O_BINARY
, "_setmode returned %x, expected _O_BINARY\n", ret
);
1835 ret
= _setmode(fd
, _O_TEXT
);
1836 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1838 ret
= _setmode(fd
, _O_U16TEXT
);
1839 ok(ret
== _O_TEXT
, "_setmode returned %x, expected _O_TEXT\n", ret
);
1841 ret
= _setmode(fd
, _O_U8TEXT
);
1842 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1844 ret
= _setmode(fd
, _O_TEXT
);
1845 ok(ret
== _O_WTEXT
, "_setmode returned %x, expected _O_WTEXT\n", ret
);
1851 static void test_get_osfhandle(void)
1854 char fname
[] = "t_get_osfhanle";
1855 DWORD bytes_written
;
1858 fd
= _sopen(fname
, _O_CREAT
|_O_RDWR
, _SH_DENYRW
, _S_IREAD
| _S_IWRITE
);
1859 handle
= (HANDLE
)_get_osfhandle(fd
);
1860 WriteFile(handle
, "bar", 3, &bytes_written
, NULL
);
1862 fd
= _open(fname
, _O_RDONLY
, 0);
1863 ok(fd
!= -1, "Couldn't open '%s' after _get_osfhandle()\n", fname
);
1869 handle
= (HANDLE
)_get_osfhandle(fd
);
1870 ok(handle
== INVALID_HANDLE_VALUE
, "_get_osfhandle returned %p\n", handle
);
1871 ok(errno
== EBADF
, "errno = %d\n", errno
);
1874 static void test_setmaxstdio(void)
1876 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
1877 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049));
1880 static void test_stat(void)
1887 /* Tests for a file */
1888 fd
= open("stat.tst", O_WRONLY
| O_CREAT
| O_BINARY
, _S_IREAD
|_S_IWRITE
);
1891 ret
= fstat(fd
, &buf
);
1892 ok(!ret
, "fstat failed: errno=%d\n", errno
);
1893 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1894 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1895 ok(buf
.st_dev
== 0, "st_dev is %d, expected 0\n", buf
.st_dev
);
1896 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1897 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1898 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1900 ret
= stat("stat.tst", &buf
);
1901 ok(!ret
, "stat failed: errno=%d\n", errno
);
1902 ok((buf
.st_mode
& _S_IFMT
) == _S_IFREG
, "bad format = %06o\n", buf
.st_mode
);
1903 ok((buf
.st_mode
& 0777) == 0666, "bad st_mode = %06o\n", buf
.st_mode
);
1904 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1905 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1906 ok(buf
.st_size
== 0, "st_size is %d, expected 0\n", buf
.st_size
);
1909 ret
= stat("stat.tst\\", &buf
);
1910 ok(ret
== -1, "stat returned %d\n", ret
);
1911 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1917 skip("open failed with errno %d\n", errno
);
1919 /* Tests for a char device */
1920 if (_dup2(0, 10) == 0)
1922 ret
= fstat(10, &buf
);
1923 ok(!ret
, "fstat(stdin) failed: errno=%d\n", errno
);
1924 if ((buf
.st_mode
& _S_IFMT
) == _S_IFCHR
)
1926 ok(buf
.st_mode
== _S_IFCHR
, "bad st_mode=%06o\n", buf
.st_mode
);
1927 ok(buf
.st_dev
== 10, "st_dev is %d, expected 10\n", buf
.st_dev
);
1928 ok(buf
.st_rdev
== 10, "st_rdev is %d, expected 10\n", buf
.st_rdev
);
1929 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1932 skip("stdin is not a char device? st_mode=%06o\n", buf
.st_mode
);
1936 skip("_dup2 failed with errno %d\n", errno
);
1938 /* Tests for pipes */
1939 if (_pipe(pipes
, 1024, O_BINARY
) == 0)
1941 ret
= fstat(pipes
[0], &buf
);
1942 ok(!ret
, "fstat(pipe) failed: errno=%d\n", errno
);
1943 ok(buf
.st_mode
== _S_IFIFO
, "bad st_mode=%06o\n", buf
.st_mode
);
1944 ok(buf
.st_dev
== pipes
[0], "st_dev is %d, expected %d\n", buf
.st_dev
, pipes
[0]);
1945 ok(buf
.st_rdev
== pipes
[0], "st_rdev is %d, expected %d\n", buf
.st_rdev
, pipes
[0]);
1946 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1951 skip("pipe failed with errno %d\n", errno
);
1953 /* Tests for directory */
1954 if(mkdir("stat.tst") == 0)
1956 ret
= stat("stat.tst ", &buf
);
1957 ok(!ret
, "stat(directory) failed: errno=%d\n", errno
);
1958 ok((buf
.st_mode
& _S_IFMT
) == _S_IFDIR
, "bad format = %06o\n", buf
.st_mode
);
1959 ok((buf
.st_mode
& 0777) == 0777, "bad st_mode = %06o\n", buf
.st_mode
);
1960 ok(buf
.st_dev
== buf
.st_rdev
, "st_dev (%d) and st_rdev (%d) differ\n", buf
.st_dev
, buf
.st_rdev
);
1961 ok(buf
.st_nlink
== 1, "st_nlink is %d, expected 1\n", buf
.st_nlink
);
1964 ret
= stat("stat.tst\\ ", &buf
);
1965 ok(ret
== -1, "stat returned %d\n", ret
);
1966 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1967 rmdir( "stat.tst" );
1970 skip("mkdir failed with errno %d\n", errno
);
1973 ret
= stat("c:", &buf
);
1974 ok(ret
== -1, "stat returned %d\n", ret
);
1975 ok(errno
== ENOENT
, "errno = %d\n", errno
);
1977 ret
= stat("c:/", &buf
);
1978 ok(!ret
, "stat returned %d\n", ret
);
1979 ok(buf
.st_dev
== 2, "st_dev = %d\n", buf
.st_dev
);
1980 ok(buf
.st_rdev
== 2, "st_rdev = %d\n", buf
.st_rdev
);
1983 static const char* pipe_string
="Hello world";
1985 /* How many messages to transfer over the pipe */
1986 #define N_TEST_MESSAGES 3
1988 static void test_pipes_child(int argc
, char** args
)
1996 ok(0, "not enough parameters: %d\n", argc
);
2002 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
2006 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
2007 nwritten
=write(fd
, pipe_string
, strlen(pipe_string
));
2008 ok(nwritten
== strlen(pipe_string
), "i %d, expected to write '%s' wrote %d\n", i
, pipe_string
, nwritten
);
2009 /* let other process wake up so they can show off their "keep reading until EOF" behavior */
2010 if (i
< N_TEST_MESSAGES
-1)
2015 ok(!i
, "unable to close %d: %d\n", fd
, errno
);
2018 static void test_pipes(const char* selfname
)
2021 char str_fdr
[12], str_fdw
[12];
2023 const char* arg_v
[6];
2025 char expected
[4096];
2029 /* Test reading from a pipe with read() */
2030 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2032 ok(0, "pipe failed with errno %d\n", errno
);
2036 arg_v
[0] = get_base_name(selfname
);
2037 arg_v
[1] = "tests/file.c";
2039 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2040 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2042 proc_handles
[0] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2044 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2046 for (i
=0; i
<N_TEST_MESSAGES
; i
++) {
2047 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2048 ok(r
== strlen(pipe_string
), "i %d, got %d\n", i
, r
);
2051 ok(strcmp(buf
, pipe_string
) == 0, "expected to read '%s', got '%s'\n", pipe_string
, buf
);
2054 r
=read(pipes
[0], buf
, sizeof(buf
)-1);
2055 ok(r
== 0, "expected to read 0 bytes, got %d\n", r
);
2057 ok(!i
, "unable to close %d: %d\n", pipes
[0], errno
);
2059 /* Test reading from a pipe with fread() */
2060 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2062 ok(0, "pipe failed with errno %d\n", errno
);
2066 arg_v
[1] = "tests/file.c";
2068 arg_v
[3] = str_fdr
; sprintf(str_fdr
, "%d", pipes
[0]);
2069 arg_v
[4] = str_fdw
; sprintf(str_fdw
, "%d", pipes
[1]);
2071 proc_handles
[1] = (HANDLE
)_spawnvp(_P_NOWAIT
, selfname
, arg_v
);
2073 ok(!i
, "unable to close %d: %d\n", pipes
[1], errno
);
2074 file
=fdopen(pipes
[0], "r");
2076 /* In blocking mode, fread will keep calling read() until it gets
2077 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal
2078 * in cooked mode instead of a pipe, it would also stop on EOL.)
2081 for (i
=0; i
<N_TEST_MESSAGES
; i
++)
2082 strcat(expected
, pipe_string
);
2083 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2084 ok(r
== strlen(expected
), "fread() returned %d: ferror=%d\n", r
, ferror(file
));
2087 ok(strcmp(buf
, expected
) == 0, "got '%s' expected '%s'\n", buf
, expected
);
2089 /* Let child close the file before we read, so we can sense EOF reliably */
2091 r
=fread(buf
, 1, sizeof(buf
)-1, file
);
2092 ok(r
== 0, "fread() returned %d instead of 0\n", r
);
2093 ok(ferror(file
) == 0, "got ferror() = %d\n", ferror(file
));
2094 ok(feof(file
), "feof() is false!\n");
2097 ok(!i
, "unable to close the pipe: %d\n", errno
);
2099 /* test \r handling when it's the last character read */
2100 if (_pipe(pipes
, 1024, O_BINARY
) < 0)
2102 ok(0, "pipe failed with errno %d\n", errno
);
2105 r
= write(pipes
[1], "\r\n\rab\r\n", 7);
2106 ok(r
== 7, "write returned %d, errno = %d\n", r
, errno
);
2107 setmode(pipes
[0], O_TEXT
);
2108 r
= read(pipes
[0], buf
, 1);
2109 ok(r
== 1, "read returned %d, expected 1\n", r
);
2110 ok(buf
[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf
[0]);
2111 r
= read(pipes
[0], buf
, 1);
2112 ok(r
== 1, "read returned %d, expected 1\n", r
);
2113 ok(buf
[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf
[0]);
2114 r
= read(pipes
[0], buf
, 1);
2115 ok(r
== 1, "read returned %d, expected 1\n", r
);
2116 ok(buf
[0] == 'a', "buf[0] = %x, expected 'a'\n", buf
[0]);
2117 r
= read(pipes
[0], buf
, 2);
2118 ok(r
== 2, "read returned %d, expected 1\n", r
);
2119 ok(buf
[0] == 'b', "buf[0] = %x, expected 'b'\n", buf
[0]);
2120 ok(buf
[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf
[1]);
2124 /* test utf16 read with insufficient data */
2125 r
= write(pipes
[1], "a\0b", 3);
2126 ok(r
== 3, "write returned %d, errno = %d\n", r
, errno
);
2129 setmode(pipes
[0], _O_WTEXT
);
2130 r
= read(pipes
[0], buf
, 4);
2131 ok(r
== 2, "read returned %d, expected 2\n", r
);
2132 ok(!memcmp(buf
, "a\0bz", 4), "read returned incorrect data\n");
2133 r
= write(pipes
[1], "\0", 1);
2134 ok(r
== 1, "write returned %d, errno = %d\n", r
, errno
);
2137 r
= read(pipes
[0], buf
, 2);
2138 ok(r
== 0, "read returned %d, expected 0\n", r
);
2139 ok(!memcmp(buf
, "\0z", 2), "read returned incorrect data\n");
2143 win_skip("unicode mode tests on pipe\n");
2150 static void test_unlink(void)
2153 ok(mkdir("test_unlink") == 0, "unable to create test dir\n");
2154 file
= fopen("test_unlink\\empty", "w");
2155 ok(file
!= NULL
, "unable to create test file\n");
2158 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n");
2159 unlink("test_unlink\\empty");
2160 rmdir("test_unlink");
2163 static void test_dup2(void)
2165 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" );
2168 static void test_stdin(void)
2170 HANDLE stdinh
= GetStdHandle(STD_INPUT_HANDLE
);
2175 stdin_dup
= _dup(STDIN_FILENO
);
2176 ok(stdin_dup
!= -1, "_dup(STDIN_FILENO) failed\n");
2178 ok(stdinh
== (HANDLE
)_get_osfhandle(STDIN_FILENO
),
2179 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
2181 r
= SetStdHandle(STD_INPUT_HANDLE
, INVALID_HANDLE_VALUE
);
2182 ok(r
== TRUE
, "SetStdHandle returned %x, expected TRUE\n", r
);
2183 h
= GetStdHandle(STD_INPUT_HANDLE
);
2184 ok(h
== INVALID_HANDLE_VALUE
, "h = %p\n", h
);
2186 close(STDIN_FILENO
);
2187 h
= GetStdHandle(STD_INPUT_HANDLE
);
2188 ok(h
== NULL
, "h != NULL\n");
2190 fd
= open("stdin.tst", O_WRONLY
| O_CREAT
, _S_IREAD
|_S_IWRITE
);
2191 ok(fd
!= -1, "open failed\n");
2192 ok(fd
== STDIN_FILENO
, "fd = %d, expected STDIN_FILENO\n", fd
);
2193 h
= GetStdHandle(STD_INPUT_HANDLE
);
2194 ok(h
!= NULL
, "h == NULL\n");
2196 unlink("stdin.tst");
2198 r
= _dup2(stdin_dup
, STDIN_FILENO
);
2199 ok(r
!= -1, "_dup2 failed\n");
2200 h
= GetStdHandle(STD_INPUT_HANDLE
);
2201 ok(h
!= NULL
, "h == NULL\n");
2204 static void test_mktemp(void)
2209 ok(!_mktemp(buf
), "_mktemp(\"a\") != NULL\n");
2211 strcpy(buf
, "testXXXXX");
2212 ok(!_mktemp(buf
), "_mktemp(\"testXXXXX\") != NULL\n");
2214 strcpy(buf
, "testXXXXXX");
2215 ok(_mktemp(buf
) != NULL
, "_mktemp(\"testXXXXXX\") == NULL\n");
2217 strcpy(buf
, "testXXXXXXa");
2218 ok(!_mktemp(buf
), "_mktemp(\"testXXXXXXa\") != NULL\n");
2220 strcpy(buf
, "**XXXXXX");
2221 ok(_mktemp(buf
) != NULL
, "_mktemp(\"**XXXXXX\") == NULL\n");
2224 static void test__open_osfhandle(void)
2231 fd
= _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE
, 0);
2232 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2233 ok(errno
== EBADF
, "errno = %d\n", errno
);
2235 h
= CreateFileA("open_osfhandle.tst", GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
2236 fd
= _open_osfhandle((intptr_t)h
, 0);
2237 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2238 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2239 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2240 ok(info
->wxflag
== 1, "info->wxflag = %x, expected 1\n", info
->wxflag
);
2242 ok(info
->handle
== INVALID_HANDLE_VALUE
, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info
->handle
);
2243 ok(info
->wxflag
== 0, "info->wxflag = %x, expected 0\n", info
->wxflag
);
2244 DeleteFileA("open_osfhandle.tst");
2247 fd
= _open_osfhandle((intptr_t)h
, 0);
2248 ok(fd
== -1, "_open_osfhandle returned %d\n", fd
);
2249 ok(errno
== EBADF
, "errno = %d\n", errno
);
2251 ok(CreatePipe(&h
, &tmp
, NULL
, 0), "CreatePipe failed\n");
2252 fd
= _open_osfhandle((intptr_t)h
, 0);
2253 ok(fd
> 0, "_open_osfhandle returned %d (%d)\n", fd
, errno
);
2254 info
= &__pioinfo
[fd
/MSVCRT_FD_BLOCK_SIZE
][fd
%MSVCRT_FD_BLOCK_SIZE
];
2255 ok(info
->handle
== h
, "info->handle = %p, expected %p\n", info
->handle
, h
);
2256 ok(info
->wxflag
== 9, "info->wxflag = %x, expected 9\n", info
->wxflag
);
2261 static void test_write_flush_size(FILE *file
, int bufsize
)
2269 inbuffer
= calloc(1, bufsize
+ 1);
2270 outbuffer
= calloc(1, bufsize
+ 1);
2271 _snprintf(outbuffer
, bufsize
+ 1, "0,1,2,3,4,5,6,7,8,9");
2273 for (size
= bufsize
+ 1; size
>= bufsize
- 1; size
--) {
2275 ok(file
->_cnt
== 0, "_cnt should be 0 after rewind, but is %d\n", file
->_cnt
);
2276 fwrite(outbuffer
, 1, size
, file
);
2277 /* lseek() below intentionally redirects the write in fflush() to detect
2278 * if fwrite() has already flushed the whole buffer or not.
2280 lseek(fd
, 1, SEEK_SET
);
2282 ok(file
->_cnt
== 0, "_cnt should be 0 after fflush, but is %d\n", file
->_cnt
);
2283 fseek(file
, 0, SEEK_SET
);
2284 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2285 if (size
== bufsize
)
2286 ok(memcmp(outbuffer
, inbuffer
, bufsize
) == 0, "missing flush by %d byte write\n", size
);
2288 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d byte write\n", size
);
2291 fwrite(outbuffer
, 1, bufsize
/ 2, file
);
2292 fwrite(outbuffer
+ bufsize
/ 2, 1, bufsize
/ 2, file
);
2293 lseek(fd
, 1, SEEK_SET
);
2295 fseek(file
, 0, SEEK_SET
);
2296 ok(fread(inbuffer
, 1, bufsize
, file
) == bufsize
, "read failed\n");
2297 ok(memcmp(outbuffer
, inbuffer
, bufsize
) != 0, "unexpected flush by %d/2 byte double write\n", bufsize
);
2299 ok(!fseek(file
, -1, SEEK_END
), "fseek failed\n");
2300 ok(!fgetpos(file
, &pos
), "fgetpos failed\n");
2301 ok(fread(inbuffer
, 1, 1, file
) == 1, "fread failed\n");
2302 ok(file
->_flag
& _IOREAD
, "file->_flag = %x\n", file
->_flag
);
2303 ok(!file
->_cnt
, "file->_cnt = %d\n", file
->_cnt
);
2304 ok(file
->_ptr
!= file
->_base
, "file->_ptr == file->_base\n");
2305 ok(fwrite(outbuffer
, 1, bufsize
, file
), "fwrite failed\n");
2306 ok(file
->_flag
& _IOREAD
, "file->_flag = %x\n", file
->_flag
);
2307 ok(!file
->_cnt
, "file->_cnt = %d\n", file
->_cnt
);
2308 ok(file
->_ptr
== file
->_base
, "file->_ptr == file->_base\n");
2309 ok(!fgetpos(file
, &pos2
), "fgetpos failed\n");
2310 ok(pos
+bufsize
+1 == pos2
, "pos = %d (%d)\n", (int)pos
, (int)pos2
);
2315 static void test_write_flush(void)
2321 tempf
= _tempnam(".","wne");
2322 file
= fopen(tempf
, "wb+");
2323 ok(file
!= NULL
, "unable to create test file\n");
2325 ok(file
->_bufsiz
== 4096, "incorrect default buffer size: %d\n", file
->_bufsiz
);
2326 test_write_flush_size(file
, file
->_bufsiz
);
2327 setvbuf(file
, iobuf
, _IOFBF
, sizeof(iobuf
));
2328 test_write_flush_size(file
, sizeof(iobuf
));
2334 static void test_close(void)
2336 ioinfo
*stdout_info
, stdout_copy
, *stderr_info
, stderr_copy
;
2337 int fd1
, fd2
, ret1
, ret2
, ret3
, ret4
;
2341 /* test close on fds that use the same handle */
2342 h
= CreateFileA("fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
2343 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2344 ok(h
!= INVALID_HANDLE_VALUE
, "error opening fdopen.tst file\n");
2346 fd1
= _open_osfhandle((intptr_t)h
, 0);
2347 ok(fd1
!= -1, "_open_osfhandle failed (%d)\n", errno
);
2348 fd2
= _open_osfhandle((intptr_t)h
, 0);
2349 ok(fd2
!= -1, "_open_osfhandle failed (%d)\n", errno
);
2350 ok(fd1
!= fd2
, "fd1 == fd2\n");
2352 ok((HANDLE
)_get_osfhandle(fd1
) == h
, "handles mismatch (%p != %p)\n",
2353 (HANDLE
)_get_osfhandle(fd1
), h
);
2354 ok((HANDLE
)_get_osfhandle(fd2
) == h
, "handles mismatch (%p != %p)\n",
2355 (HANDLE
)_get_osfhandle(fd2
), h
);
2357 ok(!ret1
, "close(fd1) failed (%d)\n", errno
);
2358 ok(!GetHandleInformation(h
, &flags
), "GetHandleInformation succeeded\n");
2359 ok(close(fd2
), "close(fd2) succeeded\n");
2361 /* test close on stdout and stderr that use the same handle */
2362 h
= CreateFileA("fdopen.tst", GENERIC_READ
|GENERIC_WRITE
,
2363 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
, 0, NULL
);
2364 ok(h
!= INVALID_HANDLE_VALUE
, "error opening fdopen.tst file\n");
2366 /* tests output will not be visible from now on */
2367 stdout_info
= &__pioinfo
[STDOUT_FILENO
/MSVCRT_FD_BLOCK_SIZE
][STDOUT_FILENO
%MSVCRT_FD_BLOCK_SIZE
];
2368 stderr_info
= &__pioinfo
[STDERR_FILENO
/MSVCRT_FD_BLOCK_SIZE
][STDERR_FILENO
%MSVCRT_FD_BLOCK_SIZE
];
2369 stdout_copy
= *stdout_info
;
2370 stderr_copy
= *stderr_info
;
2371 stdout_info
->handle
= h
;
2372 stderr_info
->handle
= h
;
2374 ret1
= close(STDOUT_FILENO
);
2375 ret2
= GetHandleInformation(h
, &flags
);
2376 ret3
= close(STDERR_FILENO
);
2377 ret4
= GetHandleInformation(h
, &flags
);
2379 *stdout_info
= stdout_copy
;
2380 *stderr_info
= stderr_copy
;
2381 SetStdHandle(STD_OUTPUT_HANDLE
, stdout_info
->handle
);
2382 SetStdHandle(STD_ERROR_HANDLE
, stderr_info
->handle
);
2383 /* stdout and stderr restored */
2385 ok(!ret1
, "close(STDOUT_FILENO) failed\n");
2386 ok(ret2
, "GetHandleInformation failed\n");
2387 ok(!ret3
, "close(STDERR_FILENO) failed\n");
2388 ok(!ret4
, "GetHandleInformation succeeded\n");
2390 DeleteFileA( "fdopen.tst" );
2393 static void test__creat(void)
2395 int fd
, pos
, count
, readonly
, old_fmode
= 0, have_fmode
;
2396 char buf
[6], testdata
[4] = {'a', '\n', 'b', '\n'};
2398 have_fmode
= p__get_fmode
&& p__set_fmode
&& !p__get_fmode(&old_fmode
);
2400 win_skip("_fmode can't be set, skipping mode tests\n");
2403 p__set_fmode(_O_TEXT
);
2404 fd
= _creat("_creat.tst", 0);
2405 ok(fd
> 0, "_creat failed\n");
2406 _write(fd
, testdata
, 4);
2409 ok(pos
== 6, "expected pos 6 (text mode), got %d\n", pos
);
2411 ok(_lseek(fd
, SEEK_SET
, 0) == 0, "_lseek failed\n");
2412 count
= _read(fd
, buf
, 6);
2413 ok(count
== 4, "_read returned %d, expected 4\n", count
);
2414 count
= count
> 0 ? count
> 4 ? 4 : count
: 0;
2415 ok(memcmp(buf
, testdata
, count
) == 0, "_read returned wrong contents\n");
2417 readonly
= GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY
;
2418 ok(readonly
, "expected read-only file\n");
2419 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL
);
2420 DeleteFileA("_creat.tst");
2423 p__set_fmode(_O_BINARY
);
2424 fd
= _creat("_creat.tst", _S_IREAD
| _S_IWRITE
);
2425 ok(fd
> 0, "_creat failed\n");
2426 _write(fd
, testdata
, 4);
2429 ok(pos
== 4, "expected pos 4 (binary mode), got %d\n", pos
);
2431 ok(_lseek(fd
, SEEK_SET
, 0) == 0, "_lseek failed\n");
2432 count
= _read(fd
, buf
, 6);
2433 ok(count
== 4, "_read returned %d, expected 4\n", count
);
2434 count
= count
> 0 ? count
> 4 ? 4 : count
: 0;
2435 ok(memcmp(buf
, testdata
, count
) == 0, "_read returned wrong contents\n");
2437 readonly
= GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY
;
2438 ok(!readonly
, "expected rw file\n");
2439 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL
);
2440 DeleteFileA("_creat.tst");
2443 p__set_fmode(old_fmode
);
2453 arg_c
= winetest_get_mainargs( &arg_v
);
2455 /* testing low-level I/O */
2458 if (strcmp(arg_v
[2], "inherit") == 0)
2459 test_file_inherit_child(arg_v
[3]);
2460 else if (strcmp(arg_v
[2], "inherit_no") == 0)
2461 test_file_inherit_child_no(arg_v
[3]);
2462 else if (strcmp(arg_v
[2], "pipes") == 0)
2463 test_pipes_child(arg_c
, arg_v
);
2465 ok(0, "invalid argument '%s'\n", arg_v
[2]);
2469 test_file_inherit(arg_v
[0]);
2470 test_file_write_read();
2475 /* testing stream I/O */
2478 test_fopen_fclose_fcloseall();
2486 test_readmode(FALSE
); /* binary mode */
2487 test_readmode(TRUE
); /* ascii mode */
2488 test_readboundary();
2494 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */
2495 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932);
2496 /* \x83 is U+0192 */
2497 test_fgetwc_locale("AB\x83\xa9", "English", 1252);
2498 /* \x83 is U+0083 */
2499 test_fgetwc_locale("AB\x83\xa9", "C", 0);
2500 test_fgetwc_unicode();
2503 test_file_put_get();
2505 test_get_osfhandle();
2507 test_pipes(arg_v
[0]);
2510 test__open_osfhandle();
2515 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
2516 * file contains lines in the correct order
2518 WaitForMultipleObjects(sizeof(proc_handles
)/sizeof(proc_handles
[0]), proc_handles
, TRUE
, 5000);