Compare commits
3 Commits
193d63c81b
...
60c6e764a4
Author | SHA1 | Date | |
---|---|---|---|
60c6e764a4 | |||
26ff964ec1 | |||
d97bf991d1 |
43
apps/cat.cpp
43
apps/cat.cpp
@ -1,45 +1,40 @@
|
|||||||
|
#include <luna/String.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
|
#include <os/File.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
using os::File;
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static void do_cat(StringView path)
|
static Result<void> do_cat(StringView path)
|
||||||
{
|
{
|
||||||
FILE* f;
|
SharedPtr<File> f;
|
||||||
|
|
||||||
if (path == "-") f = stdin;
|
auto out = File::standard_output();
|
||||||
|
|
||||||
|
if (path == "-") f = File::standard_input();
|
||||||
else
|
else
|
||||||
{
|
f = TRY(File::open(path, File::ReadOnly));
|
||||||
f = fopen(path.chars(), "r");
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
perror(path.chars());
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[4096];
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
size_t nread = fread(buffer, 1, sizeof(buffer), f);
|
String line = TRY(f->read_line());
|
||||||
if (nread == 0) return;
|
if (line.is_empty()) break;
|
||||||
fwrite(buffer, 1, nread, stdout);
|
out->write(line.view());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f != stdin) fclose(f);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView filename;
|
StringView filename;
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_positional_argument(filename, "file"_sv, "-"_sv);
|
parser.add_positional_argument(filename, "file"_sv, "-"_sv);
|
||||||
Vector<StringView> extra_files = parser.parse(argc, argv).value();
|
Vector<StringView> extra_files = TRY(parser.parse(argc, argv));
|
||||||
|
|
||||||
do_cat(filename);
|
TRY(do_cat(filename));
|
||||||
|
|
||||||
for (auto file : extra_files) { do_cat(file); }
|
for (auto file : extra_files) TRY(do_cat(file));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,27 @@
|
|||||||
|
#include <luna/String.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
|
#include <os/File.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
using os::File;
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
FILE* f;
|
|
||||||
StringView pathname;
|
StringView pathname;
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_positional_argument(pathname, "file"_sv, true);
|
parser.add_positional_argument(pathname, "path"_sv, true);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
f = fopen(pathname.chars(), "w");
|
auto file = TRY(File::open_or_create(pathname, File::WriteOnly));
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
perror(pathname.chars());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[4096];
|
auto input = File::standard_input();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
char* rc = fgets(buffer, sizeof(buffer), stdin);
|
String line = TRY(input->read_line());
|
||||||
if (rc == 0) break;
|
if (line.is_empty()) break;
|
||||||
fputs(buffer, f);
|
TRY(file->write(line.view()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView pathname;
|
StringView pathname;
|
||||||
bool show_all { false };
|
bool show_all { false };
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView path;
|
StringView path;
|
||||||
|
|
||||||
@ -14,4 +14,6 @@ int main(int argc, char** argv)
|
|||||||
perror("rm");
|
perror("rm");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ static Result<Vector<char*>> split_command_into_argv(const char* cmd)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView file;
|
StringView file;
|
||||||
StringView command;
|
StringView command;
|
||||||
|
@ -51,7 +51,7 @@ char* getpass()
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView name;
|
StringView name;
|
||||||
|
|
||||||
@ -92,4 +92,6 @@ int main(int argc, char** argv)
|
|||||||
chdir(entry->pw_dir);
|
chdir(entry->pw_dir);
|
||||||
|
|
||||||
execl(entry->pw_shell, entry->pw_shell, NULL);
|
execl(entry->pw_shell, entry->pw_shell, NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,54 @@
|
|||||||
|
typedef void* (*cxa_atexit_func_t)(void*);
|
||||||
|
|
||||||
|
struct cxa_atexit_entry
|
||||||
|
{
|
||||||
|
cxa_atexit_func_t function;
|
||||||
|
void* argument;
|
||||||
|
void* dso_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CXA_ATEXIT_MAX 64
|
||||||
|
|
||||||
|
int cxa_atexit_entry_count = 0;
|
||||||
|
|
||||||
|
cxa_atexit_entry cxa_atexit_entries[CXA_ATEXIT_MAX];
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
void __gxx_personality_v0()
|
void __gxx_personality_v0()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __cxa_atexit(cxa_atexit_func_t func, void* arg, void* dso)
|
||||||
|
{
|
||||||
|
if (cxa_atexit_entry_count >= CXA_ATEXIT_MAX) return -1;
|
||||||
|
cxa_atexit_entries[cxa_atexit_entry_count].function = func;
|
||||||
|
cxa_atexit_entries[cxa_atexit_entry_count].argument = arg;
|
||||||
|
cxa_atexit_entries[cxa_atexit_entry_count].dso_handle = dso;
|
||||||
|
cxa_atexit_entry_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cxa_finalize(void* f)
|
||||||
|
{
|
||||||
|
int i = cxa_atexit_entry_count;
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
if (cxa_atexit_entries[i].function) { cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
if (cxa_atexit_entries[i].function == (cxa_atexit_func_t)f)
|
||||||
|
{
|
||||||
|
cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument);
|
||||||
|
cxa_atexit_entries[i].function = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ Result<void> StringBuilder::add(unsigned long value)
|
|||||||
|
|
||||||
Result<void> StringBuilder::add(char value)
|
Result<void> StringBuilder::add(char value)
|
||||||
{
|
{
|
||||||
return format("%c"_sv, value);
|
return m_data.append_data((const u8*)&value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> StringBuilder::format(StringView fmt, ...)
|
Result<void> StringBuilder::format(StringView fmt, ...)
|
||||||
|
@ -5,6 +5,8 @@ file(GLOB HEADERS include/os/*.h)
|
|||||||
set(SOURCES
|
set(SOURCES
|
||||||
${HEADERS}
|
${HEADERS}
|
||||||
src/ArgumentParser.cpp
|
src/ArgumentParser.cpp
|
||||||
|
src/File.cpp
|
||||||
|
src/Main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(os ${SOURCES})
|
add_library(os ${SOURCES})
|
||||||
|
51
libos/include/os/File.h
Normal file
51
libos/include/os/File.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <bits/open-flags.h>
|
||||||
|
#include <luna/Buffer.h>
|
||||||
|
#include <luna/Result.h>
|
||||||
|
#include <luna/SharedPtr.h>
|
||||||
|
#include <luna/StringView.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
namespace os
|
||||||
|
{
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum OpenMode
|
||||||
|
{
|
||||||
|
ReadOnly = O_RDONLY,
|
||||||
|
WriteOnly = O_WRONLY | O_TRUNC,
|
||||||
|
ReadWrite = O_RDWR | O_TRUNC,
|
||||||
|
Append = O_WRONLY | O_APPEND,
|
||||||
|
ReadAppend = O_RDWR | O_APPEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Result<SharedPtr<File>> open(StringView path, OpenMode flags);
|
||||||
|
static Result<SharedPtr<File>> open_or_create(StringView path, OpenMode flags, mode_t mode = 0644);
|
||||||
|
static Result<SharedPtr<File>> create(StringView path, OpenMode flags, mode_t mode = 0644);
|
||||||
|
|
||||||
|
static SharedPtr<File> standard_input();
|
||||||
|
static SharedPtr<File> standard_output();
|
||||||
|
static SharedPtr<File> standard_error();
|
||||||
|
|
||||||
|
void set_close_on_exec();
|
||||||
|
|
||||||
|
Result<void> write(StringView str);
|
||||||
|
|
||||||
|
Result<String> read_line();
|
||||||
|
|
||||||
|
Result<int> getchar();
|
||||||
|
|
||||||
|
File(Badge<File>);
|
||||||
|
~File();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Result<SharedPtr<File>> construct(StringView path, int flags, mode_t mode);
|
||||||
|
static void initialize_standard_streams();
|
||||||
|
|
||||||
|
Result<usize> raw_read(u8* buf, usize length);
|
||||||
|
Result<usize> raw_write(const u8* buf, usize length);
|
||||||
|
|
||||||
|
int m_fd { -1 };
|
||||||
|
};
|
||||||
|
}
|
4
libos/include/os/Main.h
Normal file
4
libos/include/os/Main.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Result.h>
|
||||||
|
|
||||||
|
Result<int> luna_main(int argc, char** argv);
|
141
libos/src/File.cpp
Normal file
141
libos/src/File.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <luna/StringBuilder.h>
|
||||||
|
#include <os/File.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static SharedPtr<os::File> g_stdin = {};
|
||||||
|
static SharedPtr<os::File> g_stdout = {};
|
||||||
|
static SharedPtr<os::File> g_stderr = {};
|
||||||
|
|
||||||
|
namespace os
|
||||||
|
{
|
||||||
|
File::File(Badge<File>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
File::~File()
|
||||||
|
{
|
||||||
|
if (m_fd >= 0) close(m_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::initialize_standard_streams()
|
||||||
|
{
|
||||||
|
g_stdin = adopt_shared_if_nonnull(new (std::nothrow) File({}))
|
||||||
|
.expect_release_value("Cannot open standard input stream");
|
||||||
|
g_stdin->m_fd = STDIN_FILENO;
|
||||||
|
|
||||||
|
g_stdout = adopt_shared_if_nonnull(new (std::nothrow) File({}))
|
||||||
|
.expect_release_value("Cannot open standard output stream");
|
||||||
|
g_stdout->m_fd = STDOUT_FILENO;
|
||||||
|
|
||||||
|
g_stderr = adopt_shared_if_nonnull(new (std::nothrow) File({}))
|
||||||
|
.expect_release_value("Cannot open standard error stream");
|
||||||
|
g_stderr->m_fd = STDERR_FILENO;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<File> File::standard_input()
|
||||||
|
{
|
||||||
|
if (!g_stdin) initialize_standard_streams();
|
||||||
|
|
||||||
|
return g_stdin;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<File> File::standard_output()
|
||||||
|
{
|
||||||
|
if (!g_stdout) initialize_standard_streams();
|
||||||
|
|
||||||
|
return g_stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<File> File::standard_error()
|
||||||
|
{
|
||||||
|
if (!g_stderr) initialize_standard_streams();
|
||||||
|
|
||||||
|
return g_stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<SharedPtr<File>> File::construct(StringView path, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
auto file = TRY(adopt_shared_if_nonnull(new (std::nothrow) File({})));
|
||||||
|
|
||||||
|
long rc = syscall(SYS_open, path.chars(), flags, mode);
|
||||||
|
int fd = TRY(Result<int>::from_syscall(rc));
|
||||||
|
|
||||||
|
file->m_fd = fd;
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<SharedPtr<File>> File::open(StringView path, OpenMode flags)
|
||||||
|
{
|
||||||
|
return construct(path, (int)flags, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<SharedPtr<File>> File::open_or_create(StringView path, OpenMode flags, mode_t mode)
|
||||||
|
{
|
||||||
|
return construct(path, (int)flags | O_CREAT, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<SharedPtr<File>> File::create(StringView path, OpenMode flags, mode_t mode)
|
||||||
|
{
|
||||||
|
return construct(path, (int)flags | (O_CREAT | O_EXCL), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<usize> File::raw_read(u8* buf, usize length)
|
||||||
|
{
|
||||||
|
long rc = syscall(SYS_read, m_fd, buf, length);
|
||||||
|
return Result<usize>::from_syscall(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<usize> File::raw_write(const u8* buf, usize length)
|
||||||
|
{
|
||||||
|
long rc = syscall(SYS_write, m_fd, buf, length);
|
||||||
|
return Result<usize>::from_syscall(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void> File::write(StringView str)
|
||||||
|
{
|
||||||
|
TRY(raw_write((const u8*)str.chars(), str.length()));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<String> File::read_line()
|
||||||
|
{
|
||||||
|
Vector<char> data;
|
||||||
|
|
||||||
|
int current;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
current = TRY(getchar());
|
||||||
|
|
||||||
|
if (current == -1) break;
|
||||||
|
|
||||||
|
TRY(data.try_append((char)current));
|
||||||
|
|
||||||
|
if (current == '\n') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.size()) return String {};
|
||||||
|
|
||||||
|
TRY(data.try_append('\0'));
|
||||||
|
|
||||||
|
return String::from_cstring(data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<int> File::getchar()
|
||||||
|
{
|
||||||
|
char value;
|
||||||
|
|
||||||
|
usize nread = TRY(raw_read((u8*)&value, 1));
|
||||||
|
if (!nread) return -1;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::set_close_on_exec()
|
||||||
|
{
|
||||||
|
fcntl(m_fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
}
|
||||||
|
}
|
23
libos/src/Main.cpp
Normal file
23
libos/src/Main.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <os/Main.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int g_argc;
|
||||||
|
char** g_argv;
|
||||||
|
|
||||||
|
__attribute__((weak)) int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
g_argc = argc;
|
||||||
|
g_argv = argv;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
bool ok = luna_main(argc, argv).try_set_value_or_error(result, errno);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
perror(g_argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user