11 #include <QStringBuilder>
15 #if defined(Q_OS_POSIX)
18 #elif defined(Q_OS_WIN32)
22 # include <QNtfsPermissionCheckGuard>
32 #if defined(Q_OS_WIN32)
45 if (
exists() && !checkPermissions(mode, fileInfo))
47 m_permissionError =
true;
57 if (
exists(m_originalFilename) && !
copy(m_originalFilename,
fileName())) { ok =
false; }
74 #if defined(Q_OS_WIN32)
75 FlushFileBuffers(
reinterpret_cast<HANDLE
>(_get_osfhandle(
handle())));
108 m_renameError =
false;
109 m_permissionError =
false;
113 QString CAtomicFile::randomSuffix()
115 constexpr
auto max = 2176782335;
116 return QStringLiteral(
"%1").
arg(
117 std::uniform_int_distribution<std::decay_t<decltype(max)>>(0, max)(private_ns::defaultRandomGenerator()), 6,
121 #if defined(Q_OS_POSIX)
122 void CAtomicFile::replaceOriginal()
124 auto result =
::rename(qPrintable(
fileName()), qPrintable(m_originalFilename));
127 m_renameError =
true;
129 auto x = strerror_r(errno, s,
sizeof(s));
131 static_assert(std::is_same_v<decltype(x),
int>,
132 "Non-standard signature of POSIX function strerror_r, check documentation.");
135 #elif defined(Q_OS_WIN32)
136 void CAtomicFile::replaceOriginal()
138 auto encode = [](
const QString &s) {
144 auto replace =
exists(m_originalFilename);
145 auto result = replace ? ReplaceFile(encode(m_originalFilename).c_str(), encode(
fileName()).c_str(),
nullptr,
146 REPLACEFILE_IGNORE_MERGE_ERRORS,
nullptr,
nullptr) :
147 MoveFileEx(encode(
fileName()).c_str(), encode(m_originalFilename).c_str(),
148 MOVEFILE_WRITE_THROUGH);
151 wchar_t *s =
nullptr;
152 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, GetLastError(), 0,
153 reinterpret_cast<LPWSTR
>(&s), 0,
nullptr);
156 LocalFree(
reinterpret_cast<HLOCAL
>(s));
159 if (
exists(m_originalFilename))
161 QFile old(m_originalFilename);
165 m_renameError =
true;
166 setErrorString(windowsError % u
" QFile::remove: " % old.errorString());
170 rename(m_originalFilename);
174 void CAtomicFile::replaceOriginal()
176 if (
exists(m_originalFilename)) {
remove(m_originalFilename); }
177 rename(m_originalFilename);
virtual bool open(OpenMode mode)
bool checkedClose()
Calls close() and returns false if there was an error at any stage.
void abandon()
Closes the file without renaming it.
Free functions in swift::misc.
QString cleanPath(const QString &path)
QString toNativeSeparators(const QString &pathName)
bool copy(const QString &fileName, const QString &newName)
bool exists() const const
virtual QString fileName() const const override
bool open(FILE *fh, QIODeviceBase::OpenMode mode, QFileDevice::FileHandleFlags handleFlags)
bool rename(const QString &newName)
void setFileName(const QString &name)
virtual void close() override
QFileDevice::FileError error() const const
QString fileName() const const
bool isReadable() const const
bool isWritable() const const
bool isOpen() const const
void setErrorString(const QString &str)
QString arg(Args &&... args) const const
QString fromLocal8Bit(QByteArrayView str)
QString fromWCharArray(const wchar_t *string, qsizetype size)
QString simplified() const const