vbox的更動 34015 路徑 trunk/src/VBox/Runtime/r3/dir.cpp
- 時間撮記:
- 2010-11-12 上午12:15:05 (14 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/r3/dir.cpp
r33540 r34015 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Directory Manipulation .3 * IPRT - Directory Manipulation, Part 1. 4 4 */ 5 5 … … 719 719 720 720 721 /**722 * Recursion worker for RTDirRemoveRecursive.723 *724 * @returns IPRT status code.725 * @param pszBuf The path buffer. Contains the abs path to the726 * directory to recurse into. Trailing slash.727 * @param cchDir The length of the directory we're cursing into,728 * including the trailing slash.729 * @param pDirEntry The dir entry buffer. (Shared to save stack.)730 * @param pObjInfo The object info buffer. (ditto)731 */732 static int rtDirRemoveRecursiveSub(char *pszBuf, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo)733 {734 AssertReturn(RTPATH_IS_SLASH(pszBuf[cchDir - 1]), VERR_INTERNAL_ERROR_4);735 736 /*737 * Enumerate the directory content and dispose of it.738 */739 PRTDIR pDir;740 int rc = RTDirOpen(&pDir, pszBuf);741 if (RT_FAILURE(rc))742 return rc;743 while (RT_SUCCESS(rc = RTDirRead(pDir, pDirEntry, NULL)))744 {745 if ( pDirEntry->szName[0] != '.'746 || pDirEntry->cbName > 2747 || ( pDirEntry->cbName == 2748 && pDirEntry->szName[1] != '.')749 )750 {751 /* Construct the full name of the entry. */752 if (cchDir + pDirEntry->cbName + 1 /* dir slash */ >= RTPATH_MAX)753 {754 rc = VERR_FILENAME_TOO_LONG;755 break;756 }757 memcpy(&pszBuf[cchDir], pDirEntry->szName, pDirEntry->cbName + 1);758 759 /* Deal with the unknown type. */760 if (pDirEntry->enmType == RTDIRENTRYTYPE_UNKNOWN)761 {762 rc = RTPathQueryInfoEx(pszBuf, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);763 if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode))764 pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY;765 else if (RT_SUCCESS(rc) && RTFS_IS_FILE(pObjInfo->Attr.fMode))766 pDirEntry->enmType = RTDIRENTRYTYPE_FILE;767 else if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(pObjInfo->Attr.fMode))768 pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK;769 }770 771 /* Try the delete the fs object. */772 switch (pDirEntry->enmType)773 {774 case RTDIRENTRYTYPE_FILE:775 rc = RTFileDelete(pszBuf);776 break;777 778 case RTDIRENTRYTYPE_DIRECTORY:779 {780 size_t cchSubDir = cchDir + pDirEntry->cbName;781 pszBuf[cchSubDir++] = '/';782 pszBuf[cchSubDir] = '\0';783 rc = rtDirRemoveRecursiveSub(pszBuf, cchSubDir, pDirEntry, pObjInfo);784 if (RT_SUCCESS(rc))785 {786 pszBuf[cchSubDir] = '\0';787 rc = RTDirRemove(pszBuf);788 }789 break;790 }791 792 //case RTDIRENTRYTYPE_SYMLINK:793 // rc = RTSymlinkDelete(pszBuf);794 // break;795 796 default:797 /** @todo not implemented yet. */798 rc = VINF_SUCCESS;799 break;800 }801 if (RT_FAILURE(rc))802 break;803 }804 }805 if (rc == VERR_NO_MORE_FILES)806 rc = VINF_SUCCESS;807 RTDirClose(pDir);808 return rc;809 }810 811 812 RTDECL(int) RTDirRemoveRecursive(const char *pszPath, uint32_t fFlags)813 {814 AssertReturn(!(fFlags & ~RTDIRRMREC_F_VALID_MASK), VERR_INVALID_PARAMETER);815 816 /* Get an absolute path because this is easier to work with. */817 /** @todo use RTPathReal here instead? */818 char szAbsPath[RTPATH_MAX];819 int rc = RTPathAbs(pszPath, szAbsPath, sizeof(szAbsPath));820 if (RT_FAILURE(rc))821 return rc;822 823 /* This API is not permitted applied to the root of anything. */824 if (RTPathCountComponents(szAbsPath) <= 1)825 return VERR_ACCESS_DENIED;826 827 /* Because of the above restriction, we never have to deal with the root828 slash problem and can safely strip any trailing slashes and add a829 definite one. */830 RTPathStripTrailingSlash(szAbsPath);831 size_t cchAbsPath = strlen(szAbsPath);832 if (cchAbsPath + 1 >= RTPATH_MAX)833 return VERR_FILENAME_TOO_LONG;834 szAbsPath[cchAbsPath++] = '/';835 szAbsPath[cchAbsPath] = 0;836 837 /* Check if it exists so we can return quietly if it doesn't. */838 RTFSOBJINFO SharedObjInfoBuf;839 rc = RTPathQueryInfoEx(szAbsPath, &SharedObjInfoBuf, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);840 if ( rc == VERR_PATH_NOT_FOUND841 || rc == VERR_FILE_NOT_FOUND)842 return VINF_SUCCESS;843 if (RT_FAILURE(rc))844 return rc;845 if (!RTFS_IS_DIRECTORY(SharedObjInfoBuf.Attr.fMode))846 return VERR_NOT_A_DIRECTORY;847 848 /* We're all set for the recursion now, so get going. */849 RTDIRENTRY SharedDirEntryBuf;850 rc = rtDirRemoveRecursiveSub(szAbsPath, cchAbsPath, &SharedDirEntryBuf, &SharedObjInfoBuf);851 852 /* Remove the specified directory if desired and removing the content was853 successful. */854 if ( RT_SUCCESS(rc)855 && !(fFlags & RTDIRRMREC_F_CONTENT_ONLY))856 {857 szAbsPath[cchAbsPath] = 0;858 rc = RTDirRemove(szAbsPath);859 }860 return rc;861 }862 863 864 721 RTDECL(int) RTDirFlushParent(const char *pszChild) 865 722 {
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器