On Tue, Dec 29, 2020 at 05:57:11AM +0000, Dimitri Karamazov wrote:
>
> Apart from this, the following code is giving me grief.
> I see no way but to circumvent it's use, or is there?
> This code tries to get a file Name from a file Pointer.
>
first, it isn't supported on OpenBSD. You can't get a filename from a
file descriptor.
So, you will need to figure if it is possible to not use
ArchGetFileName().
I can't really comment on your error. I am not enough familiar with
C++ or with this code.
> string
> ArchGetFileName(FILE *file)
> {
> #if defined (ARCH_OS_LINUX)
> string result;
> char buf[PATH_MAX];
> ssize_t r = readlink(
> ArchStringPrintf("/proc/self/fd/%d", fileno(file)).c_str(),
> buf, sizeof(buf));
> if (r != -1) {
> result.assign(buf, buf + r);
> }
> return result;
> #elif defined (ARCH_OS_DARWIN)
> string result;
> char buf[MAXPATHLEN];
> if (fcntl(fileno(file), F_GETPATH, buf) != -1) {
> result = buf;
> }
> return result;
> #elif defined (ARCH_OS_WINDOWS)
> static constexpr DWORD bufSize =
> sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * 4096;
> HANDLE hfile = _FileToWinHANDLE(file);
> auto fileNameInfo = reinterpret_cast<PFILE_NAME_INFO>(malloc(bufSize));
> string result;
> if (GetFileInformationByHandleEx(
> hfile, FileNameInfo, static_cast<void *>(fileNameInfo), bufSize))
> {
> size_t outSize = WideCharToMultiByte(
> CP_UTF8, 0, fileNameInfo->FileName,
> fileNameInfo->FileNameLength/sizeof(WCHAR),
> NULL, 0, NULL, NULL);
> result.resize(outSize);
> WideCharToMultiByte(
> CP_UTF8, 0, fileNameInfo->FileName,
> fileNameInfo->FileNameLength/sizeof(WCHAR),
> &result.front(), outSize, NULL, NULL);
> }
> free(fileNameInfo);
> return result;
> #else
> #error Unknown system architecture
> #endif
> }
>
> And it is referenced here or see the attached file for better context.
>
> /* static */
> std::unique_ptr<CrateFile>
> CrateFile::Open(string const &assetPath)
> {
> TfAutoMallocTag tag2("Usd_CrateFile::CrateFile::Open");
>
> std::unique_ptr<CrateFile> result;
>
> // Fetch the asset from Ar.
> auto asset = ArGetResolver().OpenAsset(assetPath);
> if (!asset) {
> TF_RUNTIME_ERROR("Failed to open asset '%s'", assetPath.c_str());
> return result;
> }
>
> // See if we can get an underlying FILE * for the asset.
> FILE *file; size_t offset;
> std::tie(file, offset) = asset->GetFileUnsafe();
> if (file) {
> // If so, then we'll either mmap it or use pread() on it.
> if (!TfGetenvBool("USDC_USE_PREAD", false)) {
> // Try to memory-map the file.
> auto mapping = _MmapAsset(assetPath.c_str(), asset);
> result.reset(new CrateFile(assetPath, ArchGetFileName(file),
> std::move(mapping), asset));
> } else {
> // Use pread with the asset's file.
> result.reset(new CrateFile(
> assetPath, ArchGetFileName(file),
> _FileRange(
> file, offset, asset->GetSize(),
> /*hasOwnership=*/ false),
> asset));
> }
> }
> else {
> // With no underlying FILE *, we'll go through ArAsset::Read()
> directly.
> result.reset(new CrateFile(assetPath, asset));
> }
>
> // If the resulting CrateFile has no asset path, reading failed.
> if (result->GetAssetPath().empty())
> result.reset();
>
> return result;
> }
>
> I think the fileName variable which is referenced a lot in the file is
> what the ArchGetFileName tries to get but indirectly (probably as a
> check?). But I fail to alter this by just adding another argument
> as below so as to directly refer to it.
>
> --- pxr/usd/usd/crateFile.cpp.orig Wed Oct 14 23:55:19 2020
> +++ pxr/usd/usd/crateFile.cpp Sun Dec 27 10:28:48 2020
> @@ -2105,7 +2105,7 @@ CrateFile::_MmapFile(char const *fileName, FILE *file)
>
> /* static */
> std::unique_ptr<CrateFile>
> -CrateFile::Open(string const &assetPath)
> +CrateFile::Open(string const &assetPath,string const &fileName)
> {
> TfAutoMallocTag tag2("Usd_CrateFile::CrateFile::Open");
>
> @@ -2126,12 +2126,12 @@ CrateFile::Open(string const &assetPath)
> if (!TfGetenvBool("USDC_USE_PREAD", false)) {
> // Try to memory-map the file.
> auto mapping = _MmapAsset(assetPath.c_str(), asset);
> - result.reset(new CrateFile(assetPath, ArchGetFileName(file),
> + result.reset(new CrateFile(assetPath, fileName,
> std::move(mapping), asset));
> } else {
> // Use pread with the asset's file.
> result.reset(new CrateFile(
> - assetPath, ArchGetFileName(file),
> + assetPath, fileName,
> _FileRange(
> file, offset, asset->GetSize(),
> /*hasOwnership=*/ false),
> @@ -2369,7 +2369,7 @@ CrateFile::CanPackTo(string const &fileName) const
> // Try to open \p fileName and get its filename.
> bool result = false;
> if (FILE *f = ArchOpenFile(fileName.c_str(), "rb")) {
> - if (ArchGetFileName(f) == _fileReadFrom) {
> + if (fileName == _fileReadFrom) {
> result = true;
> }
> fclose(f);
> @@ -2450,7 +2450,7 @@ CrateFile::Packer::Close()
> }
>
> // Reset the filename we've read content from.
> - _crate->_fileReadFrom = ArchGetFileName(fileRange.file);
> + _crate->_fileReadFrom = _crate->_packCtx->fileName;
>
> // Reset the mapping or file so we can read values from the newly
> // written file.
>
> The build ultimately fails. I would like to know if this approach is
> right and if it is what am I missing over here.
>
> ===> Building for usd-20.11
> [1/211] /usr/ports/pobj/usd-20.11/bin/c++ -DARCH_EXPORTS=1 -DAR_EXPORTS=1
> -DBOOST_PYTHON_NO_PY_SIGNATURES -DGF_EXPORTS=1 -DGLX_GLXEXT_PROTOTYPES
> -DGL_GLEXT_PROTOTYPES -DJS_EXPORTS=1 -DKIND_EXPORTS=1
> -DMFB_ALT_PACKAGE_NAME=usd -DMFB_PACKAGE_MODULE=Usd -DMFB_PACKAGE_NAME=usd
> -DNDR_EXPORTS=1 -DPCP_EXPORTS=1 -DPLUG_EXPORTS=1 -DPXR_BUILD_LOCATION=usd
> -DPXR_PLUGIN_BUILD_LOCATION=../plugin/usd -DPXR_PYTHON_ENABLED=1
> -DPXR_PYTHON_MODULES_ENABLED=1 -DSDF_EXPORTS=1 -DSDR_EXPORTS=1 -DTF_EXPORTS=1
> -DTRACE_EXPORTS=1 -DUSDGEOM_EXPORTS=1 -DUSDHYDRA_EXPORTS=1 -DUSDLUX_EXPORTS=1
> -DUSDMEDIA_EXPORTS=1 -DUSDRENDER_EXPORTS=1 -DUSDRI_EXPORTS=1
> -DUSDSHADE_EXPORTS=1 -DUSDSKEL_EXPORTS=1 -DUSDUI_EXPORTS=1
> -DUSDUTILS_EXPORTS=1 -DUSDVOL_EXPORTS=1 -DUSD_EXPORTS=1 -DVT_EXPORTS=1
> -DWORK_EXPORTS=1 -Ipxr/usd/usd
> -I/usr/ports/pobj/usd-20.11/USD-20.11/pxr/usd/usd -Iinclude -isystem
> /usr/local/include -Wall -pthread -Wno-deprecated
> -Wno-deprecated-declarations -Wno-unused-local-typedefs
> -Wno-unused-command-line-argument -O2 -pipe -DNDEBUG -fPIC -std=c++14 -MD
> -MT pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o -MF
> pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o.d -o
> pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o -c
> /usr/ports/pobj/usd-20.11/USD-20.11/pxr/usd/usd/crateFile.cpp
> FAILED: pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o
> /usr/ports/pobj/usd-20.11/bin/c++ -DARCH_EXPORTS=1 -DAR_EXPORTS=1
> -DBOOST_PYTHON_NO_PY_SIGNATURES -DGF_EXPORTS=1 -DGLX_GLXEXT_PROTOTYPES
> -DGL_GLEXT_PROTOTYPES -DJS_EXPORTS=1 -DKIND_EXPORTS=1
> -DMFB_ALT_PACKAGE_NAME=usd -DMFB_PACKAGE_MODULE=Usd -DMFB_PACKAGE_NAME=usd
> -DNDR_EXPORTS=1 -DPCP_EXPORTS=1 -DPLUG_EXPORTS=1 -DPXR_BUILD_LOCATION=usd
> -DPXR_PLUGIN_BUILD_LOCATION=../plugin/usd -DPXR_PYTHON_ENABLED=1
> -DPXR_PYTHON_MODULES_ENABLED=1 -DSDF_EXPORTS=1 -DSDR_EXPORTS=1 -DTF_EXPORTS=1
> -DTRACE_EXPORTS=1 -DUSDGEOM_EXPORTS=1 -DUSDHYDRA_EXPORTS=1 -DUSDLUX_EXPORTS=1
> -DUSDMEDIA_EXPORTS=1 -DUSDRENDER_EXPORTS=1 -DUSDRI_EXPORTS=1
> -DUSDSHADE_EXPORTS=1 -DUSDSKEL_EXPORTS=1 -DUSDUI_EXPORTS=1
> -DUSDUTILS_EXPORTS=1 -DUSDVOL_EXPORTS=1 -DUSD_EXPORTS=1 -DVT_EXPORTS=1
> -DWORK_EXPORTS=1 -Ipxr/usd/usd
> -I/usr/ports/pobj/usd-20.11/USD-20.11/pxr/usd/usd -Iinclude -isystem
> /usr/local/include -Wall -pthread -Wno-deprecated
> -Wno-deprecated-declarations -Wno-unused-local-typedefs
> -Wno-unused-command-line-argument -O2 -pipe -DNDEBUG -fPIC -std=c++14 -MD
> -MT pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o -MF
> pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o.d -o
> pxr/usd/usd/CMakeFiles/usd.dir/crateFile.cpp.o -c
> /usr/ports/pobj/usd-20.11/USD-20.11/pxr/usd/usd/crateFile.cpp
> /usr/ports/pobj/usd-20.11/USD-20.11/pxr/usd/usd/crateFile.cpp:2108:12: error:
> out-of-line definition of 'Open' does not match any declaration in
> 'pxrInternal_v0_20__pxrReserved__::Usd_CrateFile::CrateFile'
> CrateFile::Open(string const &assetPath,string const &fileName)
> ^~~~
--
Sebastien Marie