VirtualBox

Changeset 105631 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
Aug 9, 2024 12:59:18 AM (7 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164320
Message:

IPRT/RTPathUnlink: Implemented NT and posix versions w/ simple testcase.

File:
1 edited

Legend:

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

    r98103 r105631  
    313313RTR3DECL(int) RTPathUnlink(const char *pszPath, uint32_t fUnlink)
    314314{
    315     RT_NOREF_PV(pszPath); RT_NOREF_PV(fUnlink);
    316     return VERR_NOT_IMPLEMENTED;
     315    /*
     316     * Validate input.
     317     */
     318    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     319    AssertReturn(*pszPath, VERR_INVALID_NAME);
     320    AssertReturn(!(fUnlink & ~RTPATHUNLINK_FLAGS_NO_SYMLINKS), VERR_INVALID_FLAGS);
     321
     322    /*
     323     * Convert the path.
     324     */
     325    char const *pszNativePath;
     326    int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
     327    if (RT_SUCCESS(rc))
     328    {
     329        /*
     330         * Check if it's a directory using lstat, since unlink() may have adverse
     331         * side effects when running as root on some file systems (at least on
     332         * Solaris).
     333         *
     334         * There are of course race conditions here, but w/o a NT style removal
     335         * API it is not possible to do this w/o a race.
     336         *
     337         * Note! We cannot just use rmdir here, in case the final entity is a
     338         *       symlink pointing at a directory, as we're supposed to remove
     339         *       the symlink when that's the case.
     340         */
     341        struct stat Stat;
     342        rc = lstat(pszNativePath, &Stat);
     343        if (rc || !S_ISDIR(Stat.st_mode))
     344        {
     345            rc = unlink(pszNativePath);
     346            if (rc == 0)
     347                rc = VINF_SUCCESS;
     348            else
     349            {
     350                rc = errno;
     351                if (rc != ENOENT)
     352                    rc = RTErrConvertFromErrno(rc);
     353                else
     354                {
     355                    /*
     356                     * Make the path-not-found match windows.
     357                     */
     358                    rc = VERR_FILE_NOT_FOUND;
     359                    size_t cch = strlen(pszNativePath);
     360                    while (cch > 0 && RTPATH_IS_SLASH(pszNativePath[cch - 1]))
     361                        cch--;
     362                    while (cch > 0 && !RTPATH_IS_SLASH(pszNativePath[cch - 1]))
     363                        cch--;
     364                    while (cch > 0 && RTPATH_IS_SLASH(pszNativePath[cch - 1]))
     365                        cch--;
     366                    if (cch >= 1)
     367                    {
     368                        char *pszParent = (char *)RTMemTmpAlloc(cch + 1);
     369                        if (pszParent)
     370                        {
     371                            memcpy(pszParent, pszNativePath, cch);
     372                            pszParent[cch] = '\0';
     373                            if (stat(pszParent, &Stat) && errno == ENOENT)
     374                                rc = VERR_PATH_NOT_FOUND;
     375                            RTMemTmpFree(pszParent);
     376                        }
     377                    }
     378                }
     379            }
     380        }
     381        else
     382        {
     383            rc = rmdir(pszNativePath);
     384            if (rc)
     385            {
     386                rc = errno;
     387                if (rc == EEXIST) /* Solaris returns this, the rest have ENOTEMPTY. */
     388                    rc = VERR_DIR_NOT_EMPTY;
     389                else
     390                    rc = RTErrConvertFromErrno(rc);
     391            }
     392        }
     393
     394        rtPathFreeNative(pszNativePath, pszPath);
     395    }
     396    return rc;
    317397}
    318398
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