dir-posix.cpp revision bc57d7ed1ae5b66aa39acfd75e49f17e72a98bed
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * IPRT - Directory manipulation, POSIX.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * available from http://www.virtualbox.org. This file is free software;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * you can redistribute it and/or modify it under the terms of the GNU
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * General Public License (GPL) as published by the Free Software
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * The contents of this file may alternatively be used under the terms
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * of the Common Development and Distribution License Version 1.0
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * VirtualBox OSE distribution, in which case the provisions of the
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * CDDL are applicable instead of those of the GPL.
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * You may elect to license modified versions of this file under the
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * terms and conditions of either the GPL or the CDDL or both.
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * additional information or have any questions.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync/*******************************************************************************
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync* Header Files *
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync*******************************************************************************/
ae5fc6ddd3d2ccdb941b1aacd23f6791fecc3354vboxsync bool fRc = false;
ae5fc6ddd3d2ccdb941b1aacd23f6791fecc3354vboxsync LogFlow(("RTDirExists(%p={%s}): returns %RTbool\n", pszPath, pszPath, fRc));
ae5fc6ddd3d2ccdb941b1aacd23f6791fecc3354vboxsyncRTDECL(int) RTDirCreate(const char *pszPath, RTFMODE fMode)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * mkdir on nfs mount points has been/is busted in various
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * during the Nevada development cycle. We've observed:
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * - Build 111b (2009.06) returns EACCES.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * - Build ca. 70-80 returns ENOSYS.
ed82223f8f7be1435bf9b203a0ee4fbdfc856dc8vboxsync AssertMsgFailed(("Invalid file mode! %RTfmode\n", fMode));
ed82223f8f7be1435bf9b203a0ee4fbdfc856dc8vboxsync LogFlow(("RTDirCreate(%p={%s}, %RTfmode): returns %Rrc\n", pszPath, pszPath, fMode, rc));
f3abe19bdaeea1b354674327ee95707281a6ad83vboxsync LogFlow(("RTDirRemove(%p={%s}): returns %Rrc\n", pszPath, pszPath, rc));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Convert to a native path and try opendir.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = rtPathToNative(&pszNativePath, pDir->pszPath);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Init data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync memset(&pDir->Data, 0, RT_OFFSETOF(RTDIR, Data.d_name)); /* not strictly necessary */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Validate input.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Close the handle.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgFailed(("closedir(%p) -> errno=%d (%Rrc)\n", pDir->pDir, errno, rc));
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Ensure that there is unread data in the buffer
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * and that there is a converted filename hanging around.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns IPRT status code.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pDir the open directory. Fully validated.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /** @todo try avoid the rematching on buffer overflow errors. */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Fetch data?
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = readdir_r(pDir->pDir, &pDir->Data, &pResult);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Convert the filename to UTF-8.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = rtPathFromNativeEx(&pDir->pszName, pDir->Data.d_name, pDir->pszPath);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Converts the d_type field to IPRT directory entry type.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @returns IPRT directory entry type.
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * @param Unix
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync#endif /*HAVE_DIRENT_D_TYPE */
78df65edff21c11c537f38e736707ea434ab5623vboxsyncRTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry)
78df65edff21c11c537f38e736707ea434ab5623vboxsync * Validate and digest input.
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync AssertMsgReturn(VALID_PTR(pDirEntry), ("%p\n", pDirEntry), VERR_INVALID_POINTER);
e43d0b86db65e202efb63f0fc5fce1f981267a32vboxsync AssertMsgReturn(VALID_PTR(pcbDirEntry), ("%p\n", pcbDirEntry), VERR_INVALID_POINTER);
78df65edff21c11c537f38e736707ea434ab5623vboxsync AssertMsgReturn(cbDirEntry >= RT_UOFFSETOF(RTDIRENTRY, szName[2]),
e43d0b86db65e202efb63f0fc5fce1f981267a32vboxsync ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRYEX, szName[2])),
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Fetch more data if necessary and/or convert the name.
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync * Check if we've got enough space to return the data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync const size_t cbRequired = RT_OFFSETOF(RTDIRENTRY, szName[1]) + cchName;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Setup the returned data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pDirEntry->INodeId = pDir->Data.d_ino; /* may need #ifdefing later */
e43d0b86db65e202efb63f0fc5fce1f981267a32vboxsync /* free cached data */
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync LogFlow(("RTDirRead(%p:{%s}, %p:{%s}, %p:{%u}): returns %Rrc\n",
f632be0ea31134f1ce343e84c90d7984d2bf96b2vboxsync pDir, pDir->pszPath, pDirEntry, RT_SUCCESS(rc) ? pDirEntry->szName : "<failed>",
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Fills dummy info into the info structure.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * This function is called if we cannot stat the file.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * @param pInfo The struct in question.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncstatic void rtDirSetDummyInfo(PRTFSOBJINFO pInfo, RTDIRENTRYTYPE enmType)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync pInfo->Attr.enmAdditional = RTFSOBJATTRADD_NOTHING;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_UNKNOWN: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_FIFO: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_FIFO;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_DEV_CHAR: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_DEV_CHAR;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_DIRECTORY: pInfo->Attr.fMode = RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_DEV_BLOCK: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_DEV_BLOCK;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_FILE: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_FILE;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_SYMLINK: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_SYMLINK;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_SOCKET: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_SOCKET;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync case RTDIRENTRYTYPE_WHITEOUT: pInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_WHITEOUT;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsyncRTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Validate and digest input.
5d6df5999c0e844db1af3c6def0a9abac5120d3bvboxsync AssertMsgReturn(VALID_PTR(pDirEntry), ("%p\n", pDirEntry), VERR_INVALID_POINTER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn( enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs),
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(VALID_PTR(pcbDirEntry), ("%p\n", pcbDirEntry), VERR_INVALID_POINTER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(cbDirEntry >= (unsigned)RT_OFFSETOF(RTDIRENTRYEX, szName[2]),
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRYEX, szName[2])),
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Fetch more data if necessary and/or convert the name.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Check if we've got enough space to return the data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync const size_t cbRequired = RT_OFFSETOF(RTDIRENTRYEX, szName[1]) + cchName;
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Setup the returned data.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* get the info data */
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync memcpy(pszNamePath + pDir->cchPath, pszName, cchName + 1);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rc = RTPathQueryInfo(pszNamePath, &pDirEntry->Info, enmAdditionalAttribs);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync rtDirSetDummyInfo(&pDirEntry->Info, rtDirType(pDir->Data.d_type));
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsync rtDirSetDummyInfo(&pDirEntry->Info, RTDIRENTRYTYPE_UNKNOWN);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync /* free cached data */
7fee49908ea4b9f6cb4f9cc745633c4969ed6318vboxsyncRTDECL(int) RTDirRename(const char *pszSrc, const char *pszDst, unsigned fRename)
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Validate input.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(VALID_PTR(pszSrc), ("%p\n", pszSrc), VERR_INVALID_POINTER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(VALID_PTR(pszDst), ("%p\n", pszDst), VERR_INVALID_POINTER);
090c459b9e90ca46e2ce2b8c81533ade3b23f3e9vboxsync AssertMsgReturn(*pszSrc, ("%p\n", pszSrc), VERR_INVALID_PARAMETER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(*pszDst, ("%p\n", pszDst), VERR_INVALID_PARAMETER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync AssertMsgReturn(!(fRename & ~RTPATHRENAME_FLAGS_REPLACE), ("%#x\n", fRename), VERR_INVALID_PARAMETER);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync * Take common cause with RTPathRename.
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync int rc = rtPathPosixRename(pszSrc, pszDst, fRename, RTFS_TYPE_DIRECTORY);
30a23dfc653298a09d77d3045cf873b1bd6ddecfvboxsync LogFlow(("RTDirRename(%p:{%s}, %p:{%s}): returns %Rrc\n",