Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lute/io/src/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "Luau/Variant.h"
#include "lute/runtime.h"

#include <uv.h>
#include "uv.h"
#include <memory>

#include "lua.h"
Expand Down
55 changes: 12 additions & 43 deletions lute/process/src/process.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include "lute/process.h"
#include "lute/runtime.h"
#include "lute/uvutils.h"

#include "Luau/Common.h"

#include "lua.h"
#include "lualib.h"

#include <uv.h>
#include "uv.h"

#include <functional>
#include <map>
Expand Down Expand Up @@ -432,28 +433,12 @@ int run(lua_State* L)

int homedir(lua_State* L)
{
std::string buffer;

size_t homedir_size = 255;
buffer.reserve(homedir_size);

int status = uv_os_homedir(buffer.data(), &homedir_size);
if (status == UV_ENOBUFS)
{
// libuv gives us the new size if it's under sized
buffer.reserve(homedir_size);

status = uv_os_homedir(buffer.data(), &homedir_size);
}

if (status != 0)
{
luaL_error(L, "failed to get home directory");
return 1;
}

lua_pushlstring(L, buffer.c_str(), buffer.size());
auto result = uvutils::getStringFromUv(uv_os_homedir);
if (uvutils::UvError* error = result.get_if<uvutils::UvError>())
luaL_error(L, "failed to get home directory: %s", error->toString().c_str());

std::string* homeDir = result.get_if<std::string>();
lua_pushlstring(L, homeDir->c_str(), homeDir->size());
return 1;
}

Expand All @@ -470,28 +455,12 @@ int exitFunc(lua_State* L)

int cwd(lua_State* L)
{
std::string buffer;

size_t cwd_size = 255;
buffer.reserve(cwd_size);

int status = uv_cwd(buffer.data(), &cwd_size);
if (status == UV_ENOBUFS)
{
// libuv gives us the new size if it's under sized
buffer.reserve(cwd_size);

status = uv_cwd(buffer.data(), &cwd_size);
}

if (status != 0)
{
luaL_error(L, "failed to get current working directory");
return 1;
}

lua_pushlstring(L, buffer.c_str(), buffer.size());
auto result = uvutils::getStringFromUv(uv_cwd);
if (uvutils::UvError* error = result.get_if<uvutils::UvError>())
luaL_error(L, "failed to get current working directory: %s", error->toString().c_str());

std::string* cwd = result.get_if<std::string>();
lua_pushlstring(L, cwd->c_str(), cwd->size());
return 1;
};

Expand Down
2 changes: 2 additions & 0 deletions lute/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ target_sources(Lute.Runtime PRIVATE
include/lute/ref.h
include/lute/runtime.h
include/lute/userdatas.h
include/lute/uvutils.h

src/ref.cpp
src/runtime.cpp
src/uvutils.cpp
)

target_compile_features(Lute.Runtime PUBLIC cxx_std_17)
Expand Down
24 changes: 24 additions & 0 deletions lute/runtime/include/lute/uvutils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "Luau/Variant.h"

#include <cstddef>
#include <string>

namespace uvutils
{

struct UvError
{
UvError(int code);
std::string toString() const;

int code;
};

typedef int (*BufferWriter)(char* buffer, size_t* size);

// Abstracts away buffer management when getting strings from libuv functions.
Luau::Variant<std::string, UvError> getStringFromUv(BufferWriter bufferWriter, size_t initialBufferSize = 256);

} // namespace uvutils
39 changes: 39 additions & 0 deletions lute/runtime/src/uvutils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "lute/uvutils.h"

#include "uv.h"

namespace uvutils
{

UvError::UvError(int code)
: code(code)
{
}

std::string UvError::toString() const
{
return uv_strerror(code);
}

Luau::Variant<std::string, UvError> getStringFromUv(BufferWriter bufferWriter, size_t initialBufferSize)
{
std::string buffer;
size_t size = initialBufferSize;
buffer.resize(size);

int writeStatus = bufferWriter(buffer.data(), &size);
if (writeStatus == UV_ENOBUFS)
{
// `size` now contains the required size
buffer.resize(size);
writeStatus = bufferWriter(buffer.data(), &size);
}

if (writeStatus < 0)
return UvError{writeStatus};

buffer.resize(size);
return buffer;
}

} // namespace uvutils
50 changes: 14 additions & 36 deletions lute/system/src/system.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#include "lute/system.h"
#include "lute/uvutils.h"

#include "lua.h"
#include "lualib.h"

#include "uv.h"

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <iterator>
#include <string>
#include <vector>

namespace libsystem
{
Expand Down Expand Up @@ -88,24 +91,12 @@ int lua_totalmemory(lua_State* L)

int lua_hostname(lua_State* L)
{
size_t sz = 255;
std::string hostname;
hostname.reserve(sz);

int res = uv_os_gethostname(hostname.data(), &sz);
if (res == UV_ENOBUFS)
{
hostname.reserve(sz); // libuv updates the size to what's required
res = uv_os_gethostname(hostname.data(), &sz);
}

if (res != 0)
{
luaL_error(L, "libuv error: %s", uv_strerror(res));
}

lua_pushlstring(L, hostname.c_str(), hostname.size());
auto result = uvutils::getStringFromUv(uv_os_gethostname);
if (uvutils::UvError* error = result.get_if<uvutils::UvError>())
luaL_error(L, "failed to get hostname: %s", error->toString().c_str());

std::string* hostname = result.get_if<std::string>();
lua_pushlstring(L, hostname->c_str(), hostname->size());
return 1;
}

Expand All @@ -126,26 +117,13 @@ int lua_uptime(lua_State* L)

int lua_tmpdir(lua_State* L)
{
size_t size = 255;
std::string tmpdir;
tmpdir.reserve(size);

int res = uv_os_tmpdir(tmpdir.data(), &size);
if (res == UV_ENOBUFS)
{
tmpdir.reserve(size); // libuv updates the size to what's required
res = uv_os_tmpdir(tmpdir.data(), &size);
}

if (res != 0)
{
luaL_error(L, "libuv error: %s", uv_strerror(res));
}

lua_pushlstring(L, tmpdir.c_str(), tmpdir.size());
auto result = uvutils::getStringFromUv(uv_os_tmpdir);
if (uvutils::UvError* error = result.get_if<uvutils::UvError>())
luaL_error(L, "failed to get temporary directory: %s", error->toString().c_str());

std::string* tmpDir = result.get_if<std::string>();
lua_pushlstring(L, tmpDir->c_str(), tmpDir->size());
return 1;

}
} // namespace libsystem

Expand Down
4 changes: 2 additions & 2 deletions tests/path.posix.test.luau
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ test.suite("PathPosixResolveSuite", function(suite)
-- This test assumes we're in some working directory
local result = path.posix.resolve("documents/file.txt")
-- Absolute Windows paths will be parsed as relative posix paths because they don't start with /
assert.eq(result.absolute, system.win32)
assert.neq(result.absolute, system.win32)
-- The exact parts will depend on the current working directory
-- But we can check that it ends with our relative path
local endIndex = #result.parts
Expand Down Expand Up @@ -513,7 +513,7 @@ test.suite("PathPosixResolveSuite", function(suite)
-- Should return normalized current working directory
local result = path.posix.resolve()
-- Absolute Windows paths will be parsed as relative posix paths because they don't start with /
assert.eq(result.absolute, system.win32)
assert.neq(result.absolute, system.win32)
-- Can't test exact parts since cwd varies
end)

Expand Down