VirtualBox

忽略:
時間撮記:
2010-11-12 上午12:15:05 (14 年 以前)
作者:
vboxsync
訊息:

iprt: try split out some of the RTPathQueryInfo* dependent bits into separate files in the posix world.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/r3/dir.cpp

    r33540 r34015  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Directory Manipulation.
     3 * IPRT - Directory Manipulation, Part 1.
    44 */
    55
     
    719719
    720720
    721 /**
    722  * Recursion worker for RTDirRemoveRecursive.
    723  *
    724  * @returns IPRT status code.
    725  * @param   pszBuf              The path buffer.  Contains the abs path to the
    726  *                              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 > 2
    747             || (   pDirEntry->cbName == 2
    748                 && 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 root
    828        slash problem and can safely strip any trailing slashes and add a
    829        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_FOUND
    841         || 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 was
    853        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 
    864721RTDECL(int) RTDirFlushParent(const char *pszChild)
    865722{
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette