WIP fix download manager on windows
All checks were successful
/ build (pull_request) Successful in 12m50s

This commit is contained in:
Xavier Del Campo Romero 2025-01-09 01:40:13 +01:00
parent 53a758688e
commit aaff53e0f2
Signed by: xavi
GPG key ID: 84FF3612A9BF43F2
2 changed files with 63 additions and 44 deletions

View file

@ -13,66 +13,78 @@
#include <windows.h>
#include <winerror.h>
#include <shellapi.h>
#include <cerrno>
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <cstring>
static char *getdir(const char *path)
{
/* SHFileOperation requires a double null-terminated string. */
static const char end[] = {'\0', '\0'};
size_t sz = strlen(path) + sizeof end;
char *ret = static_cast<char *>(malloc(sz));
if (!ret)
{
fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno));
goto failure;
}
strcpy(ret, path);
ret[sz - 1] = '\0';
return ret;
failure:
free(ret);
return nullptr;
}
#include <string>
int portability::rmdir_r(const char *path)
{
int ret = -1, res;
char *dir = getdir(path);
SHFILEOPSTRUCT op = {0};
int ret = -1;
_finddata_t fd;
std::string wildcard_s = std::string(path) + "/*.*";
const char *wildcard = wildcard_s.c_str();
intptr_t h = _findfirst(wildcard, &fd);
if (!dir)
if (h < 0 && errno != ENOENT)
{
fprintf(stderr, "%s: getdir failed\n", __func__);
fprintf(stderr, "_findfirst %s: %s\n", wildcard, strerror(errno));
goto end;
}
op.wFunc = FO_DELETE;
op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
op.lpszProgressTitle = "";
op.pFrom = dir;
for (;;)
{
if (*fd.name && strcmp(fd.name, ".") && strcmp(fd.name, ".."))
{
std::string entry_s = std::string(path) + "/" + fd.name;
const char *entry = entry_s.c_str();
if ((res = SHFileOperation(&op)))
{
fprintf(stderr, "%s: SHFileOperation failed with %#x\n", __func__, res);
goto end;
}
else if (op.fAnyOperationsAborted)
{
fprintf(stderr, "%s: operation aborted\n", __func__);
goto end;
if (fd.attrib & _A_SUBDIR)
{
if ((ret = rmdir_r(entry)))
goto end;
else if (!RemoveDirectoryA(entry))
{
fprintf(stderr, "RemoveDirectoryA %s: %#jx\n",
entry, (intmax_t)GetLastError());
goto end;
}
}
else if (remove(entry))
{
fprintf(stderr, "remove(3) %s: %s\n", entry, strerror(errno));
goto end;
}
}
if (_findnext(h, &fd))
{
if (errno == ENOENT)
break;
fprintf(stderr, "_findnext %s: %s\n", path, strerror(errno));
goto end;
}
}
ret = 0;
end:
free(dir);
if (h >= 0 && _findclose(h))
{
fprintf(stderr, "_findclose %s: %s\n", path, strerror(errno));
ret = -1;
}
else if (!ret && !RemoveDirectoryA(path)
&& GetLastError() != ERROR_FILE_NOT_FOUND)
{
fprintf(stderr, "RemoveDirectoryA %s: %s\n", path, strerror(errno));
ret = -1;
}
return ret;
}

View file

@ -65,7 +65,7 @@ end:
int unzip::extract(const std::string &path) const
{
std::ofstream out(path);
std::ofstream out(path, std::ios::binary);
int ret = -1, error = unzOpenCurrentFile(f);
if (error)
@ -87,7 +87,7 @@ int unzip::extract(const std::string &path) const
if (!n)
break;
if (n < 0)
else if (n < 0)
{
GfLogError("%s: unzReadCurrentFile %s failed with %d\n",
src.c_str(), path.c_str(), n);
@ -97,6 +97,13 @@ int unzip::extract(const std::string &path) const
try
{
out.write(buf, n);
out.flush();
if (!out.good())
{
GfLogError("Failed to write %d bytes\n", n);
return -1;
}
}
catch (const std::ios_base::failure &failure)
{