1 /* 2 * Unit test suite for file functions 3 * 4 * Copyright 2002 Bill Currie 5 * Copyright 2005 Paul Rupe 6 * 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. 11 * 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. 16 * 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 20 */ 21 22 #include "precomp.h" 23 24 #include <fcntl.h> 25 #include <share.h> 26 #include <sys/stat.h> 27 #include <io.h> 28 29 #define MSVCRT_FD_BLOCK_SIZE 32 30 typedef struct { 31 HANDLE handle; 32 unsigned char wxflag; 33 char lookahead[3]; 34 int exflag; 35 CRITICAL_SECTION crit; 36 } ioinfo; 37 static ioinfo **__pioinfo; 38 39 static HANDLE proc_handles[2]; 40 41 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*); 42 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*); 43 static errno_t (__cdecl *p__get_fmode)(int*); 44 static errno_t (__cdecl *p__set_fmode)(int); 45 46 static const char* get_base_name(const char *path) 47 { 48 const char *ret = path+strlen(path)-1; 49 50 while(ret >= path) { 51 if(*ret=='\\' || *ret=='/') 52 break; 53 ret--; 54 } 55 return ret+1; 56 } 57 58 static void init(void) 59 { 60 HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 61 62 setlocale(LC_CTYPE, "C"); 63 64 p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s"); 65 p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s"); 66 __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo"); 67 p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode"); 68 p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode"); 69 } 70 71 static void test_filbuf( void ) 72 { 73 FILE *fp; 74 int c; 75 fpos_t pos; 76 77 fp = fopen("filbuf.tst", "wb"); 78 fwrite("\n\n\n\n", 1, 4, fp); 79 fclose(fp); 80 81 fp = fopen("filbuf.tst", "rt"); 82 c = _filbuf(fp); 83 ok(c == '\n', "read wrong byte\n"); 84 /* See bug 16970 for why we care about _filbuf. 85 * ftell returns screwy values on files with lots 86 * of bare LFs in ascii mode because it assumes 87 * that ascii files contain only CRLFs, removes 88 * the CR's early in _filbuf, and adjusts the return 89 * value of ftell to compensate. 90 * native _filbuf will read the whole file, then consume and return 91 * the first one. That leaves fp->_fd at offset 4, and fp->_ptr 92 * pointing to a buffer of three bare LFs, so 93 * ftell will return 4 - 3 - 3 = -2. 94 */ 95 ok(ftell(fp) == -2, "ascii crlf removal does not match native\n"); 96 ok(fgetpos(fp, &pos) == 0, "fgetpos fail\n"); 97 ok(pos == -2, "ftell does not match fgetpos\n"); 98 fclose(fp); 99 unlink("filbuf.tst"); 100 } 101 102 static void test_fdopen( void ) 103 { 104 static const char buffer[] = {0,1,2,3,4,5,6,7,8,9}; 105 char ibuf[10]; 106 int fd; 107 FILE *file; 108 109 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); 110 write (fd, buffer, sizeof (buffer)); 111 close (fd); 112 113 fd = open ("fdopen.tst", O_RDONLY | O_BINARY); 114 lseek (fd, 5, SEEK_SET); 115 file = fdopen (fd, "rb"); 116 ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n"); 117 ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n"); 118 fclose (file); 119 unlink ("fdopen.tst"); 120 } 121 122 static void test_fileops( void ) 123 { 124 static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9"; 125 char buffer[256]; 126 WCHAR wbuffer[256]; 127 int fd; 128 FILE *file; 129 fpos_t pos; 130 int i, c, bufmode; 131 static const int bufmodes[] = {_IOFBF,_IONBF}; 132 133 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); 134 write (fd, outbuffer, sizeof (outbuffer)); 135 close (fd); 136 137 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++) 138 { 139 fd = open ("fdopen.tst", O_RDONLY | O_BINARY); 140 file = fdopen (fd, "rb"); 141 setvbuf(file,NULL,bufmodes[bufmode],2048); 142 if(bufmodes[bufmode] == _IOFBF) 143 ok(file->_bufsiz == 2048, "file->_bufsiz = %d\n", file->_bufsiz); 144 ok(file->_base != NULL, "file->_base = NULL\n"); 145 ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]); 146 ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 147 ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]); 148 ok(feof(file) !=0,"feof doesn't signal EOF for bufmode=%x\n", bufmodes[bufmode]); 149 rewind(file); 150 ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 151 ok(lstrlenA(buffer) == lstrlenA(outbuffer) -1,"fgets didn't read right size for bufmode=%x\n", bufmodes[bufmode]); 152 ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 153 ok(strlen(buffer) == 1,"fgets dropped chars for bufmode=%x\n", bufmodes[bufmode]); 154 ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars for bufmode=%x\n", bufmodes[bufmode]); 155 156 rewind(file); 157 for (i = 0; i < sizeof(outbuffer); i++) 158 { 159 ok(fgetc(file) == outbuffer[i], "fgetc returned wrong data for bufmode=%x\n", bufmodes[bufmode]); 160 } 161 ok((c = fgetc(file)) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 162 ok(feof(file), "feof did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 163 ok(ungetc(c, file) == EOF, "ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 164 ok(feof(file), "feof after ungetc(EOF) did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 165 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 166 c = outbuffer[sizeof(outbuffer) - 1]; 167 ok(ungetc(c, file) == c, "ungetc did not return its input for bufmode=%x\n", bufmodes[bufmode]); 168 ok(!feof(file), "feof after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]); 169 ok((c = fgetc(file)) != EOF, "getc after ungetc returned EOF for bufmode=%x\n", bufmodes[bufmode]); 170 ok(c == outbuffer[sizeof(outbuffer) - 1], 171 "getc did not return ungetc'd data for bufmode=%x\n", bufmodes[bufmode]); 172 ok(!feof(file), "feof after getc returned EOF prematurely for bufmode=%x\n", bufmodes[bufmode]); 173 ok(fgetc(file) == EOF, "getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 174 ok(feof(file), "feof after getc did not return EOF for bufmode=%x\n", bufmodes[bufmode]); 175 176 rewind(file); 177 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 178 ok(pos == 0, "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos), bufmodes[bufmode]); 179 pos = sizeof (outbuffer); 180 ok(fsetpos(file, &pos) == 0, "fsetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 181 ok(fgetpos(file,&pos) == 0, "fgetpos failed unexpected for bufmode=%x\n", bufmodes[bufmode]); 182 ok(pos == sizeof (outbuffer), "Unexpected result of fgetpos %s for bufmode=%x\n", wine_dbgstr_longlong(pos), bufmodes[bufmode]); 183 184 fclose (file); 185 } 186 fd = open ("fdopen.tst", O_RDONLY | O_TEXT); 187 file = fdopen (fd, "rt"); /* open in TEXT mode */ 188 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n"); 189 ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n"); 190 ok(feof(file) !=0,"feof doesn't signal EOF\n"); 191 rewind(file); 192 ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n"); 193 ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n"); 194 ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n"); 195 ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n"); 196 fclose (file); 197 198 file = fopen("fdopen.tst", "rb"); 199 ok( file != NULL, "fopen failed\n"); 200 /* sizeof(buffer) > content of file */ 201 ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); 202 /* feof should be set now */ 203 ok(feof(file), "feof after fread failed\n"); 204 fclose (file); 205 206 unlink ("fdopen.tst"); 207 } 208 209 #define IOMODE (ao?"ascii mode":"binary mode") 210 static void test_readmode( BOOL ascii_mode ) 211 { 212 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"; 213 static const char padbuffer[] = "ghjghjghjghj"; 214 static const char nlbuffer[] = "\r\n"; 215 char buffer[2*BUFSIZ+256]; 216 const char *optr; 217 int fd; 218 FILE *file; 219 const int *ip; 220 int i, j, m, ao, pl; 221 unsigned int fp; 222 LONG l; 223 224 fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); 225 /* an internal buffer of BUFSIZ is maintained, so make a file big 226 * enough to test operations that cross the buffer boundary 227 */ 228 j = (2*BUFSIZ-4)/strlen(padbuffer); 229 for (i=0; i<j; i++) 230 write (fd, padbuffer, strlen(padbuffer)); 231 j = (2*BUFSIZ-4)%strlen(padbuffer); 232 for (i=0; i<j; i++) 233 write (fd, &padbuffer[i], 1); 234 write (fd, nlbuffer, strlen(nlbuffer)); 235 write (fd, outbuffer, sizeof (outbuffer)); 236 close (fd); 237 238 if (ascii_mode) { 239 /* Open file in ascii mode */ 240 fd = open ("fdopen.tst", O_RDONLY); 241 file = fdopen (fd, "r"); 242 ao = -1; /* on offset to account for carriage returns */ 243 } 244 else { 245 fd = open ("fdopen.tst", O_RDONLY | O_BINARY); 246 file = fdopen (fd, "rb"); 247 ao = 0; 248 } 249 250 /* first is a test of fgets, ftell, fseek */ 251 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); 252 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE); 253 l = ftell(file); 254 pl = 2*BUFSIZ-2; 255 ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE); 256 ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n", 257 lstrlenA(buffer), pl+ao, IOMODE); 258 for (fp=0; fp<strlen(outbuffer); fp++) 259 if (outbuffer[fp] == '\n') break; 260 fp++; 261 ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE); 262 l = ftell(file); 263 ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); 264 ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n", 265 lstrlenA(buffer), fp+ao, IOMODE); 266 /* test a seek back across the buffer boundary */ 267 l = pl; 268 ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE); 269 l = ftell(file); 270 ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE); 271 ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE); 272 l = ftell(file); 273 ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); 274 ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n", 275 lstrlenA(buffer), fp+ao, IOMODE); 276 ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE); 277 fp += 2; 278 l = ftell(file); 279 ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); 280 ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n", 281 lstrlenA(buffer), 2+ao, IOMODE); 282 283 /* test fread across buffer boundary */ 284 rewind(file); 285 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); 286 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE); 287 j=strlen(outbuffer); 288 i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file); 289 ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE); 290 l = ftell(file); 291 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); 292 for (m=0; m<3; m++) 293 ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]); 294 m+=BUFSIZ+2+ao; 295 optr = outbuffer; 296 for (; m<i; m++) { 297 ok(buffer[m]==*optr,"char %d expected %c got %c in %s\n", m, *optr, buffer[m], IOMODE); 298 optr++; 299 if (ao && (*optr == '\r')) 300 optr++; 301 } 302 /* fread should return the requested number of bytes if available */ 303 rewind(file); 304 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); 305 ok(fgets(buffer,BUFSIZ-6,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE); 306 j = fp+10; 307 i=fread(buffer,1,j,file); 308 ok(i==j,"fread failed, expected %d got %d in %s\n", j, i, IOMODE); 309 /* test fread eof */ 310 ok(fseek(file,0,SEEK_END)==0,"seek failure in %s\n", IOMODE); 311 ok(feof(file)==0,"feof failure in %s\n", IOMODE); 312 ok(fread(buffer,1,1,file)==0,"fread failure in %s\n", IOMODE); 313 ok(feof(file)!=0,"feof failure in %s\n", IOMODE); 314 ok(fseek(file,-3,SEEK_CUR)==0,"seek failure in %s\n", IOMODE); 315 ok(feof(file)==0,"feof failure in %s\n", IOMODE); 316 ok(fread(buffer,2,1,file)==1,"fread failed in %s\n", IOMODE); 317 ok(feof(file)==0,"feof failure in %s\n", IOMODE); 318 ok(fread(buffer,2,1,file)==0,"fread failure in %s\n",IOMODE); 319 ok(feof(file)!=0,"feof failure in %s\n", IOMODE); 320 321 /* test some additional functions */ 322 rewind(file); 323 ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); 324 ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE); 325 i = _getw(file); 326 ip = (const int *)outbuffer; 327 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE); 328 for (fp=0; fp<strlen(outbuffer); fp++) 329 if (outbuffer[fp] == '\n') break; 330 fp++; 331 /* this will cause the next _getw to cross carriage return characters */ 332 ok(fgets(buffer,fp-6,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE); 333 for (i=0, j=0; i<6; i++) { 334 if (ao==0 || outbuffer[fp-3+i] != '\r') 335 buffer[j++] = outbuffer[fp-3+i]; 336 } 337 i = _getw(file); 338 ip = (int *)buffer; 339 ok(i == *ip,"_getw failed, expected %08x got %08x in %s\n", *ip, i, IOMODE); 340 341 fclose (file); 342 unlink ("fdopen.tst"); 343 } 344 345 static void test_asciimode(void) 346 { 347 FILE *fp; 348 char buf[64]; 349 int c, i, j; 350 351 /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */ 352 fp = fopen("ascii.tst", "wb"); 353 fputs("\r\r\n", fp); 354 fclose(fp); 355 fp = fopen("ascii.tst", "rt"); 356 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n"); 357 ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n"); 358 rewind(fp); 359 ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n"); 360 fclose(fp); 361 unlink("ascii.tst"); 362 363 /* Simple test of foo ^Z [more than one block] bar handling */ 364 fp = fopen("ascii.tst", "wb"); 365 fputs("foo\032", fp); /* foo, logical EOF, ... */ 366 fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */ 367 fputs("bar", fp); /* ... bar */ 368 fclose(fp); 369 fp = fopen("ascii.tst", "rt"); 370 ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n"); 371 ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n"); 372 ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n"); 373 rewind(fp); 374 ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n"); 375 ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n"); 376 fclose(fp); 377 378 /* Show ASCII mode handling*/ 379 fp= fopen("ascii.tst","wb"); 380 fputs("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n", fp); 381 fclose(fp); 382 383 fp = fopen("ascii.tst", "r"); 384 c= fgetc(fp); 385 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c); 386 c= fgetc(fp); 387 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c); 388 fseek(fp,0,SEEK_CUR); 389 for(i=1; i<10; i++) { 390 ok((j = ftell(fp)) == i*3, "ftell fails in TEXT mode\n"); 391 fseek(fp,0,SEEK_CUR); 392 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek failed in line %d\n", i); 393 c= fgetc(fp); 394 ok(c == '\n', "fgetc failed, expected '\\n', got '%c'\n", c); 395 } 396 /* Show that fseek doesn't skip \\r !*/ 397 rewind(fp); 398 c= fgetc(fp); 399 ok(c == '0', "fgetc failed, expected '0', got '%c'\n", c); 400 fseek(fp, 2 ,SEEK_CUR); 401 for(i=1; i<10; i++) { 402 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with pos Offset failed in line %d\n", i); 403 fseek(fp, 2 ,SEEK_CUR); 404 } 405 fseek(fp, 9*3 ,SEEK_SET); 406 c = fgetc(fp); 407 ok(c == '9', "fgetc failed, expected '9', got '%c'\n", c); 408 fseek(fp, -4 ,SEEK_CUR); 409 for(i= 8; i>=0; i--) { 410 ok((c = fgetc(fp)) == '0'+ i, "fgetc after fseek with neg Offset failed in line %d\n", i); 411 fseek(fp, -4 ,SEEK_CUR); 412 } 413 /* Show what happens if fseek positions filepointer on \\r */ 414 fclose(fp); 415 fp = fopen("ascii.tst", "r"); 416 fseek(fp, 3 ,SEEK_SET); 417 ok((c = fgetc(fp)) == '1', "fgetc fails to read next char when positioned on \\r\n"); 418 fclose(fp); 419 420 unlink("ascii.tst"); 421 } 422 423 static void test_asciimode2(void) 424 { 425 /* Error sequence from one app was getchar followed by small fread 426 * with one \r removed had last byte of buffer filled with 427 * next byte of *unbuffered* data rather than next byte from buffer 428 * Test case is a short string of one byte followed by a newline 429 * followed by filler to fill out the sector, then a sector of 430 * some different byte. 431 */ 432 433 FILE *fp; 434 char ibuf[4]; 435 int i; 436 static const char obuf[] = 437 "00\n" 438 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 439 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 440 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 441 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 442 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 443 "000000000000000000000000000000000000000000000000000000000000000000000000000000\n" 444 "000000000000000000\n" 445 "1111111111111111111"; 446 447 fp = fopen("ascii2.tst", "wt"); 448 fwrite(obuf, 1, sizeof(obuf), fp); 449 fclose(fp); 450 451 fp = fopen("ascii2.tst", "rt"); 452 ok(getc(fp) == '0', "first char not 0\n"); 453 memset(ibuf, 0, sizeof(ibuf)); 454 i = fread(ibuf, 1, sizeof(ibuf), fp); 455 ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf)\n", i); 456 ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n"); 457 fclose(fp); 458 unlink("ascii2.tst"); 459 } 460 461 static void test_filemodeT(void) 462 { 463 char DATA [] = {26, 't', 'e', 's' ,'t'}; 464 char DATA2 [100]; 465 char temppath[MAX_PATH]; 466 char tempfile[MAX_PATH]; 467 FILE* f; 468 size_t bytesWritten; 469 size_t bytesRead; 470 WIN32_FIND_DATAA findData; 471 HANDLE h; 472 473 GetTempPathA(MAX_PATH, temppath); 474 GetTempFileNameA(temppath, "", 0, tempfile); 475 476 f = fopen(tempfile, "w+bDT"); 477 bytesWritten = fwrite(DATA, 1, sizeof(DATA), f); 478 rewind(f); 479 bytesRead = fread(DATA2, 1, sizeof(DATA2), f); 480 fclose(f); 481 482 ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA), 483 "fopen file mode 'T' wrongly interpreted as 't'\n" ); 484 485 h = FindFirstFileA(tempfile, &findData); 486 487 ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" ); 488 489 if (h != INVALID_HANDLE_VALUE) FindClose(h); 490 } 491 492 static WCHAR* AtoW( const char* p ) 493 { 494 WCHAR* buffer; 495 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 ); 496 buffer = malloc( len * sizeof(WCHAR) ); 497 MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len ); 498 return buffer; 499 } 500 501 /* Test reading in text mode when the 512'th character read is \r*/ 502 static void test_readboundary(void) 503 { 504 FILE *fp; 505 char buf[513], rbuf[513]; 506 int i, j; 507 for (i = 0; i < 511; i++) 508 { 509 j = (i%('~' - ' ')+ ' '); 510 buf[i] = j; 511 } 512 buf[511] = '\n'; 513 buf[512] =0; 514 fp = fopen("boundary.tst", "wt"); 515 fwrite(buf, 512,1,fp); 516 fclose(fp); 517 fp = fopen("boundary.tst", "rt"); 518 for(i=0; i<512; i++) 519 { 520 fseek(fp,0 , SEEK_CUR); 521 rbuf[i] = fgetc(fp); 522 } 523 rbuf[512] =0; 524 fclose(fp); 525 unlink("boundary.tst"); 526 527 ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n"); 528 } 529 530 static void test_fgetc( void ) 531 { 532 char* tempf; 533 FILE *tempfh; 534 int ich=0xe0, ret; 535 536 tempf=_tempnam(".","wne"); 537 tempfh = fopen(tempf,"w+"); 538 fputc(ich, tempfh); 539 fputc(ich, tempfh); 540 rewind(tempfh); 541 ret = fgetc(tempfh); 542 ok(ich == ret, "First fgetc expected %x got %x\n", ich, ret); 543 ret = fgetc(tempfh); 544 ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret); 545 fclose(tempfh); 546 tempfh = fopen(tempf,"wt"); 547 fputc('\n', tempfh); 548 fclose(tempfh); 549 tempfh = fopen(tempf,"wt"); 550 setbuf(tempfh, NULL); 551 ret = fgetc(tempfh); 552 ok(ret == -1, "Unbuffered fgetc in text mode must failed on \\r\\n\n"); 553 fclose(tempfh); 554 unlink(tempf); 555 free(tempf); 556 } 557 558 static void test_fputc( void ) 559 { 560 char* tempf; 561 FILE *tempfh; 562 int ret; 563 564 tempf=_tempnam(".","wne"); 565 tempfh = fopen(tempf,"wb"); 566 ret = fputc(0,tempfh); 567 ok(0 == ret, "fputc(0,tempfh) expected %x got %x\n", 0, ret); 568 ret = fputc(0xff,tempfh); 569 ok(0xff == ret, "fputc(0xff,tempfh) expected %x got %x\n", 0xff, ret); 570 ret = fputc(0xffffffff,tempfh); 571 ok(0xff == ret, "fputc(0xffffffff,tempfh) expected %x got %x\n", 0xff, ret); 572 fclose(tempfh); 573 574 tempfh = fopen(tempf,"rb"); 575 ret = fputc(0,tempfh); 576 ok(EOF == ret, "fputc(0,tempfh) on r/o file expected %x got %x\n", EOF, ret); 577 fclose(tempfh); 578 579 unlink(tempf); 580 free(tempf); 581 } 582 583 static void test_flsbuf( void ) 584 { 585 char* tempf; 586 FILE *tempfh; 587 int c; 588 int ret; 589 int bufmode; 590 static const int bufmodes[] = {_IOFBF,_IONBF}; 591 592 tempf=_tempnam(".","wne"); 593 for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++) 594 { 595 tempfh = fopen(tempf,"wb"); 596 setvbuf(tempfh,NULL,bufmodes[bufmode],2048); 597 ret = _flsbuf(0,tempfh); 598 ok(0 == ret, "_flsbuf(0,tempfh) with bufmode %x expected %x got %x\n", 599 bufmodes[bufmode], 0, ret); 600 ret = _flsbuf(0xff,tempfh); 601 ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got %x\n", 602 bufmodes[bufmode], 0xff, ret); 603 ret = _flsbuf(0xffffffff,tempfh); 604 ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got %x\n", 605 bufmodes[bufmode], 0xff, ret); 606 if(tempfh->_base) { 607 fputc('x', tempfh); 608 tempfh->_cnt = -1; 609 tempfh->_base[1] = 'a'; 610 ret = _flsbuf(0xab,tempfh); 611 ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got %x\n", 612 bufmodes[bufmode], ret); 613 ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be changed (%d)\n", 614 tempfh->_base[1]); 615 } 616 617 fclose(tempfh); 618 } 619 620 tempfh = fopen(tempf,"rb"); 621 ret = _flsbuf(0,tempfh); 622 ok(EOF == ret, "_flsbuf(0,tempfh) on r/o file expected %x got %x\n", EOF, ret); 623 fclose(tempfh); 624 625 /* See bug 17123, exposed by WinAVR's make */ 626 tempfh = fopen(tempf,"w"); 627 ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt); 628 setbuf(tempfh, NULL); 629 ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt); 630 ok(tempfh->_bufsiz == 2, "_bufsiz = %d\n", tempfh->_bufsiz); 631 /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */ 632 tempfh->_cnt = 1234; 633 ret = _flsbuf('Q',tempfh); 634 ok('Q' == ret, "_flsbuf('Q',tempfh) expected %x got %x\n", 'Q', ret); 635 /* ... and reset it to zero */ 636 ok(tempfh->_cnt == 0, "after unbuf _flsbuf, _cnt was %d\n", tempfh->_cnt); 637 fclose(tempfh); 638 /* And just for grins, make sure the file is correct */ 639 tempfh = fopen(tempf,"r"); 640 c = fgetc(tempfh); 641 ok(c == 'Q', "first byte should be 'Q'\n"); 642 c = fgetc(tempfh); 643 ok(c == EOF, "there should only be one byte\n"); 644 fclose(tempfh); 645 646 unlink(tempf); 647 free(tempf); 648 } 649 650 static void test_fflush( void ) 651 { 652 static const char obuf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 653 char buf1[16], buf2[24]; 654 char *tempf; 655 FILE *tempfh; 656 int ret; 657 658 tempf=_tempnam(".","wne"); 659 660 /* Prepare the file. */ 661 tempfh = fopen(tempf,"wb"); 662 ok(tempfh != NULL, "Can't open test file.\n"); 663 fwrite(obuf, 1, sizeof(obuf), tempfh); 664 fclose(tempfh); 665 666 /* Open the file for input. */ 667 tempfh = fopen(tempf,"rb"); 668 ok(tempfh != NULL, "Can't open test file.\n"); 669 fread(buf1, 1, sizeof(buf1), tempfh); 670 671 /* Using fflush() on input stream is undefined in ANSI. 672 * But MSDN says that it clears input buffer. */ 673 _lseek(_fileno(tempfh), 0, SEEK_SET); 674 ret = fflush(tempfh); 675 ok(ret == 0, "expected 0, got %d\n", ret); 676 memset(buf2, '?', sizeof(buf2)); 677 fread(buf2, 1, sizeof(buf2), tempfh); 678 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]); 679 680 /* fflush(NULL) doesn't clear input buffer. */ 681 _lseek(_fileno(tempfh), 0, SEEK_SET); 682 ret = fflush(NULL); 683 ok(ret == 0, "expected 0, got %d\n", ret); 684 memset(buf2, '?', sizeof(buf2)); 685 fread(buf2, 1, sizeof(buf2), tempfh); 686 ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n", buf2[0]); 687 688 /* _flushall() clears input buffer. */ 689 _lseek(_fileno(tempfh), 0, SEEK_SET); 690 ret = _flushall(); 691 ok(ret >= 0, "unexpected ret %d\n", ret); 692 memset(buf2, '?', sizeof(buf2)); 693 fread(buf2, 1, sizeof(buf2), tempfh); 694 ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]); 695 696 fclose(tempfh); 697 698 unlink(tempf); 699 free(tempf); 700 } 701 702 static void test_fgetwc( void ) 703 { 704 #define LLEN 512 705 706 char* tempf; 707 FILE *tempfh; 708 static const char mytext[]= "This is test_fgetwc\r\n"; 709 WCHAR wtextW[BUFSIZ+LLEN+1]; 710 WCHAR *mytextW = NULL, *aptr, *wptr; 711 BOOL diff_found = FALSE; 712 int j; 713 unsigned int i; 714 LONG l; 715 716 tempf=_tempnam(".","wne"); 717 tempfh = fopen(tempf,"wb"); 718 j = 'a'; 719 /* pad to almost the length of the internal buffer */ 720 for (i=0; i<BUFSIZ-4; i++) 721 fputc(j,tempfh); 722 j = '\r'; 723 fputc(j,tempfh); 724 j = '\n'; 725 fputc(j,tempfh); 726 fputs(mytext,tempfh); 727 fclose(tempfh); 728 /* in text mode, getws/c expects multibyte characters */ 729 /*currently Wine only supports plain ascii, and that is all that is tested here */ 730 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ 731 fgetws(wtextW,LLEN,tempfh); 732 l=ftell(tempfh); 733 ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l); 734 fgetws(wtextW,LLEN,tempfh); 735 l=ftell(tempfh); 736 ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlenA(mytext), l); 737 mytextW = AtoW (mytext); 738 aptr = mytextW; 739 wptr = wtextW; 740 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++) 741 { 742 diff_found |= (*aptr != *wptr); 743 } 744 ok(!(diff_found), "fgetwc difference found in TEXT mode\n"); 745 ok(*wptr == '\n', "Carriage return was not skipped\n"); 746 fclose(tempfh); 747 unlink(tempf); 748 749 tempfh = fopen(tempf,"wb"); 750 j = 'a'; 751 /* pad to almost the length of the internal buffer. Use an odd number of bytes 752 to test that we can read wchars that are split across the internal buffer 753 boundary */ 754 for (i=0; i<BUFSIZ-3-strlen(mytext)*sizeof(WCHAR); i++) 755 fputc(j,tempfh); 756 j = '\r'; 757 fputwc(j,tempfh); 758 j = '\n'; 759 fputwc(j,tempfh); 760 fputws(wtextW,tempfh); 761 fputws(wtextW,tempfh); 762 fclose(tempfh); 763 /* in binary mode, getws/c expects wide characters */ 764 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */ 765 j=(BUFSIZ-2)/sizeof(WCHAR)-strlen(mytext); 766 fgetws(wtextW,j,tempfh); 767 l=ftell(tempfh); 768 j=(j-1)*sizeof(WCHAR); 769 ok(l==j, "ftell expected %d got %d\n", j, l); 770 i=fgetc(tempfh); 771 ok(i=='a', "fgetc expected %d got %d\n", 0x61, i); 772 l=ftell(tempfh); 773 j++; 774 ok(l==j, "ftell expected %d got %d\n", j, l); 775 fgetws(wtextW,3,tempfh); 776 ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]); 777 ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]); 778 l=ftell(tempfh); 779 j += 4; 780 ok(l==j, "ftell expected %d got %d\n", j, l); 781 for(i=0; i<strlen(mytext); i++) 782 wtextW[i] = 0; 783 /* the first time we get the string, it should be entirely within the local buffer */ 784 fgetws(wtextW,LLEN,tempfh); 785 l=ftell(tempfh); 786 j += (strlen(mytext)-1)*sizeof(WCHAR); 787 ok(l==j, "ftell expected %d got %d\n", j, l); 788 diff_found = FALSE; 789 aptr = mytextW; 790 wptr = wtextW; 791 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++) 792 { 793 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr); 794 diff_found |= (*aptr != *wptr); 795 } 796 ok(!(diff_found), "fgetwc difference found in BINARY mode\n"); 797 ok(*wptr == '\n', "Should get newline\n"); 798 for(i=0; i<strlen(mytext); i++) 799 wtextW[i] = 0; 800 /* the second time we get the string, it should cross the local buffer boundary. 801 One of the wchars should be split across the boundary */ 802 fgetws(wtextW,LLEN,tempfh); 803 diff_found = FALSE; 804 aptr = mytextW; 805 wptr = wtextW; 806 for (i=0; i<strlen(mytext)-2; i++, aptr++, wptr++) 807 { 808 ok(*aptr == *wptr, "Char %d expected %04hx got %04hx\n", i, *aptr, *wptr); 809 diff_found |= (*aptr != *wptr); 810 } 811 ok(!(diff_found), "fgetwc difference found in BINARY mode\n"); 812 ok(*wptr == '\n', "Should get newline\n"); 813 814 free(mytextW); 815 fclose(tempfh); 816 unlink(tempf); 817 free(tempf); 818 } 819 820 static void test_fgetwc_locale(const char* text, const char* locale, int codepage) 821 { 822 char temppath[MAX_PATH], tempfile[MAX_PATH]; 823 FILE *tempfh; 824 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' }; 825 WCHAR wtextW[BUFSIZ]; 826 int ret = 0, i; 827 wint_t ch; 828 829 if (!setlocale(LC_CTYPE, locale)) 830 { 831 win_skip("%s locale not available\n", locale); 832 return; 833 } 834 835 GetTempPathA(MAX_PATH, temppath); 836 GetTempFileNameA(temppath, "", 0, tempfile); 837 838 tempfh = fopen(tempfile, "wb"); 839 ok(tempfh != NULL, "can't open tempfile\n"); 840 fwrite(text, 1, strlen(text), tempfh); 841 fclose(tempfh); 842 843 if (codepage != 0) 844 { 845 /* mbstowcs rejects invalid multibyte sequence, 846 so we use MultiByteToWideChar here. */ 847 ret = MultiByteToWideChar(codepage, 0, text, -1, 848 wtextW, sizeof(wtextW)/sizeof(wtextW[0])); 849 ok(ret > 0, "MultiByteToWideChar failed\n"); 850 } 851 else 852 { 853 /* C locale */ 854 const char *p; 855 for (p = text; *p != '\0'; p++) 856 wtextW[ret++] = (unsigned char)*p; 857 wtextW[ret++] = 0; 858 } 859 860 tempfh = fopen(tempfile, "rt"); 861 ok(tempfh != NULL, "can't open tempfile\n"); 862 863 for (i = 0; i < ret-1; i++) 864 { 865 ch = fgetwc(tempfh); 866 ok(ch == wtextW[i], "got %04hx, expected %04hx (cp%d[%d])\n", ch, wtextW[i], codepage, i); 867 } 868 ch = fgetwc(tempfh); 869 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage); 870 fclose(tempfh); 871 872 tempfh = fopen(tempfile, "wb"); 873 ok(tempfh != NULL, "can't open tempfile\n"); 874 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh); 875 fclose(tempfh); 876 877 tempfh = fopen(tempfile, "rb"); 878 ok(tempfh != NULL, "can't open tempfile\n"); 879 for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) 880 { 881 ch = fgetwc(tempfh); 882 ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i); 883 } 884 ch = fgetwc(tempfh); 885 ok(ch == WEOF, "got %04hx, expected WEOF (cp%d)\n", ch, codepage); 886 fclose(tempfh); 887 unlink(tempfile); 888 } 889 890 static void test_fgetwc_unicode(void) 891 { 892 char temppath[MAX_PATH], tempfile[MAX_PATH]; 893 FILE *tempfh; 894 static const WCHAR wchar_text[] = { 0xfeff, 0xff1f, '!' }; 895 char utf8_text[BUFSIZ]; 896 int ret, i; 897 wint_t ch; 898 899 GetTempPathA(MAX_PATH, temppath); 900 GetTempFileNameA(temppath, "", 0, tempfile); 901 902 if (!p_fopen_s) 903 { 904 win_skip("fopen_s not available\n"); 905 return; 906 } 907 908 tempfh = fopen(tempfile, "wb"); 909 ok(tempfh != NULL, "can't open tempfile\n"); 910 fwrite(wchar_text, 1, sizeof(wchar_text), tempfh); 911 fclose(tempfh); 912 913 tempfh = fopen(tempfile, "rt,ccs=unicode"); 914 ok(tempfh != NULL, "can't open tempfile\n"); 915 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) 916 { 917 ch = fgetwc(tempfh); 918 ok(ch == wchar_text[i], 919 "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1); 920 } 921 ch = fgetwc(tempfh); 922 ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); 923 fclose(tempfh); 924 925 tempfh = fopen(tempfile, "wb"); 926 ok(tempfh != NULL, "can't open tempfile\n"); 927 ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]), 928 utf8_text, sizeof(utf8_text), NULL, NULL); 929 ok(ret > 0, "utf-8 conversion failed\n"); 930 fwrite(utf8_text, sizeof(char), ret, tempfh); 931 fclose(tempfh); 932 933 tempfh = fopen(tempfile, "rt, ccs=UTF-8"); 934 ok(tempfh != NULL, "can't open tempfile\n"); 935 for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) 936 { 937 ch = fgetwc(tempfh); 938 ok(ch == wchar_text[i], 939 "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1); 940 } 941 ch = fgetwc(tempfh); 942 ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch); 943 fclose(tempfh); 944 unlink(temppath); 945 } 946 947 static void test_fputwc(void) 948 { 949 char temppath[MAX_PATH]; 950 char tempfile[MAX_PATH]; 951 FILE *f; 952 char buf[1024]; 953 int ret; 954 955 GetTempPathA(MAX_PATH, temppath); 956 GetTempFileNameA(temppath, "", 0, tempfile); 957 958 f = fopen(tempfile, "w"); 959 ret = fputwc('a', f); 960 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret); 961 ret = fputwc('\n', f); 962 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret); 963 fclose(f); 964 965 f = fopen(tempfile, "rb"); 966 ret = fread(buf, 1, sizeof(buf), f); 967 ok(ret == 3, "fread returned %d, expected 3\n", ret); 968 ok(!memcmp(buf, "a\r\n", 3), "incorrect file data\n"); 969 fclose(f); 970 971 if(p_fopen_s) { 972 f = fopen(tempfile, "w,ccs=unicode"); 973 ret = fputwc('a', f); 974 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret); 975 ret = fputwc('\n', f); 976 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret); 977 fclose(f); 978 979 f = fopen(tempfile, "rb"); 980 ret = fread(buf, 1, sizeof(buf), f); 981 ok(ret == 8, "fread returned %d, expected 8\n", ret); 982 ok(!memcmp(buf, "\xff\xfe\x61\x00\r\x00\n\x00", 8), "incorrect file data\n"); 983 fclose(f); 984 985 f = fopen(tempfile, "w,ccs=utf-8"); 986 ret = fputwc('a', f); 987 ok(ret == 'a', "fputwc returned %x, expected 'a'\n", ret); 988 ret = fputwc('\n', f); 989 ok(ret == '\n', "fputwc returned %x, expected '\\n'\n", ret); 990 fclose(f); 991 992 f = fopen(tempfile, "rb"); 993 ret = fread(buf, 1, sizeof(buf), f); 994 ok(ret == 6, "fread returned %d, expected 6\n", ret); 995 ok(!memcmp(buf, "\xef\xbb\xbf\x61\r\n", 6), "incorrect file data\n"); 996 fclose(f); 997 }else { 998 win_skip("fputwc tests on unicode files\n"); 999 } 1000 1001 _unlink(tempfile); 1002 } 1003 1004 static void test_ctrlz( void ) 1005 { 1006 char* tempf; 1007 FILE *tempfh; 1008 static const char mytext[]= "This is test_ctrlz"; 1009 char buffer[256]; 1010 int i, j; 1011 LONG l; 1012 1013 tempf=_tempnam(".","wne"); 1014 tempfh = fopen(tempf,"wb"); 1015 fputs(mytext,tempfh); 1016 j = 0x1a; /* a ctrl-z character signals EOF in text mode */ 1017 fputc(j,tempfh); 1018 j = '\r'; 1019 fputc(j,tempfh); 1020 j = '\n'; 1021 fputc(j,tempfh); 1022 j = 'a'; 1023 fputc(j,tempfh); 1024 fclose(tempfh); 1025 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ 1026 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); 1027 i=strlen(buffer); 1028 j=strlen(mytext); 1029 ok(i==j, "returned string length expected %d got %d\n", j, i); 1030 j+=4; /* ftell should indicate the true end of file */ 1031 l=ftell(tempfh); 1032 ok(l==j, "ftell expected %d got %d\n", j, l); 1033 ok(feof(tempfh), "did not get EOF\n"); 1034 fclose(tempfh); 1035 1036 tempfh = fopen(tempf,"rb"); /* open in BINARY mode */ 1037 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); 1038 i=strlen(buffer); 1039 j=strlen(mytext)+3; /* should get through newline */ 1040 ok(i==j, "returned string length expected %d got %d\n", j, i); 1041 l=ftell(tempfh); 1042 ok(l==j, "ftell expected %d got %d\n", j, l); 1043 ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); 1044 i=strlen(buffer); 1045 ok(i==1, "returned string length expected %d got %d\n", 1, i); 1046 ok(feof(tempfh), "did not get EOF\n"); 1047 fclose(tempfh); 1048 unlink(tempf); 1049 free(tempf); 1050 } 1051 1052 static void test_file_put_get( void ) 1053 { 1054 char* tempf; 1055 FILE *tempfh; 1056 static const char mytext[]= "This is a test_file_put_get\n"; 1057 static const char dostext[]= "This is a test_file_put_get\r\n"; 1058 char btext[LLEN]; 1059 WCHAR wtextW[LLEN+1]; 1060 WCHAR *mytextW = NULL, *aptr, *wptr; 1061 BOOL diff_found = FALSE; 1062 unsigned int i; 1063 1064 tempf=_tempnam(".","wne"); 1065 tempfh = fopen(tempf,"wt"); /* open in TEXT mode */ 1066 fputs(mytext,tempfh); 1067 fclose(tempfh); 1068 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */ 1069 fgets(btext,LLEN,tempfh); 1070 ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n"); 1071 ok( btext[strlen(mytext)-1] == '\r', "CR not written\n"); 1072 fclose(tempfh); 1073 tempfh = fopen(tempf,"wb"); /* open in BINARY mode */ 1074 fputs(dostext,tempfh); 1075 fclose(tempfh); 1076 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ 1077 fgets(btext,LLEN,tempfh); 1078 ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n"); 1079 fclose(tempfh); 1080 tempfh = fopen(tempf,"rb"); /* open in TEXT mode */ 1081 fgets(btext,LLEN,tempfh); 1082 ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n"); 1083 1084 fclose(tempfh); 1085 tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ 1086 fgetws(wtextW,LLEN,tempfh); 1087 mytextW = AtoW (mytext); 1088 aptr = mytextW; 1089 wptr = wtextW; 1090 1091 for (i=0; i<strlen(mytext); i++, aptr++, wptr++) 1092 { 1093 diff_found |= (*aptr != *wptr); 1094 } 1095 ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n"); 1096 free(mytextW); 1097 fclose(tempfh); 1098 unlink(tempf); 1099 free(tempf); 1100 } 1101 1102 static void test_file_write_read( void ) 1103 { 1104 char* tempf; 1105 int tempfd; 1106 static const char mytext[]= "This is test_file_write_read\nsecond line\n"; 1107 static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n"; 1108 char btext[LLEN]; 1109 int ret, i; 1110 1111 tempf=_tempnam(".","wne"); 1112 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, 1113 _S_IREAD | _S_IWRITE); 1114 ok( tempfd != -1, 1115 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */ 1116 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext), 1117 "_write _O_BINARY bad return value\n"); 1118 _close(tempfd); 1119 i = lstrlenA(mytext); 1120 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */ 1121 ok(_read(tempfd,btext,i) == i, 1122 "_read _O_BINARY got bad length\n"); 1123 ok( memcmp(dostext,btext,i) == 0, 1124 "problems with _O_BINARY _write / _read\n"); 1125 _close(tempfd); 1126 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1127 ok(_read(tempfd,btext,i) == i-1, 1128 "_read _O_TEXT got bad length\n"); 1129 ok( memcmp(mytext,btext,i-1) == 0, 1130 "problems with _O_BINARY _write / _O_TEXT _read\n"); 1131 _close(tempfd); 1132 tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR, 1133 _S_IREAD | _S_IWRITE); 1134 ok( tempfd != -1, 1135 "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */ 1136 ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext), 1137 "_write _O_TEXT bad return value\n"); 1138 _close(tempfd); 1139 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */ 1140 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext), 1141 "_read _O_BINARY got bad length\n"); 1142 ok( memcmp(dostext,btext,strlen(dostext)) == 0, 1143 "problems with _O_TEXT _write / _O_BINARY _read\n"); 1144 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n"); 1145 _close(tempfd); 1146 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1147 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), 1148 "_read _O_TEXT got bad length\n"); 1149 ok( memcmp(mytext,btext,strlen(mytext)) == 0, 1150 "problems with _O_TEXT _write / _read\n"); 1151 _close(tempfd); 1152 1153 memset(btext, 0, LLEN); 1154 tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */ 1155 ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd)); 1156 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n"); 1157 ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n"); 1158 _close(tempfd); 1159 1160 /* Test reading only \n or \r */ 1161 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1162 _lseek(tempfd, -1, FILE_END); 1163 ret = _read(tempfd,btext,LLEN); 1164 ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret); 1165 _lseek(tempfd, -2, FILE_END); 1166 ret = _read(tempfd,btext,LLEN); 1167 ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret); 1168 _lseek(tempfd, -2, FILE_END); 1169 ret = _read(tempfd,btext,1); 1170 ok(ret == 1 && *btext == '\n', "_read returned %d, buf: %d\n", ret, *btext); 1171 ret = read(tempfd,btext,1); 1172 ok(ret == 0, "_read returned %d, expected 0\n", ret); 1173 _lseek(tempfd, -3, FILE_END); 1174 ret = _read(tempfd,btext,1); 1175 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); 1176 ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd)); 1177 _lseek(tempfd, -3, FILE_END); 1178 ret = _read(tempfd,btext,2); 1179 ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); 1180 ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd)); 1181 _lseek(tempfd, -3, FILE_END); 1182 ret = _read(tempfd,btext,3); 1183 ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); 1184 ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd)); 1185 _close(tempfd); 1186 1187 ret = unlink(tempf); 1188 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); 1189 free(tempf); 1190 1191 tempf=_tempnam(".","wne"); 1192 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR, _S_IWRITE); 1193 ok( tempfd != -1, 1194 "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */ 1195 ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext), 1196 "_write _O_BINARY bad return value\n"); 1197 _close(tempfd); 1198 tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */ 1199 ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext), 1200 "_read _O_BINARY got bad length\n"); 1201 ok( memcmp(dostext,btext,strlen(dostext)) == 0, 1202 "problems with _O_BINARY _write / _read\n"); 1203 ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n"); 1204 _close(tempfd); 1205 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1206 ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), 1207 "_read _O_TEXT got bad length\n"); 1208 ok( memcmp(mytext,btext,strlen(mytext)) == 0, 1209 "problems with _O_BINARY _write / _O_TEXT _read\n"); 1210 _close(tempfd); 1211 1212 /* test _read with single bytes. CR should be skipped and LF pulled in */ 1213 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1214 for (i=0; i<strlen(mytext); i++) /* */ 1215 { 1216 _read(tempfd,btext, 1); 1217 ok(btext[0] == mytext[i],"_read failed at pos %d 0x%02x vs 0x%02x\n", i, btext[0], mytext[i]); 1218 } 1219 while (_read(tempfd,btext, 1)); 1220 _close(tempfd); 1221 1222 /* test _read in buffered mode. Last CR should be skipped but LF not pulled in */ 1223 tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */ 1224 i = _read(tempfd,btext, strlen(mytext)); 1225 ok(i == strlen(mytext)-1, "_read_i %d\n", i); 1226 _close(tempfd); 1227 1228 /* test read/write in unicode mode */ 1229 if(p_fopen_s) 1230 { 1231 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE); 1232 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1233 ret = _write(tempfd, "a", 1); 1234 ok(ret == -1, "_write returned %d, expected -1\n", ret); 1235 ret = _write(tempfd, "a\x00\n\x00\xff\xff", 6); 1236 ok(ret == 6, "_write returned %d, expected 6\n", ret); 1237 _close(tempfd); 1238 1239 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0); 1240 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1241 ret = _read(tempfd, btext, sizeof(btext)); 1242 ok(ret == 10, "_read returned %d, expected 10\n", ret); 1243 ok(!memcmp(btext, "\xff\xfe\x61\x00\r\x00\n\x00\xff\xff", 10), "btext is incorrect\n"); 1244 _close(tempfd); 1245 1246 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0); 1247 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1248 errno = 0xdeadbeef; 1249 ret = _read(tempfd, btext, 3); 1250 ok(ret == -1, "_read returned %d, expected -1\n", ret); 1251 ok(errno == 22, "errno = %d\n", errno); 1252 ret = _read(tempfd, btext, sizeof(btext)); 1253 ok(ret == 6, "_read returned %d, expected 6\n", ret); 1254 ok(!memcmp(btext, "\x61\x00\n\x00\xff\xff", 6), "btext is incorrect\n"); 1255 _close(tempfd); 1256 1257 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_U8TEXT, _S_IWRITE); 1258 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1259 errno = 0xdeadbeef; 1260 ret = _write(tempfd, "a", 1); 1261 ok(ret == -1, "_write returned %d, expected -1\n", ret); 1262 ok(errno == 22, "errno = %d\n", errno); 1263 ret = _write(tempfd, "a\x00\n\x00\x62\x00", 6); 1264 ok(ret == 6, "_write returned %d, expected 6\n", ret); 1265 _close(tempfd); 1266 1267 tempfd = _open(tempf, _O_RDONLY|_O_BINARY, 0); 1268 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1269 ret = _read(tempfd, btext, sizeof(btext)); 1270 ok(ret == 7, "_read returned %d, expected 7\n", ret); 1271 ok(!memcmp(btext, "\xef\xbb\xbf\x61\r\n\x62", 7), "btext is incorrect\n"); 1272 _close(tempfd); 1273 1274 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0); 1275 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1276 ret = _read(tempfd, btext, sizeof(btext)); 1277 ok(ret == 6, "_read returned %d, expected 6\n", ret); 1278 ok(!memcmp(btext, "\x61\x00\n\x00\x62\x00", 6), "btext is incorrect\n"); 1279 1280 /* when buffer is small read sometimes fails in native implementation */ 1281 lseek(tempfd, 3 /* skip bom */, SEEK_SET); 1282 ret = _read(tempfd, btext, 4); 1283 todo_wine ok(ret == -1, "_read returned %d, expected -1\n", ret); 1284 1285 lseek(tempfd, 6, SEEK_SET); 1286 ret = _read(tempfd, btext, 2); 1287 ok(ret == 2, "_read returned %d, expected 2\n", ret); 1288 ok(!memcmp(btext, "\x62\x00", 2), "btext is incorrect\n"); 1289 _close(tempfd); 1290 1291 tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IWRITE); 1292 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1293 ret = _write(tempfd, "\xef\xbb\xbf\x61\xc4\x85\x62\xc5\xbc\r\r\n", 12); 1294 ok(ret == 12, "_write returned %d, expected 9\n", ret); 1295 _close(tempfd); 1296 1297 tempfd = _open(tempf, _O_RDONLY|_O_WTEXT, 0); 1298 ok(tempfd != -1, "_open failed with error: %d\n", errno); 1299 ret = _read(tempfd, btext, sizeof(btext)); 1300 ok(ret == 12, "_read returned %d, expected 12\n", ret); 1301 ok(!memcmp(btext, "\x61\x00\x05\x01\x62\x00\x7c\x01\x0d\x00\x0a\x00", 12), "btext is incorrect\n"); 1302 1303 /* test invalid utf8 sequence */ 1304 lseek(tempfd, 5, SEEK_SET); 1305 ret = _read(tempfd, btext, sizeof(btext)); 1306 todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret); 1307 /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */ 1308 todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n"); 1309 ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n"); 1310 _close(tempfd); 1311 } 1312 else 1313 { 1314 win_skip("unicode mode tests on file\n"); 1315 } 1316 1317 ret =_chmod (tempf, _S_IREAD | _S_IWRITE); 1318 ok( ret == 0, 1319 "Can't chmod '%s' to read-write: %d\n", tempf, errno); 1320 ret = unlink(tempf); 1321 ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); 1322 free(tempf); 1323 } 1324 1325 static void test_file_inherit_child(const char* fd_s) 1326 { 1327 int fd = atoi(fd_s); 1328 char buffer[32]; 1329 int ret; 1330 1331 ret =write(fd, "Success", 8); 1332 ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno)); 1333 lseek(fd, 0, SEEK_SET); 1334 ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n"); 1335 ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); 1336 } 1337 1338 static void test_file_inherit_child_no(const char* fd_s) 1339 { 1340 int fd = atoi(fd_s); 1341 int ret; 1342 1343 ret = write(fd, "Success", 8); 1344 ok( ret == -1 && errno == EBADF, 1345 "Wrong write result in child process on %d (%s)\n", fd, strerror(errno)); 1346 } 1347 1348 static void create_io_inherit_block( STARTUPINFOA *startup, unsigned int count, const HANDLE *handles ) 1349 { 1350 static BYTE block[1024]; 1351 BYTE *wxflag_ptr; 1352 HANDLE *handle_ptr; 1353 unsigned int i; 1354 1355 startup->lpReserved2 = block; 1356 startup->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * count; 1357 wxflag_ptr = block + sizeof(unsigned); 1358 handle_ptr = (HANDLE *)(wxflag_ptr + count); 1359 1360 *(unsigned*)block = count; 1361 for (i = 0; i < count; i++) 1362 { 1363 wxflag_ptr[i] = 0x81; 1364 handle_ptr[i] = handles[i]; 1365 } 1366 } 1367 1368 static const char *read_file( HANDLE file ) 1369 { 1370 static char buffer[128]; 1371 DWORD ret; 1372 SetFilePointer( file, 0, NULL, FILE_BEGIN ); 1373 if (!ReadFile( file, buffer, sizeof(buffer) - 1, &ret, NULL)) ret = 0; 1374 buffer[ret] = 0; 1375 return buffer; 1376 } 1377 1378 static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hstdout, BOOL expect_stdout, 1379 const char *descr ) 1380 { 1381 const char *data; 1382 HANDLE hErrorFile; 1383 SECURITY_ATTRIBUTES sa; 1384 PROCESS_INFORMATION proc; 1385 1386 /* make file handle inheritable */ 1387 sa.nLength = sizeof(sa); 1388 sa.lpSecurityDescriptor = NULL; 1389 sa.bInheritHandle = TRUE; 1390 1391 hErrorFile = CreateFileA( "fdopen.err", GENERIC_READ|GENERIC_WRITE, 1392 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL ); 1393 startup->dwFlags = STARTF_USESTDHANDLES; 1394 startup->hStdInput = GetStdHandle( STD_INPUT_HANDLE ); 1395 startup->hStdOutput = hErrorFile; 1396 startup->hStdError = GetStdHandle( STD_ERROR_HANDLE ); 1397 1398 CreateProcessA( NULL, cmdline, NULL, NULL, TRUE, 1399 CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc ); 1400 winetest_wait_child_process( proc.hProcess ); 1401 1402 data = read_file( hErrorFile ); 1403 if (expect_stdout) 1404 ok( strcmp( data, "Success" ), "%s: Error file shouldn't contain data\n", descr ); 1405 else 1406 ok( !strcmp( data, "Success" ), "%s: Wrong error data (%s)\n", descr, data ); 1407 1408 if (hstdout) 1409 { 1410 data = read_file( hstdout ); 1411 if (expect_stdout) 1412 ok( !strcmp( data, "Success" ), "%s: Wrong stdout data (%s)\n", descr, data ); 1413 else 1414 ok( strcmp( data, "Success" ), "%s: Stdout file shouldn't contain data\n", descr ); 1415 } 1416 1417 CloseHandle( hErrorFile ); 1418 DeleteFileA( "fdopen.err" ); 1419 } 1420 1421 static void test_file_inherit( const char* selfname ) 1422 { 1423 int fd; 1424 const char* arg_v[5]; 1425 char buffer[16]; 1426 char cmdline[MAX_PATH]; 1427 STARTUPINFOA startup; 1428 SECURITY_ATTRIBUTES sa; 1429 HANDLE handles[3]; 1430 1431 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE); 1432 ok(fd != -1, "Couldn't create test file\n"); 1433 arg_v[0] = get_base_name(selfname); 1434 arg_v[1] = "tests/file.c"; 1435 arg_v[2] = "inherit"; 1436 arg_v[3] = buffer; sprintf(buffer, "%d", fd); 1437 arg_v[4] = 0; 1438 _spawnvp(_P_WAIT, selfname, arg_v); 1439 ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd)); 1440 lseek(fd, 0, SEEK_SET); 1441 ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); 1442 close (fd); 1443 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); 1444 1445 fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE); 1446 ok(fd != -1, "Couldn't create test file\n"); 1447 arg_v[1] = "tests/file.c"; 1448 arg_v[2] = "inherit_no"; 1449 arg_v[3] = buffer; sprintf(buffer, "%d", fd); 1450 arg_v[4] = 0; 1451 _spawnvp(_P_WAIT, selfname, arg_v); 1452 ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd)); 1453 ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer); 1454 close (fd); 1455 ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); 1456 1457 /* make file handle inheritable */ 1458 sa.nLength = sizeof(sa); 1459 sa.lpSecurityDescriptor = NULL; 1460 sa.bInheritHandle = TRUE; 1461 sprintf(cmdline, "%s file inherit 1", selfname); 1462 1463 /* init an empty Reserved2, which should not be recognized as inherit-block */ 1464 ZeroMemory(&startup, sizeof(startup)); 1465 startup.cb = sizeof(startup); 1466 create_io_inherit_block( &startup, 0, NULL ); 1467 test_stdout_handle( &startup, cmdline, 0, FALSE, "empty block" ); 1468 1469 /* test with valid inheritblock */ 1470 handles[0] = GetStdHandle( STD_INPUT_HANDLE ); 1471 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE, 1472 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL ); 1473 handles[2] = GetStdHandle( STD_ERROR_HANDLE ); 1474 create_io_inherit_block( &startup, 3, handles ); 1475 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "valid block" ); 1476 CloseHandle( handles[1] ); 1477 DeleteFileA("fdopen.tst"); 1478 1479 /* test inherit block starting with unsigned zero */ 1480 handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE, 1481 FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL ); 1482 create_io_inherit_block( &startup, 3, handles ); 1483 *(unsigned int *)startup.lpReserved2 = 0; 1484 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "zero count block" ); 1485 CloseHandle( handles[1] ); 1486 DeleteFileA("fdopen.tst"); 1487 1488 /* test inherit block with smaller size */ 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 startup.cbReserved2 -= 3; 1493 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "small size block" ); 1494 CloseHandle( handles[1] ); 1495 DeleteFileA("fdopen.tst"); 1496 1497 /* test inherit block with even 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 = sizeof(unsigned int) + sizeof(HANDLE) + sizeof(char); 1502 test_stdout_handle( &startup, cmdline, handles[1], FALSE, "smaller size block" ); 1503 CloseHandle( handles[1] ); 1504 DeleteFileA("fdopen.tst"); 1505 1506 /* test inherit block with larger 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 += 7; 1511 test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" ); 1512 CloseHandle( handles[1] ); 1513 DeleteFileA("fdopen.tst"); 1514 } 1515 1516 static void test_tmpnam( void ) 1517 { 1518 char name[MAX_PATH] = "abc"; 1519 char *res; 1520 1521 res = tmpnam(NULL); 1522 ok(res != NULL, "tmpnam returned NULL\n"); 1523 ok(res[0] == '\\', "first character is not a backslash\n"); 1524 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n"); 1525 ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n"); 1526 1527 res = tmpnam(name); 1528 ok(res != NULL, "tmpnam returned NULL\n"); 1529 ok(res == name, "supplied buffer was not used\n"); 1530 ok(res[0] == '\\', "first character is not a backslash\n"); 1531 ok(strchr(res+1, '\\') == 0, "file not in the root directory\n"); 1532 ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n"); 1533 } 1534 1535 static void test_chsize( void ) 1536 { 1537 int fd; 1538 LONG cur, pos, count; 1539 char temptext[] = "012345678"; 1540 char *tempfile = _tempnam( ".", "tst" ); 1541 1542 ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile ); 1543 1544 fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE ); 1545 ok( fd > 0, "Couldn't open test file\n" ); 1546 1547 count = _write( fd, temptext, sizeof(temptext) ); 1548 ok( count > 0, "Couldn't write to test file\n" ); 1549 1550 /* get current file pointer */ 1551 cur = _lseek( fd, 0, SEEK_CUR ); 1552 1553 /* make the file smaller */ 1554 ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" ); 1555 1556 pos = _lseek( fd, 0, SEEK_CUR ); 1557 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); 1558 ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" ); 1559 1560 /* enlarge the file */ 1561 ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); 1562 1563 pos = _lseek( fd, 0, SEEK_CUR ); 1564 ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); 1565 ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" ); 1566 1567 _close( fd ); 1568 _unlink( tempfile ); 1569 free( tempfile ); 1570 } 1571 1572 static void test_fopen_fclose_fcloseall( void ) 1573 { 1574 char fname1[] = "empty1"; 1575 char fname2[] = "empty2"; 1576 char fname3[] = "empty3"; 1577 FILE *stream1, *stream2, *stream3, *stream4; 1578 int ret, numclosed; 1579 1580 /* testing fopen() */ 1581 stream1 = fopen(fname1, "w+"); 1582 ok(stream1 != NULL, "The file '%s' was not opened\n", fname1); 1583 stream2 = fopen(fname2, "w "); 1584 ok(stream2 != NULL, "The file '%s' was not opened\n", fname2 ); 1585 _unlink(fname3); 1586 stream3 = fopen(fname3, "r"); 1587 ok(stream3 == NULL, "The file '%s' shouldn't exist before\n", fname3 ); 1588 stream3 = fopen(fname3, "w+"); 1589 ok(stream3 != NULL, "The file '%s' should be opened now\n", fname3 ); 1590 errno = 0xfaceabad; 1591 stream4 = fopen("", "w+"); 1592 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), 1593 "filename is empty, errno = %d (expected 2 or 22)\n", errno); 1594 errno = 0xfaceabad; 1595 stream4 = fopen(NULL, "w+"); 1596 ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), 1597 "filename is NULL, errno = %d (expected 2 or 22)\n", errno); 1598 1599 /* testing fclose() */ 1600 ret = fclose(stream2); 1601 ok(ret == 0, "The file '%s' was not closed\n", fname2); 1602 ret = fclose(stream3); 1603 ok(ret == 0, "The file '%s' was not closed\n", fname3); 1604 ret = fclose(stream2); 1605 ok(ret == EOF, "Closing file '%s' returned %d\n", fname2, ret); 1606 ret = fclose(stream3); 1607 ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret); 1608 1609 /* testing fcloseall() */ 1610 numclosed = _fcloseall(); 1611 /* fname1 should be closed here */ 1612 ok(numclosed == 1, "Number of files closed by fcloseall(): %u\n", numclosed); 1613 numclosed = _fcloseall(); 1614 ok(numclosed == 0, "Number of files closed by fcloseall(): %u\n", numclosed); 1615 1616 ok(_unlink(fname1) == 0, "Couldn't unlink file named '%s'\n", fname1); 1617 ok(_unlink(fname2) == 0, "Couldn't unlink file named '%s'\n", fname2); 1618 ok(_unlink(fname3) == 0, "Couldn't unlink file named '%s'\n", fname3); 1619 } 1620 1621 static void test_fopen_s( void ) 1622 { 1623 const char name[] = "empty1"; 1624 char buff[16]; 1625 unsigned char *ubuff = (unsigned char*)buff; 1626 FILE *file, *file2; 1627 int ret; 1628 int len; 1629 1630 if (!p_fopen_s) 1631 { 1632 win_skip("Skipping fopen_s test\n"); 1633 return; 1634 } 1635 /* testing fopen_s */ 1636 ret = p_fopen_s(&file, name, "w"); 1637 ok(ret == 0, "fopen_s failed with %d\n", ret); 1638 ok(file != 0, "fopen_s failed to return value\n"); 1639 fwrite(name, sizeof(name), 1, file); 1640 1641 ret = fclose(file); 1642 ok(ret != EOF, "File failed to close\n"); 1643 1644 file = fopen(name, "r"); 1645 ok(file != 0, "fopen failed\n"); 1646 len = fread(buff, 1, sizeof(name), file); 1647 ok(len == sizeof(name), "File length is %d\n", len); 1648 buff[sizeof(name)] = '\0'; 1649 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name); 1650 1651 ret = fclose(file); 1652 ok(ret != EOF, "File failed to close\n"); 1653 1654 ret = p_fopen_s(&file, name, "w, ccs=UNIcode"); 1655 ok(ret == 0, "fopen_s failed with %d\n", ret); 1656 ret = fwrite("a", 1, 2, file); 1657 ok(ret == 2, "fwrite returned %d\n", ret); 1658 fclose(file); 1659 1660 ret = p_fopen_s(&file, name, "r"); 1661 ok(ret == 0, "fopen_s failed with %d\n", ret); 1662 len = fread(buff, 1, 2, file); 1663 ok(len == 2, "len = %d\n", len); 1664 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n", 1665 ubuff[0], ubuff[1]); 1666 fclose(file); 1667 1668 ret = p_fopen_s(&file, name, "r,ccs=unicode"); 1669 ok(ret == 0, "fopen_s failed with %d\n", ret); 1670 len = fread(buff, 1, 2, file); 1671 ok(len == 2, "len = %d\n", len); 1672 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n", 1673 ubuff[0], ubuff[1]); 1674 fclose(file); 1675 1676 ret = p_fopen_s(&file, name, "r,ccs=utf-16le"); 1677 ok(ret == 0, "fopen_s failed with %d\n", ret); 1678 len = fread(buff, 1, 2, file); 1679 ok(len == 2, "len = %d\n", len); 1680 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n", 1681 ubuff[0], ubuff[1]); 1682 fclose(file); 1683 1684 ret = p_fopen_s(&file, name, "r,ccs=utf-8"); 1685 ok(ret == 0, "fopen_s failed with %d\n", ret); 1686 len = fread(buff, 1, 2, file); 1687 ok(len == 2, "len = %d\n", len); 1688 ok(ubuff[0]=='a' && ubuff[1]==0, "buff[0]=%02x, buff[1]=%02x\n", 1689 ubuff[0], ubuff[1]); 1690 fclose(file); 1691 1692 ret = p_fopen_s(&file, name, "w,ccs=utf-16le"); 1693 ok(ret == 0, "fopen_s failed with %d\n", ret); 1694 fclose(file); 1695 1696 ret = p_fopen_s(&file, name, "r"); 1697 ok(ret == 0, "fopen_s failed with %d\n", ret); 1698 len = fread(buff, 1, 3, file); 1699 ok(len == 2, "len = %d\n", len); 1700 ok(ubuff[0]==0xff && ubuff[1]==0xfe, "buff[0]=%02x, buff[1]=%02x\n", 1701 ubuff[0], ubuff[1]); 1702 fclose(file); 1703 1704 ret = p_fopen_s(&file, name, "w,ccs=utf-8"); 1705 ok(ret == 0, "fopen_s failed with %d\n", ret); 1706 fclose(file); 1707 1708 ret = p_fopen_s(&file, name, "r"); 1709 ok(ret == 0, "fopen_s failed with %d\n", ret); 1710 len = fread(buff, 1, 4, file); 1711 ok(len == 3, "len = %d\n", len); 1712 ok(ubuff[0]==0xef && ubuff[1]==0xbb && ubuff[2]==0xbf, 1713 "buff[0]=%02x, buff[1]=%02x, buff[2]=%02x\n", 1714 ubuff[0], ubuff[1], ubuff[2]); 1715 fclose(file); 1716 1717 /* test initial FILE values */ 1718 memset(file, 0xfe, sizeof(*file)); 1719 file->_flag = 0; 1720 ret = p_fopen_s(&file2, name, "r"); 1721 ok(!ret, "fopen_s failed with %d\n", ret); 1722 ok(file == file2, "file != file2 %p %p\n", file, file2); 1723 ok(!file->_ptr, "file->_ptr != NULL\n"); 1724 ok(!file->_cnt, "file->_cnt != 0\n"); 1725 ok(!file->_base, "file->_base != NULL\n"); 1726 ok(file->_flag == 1, "file->_flag = %x\n", file->_flag); 1727 ok(file->_file, "file->_file == 0\n"); 1728 ok(file->_charbuf == 0xfefefefe, "file->_charbuf = %x\n", file->_charbuf); 1729 ok(file->_bufsiz == 0xfefefefe, "file->_bufsiz = %x\n", file->_bufsiz); 1730 ok(!file->_tmpfname, "file->_tmpfname != NULL\n"); 1731 fclose(file2); 1732 1733 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name); 1734 } 1735 1736 static void test__wfopen_s( void ) 1737 { 1738 const char name[] = "empty1"; 1739 const WCHAR wname[] = { 1740 'e','m','p','t','y','1',0 1741 }; 1742 const WCHAR wmode[] = { 1743 'w',0 1744 }; 1745 char buff[16]; 1746 FILE *file; 1747 int ret; 1748 int len; 1749 1750 if (!p__wfopen_s) 1751 { 1752 win_skip("Skipping _wfopen_s test\n"); 1753 return; 1754 } 1755 /* testing _wfopen_s */ 1756 ret = p__wfopen_s(&file, wname, wmode); 1757 ok(ret == 0, "_wfopen_s failed with %d\n", ret); 1758 ok(file != 0, "_wfopen_s failed to return value\n"); 1759 fwrite(name, sizeof(name), 1, file); 1760 1761 ret = fclose(file); 1762 ok(ret != EOF, "File failed to close\n"); 1763 1764 file = fopen(name, "r"); 1765 ok(file != 0, "fopen failed\n"); 1766 len = fread(buff, 1, sizeof(name), file); 1767 ok(len == sizeof(name), "File length is %d\n", len); 1768 buff[sizeof(name)] = '\0'; 1769 ok(strcmp(name, buff) == 0, "File content mismatch! Got %s, expected %s\n", buff, name); 1770 1771 ret = fclose(file); 1772 ok(ret != EOF, "File failed to close\n"); 1773 1774 ok(_unlink(name) == 0, "Couldn't unlink file named '%s'\n", name); 1775 } 1776 1777 static void test_setmode(void) 1778 { 1779 const char name[] = "empty1"; 1780 int fd, ret; 1781 1782 if(!p_fopen_s) { 1783 win_skip("unicode file modes are not available, skipping setmode tests\n"); 1784 return; 1785 } 1786 1787 errno = 0xdeadbeef; 1788 ret = _setmode(-2, 0); 1789 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1790 ok(errno == EINVAL, "errno = %d\n", errno); 1791 1792 errno = 0xdeadbeef; 1793 ret = _setmode(-2, _O_TEXT); 1794 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1795 ok(errno == EBADF, "errno = %d\n", errno); 1796 1797 fd = _open(name, _O_CREAT|_O_WRONLY, _S_IWRITE); 1798 ok(fd != -1, "failed to open file\n"); 1799 1800 errno = 0xdeadbeef; 1801 ret = _setmode(fd, 0xffffffff); 1802 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1803 ok(errno == EINVAL, "errno = %d\n", errno); 1804 1805 errno = 0xdeadbeef; 1806 ret = _setmode(fd, 0); 1807 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1808 ok(errno == EINVAL, "errno = %d\n", errno); 1809 1810 errno = 0xdeadbeef; 1811 ret = _setmode(fd, _O_BINARY|_O_TEXT); 1812 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1813 ok(errno == EINVAL, "errno = %d\n", errno); 1814 1815 errno = 0xdeadbeef; 1816 ret = _setmode(fd, _O_WTEXT|_O_U16TEXT); 1817 ok(ret == -1, "_setmode returned %x, expected -1\n", ret); 1818 ok(errno == EINVAL, "errno = %d\n", errno); 1819 1820 ret = _setmode(fd, _O_BINARY); 1821 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret); 1822 1823 ret = _setmode(fd, _O_WTEXT); 1824 ok(ret == _O_BINARY, "_setmode returned %x, expected _O_BINARY\n", ret); 1825 1826 ret = _setmode(fd, _O_TEXT); 1827 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret); 1828 1829 ret = _setmode(fd, _O_U16TEXT); 1830 ok(ret == _O_TEXT, "_setmode returned %x, expected _O_TEXT\n", ret); 1831 1832 ret = _setmode(fd, _O_U8TEXT); 1833 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret); 1834 1835 ret = _setmode(fd, _O_TEXT); 1836 ok(ret == _O_WTEXT, "_setmode returned %x, expected _O_WTEXT\n", ret); 1837 1838 _close(fd); 1839 _unlink(name); 1840 } 1841 1842 static void test_get_osfhandle(void) 1843 { 1844 int fd; 1845 char fname[] = "t_get_osfhanle"; 1846 DWORD bytes_written; 1847 HANDLE handle; 1848 1849 fd = _sopen(fname, _O_CREAT|_O_RDWR, _SH_DENYRW, _S_IREAD | _S_IWRITE); 1850 handle = (HANDLE)_get_osfhandle(fd); 1851 WriteFile(handle, "bar", 3, &bytes_written, NULL); 1852 _close(fd); 1853 fd = _open(fname, _O_RDONLY, 0); 1854 ok(fd != -1, "Couldn't open '%s' after _get_osfhandle()\n", fname); 1855 1856 _close(fd); 1857 _unlink(fname); 1858 1859 errno = 0xdeadbeef; 1860 handle = (HANDLE)_get_osfhandle(fd); 1861 ok(handle == INVALID_HANDLE_VALUE, "_get_osfhandle returned %p\n", handle); 1862 ok(errno == EBADF, "errno = %d\n", errno); 1863 } 1864 1865 static void test_setmaxstdio(void) 1866 { 1867 ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048)); 1868 ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049)); 1869 } 1870 1871 static void test_stat(void) 1872 { 1873 int fd; 1874 int pipes[2]; 1875 int ret; 1876 struct stat buf; 1877 1878 /* Tests for a file */ 1879 fd = open("stat.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); 1880 if (fd >= 0) 1881 { 1882 ret = fstat(fd, &buf); 1883 ok(!ret, "fstat failed: errno=%d\n", errno); 1884 ok((buf.st_mode & _S_IFMT) == _S_IFREG, "bad format = %06o\n", buf.st_mode); 1885 ok((buf.st_mode & 0777) == 0666, "bad st_mode = %06o\n", buf.st_mode); 1886 ok(buf.st_dev == 0, "st_dev is %d, expected 0\n", buf.st_dev); 1887 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev); 1888 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink); 1889 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size); 1890 1891 ret = stat("stat.tst", &buf); 1892 ok(!ret, "stat 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 == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev); 1896 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink); 1897 ok(buf.st_size == 0, "st_size is %d, expected 0\n", buf.st_size); 1898 1899 errno = 0xdeadbeef; 1900 ret = stat("stat.tst\\", &buf); 1901 ok(ret == -1, "stat returned %d\n", ret); 1902 ok(errno == ENOENT, "errno = %d\n", errno); 1903 1904 close(fd); 1905 remove("stat.tst"); 1906 } 1907 else 1908 skip("open failed with errno %d\n", errno); 1909 1910 /* Tests for a char device */ 1911 if (_dup2(0, 10) == 0) 1912 { 1913 ret = fstat(10, &buf); 1914 ok(!ret, "fstat(stdin) failed: errno=%d\n", errno); 1915 if ((buf.st_mode & _S_IFMT) == _S_IFCHR) 1916 { 1917 ok(buf.st_mode == _S_IFCHR, "bad st_mode=%06o\n", buf.st_mode); 1918 ok(buf.st_dev == 10, "st_dev is %d, expected 10\n", buf.st_dev); 1919 ok(buf.st_rdev == 10, "st_rdev is %d, expected 10\n", buf.st_rdev); 1920 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink); 1921 } 1922 else 1923 skip("stdin is not a char device? st_mode=%06o\n", buf.st_mode); 1924 close(10); 1925 } 1926 else 1927 skip("_dup2 failed with errno %d\n", errno); 1928 1929 /* Tests for pipes */ 1930 if (_pipe(pipes, 1024, O_BINARY) == 0) 1931 { 1932 ret = fstat(pipes[0], &buf); 1933 ok(!ret, "fstat(pipe) failed: errno=%d\n", errno); 1934 ok(buf.st_mode == _S_IFIFO, "bad st_mode=%06o\n", buf.st_mode); 1935 ok(buf.st_dev == pipes[0], "st_dev is %d, expected %d\n", buf.st_dev, pipes[0]); 1936 ok(buf.st_rdev == pipes[0], "st_rdev is %d, expected %d\n", buf.st_rdev, pipes[0]); 1937 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink); 1938 close(pipes[0]); 1939 close(pipes[1]); 1940 } 1941 else 1942 skip("pipe failed with errno %d\n", errno); 1943 1944 /* Tests for directory */ 1945 if(mkdir("stat.tst") == 0) 1946 { 1947 ret = stat("stat.tst ", &buf); 1948 ok(!ret, "stat(directory) failed: errno=%d\n", errno); 1949 ok((buf.st_mode & _S_IFMT) == _S_IFDIR, "bad format = %06o\n", buf.st_mode); 1950 ok((buf.st_mode & 0777) == 0777, "bad st_mode = %06o\n", buf.st_mode); 1951 ok(buf.st_dev == buf.st_rdev, "st_dev (%d) and st_rdev (%d) differ\n", buf.st_dev, buf.st_rdev); 1952 ok(buf.st_nlink == 1, "st_nlink is %d, expected 1\n", buf.st_nlink); 1953 1954 errno = 0xdeadbeef; 1955 ret = stat("stat.tst\\ ", &buf); 1956 ok(ret == -1, "stat returned %d\n", ret); 1957 ok(errno == ENOENT, "errno = %d\n", errno); 1958 rmdir( "stat.tst" ); 1959 } 1960 else 1961 skip("mkdir failed with errno %d\n", errno); 1962 1963 errno = 0xdeadbeef; 1964 ret = stat("c:", &buf); 1965 ok(ret == -1, "stat returned %d\n", ret); 1966 ok(errno == ENOENT, "errno = %d\n", errno); 1967 1968 ret = stat("c:/", &buf); 1969 ok(!ret, "stat returned %d\n", ret); 1970 ok(buf.st_dev == 2, "st_dev = %d\n", buf.st_dev); 1971 ok(buf.st_rdev == 2, "st_rdev = %d\n", buf.st_rdev); 1972 } 1973 1974 static const char* pipe_string="Hello world"; 1975 1976 /* How many messages to transfer over the pipe */ 1977 #define N_TEST_MESSAGES 3 1978 1979 static void test_pipes_child(int argc, char** args) 1980 { 1981 int fd; 1982 int nwritten; 1983 int i; 1984 1985 if (argc < 5) 1986 { 1987 ok(0, "not enough parameters: %d\n", argc); 1988 return; 1989 } 1990 1991 fd=atoi(args[3]); 1992 i=close(fd); 1993 ok(!i, "unable to close %d: %d\n", fd, errno); 1994 1995 fd=atoi(args[4]); 1996 1997 for (i=0; i<N_TEST_MESSAGES; i++) { 1998 nwritten=write(fd, pipe_string, strlen(pipe_string)); 1999 ok(nwritten == strlen(pipe_string), "i %d, expected to write '%s' wrote %d\n", i, pipe_string, nwritten); 2000 /* let other process wake up so they can show off their "keep reading until EOF" behavior */ 2001 if (i < N_TEST_MESSAGES-1) 2002 Sleep(100); 2003 } 2004 2005 i=close(fd); 2006 ok(!i, "unable to close %d: %d\n", fd, errno); 2007 } 2008 2009 static void test_pipes(const char* selfname) 2010 { 2011 int pipes[2]; 2012 char str_fdr[12], str_fdw[12]; 2013 FILE* file; 2014 const char* arg_v[6]; 2015 char buf[4096]; 2016 char expected[4096]; 2017 int r; 2018 int i; 2019 2020 /* Test reading from a pipe with read() */ 2021 if (_pipe(pipes, 1024, O_BINARY) < 0) 2022 { 2023 ok(0, "pipe failed with errno %d\n", errno); 2024 return; 2025 } 2026 2027 arg_v[0] = get_base_name(selfname); 2028 arg_v[1] = "tests/file.c"; 2029 arg_v[2] = "pipes"; 2030 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); 2031 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); 2032 arg_v[5] = NULL; 2033 proc_handles[0] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v); 2034 i=close(pipes[1]); 2035 ok(!i, "unable to close %d: %d\n", pipes[1], errno); 2036 2037 for (i=0; i<N_TEST_MESSAGES; i++) { 2038 r=read(pipes[0], buf, sizeof(buf)-1); 2039 ok(r == strlen(pipe_string), "i %d, got %d\n", i, r); 2040 if (r > 0) 2041 buf[r]='\0'; 2042 ok(strcmp(buf, pipe_string) == 0, "expected to read '%s', got '%s'\n", pipe_string, buf); 2043 } 2044 2045 r=read(pipes[0], buf, sizeof(buf)-1); 2046 ok(r == 0, "expected to read 0 bytes, got %d\n", r); 2047 i=close(pipes[0]); 2048 ok(!i, "unable to close %d: %d\n", pipes[0], errno); 2049 2050 /* Test reading from a pipe with fread() */ 2051 if (_pipe(pipes, 1024, O_BINARY) < 0) 2052 { 2053 ok(0, "pipe failed with errno %d\n", errno); 2054 return; 2055 } 2056 2057 arg_v[1] = "tests/file.c"; 2058 arg_v[2] = "pipes"; 2059 arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); 2060 arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); 2061 arg_v[5] = NULL; 2062 proc_handles[1] = (HANDLE)_spawnvp(_P_NOWAIT, selfname, arg_v); 2063 i=close(pipes[1]); 2064 ok(!i, "unable to close %d: %d\n", pipes[1], errno); 2065 file=fdopen(pipes[0], "r"); 2066 2067 /* In blocking mode, fread will keep calling read() until it gets 2068 * enough bytes, or EOF, even on Unix. (If this were a Unix terminal 2069 * in cooked mode instead of a pipe, it would also stop on EOL.) 2070 */ 2071 expected[0] = 0; 2072 for (i=0; i<N_TEST_MESSAGES; i++) 2073 strcat(expected, pipe_string); 2074 r=fread(buf, 1, sizeof(buf)-1, file); 2075 ok(r == strlen(expected), "fread() returned %d: ferror=%d\n", r, ferror(file)); 2076 if (r > 0) 2077 buf[r]='\0'; 2078 ok(strcmp(buf, expected) == 0, "got '%s' expected '%s'\n", buf, expected); 2079 2080 /* Let child close the file before we read, so we can sense EOF reliably */ 2081 Sleep(100); 2082 r=fread(buf, 1, sizeof(buf)-1, file); 2083 ok(r == 0, "fread() returned %d instead of 0\n", r); 2084 ok(ferror(file) == 0, "got ferror() = %d\n", ferror(file)); 2085 ok(feof(file), "feof() is false!\n"); 2086 2087 i=fclose(file); 2088 ok(!i, "unable to close the pipe: %d\n", errno); 2089 2090 /* test \r handling when it's the last character read */ 2091 if (_pipe(pipes, 1024, O_BINARY) < 0) 2092 { 2093 ok(0, "pipe failed with errno %d\n", errno); 2094 return; 2095 } 2096 r = write(pipes[1], "\r\n\rab\r\n", 7); 2097 ok(r == 7, "write returned %d, errno = %d\n", r, errno); 2098 setmode(pipes[0], O_TEXT); 2099 r = read(pipes[0], buf, 1); 2100 ok(r == 1, "read returned %d, expected 1\n", r); 2101 ok(buf[0] == '\n', "buf[0] = %x, expected '\\n'\n", buf[0]); 2102 r = read(pipes[0], buf, 1); 2103 ok(r == 1, "read returned %d, expected 1\n", r); 2104 ok(buf[0] == '\r', "buf[0] = %x, expected '\\r'\n", buf[0]); 2105 r = read(pipes[0], buf, 1); 2106 ok(r == 1, "read returned %d, expected 1\n", r); 2107 ok(buf[0] == 'a', "buf[0] = %x, expected 'a'\n", buf[0]); 2108 r = read(pipes[0], buf, 2); 2109 ok(r == 2, "read returned %d, expected 1\n", r); 2110 ok(buf[0] == 'b', "buf[0] = %x, expected 'b'\n", buf[0]); 2111 ok(buf[1] == '\n', "buf[1] = %x, expected '\\n'\n", buf[1]); 2112 2113 if (p_fopen_s) 2114 { 2115 /* test utf16 read with insufficient data */ 2116 r = write(pipes[1], "a\0b", 3); 2117 ok(r == 3, "write returned %d, errno = %d\n", r, errno); 2118 buf[2] = 'z'; 2119 buf[3] = 'z'; 2120 setmode(pipes[0], _O_WTEXT); 2121 r = read(pipes[0], buf, 4); 2122 ok(r == 2, "read returned %d, expected 2\n", r); 2123 ok(!memcmp(buf, "a\0bz", 4), "read returned incorrect data\n"); 2124 r = write(pipes[1], "\0", 1); 2125 ok(r == 1, "write returned %d, errno = %d\n", r, errno); 2126 buf[0] = 'z'; 2127 buf[1] = 'z'; 2128 r = read(pipes[0], buf, 2); 2129 ok(r == 0, "read returned %d, expected 0\n", r); 2130 ok(!memcmp(buf, "\0z", 2), "read returned incorrect data\n"); 2131 } 2132 else 2133 { 2134 win_skip("unicode mode tests on pipe\n"); 2135 } 2136 2137 close(pipes[1]); 2138 close(pipes[0]); 2139 } 2140 2141 static void test_unlink(void) 2142 { 2143 FILE* file; 2144 ok(mkdir("test_unlink") == 0, "unable to create test dir\n"); 2145 file = fopen("test_unlink\\empty", "w"); 2146 ok(file != NULL, "unable to create test file\n"); 2147 if(file) 2148 fclose(file); 2149 ok(_unlink("test_unlink") != 0, "unlinking a non-empty directory must fail\n"); 2150 unlink("test_unlink\\empty"); 2151 rmdir("test_unlink"); 2152 } 2153 2154 static void test_dup2(void) 2155 { 2156 ok(-1 == _dup2(0, -1), "expected _dup2 to fail when second arg is negative\n" ); 2157 } 2158 2159 static void test_stdin(void) 2160 { 2161 HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE); 2162 int stdin_dup, fd; 2163 HANDLE h; 2164 DWORD r; 2165 2166 stdin_dup = _dup(STDIN_FILENO); 2167 ok(stdin_dup != -1, "_dup(STDIN_FILENO) failed\n"); 2168 2169 ok(stdinh == (HANDLE)_get_osfhandle(STDIN_FILENO), 2170 "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n"); 2171 2172 r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE); 2173 ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r); 2174 h = GetStdHandle(STD_INPUT_HANDLE); 2175 ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h); 2176 2177 close(STDIN_FILENO); 2178 h = GetStdHandle(STD_INPUT_HANDLE); 2179 ok(h == NULL, "h != NULL\n"); 2180 2181 fd = open("stdin.tst", O_WRONLY | O_CREAT, _S_IREAD |_S_IWRITE); 2182 ok(fd != -1, "open failed\n"); 2183 ok(fd == STDIN_FILENO, "fd = %d, expected STDIN_FILENO\n", fd); 2184 h = GetStdHandle(STD_INPUT_HANDLE); 2185 ok(h != NULL, "h == NULL\n"); 2186 close(fd); 2187 unlink("stdin.tst"); 2188 2189 r = _dup2(stdin_dup, STDIN_FILENO); 2190 ok(r != -1, "_dup2 failed\n"); 2191 h = GetStdHandle(STD_INPUT_HANDLE); 2192 ok(h != NULL, "h == NULL\n"); 2193 } 2194 2195 static void test_mktemp(void) 2196 { 2197 char buf[16]; 2198 2199 strcpy(buf, "a"); 2200 ok(!_mktemp(buf), "_mktemp(\"a\") != NULL\n"); 2201 2202 strcpy(buf, "testXXXXX"); 2203 ok(!_mktemp(buf), "_mktemp(\"testXXXXX\") != NULL\n"); 2204 2205 strcpy(buf, "testXXXXXX"); 2206 ok(_mktemp(buf) != NULL, "_mktemp(\"testXXXXXX\") == NULL\n"); 2207 2208 strcpy(buf, "testXXXXXXa"); 2209 ok(!_mktemp(buf), "_mktemp(\"testXXXXXXa\") != NULL\n"); 2210 2211 strcpy(buf, "**XXXXXX"); 2212 ok(_mktemp(buf) != NULL, "_mktemp(\"**XXXXXX\") == NULL\n"); 2213 } 2214 2215 static void test__open_osfhandle(void) 2216 { 2217 ioinfo *info; 2218 HANDLE h, tmp; 2219 int fd; 2220 2221 errno = 0xdeadbeef; 2222 fd = _open_osfhandle((intptr_t)INVALID_HANDLE_VALUE, 0); 2223 ok(fd == -1, "_open_osfhandle returned %d\n", fd); 2224 ok(errno == EBADF, "errno = %d\n", errno); 2225 2226 h = CreateFileA("open_osfhandle.tst", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 2227 fd = _open_osfhandle((intptr_t)h, 0); 2228 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno); 2229 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE]; 2230 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h); 2231 ok(info->wxflag == 1, "info->wxflag = %x, expected 1\n", info->wxflag); 2232 close(fd); 2233 ok(info->handle == INVALID_HANDLE_VALUE, "info->handle = %p, expected INVALID_HANDLE_VALUE\n", info->handle); 2234 ok(info->wxflag == 0, "info->wxflag = %x, expected 0\n", info->wxflag); 2235 DeleteFileA("open_osfhandle.tst"); 2236 2237 errno = 0xdeadbeef; 2238 fd = _open_osfhandle((intptr_t)h, 0); 2239 ok(fd == -1, "_open_osfhandle returned %d\n", fd); 2240 ok(errno == EBADF, "errno = %d\n", errno); 2241 2242 ok(CreatePipe(&h, &tmp, NULL, 0), "CreatePipe failed\n"); 2243 fd = _open_osfhandle((intptr_t)h, 0); 2244 ok(fd > 0, "_open_osfhandle returned %d (%d)\n", fd, errno); 2245 info = &__pioinfo[fd/MSVCRT_FD_BLOCK_SIZE][fd%MSVCRT_FD_BLOCK_SIZE]; 2246 ok(info->handle == h, "info->handle = %p, expected %p\n", info->handle, h); 2247 ok(info->wxflag == 9, "info->wxflag = %x, expected 9\n", info->wxflag); 2248 close(fd); 2249 CloseHandle(tmp); 2250 } 2251 2252 static void test_write_flush_size(FILE *file, int bufsize) 2253 { 2254 char *inbuffer; 2255 char *outbuffer; 2256 int size, fd; 2257 fpos_t pos, pos2; 2258 2259 fd = fileno(file); 2260 inbuffer = calloc(1, bufsize + 1); 2261 outbuffer = calloc(1, bufsize + 1); 2262 _snprintf(outbuffer, bufsize + 1, "0,1,2,3,4,5,6,7,8,9"); 2263 2264 for (size = bufsize + 1; size >= bufsize - 1; size--) { 2265 rewind(file); 2266 ok(file->_cnt == 0, "_cnt should be 0 after rewind, but is %d\n", file->_cnt); 2267 fwrite(outbuffer, 1, size, file); 2268 /* lseek() below intentionally redirects the write in fflush() to detect 2269 * if fwrite() has already flushed the whole buffer or not. 2270 */ 2271 lseek(fd, 1, SEEK_SET); 2272 fflush(file); 2273 ok(file->_cnt == 0, "_cnt should be 0 after fflush, but is %d\n", file->_cnt); 2274 fseek(file, 0, SEEK_SET); 2275 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n"); 2276 if (size == bufsize) 2277 ok(memcmp(outbuffer, inbuffer, bufsize) == 0, "missing flush by %d byte write\n", size); 2278 else 2279 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d byte write\n", size); 2280 } 2281 rewind(file); 2282 fwrite(outbuffer, 1, bufsize / 2, file); 2283 fwrite(outbuffer + bufsize / 2, 1, bufsize / 2, file); 2284 lseek(fd, 1, SEEK_SET); 2285 fflush(file); 2286 fseek(file, 0, SEEK_SET); 2287 ok(fread(inbuffer, 1, bufsize, file) == bufsize, "read failed\n"); 2288 ok(memcmp(outbuffer, inbuffer, bufsize) != 0, "unexpected flush by %d/2 byte double write\n", bufsize); 2289 2290 ok(!fseek(file, -1, SEEK_END), "fseek failed\n"); 2291 ok(!fgetpos(file, &pos), "fgetpos failed\n"); 2292 ok(fread(inbuffer, 1, 1, file) == 1, "fread failed\n"); 2293 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag); 2294 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt); 2295 ok(file->_ptr != file->_base, "file->_ptr == file->_base\n"); 2296 ok(fwrite(outbuffer, 1, bufsize, file), "fwrite failed\n"); 2297 ok(file->_flag & _IOREAD, "file->_flag = %x\n", file->_flag); 2298 ok(!file->_cnt, "file->_cnt = %d\n", file->_cnt); 2299 ok(file->_ptr == file->_base, "file->_ptr == file->_base\n"); 2300 ok(!fgetpos(file, &pos2), "fgetpos failed\n"); 2301 ok(pos+bufsize+1 == pos2, "pos = %d (%d)\n", (int)pos, (int)pos2); 2302 free(inbuffer); 2303 free(outbuffer); 2304 } 2305 2306 static void test_write_flush(void) 2307 { 2308 char iobuf[1024]; 2309 char *tempf; 2310 FILE *file; 2311 2312 tempf = _tempnam(".","wne"); 2313 file = fopen(tempf, "wb+"); 2314 ok(file != NULL, "unable to create test file\n"); 2315 iobuf[0] = 0; 2316 ok(file->_bufsiz == 4096, "incorrect default buffer size: %d\n", file->_bufsiz); 2317 test_write_flush_size(file, file->_bufsiz); 2318 setvbuf(file, iobuf, _IOFBF, sizeof(iobuf)); 2319 test_write_flush_size(file, sizeof(iobuf)); 2320 fclose(file); 2321 unlink(tempf); 2322 free(tempf); 2323 } 2324 2325 static void test_close(void) 2326 { 2327 ioinfo *stdout_info, stdout_copy, *stderr_info, stderr_copy; 2328 int fd1, fd2, ret1, ret2, ret3, ret4; 2329 DWORD flags; 2330 HANDLE h; 2331 2332 /* test close on fds that use the same handle */ 2333 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE, 2334 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); 2335 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n"); 2336 2337 fd1 = _open_osfhandle((intptr_t)h, 0); 2338 ok(fd1 != -1, "_open_osfhandle failed (%d)\n", errno); 2339 fd2 = _open_osfhandle((intptr_t)h, 0); 2340 ok(fd2 != -1, "_open_osfhandle failed (%d)\n", errno); 2341 ok(fd1 != fd2, "fd1 == fd2\n"); 2342 2343 ok((HANDLE)_get_osfhandle(fd1) == h, "handles mismatch (%p != %p)\n", 2344 (HANDLE)_get_osfhandle(fd1), h); 2345 ok((HANDLE)_get_osfhandle(fd2) == h, "handles mismatch (%p != %p)\n", 2346 (HANDLE)_get_osfhandle(fd2), h); 2347 ret1 = close(fd1); 2348 ok(!ret1, "close(fd1) failed (%d)\n", errno); 2349 ok(!GetHandleInformation(h, &flags), "GetHandleInformation succeeded\n"); 2350 ok(close(fd2), "close(fd2) succeeded\n"); 2351 2352 /* test close on stdout and stderr that use the same handle */ 2353 h = CreateFileA("fdopen.tst", GENERIC_READ|GENERIC_WRITE, 2354 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); 2355 ok(h != INVALID_HANDLE_VALUE, "error opening fdopen.tst file\n"); 2356 2357 /* tests output will not be visible from now on */ 2358 stdout_info = &__pioinfo[STDOUT_FILENO/MSVCRT_FD_BLOCK_SIZE][STDOUT_FILENO%MSVCRT_FD_BLOCK_SIZE]; 2359 stderr_info = &__pioinfo[STDERR_FILENO/MSVCRT_FD_BLOCK_SIZE][STDERR_FILENO%MSVCRT_FD_BLOCK_SIZE]; 2360 stdout_copy = *stdout_info; 2361 stderr_copy = *stderr_info; 2362 stdout_info->handle = h; 2363 stderr_info->handle = h; 2364 2365 ret1 = close(STDOUT_FILENO); 2366 ret2 = GetHandleInformation(h, &flags); 2367 ret3 = close(STDERR_FILENO); 2368 ret4 = GetHandleInformation(h, &flags); 2369 2370 *stdout_info = stdout_copy; 2371 *stderr_info = stderr_copy; 2372 SetStdHandle(STD_OUTPUT_HANDLE, stdout_info->handle); 2373 SetStdHandle(STD_ERROR_HANDLE, stderr_info->handle); 2374 /* stdout and stderr restored */ 2375 2376 ok(!ret1, "close(STDOUT_FILENO) failed\n"); 2377 ok(ret2, "GetHandleInformation failed\n"); 2378 ok(!ret3, "close(STDERR_FILENO) failed\n"); 2379 ok(!ret4, "GetHandleInformation succeeded\n"); 2380 2381 DeleteFileA( "fdopen.tst" ); 2382 } 2383 2384 static void test__creat(void) 2385 { 2386 int fd, pos, count, readonly, old_fmode = 0, have_fmode; 2387 char buf[6], testdata[4] = {'a', '\n', 'b', '\n'}; 2388 2389 have_fmode = p__get_fmode && p__set_fmode && !p__get_fmode(&old_fmode); 2390 if (!have_fmode) 2391 win_skip("_fmode can't be set, skipping mode tests\n"); 2392 2393 if (have_fmode) 2394 p__set_fmode(_O_TEXT); 2395 fd = _creat("_creat.tst", 0); 2396 ok(fd > 0, "_creat failed\n"); 2397 _write(fd, testdata, 4); 2398 if (have_fmode) { 2399 pos = _tell(fd); 2400 ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos); 2401 } 2402 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); 2403 count = _read(fd, buf, 6); 2404 ok(count == 4, "_read returned %d, expected 4\n", count); 2405 count = count > 0 ? count > 4 ? 4 : count : 0; 2406 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n"); 2407 _close(fd); 2408 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY; 2409 ok(readonly, "expected read-only file\n"); 2410 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL); 2411 DeleteFileA("_creat.tst"); 2412 2413 if (have_fmode) 2414 p__set_fmode(_O_BINARY); 2415 fd = _creat("_creat.tst", _S_IREAD | _S_IWRITE); 2416 ok(fd > 0, "_creat failed\n"); 2417 _write(fd, testdata, 4); 2418 if (have_fmode) { 2419 pos = _tell(fd); 2420 ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos); 2421 } 2422 ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); 2423 count = _read(fd, buf, 6); 2424 ok(count == 4, "_read returned %d, expected 4\n", count); 2425 count = count > 0 ? count > 4 ? 4 : count : 0; 2426 ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n"); 2427 _close(fd); 2428 readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY; 2429 ok(!readonly, "expected rw file\n"); 2430 SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL); 2431 DeleteFileA("_creat.tst"); 2432 2433 if (have_fmode) 2434 p__set_fmode(old_fmode); 2435 } 2436 2437 START_TEST(file) 2438 { 2439 int arg_c; 2440 char** arg_v; 2441 2442 init(); 2443 2444 arg_c = winetest_get_mainargs( &arg_v ); 2445 2446 /* testing low-level I/O */ 2447 if (arg_c >= 3) 2448 { 2449 if (strcmp(arg_v[2], "inherit") == 0) 2450 test_file_inherit_child(arg_v[3]); 2451 else if (strcmp(arg_v[2], "inherit_no") == 0) 2452 test_file_inherit_child_no(arg_v[3]); 2453 else if (strcmp(arg_v[2], "pipes") == 0) 2454 test_pipes_child(arg_c, arg_v); 2455 else 2456 ok(0, "invalid argument '%s'\n", arg_v[2]); 2457 return; 2458 } 2459 test_dup2(); 2460 test_file_inherit(arg_v[0]); 2461 test_file_write_read(); 2462 test_chsize(); 2463 test_stat(); 2464 test_unlink(); 2465 2466 /* testing stream I/O */ 2467 test_filbuf(); 2468 test_fdopen(); 2469 test_fopen_fclose_fcloseall(); 2470 test_fopen_s(); 2471 test__wfopen_s(); 2472 test_setmode(); 2473 test_fileops(); 2474 test_asciimode(); 2475 test_asciimode2(); 2476 test_filemodeT(); 2477 test_readmode(FALSE); /* binary mode */ 2478 test_readmode(TRUE); /* ascii mode */ 2479 test_readboundary(); 2480 test_fgetc(); 2481 test_fputc(); 2482 test_flsbuf(); 2483 test_fflush(); 2484 test_fgetwc(); 2485 /* \x83\xa9 is double byte character, \xe0\x7f is not (undefined). */ 2486 test_fgetwc_locale("AB\x83\xa9\xe0\x7f", "Japanese_Japan.932", 932); 2487 /* \x83 is U+0192 */ 2488 test_fgetwc_locale("AB\x83\xa9", "English", 1252); 2489 /* \x83 is U+0083 */ 2490 test_fgetwc_locale("AB\x83\xa9", "C", 0); 2491 test_fgetwc_unicode(); 2492 test_fputwc(); 2493 test_ctrlz(); 2494 test_file_put_get(); 2495 test_tmpnam(); 2496 test_get_osfhandle(); 2497 test_setmaxstdio(); 2498 test_pipes(arg_v[0]); 2499 test_stdin(); 2500 test_mktemp(); 2501 test__open_osfhandle(); 2502 test_write_flush(); 2503 test_close(); 2504 test__creat(); 2505 2506 /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report 2507 * file contains lines in the correct order 2508 */ 2509 WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000); 2510 } 2511