Changeset 95977 in vbox
- Timestamp:
- Aug 2, 2022 1:23:43 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 152735
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/stream.h
r95934 r95977 62 62 * @param pszFilename Path to the file to open. 63 63 * @param pszMode The open mode. See fopen() standard. 64 * Format: <a|r|w>[+][b] 64 * Format: <a|r|w>[+][b|t][x][e|N|E] 65 * - 'a': Open or create file and writes 66 * append tos it. 67 * - 'r': Open existing file and read from it. 68 * - 'w': Open or truncate existing file and write 69 * to it. 70 * - '+': Open for both read and write access. 71 * - 'b' / 't': binary / text 72 * - 'x': exclusively create, no open. Only 73 * possible with 'w'. 74 * - 'e' / 'N': No inherit on exec. (The 'e' is 75 * how Linux and FreeBSD expresses this, the 76 * latter is Visual C++). 65 77 * @param ppStream Where to store the opened stream. 66 78 */ … … 72 84 * @returns iprt status code. 73 85 * @param pszMode The open mode. See fopen() standard. 74 * Format: <a|r|w>[+][b] 86 * Format: <a|r|w>[+][b|t][x][e|N|E] 87 * - 'a': Open or create file and writes 88 * append tos it. 89 * - 'r': Open existing file and read from it. 90 * - 'w': Open or truncate existing file and write 91 * to it. 92 * - '+': Open for both read and write access. 93 * - 'b' / 't': binary / text 94 * - 'x': exclusively create, no open. Only 95 * possible with 'w'. 96 * - 'e' / 'N': No inherit on exec. (The 'e' is 97 * how Linux and FreeBSD expresses this, the 98 * latter is Visual C++). 75 99 * @param ppStream Where to store the opened stream. 76 100 * @param pszFilenameFmt Filename path format string. … … 85 109 * @returns iprt status code. 86 110 * @param pszMode The open mode. See fopen() standard. 87 * Format: <a|r|w>[+][b] 111 * Format: <a|r|w>[+][b|t][x][e|N|E] 112 * - 'a': Open or create file and writes 113 * append tos it. 114 * - 'r': Open existing file and read from it. 115 * - 'w': Open or truncate existing file and write 116 * to it. 117 * - '+': Open for both read and write access. 118 * - 'b' / 't': binary / text 119 * - 'x': exclusively create, no open. Only 120 * possible with 'w'. 121 * - 'e' / 'N': No inherit on exec. (The 'e' is 122 * how Linux and FreeBSD expresses this, the 123 * latter is Visual C++). 88 124 * @param ppStream Where to store the opened stream. 89 125 * @param pszFilenameFmt Filename path format string. -
trunk/src/VBox/Runtime/r3/stream.cpp
r95943 r95977 66 66 #include <iprt/ctype.h> 67 67 #include <iprt/err.h> 68 #ifdef RTSTREAM_STANDALONE69 68 # include <iprt/file.h> 69 #ifdef RTSTREAM_STANDALONE 70 70 # include <iprt/list.h> 71 71 #endif … … 410 410 * @param pszFilename Path to the file to open. 411 411 * @param pszMode The open mode. See fopen() standard. 412 * Format: <a|r|w>[+][b] 412 * Format: <a|r|w>[+][b|t][x][e|N|E] 413 * - 'a': Open or create file and writes 414 * append tos it. 415 * - 'r': Open existing file and read from it. 416 * - 'w': Open or truncate existing file and write 417 * to it. 418 * - '+': Open for both read and write access. 419 * - 'b' / 't': binary / text 420 * - 'x': exclusively create, no open. Only 421 * possible with 'w'. 422 * - 'e' / 'N': No inherit on exec. (The 'e' is 423 * how Linux and FreeBSD expresses this, the 424 * latter is Visual C++). 413 425 * @param ppStream Where to store the opened stream. 414 426 */ … … 421 433 AssertReturn(pszFilename, VERR_INVALID_PARAMETER); 422 434 423 bool fOk = true; 424 bool fBinary = false; 425 #ifdef RTSTREAM_STANDALONE 426 uint64_t fOpen = RTFILE_O_DENY_NONE; 427 #endif 428 switch (*pszMode) 429 { 430 case 'a': 431 case 'w': 432 case 'r': 433 switch (pszMode[1]) 434 { 435 case 'b': 436 fBinary = true; 437 RT_FALL_THRU(); 438 case '\0': 439 #ifdef RTSTREAM_STANDALONE 440 fOpen |= *pszMode == 'a' ? RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_APPEND 441 : *pszMode == 'w' ? RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE 442 : RTFILE_O_OPEN | RTFILE_O_READ; 443 #endif 444 break; 445 446 case '+': 447 #ifdef RTSTREAM_STANDALONE 448 fOpen |= *pszMode == 'a' ? RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_APPEND 449 : *pszMode == 'w' ? RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE 450 : RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE; 451 #endif 452 switch (pszMode[2]) 453 { 454 case '\0': 455 break; 456 457 case 'b': 458 fBinary = true; 459 break; 460 461 default: 462 fOk = false; 463 break; 464 } 465 break; 466 467 default: 468 fOk = false; 469 break; 470 } 471 break; 435 /* 436 * Process the mode string. 437 */ 438 char chMode = '\0'; /* a|r|w */ 439 bool fPlus = false; /* + */ 440 bool fBinary = false; /* b | !t */ 441 bool fExclusive = false; /* x */ 442 bool fNoInherit = false; /* e (linux, freebsd) | N (win) | E (our for reverse) */ 443 const char *psz = pszMode; 444 char ch; 445 while ((ch = *psz++) != '\0') 446 { 447 switch (ch) 448 { 449 case 'a': 450 case 'r': 451 case 'w': 452 chMode = ch; 453 break; 454 case '+': 455 fPlus = true; 456 break; 457 case 'b': 458 fBinary = true; 459 break; 460 case 't': 461 fBinary = false; 462 break; 463 case 'x': 464 fExclusive = true; 465 break; 466 case 'e': 467 case 'N': 468 fNoInherit = true; 469 break; 470 case 'E': 471 fNoInherit = false; 472 break; 473 default: 474 AssertMsgFailedReturn(("Invalid ch='%c' in pszMode='%s', '<a|r|w>[+][b|t][x][e|N|E]'\n", pszMode), 475 VERR_INVALID_FLAGS); 476 } 477 } 478 479 /* 480 * Translate into to RTFILE_O_* flags: 481 */ 482 uint64_t fOpen; 483 switch (chMode) 484 { 485 case 'a': fOpen = RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_APPEND; break; 486 case 'w': fOpen = !fExclusive 487 ? RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE 488 : RTFILE_O_CREATE | RTFILE_O_WRITE; break; 489 case 'r': fOpen = RTFILE_O_OPEN | RTFILE_O_READ; 472 490 default: 473 fOk = false; 474 break; 475 } 476 if (!fOk) 477 { 478 AssertMsgFailed(("Invalid pszMode='%s', '<a|r|w>[+][b]'\n", pszMode)); 479 return VINF_SUCCESS; 480 } 491 AssertMsgReturn(chMode, ("No main mode (a|r|w) specified in '%s'!\n", pszMode), VERR_INVALID_FLAGS); 492 } 493 AssertMsgReturn(!fExclusive || chMode == 'w', ("the 'x' flag is only allowed with 'w'! (%s)\n", pszMode), 494 VERR_INVALID_FLAGS); 495 if (fExclusive) 496 fOpen |= RTFILE_O_READ | RTFILE_O_WRITE; 497 if (fPlus) 498 fOpen |= RTFILE_O_READ | RTFILE_O_WRITE; 499 if (!fNoInherit) 500 fOpen |= RTFILE_O_INHERIT; 501 fOpen |= RTFILE_O_DENY_NONE; 502 fOpen |= 0666 << RTFILE_O_CREATE_MODE_SHIFT; 503 504 #ifndef RTSTREAM_STANDALONE 505 /* 506 * Normalize mode for fdopen. 507 */ 508 char szNormalizedMode[8]; 509 szNormalizedMode[0] = chMode; 510 size_t off = 1; 511 if (fPlus) 512 szNormalizedMode[off++] = '+'; 513 if (fBinary) 514 szNormalizedMode[off++] = 'b'; 515 szNormalizedMode[off] = '\0'; 516 #endif 481 517 482 518 #ifdef RTSTREAM_STANDALONE … … 516 552 pStream->pCritSect = NULL; 517 553 #endif 518 #ifdef RTSTREAM_STANDALONE 519 rc = RTFileOpen(&pStream->hFile, pszFilename, fOpen); 520 #else 521 pStream->pFile = fopen(pszFilename, pszMode); 522 rc = pStream->pFile ? VINF_SUCCESS : RTErrConvertFromErrno(errno); 523 if (pStream->pFile) 524 #endif 554 RTFILE hFile = NIL_RTFILE; 555 RTFILEACTION enmActionTaken = RTFILEACTION_INVALID; 556 rc = RTFileOpenEx(pszFilename, fOpen, &hFile, &enmActionTaken); 525 557 if (RT_SUCCESS(rc)) 526 558 { 527 #ifdef RTSTREAM_STANDALONE 528 /* We keep a list of these for cleanup purposes. */ 529 RTCritSectEnter(&g_StreamListCritSect); 530 RTListAppend(&g_StreamList, &pStream->ListEntry); 531 RTCritSectLeave(&g_StreamListCritSect); 532 #endif 533 *ppStream = pStream; 534 return VINF_SUCCESS; 559 #ifndef RTSTREAM_STANDALONE 560 # ifndef _MSC_VER 561 int fd = (int)RTFileToNative(hFile); 562 # else 563 int fd = _open_osfhandle(RTFileToNative(hFile), 564 (fPlus ? _O_RDWR : chMode == 'r' ? _O_RDONLY : _O_WRONLY) 565 | (chMode == 'a' ? _O_APPEND : 0) 566 | (fBinary ? _O_BINARY : _O_TEXT) 567 | (fNoInherit ? _O_NOINHERIT : 0)); 568 # endif 569 if (fd >= 0) 570 { 571 pStream->pFile = fdopen(fd, szNormalizedMode); 572 if (pStream->pFile) 573 #endif 574 { 575 #ifdef RTSTREAM_STANDALONE 576 pStream->hFile = hFile; 577 578 /* We keep a list of these for cleanup purposes. */ 579 RTCritSectEnter(&g_StreamListCritSect); 580 RTListAppend(&g_StreamList, &pStream->ListEntry); 581 RTCritSectLeave(&g_StreamListCritSect); 582 #endif 583 *ppStream = pStream; 584 return VINF_SUCCESS; 585 } 586 587 /* 588 * This better not happen too often as in 'w' mode we might've 589 * truncated a file, and in 'w' and 'a' modes there is a chance 590 * that we'll race other access to the file when deleting it. 591 */ 592 #ifndef RTSTREAM_STANDALONE 593 rc = RTErrConvertFromErrno(errno); 594 # ifdef _MSC_VER 595 close(fd); 596 hFile = NIL_RTFILE; 597 # endif 598 } 599 else 600 { 601 # ifdef _MSC_VER 602 rc = RTErrConvertFromErrno(errno); 603 # else 604 AssertFailedStmt(rc = VERR_INVALID_HANDLE); 605 # endif 606 } 607 RTFileClose(hFile); 608 if (enmActionTaken == RTFILEACTION_CREATED) 609 RTFileDelete(pszFilename); 610 #endif 535 611 } 536 612 RTMemFree(pStream);
Note:
See TracChangeset
for help on using the changeset viewer.