aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-09-25 23:22:08 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:39:33 +0200
commitdbb06eac9bae1b8dbc50275b66c975da09b1d09a (patch)
tree4cfa3cc326a11aa8cd8b7ff83d8afb1b2754f150 /src
parentc4d1491af938a12a0167dae4fd3ea8f1810c752a (diff)
Fix build with msvc (windows)
Fix freeze when sub process (exec) returns a lot of data (in stdout)
Diffstat (limited to 'src')
-rw-r--r--src/Exec.cpp10
-rw-r--r--src/FileUtil.cpp154
-rw-r--r--src/PkgConfig.cpp28
-rw-r--r--src/main.cpp64
4 files changed, 125 insertions, 131 deletions
diff --git a/src/Exec.cpp b/src/Exec.cpp
index 6c1a72e..659d812 100644
--- a/src/Exec.cpp
+++ b/src/Exec.cpp
@@ -99,13 +99,8 @@ namespace sibs
if (!CreateProcessW(nullptr, (LPWSTR)cmdNonConst.data(), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &siStartInfo, &piProcInfo))
goto cleanupAndExit;
- WaitForSingleObject(piProcInfo.hProcess, INFINITE);
- GetExitCodeProcess(piProcInfo.hProcess, &exitCode);
- CloseHandle(piProcInfo.hProcess);
- CloseHandle(piProcInfo.hThread);
CloseHandle(childStdoutHandle);
childStdoutHandle = nullptr;
-
DWORD bytesRead;
CHAR buffer[BUFSIZE];
while (true)
@@ -119,6 +114,11 @@ namespace sibs
printf("%.*s", bytesRead, buffer);
}
+ WaitForSingleObject(piProcInfo.hProcess, INFINITE);
+ GetExitCodeProcess(piProcInfo.hProcess, &exitCode);
+ CloseHandle(piProcInfo.hProcess);
+ CloseHandle(piProcInfo.hThread);
+
{
ExecResult execResult;
execResult.execStdout = move(execStdout);
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index 77669e5..e29ed36 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -16,6 +16,19 @@
using namespace std;
+#if OS_FAMILY == OS_FAMILY_POSIX
+static int makedir(const _tinydir_char_t *dir)
+{
+ return mkdir(dir, S_IRWXU);
+}
+#elif OS_FAMILY == OS_FAMILY_WINDOWS
+
+static int makedir(const _tinydir_char_t *dir)
+{
+ return _wmkdir(dir);
+}
+#endif
+
namespace sibs
{
#if OS_FAMILY == OS_FAMILY_POSIX
@@ -263,45 +276,21 @@ namespace sibs
fclose(file);
return Result<bool>::Ok(true);
}
-#if OS_FAMILY == OS_FAMILY_POSIX
- Result<FileString> getHomeDir()
- {
- const char *homeDir = getenv("HOME");
- if(!homeDir)
- {
- passwd *pw = getpwuid(getuid());
- homeDir = pw->pw_dir;
- }
- return Result<FileString>::Ok(homeDir);
- }
-
- Result<FileString> getCwd()
- {
- FileString cwd;
- cwd.resize(_TINYDIR_PATH_MAX);
- if(getcwd(&cwd[0], _TINYDIR_PATH_MAX) != 0)
- {
- if(cwd.empty()) cwd = ".";
- cwd.resize(_tinydir_strlen(cwd.c_str()));
- return Result<FileString>::Ok(cwd);
- }
- return Result<FileString>::Err(strerror(errno));
- }
Result<bool> createDirectory(const _tinydir_char_t *path)
{
- size_t pathLength = strlen(path);
- if(pathLength > _TINYDIR_PATH_MAX - 1)
+ size_t pathLength = _tinydir_strlen(path);
+ if (pathLength > _TINYDIR_PATH_MAX - 1)
{
string errMsg = "Directory path too long: ";
- errMsg += string(path, pathLength);
+ errMsg += toUtf8(FileString(path, pathLength));
return Result<bool>::Err(errMsg, ENAMETOOLONG);
}
- if(mkdir(path, S_IRWXU) != 0)
+ if (makedir(path) != 0)
{
int error = errno;
- if(error != EEXIST)
+ if (error != EEXIST)
{
string errMsg = "Failed to create directory: ";
errMsg += toUtf8(path);
@@ -315,47 +304,46 @@ namespace sibs
Result<bool> createDirectoryRecursive(const _tinydir_char_t *path)
{
- char pathBuffer[_TINYDIR_PATH_MAX];
- size_t pathLength = strlen(path);
- if(pathLength > sizeof(pathBuffer) - 1)
+ _tinydir_char_t pathBuffer[_TINYDIR_PATH_MAX];
+ size_t pathLength = _tinydir_strlen(path);
+ if (pathLength > sizeof(pathBuffer) - 1)
{
string errMsg = "Directory path too long: ";
- errMsg += string(path, pathLength);
+ errMsg += toUtf8(FileString(path, pathLength));
return Result<bool>::Err(errMsg, ENAMETOOLONG);
}
- strcpy(pathBuffer, path);
+ _tinydir_strcpy(pathBuffer, path);
- char *p = pathBuffer;
- for(size_t i = 0; i < pathLength; ++i)
+ _tinydir_char_t *p = pathBuffer;
+ for (size_t i = 0; i < pathLength; ++i)
{
- char c = *p;
- if(i > 0 && (c == '/' || c == '\\'))
+ if (i > 0 && *p == '/')
{
*p = '\0';
- if(mkdir(pathBuffer, S_IRWXU) != 0)
+ if (makedir(pathBuffer) != 0)
{
int error = errno;
- if(error != EEXIST)
+ if (error != EEXIST)
{
string errMsg = "Failed to create directory: ";
- errMsg += pathBuffer;
+ errMsg += toUtf8(pathBuffer);
errMsg += "; reason: ";
errMsg += strerror(error);
return Result<bool>::Err(errMsg, error);
}
}
- *p = c;
+ *p = '/';
}
++p;
}
- if(mkdir(pathBuffer, S_IRWXU) != 0)
+ if (makedir(pathBuffer) != 0)
{
int error = errno;
- if(error != EEXIST)
+ if (error != EEXIST)
{
string errMsg = "Failed to create directory: ";
- errMsg += pathBuffer;
+ errMsg += toUtf8(pathBuffer);
errMsg += "; reason: ";
errMsg += strerror(error);
return Result<bool>::Err(errMsg, error);
@@ -365,6 +353,31 @@ namespace sibs
return Result<bool>::Ok(true);
}
+#if OS_FAMILY == OS_FAMILY_POSIX
+ Result<FileString> getHomeDir()
+ {
+ const char *homeDir = getenv("HOME");
+ if(!homeDir)
+ {
+ passwd *pw = getpwuid(getuid());
+ homeDir = pw->pw_dir;
+ }
+ return Result<FileString>::Ok(homeDir);
+ }
+
+ Result<FileString> getCwd()
+ {
+ FileString cwd;
+ cwd.resize(_TINYDIR_PATH_MAX);
+ if(getcwd(&cwd[0], _TINYDIR_PATH_MAX) != 0)
+ {
+ if(cwd.empty()) cwd = ".";
+ cwd.resize(_tinydir_strlen(cwd.c_str()));
+ return Result<FileString>::Ok(cwd);
+ }
+ return Result<FileString>::Err(strerror(errno));
+ }
+
Result<FileString> getRealPath(const _tinydir_char_t *path)
{
// TODO: Verify NULL can be passed as 'resolved' argument with different compilers and operating systems (clang, freebsd etc)
@@ -420,57 +433,6 @@ namespace sibs
return Result<FileString>::Ok(cwd);
}
- Result<bool> createDirectoryRecursive(const _tinydir_char_t *path)
- {
- _tinydir_char_t pathBuffer[_TINYDIR_PATH_MAX];
- size_t pathLength = _tinydir_strlen(path);
- if (pathLength > sizeof(pathBuffer) - 1)
- {
- string errMsg = "Directory path too long: ";
- errMsg += toUtf8(FileString(path, pathLength));
- return Result<bool>::Err(errMsg, ENAMETOOLONG);
- }
- _tinydir_strcpy(pathBuffer, path);
-
- _tinydir_char_t *p = pathBuffer;
- for (size_t i = 0; i < pathLength; ++i)
- {
- if (i > 0 && *p == '/')
- {
- *p = '\0';
- if (_wmkdir(pathBuffer) != 0)
- {
- int error = errno;
- if (error != EEXIST)
- {
- string errMsg = "Failed to create directory: ";
- errMsg += toUtf8(pathBuffer);
- errMsg += "; reason: ";
- errMsg += strerror(error);
- return Result<bool>::Err(errMsg, error);
- }
- }
- *p = '/';
- }
- ++p;
- }
-
- if (_wmkdir(pathBuffer) != 0)
- {
- int error = errno;
- if (error != EEXIST)
- {
- string errMsg = "Failed to create directory: ";
- errMsg += toUtf8(pathBuffer);
- errMsg += "; reason: ";
- errMsg += strerror(error);
- return Result<bool>::Err(errMsg, error);
- }
- }
-
- return Result<bool>::Ok(true);
- }
-
Result<FileString> getRealPath(const _tinydir_char_t *path)
{
FileString fullPath;
diff --git a/src/PkgConfig.cpp b/src/PkgConfig.cpp
index 3a36f39..faed146 100644
--- a/src/PkgConfig.cpp
+++ b/src/PkgConfig.cpp
@@ -1,5 +1,4 @@
#include "../include/PkgConfig.hpp"
-#if OS_FAMILY == OS_FAMILY_POSIX
#include "../include/Exec.hpp"
#include "../include/Dependency.hpp"
@@ -35,9 +34,9 @@ namespace sibs
Result<bool> PkgConfig::validatePackageExists(const string &name)
{
- string command = "pkg-config --exists '";
- command += name;
- command += "'";
+ FileString command = TINYDIR_STRING("pkg-config --exists '");
+ command += toFileString(name);
+ command += TINYDIR_STRING("'");
Result<ExecResult> execResult = exec(command.c_str());
if(execResult.isErr())
return Result<bool>::Err(execResult.getErrMsg());
@@ -69,11 +68,11 @@ namespace sibs
// Use --modversion instead and check if the version returned is newer or equal to dependency version.
// This way we can output installed version vs expected dependency version
- string command = "pkg-config '--atleast-version=";
- command += version;
- command += "' '";
- command += name;
- command += "'";
+ FileString command = TINYDIR_STRING("pkg-config '--atleast-version=");
+ command += toFileString(version);
+ command += TINYDIR_STRING("' '");
+ command += toFileString(name);
+ command += TINYDIR_STRING("'");
Result<ExecResult> execResult = exec(command.c_str());
if(execResult.isErr())
return Result<bool>::Err(execResult.getErrMsg());
@@ -112,8 +111,8 @@ namespace sibs
args += "'";
}
- string command = "pkg-config --libs";
- command += args;
+ FileString command = TINYDIR_STRING("pkg-config --libs");
+ command += toFileString(args);
Result<ExecResult> execResult = exec(command.c_str());
if(execResult.isErr())
return Result<string>::Err(execResult.getErrMsg());
@@ -155,8 +154,8 @@ namespace sibs
args += "'";
}
- string command = "pkg-config --cflags";
- command += args;
+ FileString command = TINYDIR_STRING("pkg-config --cflags");
+ command += toFileString(args);
Result<ExecResult> execResult = exec(command.c_str());
if(execResult.isErr())
return Result<string>::Err(execResult.getErrMsg());
@@ -202,5 +201,4 @@ namespace sibs
flags.cflags = move(cflagsResult.unwrap());
return Result<PkgConfigFlags>::Ok(flags);
}
-}
-#endif // OS_FAMILY_POSIX
+} \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index cb1c611..1da5202 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -227,15 +227,32 @@ static bool isPathSubPathOf(const FileString &path, const FileString &subPathOf)
}
#if OS_FAMILY == OS_FAMILY_WINDOWS
-static char* join(const char *str1, const char *str2, const char separator)
+static char* join(const vector<const char *> &strs, const char separator)
{
- int str1len = strlen(str1);
- int str2len = strlen(str2);
- char *result = new char[str1len + 1 + str2len + 1];
- memcpy(result, str1, str1len);
- result[str1len] = separator;
- memcpy(result + str1len + 1, str2, str2len);
- result[str1len + 1 + str2len] = '\0';
+ vector<int> lengths;
+ lengths.reserve(strs.size());
+ int totalLength = strs.size() - 1;
+ for (const char *str : strs)
+ {
+ int length = strlen(str);
+ totalLength += length;
+ lengths.push_back(length);
+ }
+
+ char *result = new char[totalLength + 1];
+ result[totalLength] = '\0';
+ int offset = 0;
+ for (int i = 0; i < strs.size(); ++i)
+ {
+ if (i > 0)
+ {
+ result[offset] = separator;
+ ++offset;
+ }
+ memcpy(result + offset, strs[i], lengths[i]);
+ offset += lengths[i];
+ }
+
return result;
}
@@ -246,9 +263,17 @@ struct MicrosoftBuildTool
// empty if not found
char binPath[_TINYDIR_PATH_MAX];
// empty if not found
+ char vsLibPath[_TINYDIR_PATH_MAX];
+ // empty if not found
char umLibPath[_TINYDIR_PATH_MAX];
// empty if not found
char ucrtLibPath[_TINYDIR_PATH_MAX];
+ // empty if not found
+ char vsIncludePath[_TINYDIR_PATH_MAX];
+ // empty if not found
+ char umIncludePath[_TINYDIR_PATH_MAX];
+ // empty if not found
+ char ucrtIncludePath[_TINYDIR_PATH_MAX];
bool found()
{
@@ -259,32 +284,41 @@ struct MicrosoftBuildTool
static MicrosoftBuildTool locateLatestMicrosoftBuildTool()
{
MicrosoftBuildTool result = { 0 };
- Result<ExecResult> execResult = exec(TINYDIR_STRING("locate_windows_sdk"));
+ Result<ExecResult> execResult = exec(TINYDIR_STRING("locate_windows_sdk x64"));
if (execResult && execResult.unwrap().exitCode == 0)
{
auto &str = execResult.unwrap().execStdout;
- sscanf(execResult.unwrap().execStdout.c_str(), "%d %[^\r\n] %[^\r\n] %[^\r\n]", &result.version, result.binPath, result.umLibPath, result.ucrtLibPath);
+ sscanf(execResult.unwrap().execStdout.c_str(), "%d %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n]",
+ &result.version,
+ result.binPath,
+ result.vsLibPath,
+ result.umLibPath,
+ result.ucrtLibPath,
+ result.vsIncludePath,
+ result.umIncludePath,
+ result.ucrtIncludePath);
}
return result;
}
+// We do not free allocated data here because they needs to live as long as they're used as env (in _putenv)
static void appendMicrosoftBuildToolToPathEnv()
{
MicrosoftBuildTool msBuildTool = locateLatestMicrosoftBuildTool();
if (msBuildTool.found())
{
fprintf(stderr, "Located microsoft build tools at %s\n", msBuildTool.binPath);
- fprintf(stderr, "Located microsoft build libraries at %s;%s\n", msBuildTool.umLibPath, msBuildTool.ucrtLibPath);
if (const char *pathEnv = getenv("PATH"))
{
- // We do not free this because it needs to live as long as it's used as env (in _putenv)
- if (_putenv_s("PATH", join(pathEnv, msBuildTool.binPath, ';')) != 0)
+ if (_putenv_s("PATH", join({ pathEnv, msBuildTool.binPath }, ';')) != 0)
fprintf(stderr, "Warning: Failed to add microsoft build tools to PATH env\n");
}
- // We do not free this because it needs to live as long as it's used as env (in _putenv)
- if (_putenv_s("LIB", join(msBuildTool.umLibPath, msBuildTool.ucrtLibPath, ';')) != 0)
+ if (_putenv_s("INCLUDE", join({ msBuildTool.vsIncludePath, msBuildTool.umIncludePath, msBuildTool.ucrtIncludePath }, ';')) != 0)
+ fprintf(stderr, "Warning: Failed to add microsoft build libraries to INCLUDE env\n");
+
+ if (_putenv_s("LIB", join({ msBuildTool.vsLibPath, msBuildTool.umLibPath, msBuildTool.ucrtLibPath }, ';')) != 0)
fprintf(stderr, "Warning: Failed to add microsoft build libraries to LIB env\n");
}
}