Compare commits

...

5 Commits

Author SHA1 Message Date
fbb7de7156
sh: Do not leak memory when using cd
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 16:49:05 +02:00
4baee3a91f
sh: Close script file on exec 2023-04-18 16:42:43 +02:00
407e81b107
cat: Read into buffers instead of lines 2023-04-18 16:41:58 +02:00
fe11b04832
File: Add methods to read/write using buffers 2023-04-18 16:41:17 +02:00
51eedf2b16
Buffer: Add an is_empty() method 2023-04-18 16:40:37 +02:00
5 changed files with 42 additions and 6 deletions

View File

@ -14,11 +14,12 @@ static Result<void> do_cat(StringView path)
else
f = TRY(File::open(path, File::ReadOnly));
auto buf = TRY(Buffer::create_sized(4096));
while (1)
{
String line = TRY(f->read_line());
if (line.is_empty()) break;
out->write(line.view());
TRY(f->read(buf, 4096));
if (buf.is_empty()) break;
out->write(buf);
}
return {};

View File

@ -14,7 +14,7 @@
using os::File;
static Result<Vector<char*>> split_command_into_argv(StringView cmd)
static Result<Vector<char*>> split_command_into_argv(StringView cmd, char** out)
{
char* str = strdup(cmd.chars());
@ -33,13 +33,15 @@ static Result<Vector<char*>> split_command_into_argv(StringView cmd)
if (segment == NULL) return result;
}
if (out) *out = str;
return result;
}
[[noreturn]] static void execute_command(StringView command)
{
Vector<char*> argv;
bool ok = split_command_into_argv(command).try_move_value_or_error(argv, errno);
bool ok = split_command_into_argv(command, nullptr).try_move_value_or_error(argv, errno);
if (!ok)
{
perror("failed to parse command");
@ -73,7 +75,10 @@ Result<int> luna_main(int argc, char** argv)
interactive = true;
}
else
{
input_file = TRY(File::open(path, File::ReadOnly));
input_file->set_close_on_exec();
}
while (1)
{
@ -90,17 +95,21 @@ Result<int> luna_main(int argc, char** argv)
if (!strncmp(cmd.chars(), "cd", 2))
{
auto args = TRY(split_command_into_argv(cmd.view()));
char* copy = nullptr;
auto args = TRY(split_command_into_argv(cmd.view(), &copy));
check("cd"_sv == args[0]);
if (args.size() == 2)
{
auto home = TRY(os::FileSystem::home_directory());
if (chdir(home.chars()) < 0) perror("cd");
free(copy);
continue;
}
if (chdir(args[1]) < 0) perror("cd");
free(copy);
continue;
}

View File

@ -46,6 +46,11 @@ class Buffer
return m_size;
}
bool is_empty() const
{
return m_size == 0;
}
private:
Buffer(u8* data, usize size);

View File

@ -31,9 +31,12 @@ namespace os
void set_close_on_exec();
Result<void> write(StringView str);
Result<void> write(const Buffer& buf);
Result<String> read_line();
Result<void> read(Buffer& buf, usize size);
Result<int> getchar();
File(Badge<File>);

View File

@ -101,6 +101,13 @@ namespace os
return {};
}
Result<void> File::write(const Buffer& buf)
{
TRY(raw_write(buf.data(), buf.size()));
return {};
}
Result<String> File::read_line()
{
Vector<char> data;
@ -124,6 +131,17 @@ namespace os
return String::from_cstring(data.data());
}
Result<void> File::read(Buffer& buf, usize size)
{
u8* slice = TRY(buf.slice(0, size));
usize nread = TRY(raw_read(slice, size));
TRY(buf.try_resize(nread));
return {};
}
Result<int> File::getchar()
{
char value;