VirtualBox

Changeset 3365 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jul 3, 2007 12:01:44 AM (17 years ago)
Author:
vboxsync
Message:

Runtime: Fixed the POSIX version of RTPathAbs() so that it now correctly works on systems that HAVE_DRIVE and HAVE_UNS (e.g. OS/2).

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/path-posix.cpp

    r2981 r3365  
    9797 * Cleans up a path specifier a little bit.
    9898 * This includes removing duplicate slashes, uncessary single dots, and
    99  * trailing slashes.
     99 * trailing slashes. Also, replaces all RTPATH_SLASH characters with '/'.
    100100 *
    101101 * @returns Number of bytes in the clean path.
     
    124124    {
    125125        char ch = *pszSrc++;
    126         if (RTPATH_IS_SEP(ch))
    127         {
    128             *pszTrg++ = RTPATH_SLASH;
     126        if (RTPATH_IS_SLASH(ch))
     127        {
     128            *pszTrg++ = '/';
    129129            for (;;)
    130130            {
    131131                do  ch = *pszSrc++;
    132                 while (RTPATH_IS_SEP(ch));
     132                while (RTPATH_IS_SLASH(ch));
    133133
    134134                /* Remove '/./' and '/.'. */
    135                 if (ch != '.' || (*pszSrc && !RTPATH_IS_SEP(*pszSrc)))
     135                if (ch != '.' || (*pszSrc && !RTPATH_IS_SLASH(*pszSrc)))
    136136                    break;
    137137            }
     
    148148    int cch = pszTrg - pszPath;
    149149    if (    cch > 1
    150         &&  pszTrg[-1] == RTPATH_SLASH
     150        &&  RTPATH_IS_SLASH(pszTrg[-1])
    151151#ifdef HAVE_DRIVE
    152         &&  pszTrg[-2] != ':'
    153 #endif
    154         &&  pszTrg[-2] != RTPATH_SLASH)
     152        &&  !RTPATH_IS_VOLSEP(pszTrg[-2])
     153#endif
     154        &&  !RTPATH_IS_SLASH(pszTrg[-2]))
    155155        pszPath[--cch] = '\0';
    156156
     
    168168    if (RT_FAILURE(rc))
    169169    {
    170         LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath));
     170        LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
     171                 pszPath, pszAbsPath, cchAbsPath, rc));
    171172        return rc;
    172173    }
     
    180181    if (!psz)
    181182    {
    182         if (errno == ENOENT || errno == ENOTDIR)
     183        if (errno == ENOENT || errno == ENOTDIR
     184#ifdef __OS2__
     185            /// @todo realpath() returns EIO for non-existent UNC paths like
     186            //  //server/share/subdir (i.e. when a subdir is specified within
     187            //  a share). We should either fix realpath() in libc or remove
     188            //  this todo.
     189            || errno == EIO
     190#endif
     191            )
    183192        {
    184193            if (strlen(pszNativePath) <= PATH_MAX)
     
    195204                char *pszCur = szTmpSrc;
    196205
    197                 if (*pszCur == RTPATH_SLASH)
     206#ifdef HAVE_DRIVE
     207                if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/')
     208                {
     209                    psz = szTmpPath;
     210                    cch = 2;
     211                    pszCur += 3;
     212                }
     213#ifdef HAVE_UNC
     214                else
     215                if (pszCur[0] == '/' && pszCur[1] == '/')
     216                {
     217                    pszCur += 2;
     218                    char *pszSlash = strchr(pszCur, '/');
     219                    size_t cchElement = pszSlash ? pszSlash - pszCur : strlen(pszCur);
     220                    if (cchElement && pszCur[cchElement])
     221                    {
     222                        psz = szTmpPath;
     223                        cch = cchElement + 2;
     224                        pszCur += cchElement + 1;
     225                    }
     226                    else
     227                        /* we've got just "//server" or "//" */
     228                        /// @todo (r=dmik) not 100% sure we should fail, but the
     229                        //  above cases are just invalid (incomplete) paths,
     230                        //  no matter that Win32 returns these paths as is.
     231                        rc = VERR_INVALID_NAME;
     232                }
     233#endif
     234#else
     235                if (*pszCur == '/')
    198236                {
    199237                    psz = szTmpPath;
    200238                    pszCur++;
    201239                }
     240#endif
    202241                else
    203242                {
     
    206245                    AssertMsg(psz, ("Couldn't get cwd!\n"));
    207246                    if (psz)
    208                         cch = strlen(psz);
     247                    {
     248#ifdef HAVE_DRIVE
     249                        if (*pszCur == '/')
     250                        {
     251                            cch = 2;
     252                            pszCur++;
     253                        }
     254                        else
     255#endif
     256                            cch = strlen(psz);
     257                    }
    209258                    else
    210259                        rc = RTErrConvertFromErrno(errno);
     
    216265                    char szTmpPath2[PATH_MAX + 1];
    217266
     267                    /* make sure strrchr() will work correctly */
     268                    psz[cch] = '\0';
     269
    218270                    while (*pszCur)
    219271                    {
    220                         char *pszSlash = strchr(pszCur, RTPATH_SLASH);
     272                        char *pszSlash = strchr(pszCur, '/');
    221273                        size_t cchElement = pszSlash ? pszSlash - pszCur : strlen(pszCur);
    222274                        if (cch + cchElement + 1 > PATH_MAX)
     
    228280                        if (!strncmp(pszCur, "..", cchElement))
    229281                        {
    230                             char *pszLastSlash = strrchr(psz, RTPATH_SLASH);
     282                            char *pszLastSlash = strrchr(psz, '/');
     283#ifdef HAVE_UNC
     284                            if (pszLastSlash && pszLastSlash > psz &&
     285                                pszLastSlash[-1] != '/')
     286#else
    231287                            if (pszLastSlash)
     288#endif
    232289                            {
    233290                                cch = pszLastSlash - psz;
    234291                                psz[cch] = '\0';
    235292                            }
    236                             /* else: We've reached the root and the parent of the root is the root. */
     293                            /* else: We've reached the root and the parent of
     294                             * the root is the root. */
    237295                        }
    238296                        else
    239297                        {
    240                             psz[cch++] = RTPATH_SLASH;
     298                            psz[cch++] = '/';
    241299                            memcpy(psz + cch, pszCur, cchElement);
    242300                            cch += cchElement;
     
    256314                                else
    257315                                {
    258                                     if (errno != ENOENT && errno != ENOTDIR)
     316                                    if (errno != ENOENT && errno != ENOTDIR
     317#ifdef __OS2__
     318                                        /// @todo see above
     319                                        && errno != EIO
     320#endif
     321                                        )
    259322                                    {
    260323                                        rc = RTErrConvertFromErrno(errno);
     
    274337                    }
    275338
    276                     /* if the length is zero here, then we're at the root (Not true for half-posixs stuff such as libc!) */
     339#ifdef HAVE_DRIVE
     340                    /* check if we're at the root */
     341                    if (cch == 2 && RTPATH_IS_VOLSEP(psz[1]))
     342#else
     343                    /* if the length is zero here, then we're at the root */
    277344                    if (!cch)
     345#endif
    278346                    {
    279                         psz[cch++] = RTPATH_SLASH;
     347                        psz[cch++] = '/';
    280348                        psz[cch] = '\0';
    281349                    }
     
    300368        if (RT_FAILURE(rc))
    301369        {
    302             LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath));
     370            LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
     371                     pszPath, pszAbsPath, cchAbsPath, rc));
    303372            return rc;
    304373        }
     374
     375        /* replace '/' back with native RTPATH_SLASH */
     376        psz = pszUtf8AbsPath;
     377        for (; *psz; psz++)
     378            if (*psz == '/')
     379                *psz = RTPATH_SLASH;
    305380
    306381        unsigned cch = strlen(pszUtf8AbsPath) + 1;
     
    312387    }
    313388
    314     LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, pszPath,
    315              pszAbsPath, RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cchAbsPath));
     389    LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath,
     390             pszPath, pszAbsPath, RT_SUCCESS(rc) ? pszAbsPath : "<failed>",
     391             cchAbsPath, rc));
    316392    return rc;
    317393}
  • trunk/src/VBox/Runtime/testcase/tstPath.cpp

    r2981 r3365  
    6969        NULL,                           "/absolute/../../path",
    7070        NULL,                           "relative/../dir\\.\\.\\.\\file.txt",
     71        NULL,                           "\\",
    7172        "relative_base/dir\\",          "\\from_root",
    7273        "relative_base/dir/",           "relative_also",
    7374#if defined (__OS2__) || defined (__WIN__)
     75        NULL,                           "C:\\",
     76        "C:\\",                         "..",
    7477        "C:\\temp",                     "..",
    7578        "C:\\VirtualBox/Machines",      "..\\VirtualBox.xml",
    7679        "C:\\MustDie",                  "\\from_root/dir/..",
    7780        "C:\\temp",                     "D:\\data",
    78         NULL,                           "\\\\server\\../share", // -- GetFullPathName doesn't remove .. here
     81        NULL,                           "\\\\server\\../share", // -- on Win32, GetFullPathName doesn't remove .. here
     82        /* the three below use cases should fail with VERR_INVALID_NAME */
     83        //NULL,                           "\\\\server",
     84        //NULL,                           "\\\\",
     85        //NULL,                           "\\\\\\something",
    7986        "\\\\server\\share_as_base",    "/from_root",
    8087        "\\\\just_server",              "/from_root",
    8188        "\\\\server\\share_as_base",    "relative\\data",
    8289        "base",                         "\\\\?\\UNC\\relative/edwef/..",
    83         // this is not (and I guess should not be) supported
    84         ///@todo "\\\\?\\UNC\\base",             "/from_root", - r=bird: negative tests shouldn't fail the testcase!
     90        "base",                         "\\\\?\\UNC\\relative/edwef/..",
     91        /* this is not (and I guess should not be) supported, should fail */
     92        ///@todo "\\\\?\\UNC\\base",             "/from_root",
    8593#else
    8694        "\\temp",                       "..",
Note: See TracChangeset for help on using the changeset viewer.

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