Changeset 104286 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Apr 11, 2024 1:56:27 AM (9 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/log/log.cpp
r103685 r104286 49 49 #include <iprt/mp.h> 50 50 #ifdef IN_RING3 51 # ifdef RT_OS_WINDOWS 52 # include <iprt/dir.h> 53 # endif 51 54 # include <iprt/env.h> 52 55 # include <iprt/file.h> … … 227 230 PCRTLOGOUTPUTIF pOutputIf; 228 231 /** Opaque user data passed to the callbacks in the output interface. */ 229 void *pvOutputIfUser; 232 void *pvOutputIfUser; 233 /** Opaque directory context. 234 * This is kept open while we have an open log file. */ 235 void *pvDirCtx; 230 236 231 237 /** Handle to log file (if open) - only used by the default output interface to avoid additional layers of indirection. */ … … 259 265 260 266 /** The revision of the internal logger structure. */ 261 # define RTLOGGERINTERNAL_REV UINT32_C(1 3)267 # define RTLOGGERINTERNAL_REV UINT32_C(14) 262 268 263 269 AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbRingBufUnflushed, sizeof(uint64_t)); … … 267 273 #endif 268 274 269 270 275 /** Pointer to internal logger bits. */ 271 276 typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL; 277 278 272 279 /** 273 280 * Arguments passed to the output function. … … 760 767 761 768 #ifdef IN_RING3 762 static DECLCALLBACK(int) rtLogOutputIfDefOpen(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename, uint32_t fFlags) 763 { 764 RT_NOREF(pIf); 769 # ifdef RT_OS_WINDOWS 770 # define RTLOG_DIR_CTX_IS_PARENT_DIR 771 # endif 772 773 /** 774 * @callback_method_impl{RTLOGOUTPUTIF,pfnDirCtxOpen} 775 */ 776 static DECLCALLBACK(int) rtLogOutputIfDefDirCtxOpen(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename, void **ppvDirCtx) 777 { 778 RT_NOREF(pIf, pvUser); 779 # ifdef RTLOG_DIR_CTX_IS_PARENT_DIR 780 /* Open the parent directory to make sure it is a real directory and not 781 object directory placed there by someone with evil intent. @bugref{10632} */ 782 RTDIR hDir = NIL_RTDIR; 783 int rc = RTDirOpenFiltered(&hDir, pszFilename, RTDIRFILTER_WINNT, 0); 784 if (RT_FAILURE(rc)) 785 return rc; 786 AssertCompile(sizeof(*ppvDirCtx) == sizeof(hDir)); 787 *ppvDirCtx = hDir; 788 # else 789 RT_NOREF(pIf, pvUser, pszFilename); 790 *ppvDirCtx = (void *)(intptr_t)42; 791 # endif 792 return VINF_SUCCESS; 793 } 794 795 796 /** 797 * @callback_method_impl{RTLOGOUTPUTIF,pfnDirCtxClose} 798 */ 799 static DECLCALLBACK(int) rtLogOutputIfDefDirCtxClose(PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx) 800 { 801 RT_NOREF(pIf, pvUser); 802 # ifdef RTLOG_DIR_CTX_IS_PARENT_DIR 803 RTDIR hDir = (RTDIR)pvDirCtx; 804 int rc = RTDirClose(hDir); 805 AssertRC(rc); 806 return rc; 807 # else 808 Assert((intptr_t)pvDirCtx == 42); 809 RT_NOREF(pvDirCtx); 810 return VINF_SUCCESS; 811 # endif 812 } 813 814 815 /** 816 * @callback_method_impl{RTLOGOUTPUTIF,pfnDelete} 817 */ 818 static DECLCALLBACK(int) rtLogOutputIfDefDelete(PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx, const char *pszFilename) 819 { 820 RT_NOREF(pIf, pvUser, pvDirCtx); 821 # ifdef RTLOG_DIR_CTX_IS_PARENT_DIR 822 /** @todo use RTDirRelPathUnlink when it adds any improvements. */ 823 # else 824 Assert((intptr_t)pvDirCtx == 42); 825 # endif 826 827 return RTFileDelete(pszFilename); 828 } 829 830 831 /** 832 * @callback_method_impl{RTLOGOUTPUTIF,pfnRename} 833 */ 834 static DECLCALLBACK(int) rtLogOutputIfDefRename(PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx, 835 const char *pszFilenameOld, const char *pszFilenameNew, uint32_t fFlags) 836 { 837 RT_NOREF(pIf, pvUser, pvDirCtx); 838 # ifdef RTLOG_DIR_CTX_IS_PARENT_DIR 839 /** @todo use RTDirRelPathRename when it adds any improvements. */ 840 # else 841 Assert((intptr_t)pvDirCtx == 42); 842 # endif 843 return RTFileRename(pszFilenameOld, pszFilenameNew, fFlags); 844 } 845 846 847 /** 848 * @callback_method_impl{RTLOGOUTPUTIF,pfnOpen} 849 */ 850 static DECLCALLBACK(int) rtLogOutputIfDefOpen(PCRTLOGOUTPUTIF pIf, void *pvUser, void *pvDirCtx, 851 const char *pszFilename, uint32_t fFlags) 852 { 765 853 PRTLOGGERINTERNAL pLoggerInt = (PRTLOGGERINTERNAL)pvUser; 854 RT_NOREF(pIf, pvDirCtx); 855 # ifdef RTLOG_DIR_CTX_IS_PARENT_DIR 856 /** @todo use RTDirRelFileOpen */ 857 # else 858 Assert((intptr_t)pvDirCtx == 42); 859 # endif 766 860 767 861 return RTFileOpen(&pLoggerInt->hFile, pszFilename, fFlags); … … 769 863 770 864 865 /** 866 * @callback_method_impl{RTLOGOUTPUTIF,pfnClose} 867 */ 771 868 static DECLCALLBACK(int) rtLogOutputIfDefClose(PCRTLOGOUTPUTIF pIf, void *pvUser) 772 869 { … … 783 880 784 881 785 static DECLCALLBACK(int) rtLogOutputIfDefDelete(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename) 786 { 787 RT_NOREF(pIf, pvUser); 788 return RTFileDelete(pszFilename); 789 } 790 791 792 static DECLCALLBACK(int) rtLogOutputIfDefRename(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilenameOld, 793 const char *pszFilenameNew, uint32_t fFlags) 794 { 795 RT_NOREF(pIf, pvUser); 796 return RTFileRename(pszFilenameOld, pszFilenameNew, fFlags); 797 } 798 799 882 /** 883 * @callback_method_impl{RTLOGOUTPUTIF,pfnQuerySize} 884 */ 800 885 static DECLCALLBACK(int) rtLogOutputIfDefQuerySize(PCRTLOGOUTPUTIF pIf, void *pvUser, uint64_t *pcbSize) 801 886 { … … 811 896 812 897 898 /** 899 * @callback_method_impl{RTLOGOUTPUTIF,pfnWrite} 900 */ 813 901 static DECLCALLBACK(int) rtLogOutputIfDefWrite(PCRTLOGOUTPUTIF pIf, void *pvUser, const void *pvBuf, 814 902 size_t cbWrite, size_t *pcbWritten) … … 824 912 825 913 914 /** 915 * @callback_method_impl{RTLOGOUTPUTIF,pfnFlush} 916 */ 826 917 static DECLCALLBACK(int) rtLogOutputIfDefFlush(PCRTLOGOUTPUTIF pIf, void *pvUser) 827 918 { … … 841 932 static const RTLOGOUTPUTIF g_LogOutputIfDef = 842 933 { 934 rtLogOutputIfDefDirCtxOpen, 935 rtLogOutputIfDefDirCtxClose, 936 rtLogOutputIfDefDelete, 937 rtLogOutputIfDefRename, 843 938 rtLogOutputIfDefOpen, 844 939 rtLogOutputIfDefClose, 845 rtLogOutputIfDefDelete,846 rtLogOutputIfDefRename,847 940 rtLogOutputIfDefQuerySize, 848 941 rtLogOutputIfDefWrite, 849 942 rtLogOutputIfDefFlush 850 943 }; 851 #endif 944 945 #endif /* IN_RING3 */ 852 946 853 947 … … 1492 1586 } 1493 1587 # ifdef IN_RING3 1494 pLoggerInt->pOutputIf->pfnClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser); 1495 # endif 1588 if (pLoggerInt->fLogOpened) 1589 { 1590 pLoggerInt->pOutputIf->pfnClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser); 1591 pLoggerInt->pOutputIf->pfnDirCtxClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx); 1592 pLoggerInt->pvDirCtx = NULL; 1593 } 1594 #endif 1496 1595 # if defined(RT_ARCH_X86) && !defined(LOG_USE_C99) && 0 /* retired */ 1497 1596 if (pLoggerInt->Core.pfnLogger) … … 1580 1679 rc = rc2; 1581 1680 pLoggerInt->fLogOpened = false; 1681 1682 pLoggerInt->pOutputIf->pfnDirCtxClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx); 1683 pLoggerInt->pvDirCtx = NULL; 1582 1684 } 1583 1685 # endif … … 2697 2799 else 2698 2800 { 2699 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2801 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2700 2802 pLoggerInt->szFilename); 2701 2803 fOpen |= RTFILE_O_CREATE; … … 2707 2809 2708 2810 unsigned cBackoff = 0; 2709 int rc = pLoggerInt->pOutputIf->pfnOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2811 int rc = pLoggerInt->pOutputIf->pfnOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2710 2812 pLoggerInt->szFilename, fOpen); 2711 2813 while ( ( rc == VERR_SHARING_VIOLATION … … 2715 2817 RTThreadSleep(g_acMsLogBackoff[cBackoff++]); 2716 2818 if (!(pLoggerInt->fFlags & RTLOGFLAGS_APPEND)) 2717 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2819 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2718 2820 pLoggerInt->szFilename); 2719 rc = pLoggerInt->pOutputIf->pfnOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2821 rc = pLoggerInt->pOutputIf->pfnOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2720 2822 pLoggerInt->szFilename, fOpen); 2721 2823 } … … 2799 2901 pLoggerInt->pOutputIf->pfnClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser); 2800 2902 } 2903 /* 2904 * If the log file was closed and we're being called from rtR3LogOpenFileDestination 2905 * we must open a log directory context before going on. 2906 */ 2907 else if (!fFirst) 2908 { 2909 int rc = pLoggerInt->pOutputIf->pfnDirCtxOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2910 pLoggerInt->szFilename, &pLoggerInt->pvDirCtx); 2911 if (RT_FAILURE(rc)) 2912 return; 2913 } 2801 2914 2802 2915 if (cSavedHistory) … … 2817 2930 2818 2931 unsigned cBackoff = 0; 2819 int rc = pLoggerInt->pOutputIf->pfnRename(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2932 int rc = pLoggerInt->pOutputIf->pfnRename(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2820 2933 szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE); 2821 2934 while ( rc == VERR_SHARING_VIOLATION … … 2823 2936 { 2824 2937 RTThreadSleep(g_acMsLogBackoff[cBackoff++]); 2825 rc = pLoggerInt->pOutputIf->pfnRename(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 2938 rc = pLoggerInt->pOutputIf->pfnRename(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2826 2939 szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE); 2827 2940 } 2828 2941 2829 2942 if (rc == VERR_FILE_NOT_FOUND) 2830 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, szNewName); 2943 pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2944 szNewName); 2831 2945 } 2832 2946 … … 2838 2952 char szExcessName[sizeof(pLoggerInt->szFilename) + 32]; 2839 2953 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLoggerInt->szFilename, i); 2840 int rc = pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, szExcessName); 2954 int rc = pLoggerInt->pOutputIf->pfnDelete(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx, 2955 szExcessName); 2841 2956 if (RT_FAILURE(rc)) 2842 2957 break; … … 2864 2979 } 2865 2980 2866 /* Restore saved values. */ 2981 /* 2982 * Close the context if we didn't get a log file, unless we're being 2983 * called by rtR3LogOpenFileDestination. 2984 */ 2985 if (!pLoggerInt->fLogOpened && !fFirst) 2986 { 2987 pLoggerInt->pOutputIf->pfnDirCtxClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx); 2988 pLoggerInt->pvDirCtx = NULL; 2989 } 2990 2991 /* 2992 * Restore saved values. 2993 */ 2867 2994 pLoggerInt->cHistory = cSavedHistory; 2868 2995 pLoggerInt->fFlags = fSavedFlags; … … 2882 3009 static int rtR3LogOpenFileDestination(PRTLOGGERINTERNAL pLoggerInt, PRTERRINFO pErrInfo) 2883 3010 { 2884 int rc; 2885 if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND) 2886 { 2887 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 2888 2889 /* Rotate in case of appending to a too big log file, 2890 otherwise this simply doesn't do anything. */ 2891 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 2892 } 2893 else 2894 { 2895 /* Force rotation if it is configured. */ 2896 pLoggerInt->cbHistoryFileWritten = UINT64_MAX; 2897 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 2898 2899 /* If the file is not open then rotation is not set up. */ 3011 /* 3012 * Open a log directory context so the output backend can better secure 3013 * the log file opening, renaming and deleting. (See @bugref{10632}.) 3014 */ 3015 Assert(!pLoggerInt->fLogOpened); 3016 int rc = pLoggerInt->pOutputIf->pfnDirCtxOpen(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, 3017 pLoggerInt->szFilename, &pLoggerInt->pvDirCtx); 3018 if (RT_SUCCESS(rc)) 3019 { 3020 if (pLoggerInt->fFlags & RTLOGFLAGS_APPEND) 3021 { 3022 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 3023 3024 /* Rotate in case of appending to a too big log file, 3025 otherwise this simply doesn't do anything. */ 3026 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 3027 } 3028 else 3029 { 3030 /* Force rotation if it is configured. */ 3031 pLoggerInt->cbHistoryFileWritten = UINT64_MAX; 3032 rtlogRotate(pLoggerInt, 0, true /* fFirst */, pErrInfo); 3033 3034 /* If the file is not open then rotation is not set up. */ 3035 if (!pLoggerInt->fLogOpened) 3036 { 3037 pLoggerInt->cbHistoryFileWritten = 0; 3038 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 3039 } 3040 else 3041 rc = VINF_SUCCESS; 3042 } 3043 3044 /* 3045 * Close the directory context if we failed to get open a log file. 3046 * This gives the user a chance to make changes so it may succeed later. 3047 */ 2900 3048 if (!pLoggerInt->fLogOpened) 2901 3049 { 2902 pLoggerInt->cbHistoryFileWritten = 0; 2903 rc = rtlogFileOpen(pLoggerInt, pErrInfo); 2904 } 2905 else 2906 rc = VINF_SUCCESS; 3050 pLoggerInt->pOutputIf->pfnDirCtxClose(pLoggerInt->pOutputIf, pLoggerInt->pvOutputIfUser, pLoggerInt->pvDirCtx); 3051 pLoggerInt->pvDirCtx = NULL; 3052 } 2907 3053 } 2908 3054 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.