From: VMware, Inc <> Date: Wed, 26 Dec 2012 21:26:12 +0000 (-0800) Subject: HGFS: Cleanup the directory entry code to be really platform specific - part V X-Git-Tag: 2012.12.26-958366~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3fd89fa76b058b58356a32d045e7575a5ad69a4a;p=thirdparty%2Fopen-vm-tools.git HGFS: Cleanup the directory entry code to be really platform specific - part V Moving the platform dependent definitions to the platform specific files. They should be private types to each platform so each can define and use them as efficiently as makes sense for that platform. Now moving the structure types to the platform only code. Only a forward declaration is now public. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index 706390743..c88e9ee61 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -2522,14 +2522,14 @@ exit: */ HgfsInternalStatus -HgfsServerGetDirEntry(HgfsHandle handle, // IN: Handle to search - HgfsSessionInfo *session, // IN: Session info - uint32 index, // IN: index to retrieve at - Bool remove, // IN: If true, removes the result - DirectoryEntry **dirEntry) // OUT: directory entry +HgfsServerGetDirEntry(HgfsHandle handle, // IN: Handle to search + HgfsSessionInfo *session, // IN: Session info + uint32 index, // IN: index to retrieve at + Bool remove, // IN: If true, removes the result + struct DirectoryEntry **dirEntry) // OUT: directory entry { HgfsSearch *search; - DirectoryEntry *dent = NULL; + struct DirectoryEntry *dent = NULL; HgfsInternalStatus status = HGFS_ERROR_SUCCESS; MXUser_AcquireExclLock(session->searchArrayLock); @@ -7434,7 +7434,7 @@ HgfsGetDirEntry(HgfsHandle hgfsSearchHandle, // IN: ID for search data Bool *moreEntries) // OUT: any more entries { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; - DirectoryEntry *dent; + struct DirectoryEntry *dent; HgfsSearchReadMask infoRetrieved; HgfsSearchReadMask infoRequested; HgfsFileAttrInfo *entryAttr; diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h index 6b0c4dfa0..a2a63f2ce 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h +++ b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h @@ -22,50 +22,13 @@ #include "vm_basic_types.h" -/* - * Definitions of wrapped internal primitives. - * - * We wrap open file handles and directory entries so that cross-platform HGFS - * server code can use them without platform-specific pre-processing. - * - * On Linux, we use dirent64 from the kernel headers so as to alleviate any - * confusion between what the kernel will give us from the getdents64() - * syscall and what userspace will expect. Note that to avoid depending on - * kernel headers directly, I've copied the dirent struct, replacing certain - * kernel basic types with our own. - * - * On Windows, we define our own DirectoryEntry struct with d_reclen and - * d_name, as those are the only two fields we're interested in. It's not - * essential that it match the dirents from another platform, because we - * control how they get created and populated, and they never pass down a wire. - * - * Otherwise, we use the native dirent struct provided by the platform's libc, - * as nobody else seems to suffer from the 32-bit vs. 64-bit ino_t and off_t - * insanity that plagues Linux. - */ +struct DirectoryEntry; + #ifndef _WIN32 -# ifdef linux - typedef struct DirectoryEntry { - uint64 d_ino; - uint64 d_off; - uint16 d_reclen; - uint8 d_type; - char d_name[256]; - } DirectoryEntry; -# else -# include - typedef struct dirent DirectoryEntry; -# endif typedef int fileDesc; #else # include typedef HANDLE fileDesc; - typedef struct DirectoryEntry { - unsigned short d_reclen; /* The total length of this record. */ - char d_name[PATH_MAX * 4]; /* 4 bytes is the maximum size of a utf8 */ - /* representation of utf-16 encoded */ - /* unicode character in the BMP */ - } DirectoryEntry; #endif #include "dbllnklst.h" @@ -259,7 +222,7 @@ typedef struct HgfsSearch { size_t utf8ShareNameLen; /* Directory entries for this search */ - DirectoryEntry **dents; + struct DirectoryEntry **dents; /* Number of dents */ uint32 numDents; @@ -576,7 +539,7 @@ HgfsServerDirDumpDents(HgfsHandle searchHandle, // IN: Handle to dump dents fr #endif -DirectoryEntry * +struct DirectoryEntry * HgfsGetSearchResult(HgfsHandle handle, // IN: Handle to search HgfsSessionInfo *session, // IN: Session info uint32 offset, // IN: Offset to retrieve at @@ -609,11 +572,11 @@ HgfsServerIsSharedFolderOnly(char const *in, // IN: CP filename to check size_t inSize); // IN: Size of name in HgfsInternalStatus -HgfsServerGetDirEntry(HgfsHandle handle, // IN: Handle to search - HgfsSessionInfo *session, // IN: Session info - uint32 index, // IN: index to retrieve at - Bool remove, // IN: If true, removes the result - DirectoryEntry **dirEntry);// OUT: directory entry +HgfsServerGetDirEntry(HgfsHandle handle, // IN: Handle to search + HgfsSessionInfo *session, // IN: Session info + uint32 index, // IN: index to retrieve at + Bool remove, // IN: If true, removes the result + struct DirectoryEntry **dirEntry);// OUT: directory entry HgfsInternalStatus HgfsServerSearchRealDir(char const *baseDir, // IN: Directory to search @@ -1144,31 +1107,31 @@ HgfsPlatformGetattrFromName(char *fileName, // IN: file name HgfsFileAttrInfo *attr, // OUT: file attributes char **targetName); // OUT: Symlink target HgfsInternalStatus -HgfsPlatformGetDirEntry(HgfsSearch *search, // IN: search - HgfsSessionInfo *session, // IN: Session info - uint32 offset, // IN: Offset to retrieve at - Bool remove, // IN: If true, removes the result - DirectoryEntry **dirEntry); // OUT: dirent +HgfsPlatformGetDirEntry(HgfsSearch *search, // IN: search + HgfsSessionInfo *session, // IN: Session info + uint32 offset, // IN: Offset to retrieve at + Bool remove, // IN: If true, removes the result + struct DirectoryEntry **dirEntry); // OUT: dirent HgfsInternalStatus -HgfsPlatformSetDirEntry(HgfsSearch *search, // IN: search +HgfsPlatformSetDirEntry(HgfsSearch *search, // IN: search HgfsShareOptions configOptions, // IN: share configuration settings - HgfsSessionInfo *session, // IN: session info - DirectoryEntry *dirEntry, // IN: the indexed dirent - Bool getAttr, // IN: get the entry attributes - HgfsFileAttrInfo *entryAttr, // OUT: entry attributes, optional - char **entryName, // OUT: entry name - uint32 *entryNameLength); // OUT: entry name length + HgfsSessionInfo *session, // IN: session info + struct DirectoryEntry *dirEntry, // IN: the indexed dirent + Bool getAttr, // IN: get the entry attributes + HgfsFileAttrInfo *entryAttr, // OUT: entry attributes, optional + char **entryName, // OUT: entry name + uint32 *entryNameLength); // OUT: entry name length HgfsInternalStatus -HgfsPlatformScandir(char const *baseDir, // IN: Directory to search in - size_t baseDirLen, // IN: Length of directory - Bool followSymlinks, // IN: followSymlinks config option - DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys - int *numDents); // OUT: Number of DirectoryEntrys +HgfsPlatformScandir(char const *baseDir, // IN: Directory to search in + size_t baseDirLen, // IN: Length of directory + Bool followSymlinks, // IN: followSymlinks config option + struct DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys + int *numDents); // OUT: Number of DirectoryEntrys HgfsInternalStatus HgfsPlatformScanvdir(HgfsGetNameFunc enumNamesGet, // IN: Function to get name HgfsInitFunc enumNamesInit, // IN: Setup function HgfsCleanupFunc enumNamesExit, // IN: Cleanup function - DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys + struct DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys uint32 *numDents); // OUT: total number of directory entrys HgfsInternalStatus HgfsPlatformSearchDir(HgfsNameStatus nameStatus, // IN: name status diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerLinux.c b/open-vm-tools/lib/hgfsServer/hgfsServerLinux.c index 8c6a013c7..1188ed0a2 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerLinux.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServerLinux.c @@ -85,6 +85,25 @@ #include // for VERG / VDIR #endif +#ifdef linux +typedef struct DirectoryEntry { + uint64 d_ino; + uint64 d_off; + uint16 d_reclen; + uint8 d_type; + char d_name[256]; +} DirectoryEntry; +#else +#include +typedef struct DirectoryEntry { + uint64 d_ino; + uint16 d_reclen; + uint16 d_namlen; + uint8 d_type; + char d_name[1024]; +} DirectoryEntry; +#endif + /* * ALLPERMS (mode 07777) and ACCESSPERMS (mode 0777) are not defined in the * Solaris version of . @@ -173,8 +192,18 @@ getdents_apple(DIR *fd, // IN struct dirent *dirEntry; dirEntry = readdir(fd); if (NULL != dirEntry) { - memcpy(dirp, dirEntry, dirEntry->d_reclen); - res = dirEntry->d_reclen; + /* + * Assert that the hgfs DirectoryEntry version and system dirent + * name fields are of the same size. Since that is where it was taken from. + */ + ASSERT_ON_COMPILE(sizeof dirp->d_name == sizeof dirEntry->d_name); + + dirp->d_ino = dirEntry->d_ino; + dirp->d_type = dirEntry->d_type; + dirp->d_namlen = dirEntry->d_namlen; + memcpy(dirp->d_name, dirEntry->d_name, dirEntry->d_namlen + 1); + dirp->d_reclen = offsetof(DirectoryEntry, d_name) + dirp->d_namlen + 1; + res = dirp->d_reclen; } return res; } @@ -3300,11 +3329,11 @@ HgfsConvertToUtf8FormC(char *buffer, // IN/OUT: name to normalize */ HgfsInternalStatus -HgfsPlatformGetDirEntry(HgfsSearch *search, // IN: search - HgfsSessionInfo *session, // IN: Session info - uint32 index, // IN: Offset to retrieve at - Bool remove, // IN: If true, removes the result - DirectoryEntry **dirEntry) // OUT: dirent +HgfsPlatformGetDirEntry(HgfsSearch *search, // IN: search + HgfsSessionInfo *session, // IN: Session info + uint32 index, // IN: Offset to retrieve at + Bool remove, // IN: If true, removes the result + struct DirectoryEntry **dirEntry) // OUT: dirent { DirectoryEntry *dent = NULL; HgfsInternalStatus status = HGFS_ERROR_SUCCESS; @@ -3385,14 +3414,14 @@ out: */ HgfsInternalStatus -HgfsPlatformSetDirEntry(HgfsSearch *search, // IN: partially valid search +HgfsPlatformSetDirEntry(HgfsSearch *search, // IN: partially valid search HgfsShareOptions configOptions, // IN: share configuration settings - HgfsSessionInfo *session, // IN: session info - DirectoryEntry *dirEntry, // IN: the indexed dirent - Bool getAttr, // IN: get the entry attributes - HgfsFileAttrInfo *entryAttr, // OUT: entry attributes, optional - char **entryName, // OUT: entry name - uint32 *entryNameLength) // OUT: entry name length + HgfsSessionInfo *session, // IN: session info + struct DirectoryEntry *dirEntry, // IN: the indexed dirent + Bool getAttr, // IN: get the entry attributes + HgfsFileAttrInfo *entryAttr, // OUT: entry attributes, optional + char **entryName, // OUT: entry name + uint32 *entryNameLength) // OUT: entry name length { HgfsInternalStatus status = HGFS_ERROR_SUCCESS; unsigned int length; @@ -3583,11 +3612,11 @@ HgfsPlatformSetDirEntry(HgfsSearch *search, // IN: partially valid sear */ HgfsInternalStatus -HgfsPlatformScandir(char const *baseDir, // IN: Directory to search in - size_t baseDirLen, // IN: Ignored - Bool followSymlinks, // IN: followSymlinks config option - DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys - int *numDents) // OUT: Number of DirectoryEntrys +HgfsPlatformScandir(char const *baseDir, // IN: Directory to search in + size_t baseDirLen, // IN: Ignored + Bool followSymlinks, // IN: followSymlinks config option + struct DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys + int *numDents) // OUT: Number of DirectoryEntrys { #if defined(__APPLE__) DIR *fd = NULL; @@ -3766,7 +3795,7 @@ HgfsInternalStatus HgfsPlatformScanvdir(HgfsGetNameFunc enumNamesGet, // IN: Function to get name HgfsInitFunc enumNamesInit, // IN: Setup function HgfsCleanupFunc enumNamesExit, // IN: Cleanup function - DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys + struct DirectoryEntry ***dents, // OUT: Array of DirectoryEntrys uint32 *numDents) // OUT: total number of directory entrys { HgfsInternalStatus status = HGFS_ERROR_SUCCESS;