Skip to content

Commit

Permalink
Merge pull request xbmc#13253 from Paxxi/temp_name
Browse files Browse the repository at this point in the history
[xbmc][improvement] Add a platform abstraction for temp files / directories
  • Loading branch information
Paxxi authored Jan 12, 2018
2 parents cb57886 + f6203e2 commit 863266b
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 65 deletions.
6 changes: 5 additions & 1 deletion xbmc/platform/Filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ struct space_info {
std::uintmax_t available;
};

space_info space(const std::string& path, std::error_code& ec);
space_info space(const std::string &path, std::error_code &ec);

std::string temp_directory_path(std::error_code &ec);
std::string create_temp_directory(std::error_code &ec);
std::string temp_file_path(std::string suffix, std::error_code &ec);
}
}
}
67 changes: 66 additions & 1 deletion xbmc/platform/posix/Filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "platform/Filesystem.h"
#include "system.h"
#include "filesystem/SpecialProtocol.h"
#include "utils/URIUtils.h"

#if defined(TARGET_LINUX)
#include <sys/statvfs.h>
Expand All @@ -31,6 +32,9 @@
#include <sys/statfs.h>
#endif

#include <cstdlib>
#include <limits.h>

namespace KODI
{
namespace PLATFORM
Expand Down Expand Up @@ -65,6 +69,67 @@ space_info space(const std::string& path, std::error_code& ec)

return sp;
}

std::string temp_directory_path(std::error_code &ec)
{
ec.clear();

auto result = getenv("TMPDIR");
if (result)
return URIUtils::AppendSlash(result);

return "/tmp/";
}

std::string create_temp_directory(std::error_code &ec)
{
char buf[PATH_MAX];

auto path = temp_directory_path(ec);

strcpy(buf, (path + "xbmctempXXXXXX").c_str());

auto tmp = mkdtemp(buf);
if (!tmp)
{
ec.assign(errno, std::system_category());
return std::string();
}

ec.clear();
return std::string(tmp);
}

std::string temp_file_path(std::string suffix, std::error_code &ec)
{
char tmp[PATH_MAX];

auto tempPath = create_temp_directory(ec);
if (ec)
return std::string();

tempPath = URIUtils::AddFileToFolder(tempPath, "xbmctempfileXXXXXX" + suffix);
if (tempPath.length() >= PATH_MAX)
{
ec.assign(EOVERFLOW, std::system_category());
return std::string();
}

strcpy(tmp, tempPath.c_str());

auto fd = mkstemps(tmp, suffix.length());
if (fd < 0)
{
ec.assign(errno, std::system_category());
return std::string();
}

close(fd);

ec.clear();
return std::string(tmp);
}

}
}
}
}
68 changes: 66 additions & 2 deletions xbmc/platform/win32/Filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#endif
#include <Windows.h>

namespace win = KODI::PLATFORM::WINDOWS;

namespace KODI
{
namespace PLATFORM
Expand All @@ -34,11 +36,10 @@ namespace FILESYSTEM
{
space_info space(const std::string& path, std::error_code& ec)
{
using WINDOWS::ToW;

ec.clear();
space_info sp;
auto pathW = ToW(path);
auto pathW = win::ToW(path);

ULARGE_INTEGER capacity;
ULARGE_INTEGER available;
Expand All @@ -60,6 +61,69 @@ space_info space(const std::string& path, std::error_code& ec)

return sp;
}

std::string temp_directory_path(std::error_code &ec)
{
wchar_t lpTempPathBuffer[MAX_PATH + 1];

if (!GetTempPathW(MAX_PATH, lpTempPathBuffer))
{
ec.assign(GetLastError(), std::system_category());
return std::string();
}

ec.clear();
return win::FromW(lpTempPathBuffer);
}

std::string create_temp_directory(std::error_code &ec)
{
wchar_t lpTempPathBuffer[MAX_PATH + 1];

std::wstring xbmcTempPath = win::ToW(temp_directory_path(ec));

if (ec)
return std::string();

if (!GetTempFileNameW(xbmcTempPath.c_str(), L"xbm", 0, lpTempPathBuffer))
{
ec.assign(GetLastError(), std::system_category());
return std::string();
}

DeleteFileW(lpTempPathBuffer);

if (!CreateDirectoryW(lpTempPathBuffer, nullptr))
{
ec.assign(GetLastError(), std::system_category());
return std::string();
}

ec.clear();
return win::FromW(lpTempPathBuffer);
}

std::string temp_file_path(std::string, std::error_code &ec)
{
wchar_t lpTempPathBuffer[MAX_PATH + 1];

std::wstring xbmcTempPath = win::ToW(create_temp_directory(ec));

if (ec)
return std::string();

if (!GetTempFileNameW(xbmcTempPath.c_str(), L"xbm", 0, lpTempPathBuffer))
{
ec.assign(GetLastError(), std::system_category());
return std::string();
}

DeleteFileW(lpTempPathBuffer);

ec.clear();
return win::FromW(lpTempPathBuffer);
}

}
}
}
47 changes: 18 additions & 29 deletions xbmc/test/TestBasicEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@
#include "Application.h"
#include "AppParamParser.h"
#include "windowing/WinSystem.h"

#if defined(TARGET_WINDOWS)
#include "platform/win32/WIN32Util.h"
#include "platform/win32/CharsetConverter.h"
#endif
#include "platform/Filesystem.h"

#ifdef TARGET_DARWIN
#include "Util.h"
Expand All @@ -42,6 +38,9 @@
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <system_error>

namespace fs = KODI::PLATFORM::FILESYSTEM;

void TestBasicEnvironment::SetUp()
{
Expand Down Expand Up @@ -74,29 +73,19 @@ void TestBasicEnvironment::SetUp()
/* Create a temporary directory and set it to be used throughout the
* test suite run.
*/
#ifdef TARGET_WINDOWS
using KODI::PLATFORM::WINDOWS::FromW;
std::wstring xbmcTempPath;
TCHAR lpTempPathBuffer[MAX_PATH];
if (!GetTempPath(MAX_PATH, lpTempPathBuffer))
SetUpError();
xbmcTempPath = lpTempPathBuffer;
if (!GetTempFileName(xbmcTempPath.c_str(), L"xbmctempdir", 0, lpTempPathBuffer))
SetUpError();
DeleteFile(lpTempPathBuffer);
if (!CreateDirectory(lpTempPathBuffer, NULL))
SetUpError();
CSpecialProtocol::SetTempPath(FromW(lpTempPathBuffer));
CSpecialProtocol::SetProfilePath(FromW(lpTempPathBuffer));
#else
char buf[MAX_PATH];
char *tmp;
strcpy(buf, "/tmp/xbmctempdirXXXXXX");
if ((tmp = mkdtemp(buf)) == NULL)

g_application.EnablePlatformDirectories(false);

std::error_code ec;
m_tempPath = fs::create_temp_directory(ec);
if (ec)
{
TearDown();
SetUpError();
CSpecialProtocol::SetTempPath(tmp);
CSpecialProtocol::SetProfilePath(tmp);
#endif
}

CSpecialProtocol::SetTempPath(m_tempPath);
CSpecialProtocol::SetProfilePath(m_tempPath);

/* Create and delete a tempfile to initialize the VFS (really to initialize
* CLibcdio). This is done so that the initialization of the VFS does not
Expand All @@ -120,8 +109,8 @@ void TestBasicEnvironment::SetUp()

void TestBasicEnvironment::TearDown()
{
std::string xbmcTempPath = CSpecialProtocol::TranslatePath("special://temp/");
XFILE::CDirectory::Remove(xbmcTempPath);
XFILE::CDirectory::RemoveRecursive(m_tempPath);

CServiceBroker::GetSettings().Uninitialize();
g_application.m_ServiceManager->DeinitTesting();
}
Expand Down
3 changes: 3 additions & 0 deletions xbmc/test/TestBasicEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@

#include "gtest/gtest.h"

#include <string>

class TestBasicEnvironment : public testing::Environment
{
public:
void SetUp() override;
void TearDown() override;
private:
void SetUpError();
std::string m_tempPath;
};
42 changes: 10 additions & 32 deletions xbmc/test/TestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "Util.h"
#include "filesystem/File.h"
#include "filesystem/SpecialProtocol.h"
#include "platform/win32/CharsetConverter.h"
#include "platform/Filesystem.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"

Expand All @@ -34,6 +34,10 @@
#include <ctime>
#endif

#include <system_error>

namespace fs = KODI::PLATFORM::FILESYSTEM;

class CTempFile : public XFILE::CFile
{
public:
Expand All @@ -44,38 +48,13 @@ class CTempFile : public XFILE::CFile
}
bool Create(const std::string &suffix)
{
char tmp[MAX_PATH];

m_ptempFileDirectory = CSpecialProtocol::TranslatePath("special://temp/");
m_ptempFilePath = m_ptempFileDirectory + "xbmctempfileXXXXXX";
m_ptempFilePath += suffix;
if (m_ptempFilePath.length() >= MAX_PATH)
{
m_ptempFilePath = "";
std::error_code ec;
m_ptempFilePath = fs::temp_file_path(suffix, ec);
if (ec)
return false;
}
strcpy(tmp, m_ptempFilePath.c_str());

#ifdef TARGET_WINDOWS
using namespace KODI::PLATFORM::WINDOWS;
wchar_t tmpW[MAX_PATH];
if (!GetTempFileName(ToW(CSpecialProtocol::TranslatePath("special://temp/")).c_str(),
L"xbmctempfile", 0, tmpW))
{
m_ptempFilePath = "";
if (m_ptempFilePath.empty())
return false;
}
m_ptempFilePath = FromW(tmpW);
#else
int fd;
if ((fd = mkstemps(tmp, suffix.length())) < 0)
{
m_ptempFilePath = "";
return false;
}
close(fd);
m_ptempFilePath = tmp;
#endif

OpenForWrite(m_ptempFilePath.c_str(), true);
return true;
Expand All @@ -91,11 +70,10 @@ class CTempFile : public XFILE::CFile
}
std::string getTempFileDirectory() const
{
return m_ptempFileDirectory;
return URIUtils::GetDirectory(m_ptempFilePath);
}
private:
std::string m_ptempFilePath;
std::string m_ptempFileDirectory;
};

CXBMCTestUtils::CXBMCTestUtils()
Expand Down
Loading

0 comments on commit 863266b

Please sign in to comment.