Skip to content

Commit

Permalink
0.34.0 streams with read timeouts and files as streams (#52)
Browse files Browse the repository at this point in the history
* streams with read timeouts and open files as streams

Fixes #50
  • Loading branch information
cryi authored Sep 19, 2024
1 parent 0ed3bbf commit 1728c4d
Show file tree
Hide file tree
Showing 27 changed files with 247 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,6 @@
path = deps/zlib-ng
url = https://github.com/zlib-ng/zlib-ng.git
ignore = dirty
[submodule "deps/c11threads"]
path = deps/c11threads
url = https://github.com/cryi/c11threads.git
17 changes: 16 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,22 @@
"crypto.h": "c",
"types.h": "c",
"utime.h": "c",
"system_error": "c"
"system_error": "c",
"variant": "c",
"istream": "c",
"cstring": "c",
"cstdlib": "c",
"array": "c",
"string_view": "c",
"format": "c",
"initializer_list": "c",
"span": "c",
"cerrno": "c",
"string": "cpp",
"sleep.h": "c",
"numbers": "cpp",
"lerror.h": "c",
"stream_win.h": "c"
},
"C_Cpp.default.compilerPath": "/usr/bin/cpp",
"editor.formatOnSave": true,
Expand Down
17 changes: 12 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_CROSSCOMPILING CACHE BOOL ON FORCE)
project(eli)

set_directory_properties(PROPERTIES CURL_CA_BUNDLE "none")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BUILD_FLAGS} -fPIC -fPIE -ffunction-sections -fdata-sections -g0 -Wl,--as-needed -Wno-sign-compare -Wl,--gc-sections -static -DCURL_STATICLIB")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BUILD_FLAGS} -fPIC -fPIE -ffunction-sections -fdata-sections -g0 -Wl,--as-needed -Wno-sign-compare -Wl,--gc-sections -static")
set(LD_FLAGS "${LD_FLAGS} -Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")

Expand Down Expand Up @@ -48,13 +47,17 @@ add_subdirectory(deps/mbedtls/ EXCLUDE_FROM_ALL)
set(ELI_STREAM_EXTRA_INCLUDE ${CMAKE_SOURCE_DIR}/deps/eli-stream-extra/src)
set(ELI_OS_EXTRA_INCLUDE ${CMAKE_SOURCE_DIR}/deps/eli-os-extra/src)
set(ELI_EXTRA_UTILS_INCLUDE ${CMAKE_SOURCE_DIR}/deps/eli-extra-utils/src)
set(ELI_PIPE_EXTRA_INCLUDE ${CMAKE_SOURCE_DIR}/deps/eli-pipe-extra/src)
set(C11THREADS_INCLUDE ${CMAKE_SOURCE_DIR}/deps/c11threads)

set(LSS_INCLUDE ${CMAKE_SOURCE_DIR}/deps/lua-simple-socket/src)

add_subdirectory(deps/lua-is-tty/)
add_subdirectory(deps/lua-mbed-hash/)

add_subdirectory(deps/c11threads/)
add_subdirectory(deps/eli-extra-utils/)
target_include_directories(eli_extra_utils PRIVATE ${C11THREADS_INCLUDE})
add_subdirectory(deps/lua-simple-socket/)
target_include_directories(lssocket PRIVATE ${ELI_EXTRA_UTILS_INCLUDE} ${HTTP_INCLUDE_PUBLIC_DIRS})
target_compile_definitions(lssocket PRIVATE LSS_HAS_BUNDLED_ROOT_CERTIFICATES)
Expand All @@ -72,7 +75,7 @@ target_include_directories(eli_os_extra PRIVATE ${ELI_EXTRA_UTILS_INCLUDE})
add_subdirectory(deps/eli-pipe-extra/)
target_include_directories(eli_pipe_extra PRIVATE ${ELI_EXTRA_UTILS_INCLUDE} ${ELI_STREAM_EXTRA_INCLUDE})
add_subdirectory(deps/eli-proc-extra/)
target_include_directories(eli_proc_extra PRIVATE ${ELI_EXTRA_UTILS_INCLUDE} ${ELI_STREAM_EXTRA_INCLUDE} ${ELI_OS_EXTRA_INCLUDE})
target_include_directories(eli_proc_extra PRIVATE ${ELI_EXTRA_UTILS_INCLUDE} ${ELI_STREAM_EXTRA_INCLUDE} ${ELI_OS_EXTRA_INCLUDE} ${ELI_PIPE_EXTRA_INCLUDE})
add_subdirectory(deps/eli-stream-extra/)
target_include_directories(eli_stream_extra PRIVATE ${ELI_EXTRA_UTILS_INCLUDE})
add_subdirectory(deps/lua-mbed-bigint/)
Expand Down Expand Up @@ -118,10 +121,14 @@ set(MBEDTLS_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/mbedtls/include CACHE
# ELI
# 1. eli interpreter
add_executable(eli deps/lua/onelua.c)
target_link_libraries(eli lis_tty lua_zip ltar eli_fs_extra eli_proc_extra eli_pipe_extra eli_stream_extra eli_os_extra eli_env_extra eli_extra_utils lua_mbed_bigint lua_mbed_base64 lua_simple_ipc lssocket corehttp lcorehttp mbedx509 mbedtls mbedcrypto lhash zip lzlib zlibstatic "-static")
target_link_libraries(eli lis_tty lua_zip ltar eli_fs_extra eli_pipe_extra eli_proc_extra eli_stream_extra eli_os_extra eli_env_extra eli_extra_utils lua_mbed_bigint lua_mbed_base64 lua_simple_ipc lssocket corehttp lcorehttp mbedx509 mbedtls mbedcrypto lhash zip lzlib zlibstatic "-static")

if(APPLE)
target_link_libraries(eli c11threads)
endif()

if(WIN32 OR MINGW)
target_link_libraries(eli bcrypt advapi32 ws2_32)
target_link_libraries(eli bcrypt advapi32 ws2_32 c11threads)
endif()

set_target_properties(eli PROPERTIES OUTPUT_NAME "eli")
Expand Down
2 changes: 1 addition & 1 deletion config.hjson
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
version: 0.33.2
version: 0.34.0
global_modules: false //disables global modules loading (only looks up for modules in cwd)
minify: true
compress: true
Expand Down
1 change: 1 addition & 0 deletions deps/c11threads
Submodule c11threads added at c2d0de
2 changes: 1 addition & 1 deletion deps/eli-env-extra
Submodule eli-env-extra updated 1 files
+51 −53 src/lenv.c
2 changes: 1 addition & 1 deletion deps/eli-extra-utils
2 changes: 1 addition & 1 deletion deps/eli-fs-extra
Submodule eli-fs-extra updated 5 files
+317 −336 src/ldir.c
+1 −1 src/lfile.c
+36 −46 src/llink.c
+238 −234 src/llocking.c
+62 −64 src/lperm.c
2 changes: 1 addition & 1 deletion deps/eli-os-extra
2 changes: 1 addition & 1 deletion deps/eli-pipe-extra
Submodule eli-pipe-extra updated 3 files
+6 −6 src/lpipe.c
+59 −62 src/pipe.c
+6 −2 src/pipe.h
2 changes: 1 addition & 1 deletion deps/eli-proc-extra
2 changes: 1 addition & 1 deletion deps/eli-stream-extra
2 changes: 1 addition & 1 deletion deps/lua-corehttp
2 changes: 1 addition & 1 deletion deps/lua-simple-ipc
2 changes: 1 addition & 1 deletion deps/lua-simple-socket
Submodule lua-simple-socket updated 1 files
+1 −1 src/lss.c
2 changes: 1 addition & 1 deletion deps/lua-tar-read-native
23 changes: 23 additions & 0 deletions lib/eli/extensions/io.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
local ok, stream_extra = pcall(require, "eli.stream.extra")

if not ok then
return {}
end

---#DES 'io.open_fstream'
---
---@param filename string
---@param mode? openmode
---@return EliReadableStream | EliWritableStream | EliRWStream | nil
---@return string? errmsg
local function open_fstream(filename, mode)
if not ok then
error"eli.stream is not available"
end

return stream_extra.open_fstream(filename, mode)
end

return {
open_fstream = open_fstream,
}
2 changes: 1 addition & 1 deletion lib/eli/fs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ function fs.chmod(path, mode, options)
return true
end

---#DES fs.EliFileLock'
---#DES 'fs.EliFileLock'
---
---@class EliFileLock
---@field free fun(eliFileLock: EliFileLock):nil
Expand Down
28 changes: 17 additions & 11 deletions lib/eli/proc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ local function _get_stdstream_cmd_part(stdname, file, options)
end
if file == "ignore" then return "", nil end
local _template = options[stdname .. "RedirectTemplate"] or
proc.settings[stdname .. "RedirectTemplate"]
proc.settings[stdname .. "RedirectTemplate"]
if type(_template) == "function" then
return _template(file), file, _tmpMode
elseif type(_template) == "string" then
Expand Down Expand Up @@ -126,22 +126,22 @@ function proc.exec(cmd, options)
if type(options) ~= "table" then options = {} end

local _stdoutPart, _stdout, _tmpStdout =
_get_stdstream_cmd_part("stdout", options.stdout, options)
_get_stdstream_cmd_part("stdout", options.stdout, options)
local _stderrPart, _stderr, _tmpStderr =
_get_stdstream_cmd_part("stderr", options.stderr, options)
_get_stdstream_cmd_part("stderr", options.stderr, options)
local _stdinPart = _get_stdstream_cmd_part("stdin", options.stdin, options)

local _cmd =
_sx.join_strings(" ", _stdinPart, cmd, _stdoutPart, _stderrPart)
_sx.join_strings(" ", _stdinPart, cmd, _stdoutPart, _stderrPart)
local _, _exitType, _code = os.execute(_cmd)

return {
exitcode = _code,
exittype = _exitType,
stdoutStream = _stdout and
(_tmpStdout and ExecTmpFile:new(_stdout) or io.open(_stdout)),
(_tmpStdout and ExecTmpFile:new(_stdout) or io.open(_stdout)),
stderrStream = _stderr and
(_tmpStderr and ExecTmpFile:new(_stderr) or io.open(_stderr)),
(_tmpStderr and ExecTmpFile:new(_stderr) or io.open(_stderr)),
}
end

Expand Down Expand Up @@ -173,13 +173,19 @@ if not eprocLoaded then return _util.generate_safe_functions(proc) end
---@field stdout '"ignore"' | '"pipe"' | '"inherit"' | '"external' | '"file"'
---@field stderr '"ignore"' | '"pipe"' | '"inherit"' | '"external' | '"file"'

---@class EliWritableStream
---@class EliStreamBase
---@field close fun(self: EliReadableStream)

---@class EliWritableStream : EliStreamBase
---@field __type '"ELI_STREAM_W_METATABLE"'
---@field wirte fun(self: EliWritableStream, content: string)
---@field write fun(self: EliWritableStream, content: string)

---@class EliReadableStream
---@class EliReadableStream : EliStreamBase
---@field __type '"ELI_STREAM_R_METATABLE"'
---@field read fun(self: EliReadableStream, opt: integer | "a" | "l" | "L"): string
---@field read fun(self: EliReadableStream, opt: integer | "a" | "l" | "L", timeout: integer?, divider_or_units: "s" | "ms" | integer | nil): string

---@class EliRWStream: EliReadableStream, EliWritableStream
---@field __type '"ELI_STREAM_RW_METATABLE"'

---@class EliProcessGroup
---@field kill fun(self: EliProcessGroup, signal: integer?): integer
Expand All @@ -188,7 +194,7 @@ if not eprocLoaded then return _util.generate_safe_functions(proc) end
---@field __type '"ELI_PROCESS"'
---@field __tostring fun(self: EliProcess): string
---@field get_pid fun(self: EliProcess): integer
---@field wait fun(self: EliProcess, intervalSeconds: integer?, unitsDivider: integer?): integer
---@field wait fun(self: EliProcess, intervalSeconds: integer?, unitsDivider: integer | '"s"' | '"ms"' | nil): integer
---@field kill fun(self: EliProcess, signal: integer?): integer
---@field get_exitcode fun(self: EliProcess): integer
---@field exited fun(self: EliProcess): boolean
Expand Down
4 changes: 2 additions & 2 deletions lib/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ELI_LIB_VERSION = "0.33.1"
ELI_VERSION = "0.33.1"
ELI_LIB_VERSION = '0.34.0'
ELI_VERSION = '0.34.0'
do
local path = require"eli.path"
local _eos = require"eli.os"
Expand Down
1 change: 1 addition & 0 deletions lib/tests/all.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require"ipc"

require"extensions.string"
require"extensions.table"
require"extensions.io"

require"internals.util"

Expand Down
2 changes: 2 additions & 0 deletions lib/tests/assets/scripts/delayed.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ping localhost -n 2
echo 12345
4 changes: 4 additions & 0 deletions lib/tests/assets/scripts/delayed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

sleep 2
echo 12345
86 changes: 86 additions & 0 deletions lib/tests/extensions/io.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
local test = TEST or require"u-test"
local ok, exIo = pcall(require, "eli.extensions.io")
local fs = require"eli.fs"

if not ok then
test["eli.extensions.io available"] = function ()
test.assert(false, "eli.extensions.io not available")
end
if not TEST then
test.summary()
os.exit()
else
return
end
end

test["eli.extensions.io available"] = function ()
test.assert(true)
end

test["file as stream - line"] = function ()
local refContent = io.open"assets/test.file":read"l"
local streamContent = exIo.open_fstream"assets/test.file":read"l"
test.assert(refContent == streamContent, "content does not match")

local refContent = io.open"assets/test.file":read"a"
local stream = exIo.open_fstream"assets/test.file"
local streamContent = stream:read"a"
while true do
local line = stream:read"L"
if not line then
break
end
streamContent = streamContent .. line
end

test.assert(refContent == streamContent, "content does not match")
end

test["file as stream - all"] = function ()
local refContent = io.open"assets/test.file":read"a"
local streamContent = exIo.open_fstream"assets/test.file":read"a"

test.assert(refContent == streamContent, "content does not match")
end

test["file as stream - bytes"] = function ()
local refContent = io.open"assets/test.file":read"l"
local streamContent = exIo.open_fstream"assets/test.file":read"l"

test.assert(refContent == streamContent, "content does not match")

local refContent = io.open"assets/test.file":read"a"
local stream = exIo.open_fstream"assets/test.file"
local streamContent = stream:read"a"
while true do
local line = stream:read(100)
if not line then
break
end
streamContent = streamContent .. line
end

test.assert(refContent == streamContent, "content does not match")
end

test["file as stream - write"] = function ()
fs.remove"tmp/test-streamed.file"
fs.remove"tmp/test-write.file"

local content = "12345"
local stream = exIo.open_fstream("tmp/test-streamed.file", "w")
stream:write(content)
stream:close()
fs.write_file("tmp/test-write.file", content)

local hashOfStreamContent = fs.hash_file"tmp/test-streamed.file"
local hashOfWriteContent = fs.hash_file"tmp/test-write.file"

test.assert(hashOfStreamContent == hashOfWriteContent, "content does not match")
end


if not TEST then
test.summary()
end
Loading

0 comments on commit 1728c4d

Please sign in to comment.