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