From a3f6236bec3cb7e51bda3cc5f6898a3bc9489e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Mon, 26 Jun 2023 20:51:12 +0200 Subject: [PATCH] LibC: Convert semaphore and termcap to String --- Userland/Libraries/LibC/semaphore.cpp | 17 ++++-- Userland/Libraries/LibC/termcap.cpp | 86 ++++++++++++++------------- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/Userland/Libraries/LibC/semaphore.cpp b/Userland/Libraries/LibC/semaphore.cpp index 10a302c638..f6a6dbaf9d 100644 --- a/Userland/Libraries/LibC/semaphore.cpp +++ b/Userland/Libraries/LibC/semaphore.cpp @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -31,7 +31,9 @@ static constexpr u32 POST_WAKES = 1 << 31; static constexpr auto sem_path_prefix = "/tmp/semaphore/"sv; static constexpr auto SEM_NAME_MAX = PATH_MAX - sem_path_prefix.length(); -static ErrorOr sem_name_to_path(char const* name) + +// The returned string will always contain a null terminator, since it is used in C APIs. +static ErrorOr sem_name_to_path(char const* name) { if (name[0] != '/') return EINVAL; @@ -48,7 +50,9 @@ static ErrorOr sem_name_to_path(char const* name) StringBuilder builder; TRY(builder.try_append(sem_path_prefix)); TRY(builder.try_append(name_view)); - return builder.to_deprecated_string(); + + TRY(builder.try_append_code_point(0)); + return builder.to_string(); } struct NamedSemaphore { @@ -58,7 +62,7 @@ struct NamedSemaphore { sem_t* sem { nullptr }; }; -static HashMap s_named_semaphores; +static HashMap s_named_semaphores; static pthread_mutex_t s_sem_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t s_sem_once = PTHREAD_ONCE_INIT; @@ -95,7 +99,8 @@ sem_t* sem_open(char const* name, int flags, ...) pthread_mutex_lock(&s_sem_mutex); ScopeGuard unlock_guard = [] { pthread_mutex_unlock(&s_sem_mutex); }; - int fd = open(path.characters(), O_RDWR | O_CLOEXEC | flags, mode); + // sem_name_to_path guarantees a null terminator. + int fd = open(path.bytes_as_string_view().characters_without_null_termination(), O_RDWR | O_CLOEXEC | flags, mode); if (fd == -1) return SEM_FAILED; @@ -200,7 +205,7 @@ int sem_unlink(char const* name) } auto path = path_or_error.release_value(); - return unlink(path.characters()); + return unlink(path.bytes_as_string_view().characters_without_null_termination()); } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html diff --git a/Userland/Libraries/LibC/termcap.cpp b/Userland/Libraries/LibC/termcap.cpp index 210e5d167f..da3a1c5dd8 100644 --- a/Userland/Libraries/LibC/termcap.cpp +++ b/Userland/Libraries/LibC/termcap.cpp @@ -5,8 +5,8 @@ */ #include -#include #include +#include #include #include #include @@ -27,47 +27,47 @@ int __attribute__((weak)) tgetent([[maybe_unused]] char* bp, [[maybe_unused]] ch return 1; } -static HashMap* caps = nullptr; +static HashMap* caps = nullptr; static void ensure_caps() { if (caps) return; - caps = new HashMap; - caps->set("DC", "\033[%p1%dP"); - caps->set("IC", "\033[%p1%d@"); - caps->set("ce", "\033[K"); - caps->set("cl", "\033[H\033[J"); - caps->set("cr", "\015"); - caps->set("dc", "\033[P"); - caps->set("ei", ""); - caps->set("ic", ""); - caps->set("im", ""); - caps->set("kd", "\033[B"); - caps->set("kl", "\033[D"); - caps->set("kr", "\033[C"); - caps->set("ku", "\033[A"); - caps->set("ks", ""); - caps->set("ke", ""); - caps->set("le", "\033[D"); - caps->set("mm", ""); - caps->set("mo", ""); - caps->set("pc", ""); - caps->set("up", "\033[A"); - caps->set("vb", ""); - caps->set("am", ""); - caps->set("@7", ""); - caps->set("kH", ""); - caps->set("kI", "\033[L"); - caps->set("kh", "\033[H"); - caps->set("vs", ""); - caps->set("ve", ""); - caps->set("E3", ""); - caps->set("kD", ""); - caps->set("nd", "\033[C"); + caps = new HashMap; + caps->set("DC"_short_string, "\033[%p1%dP"); + caps->set("IC"_short_string, "\033[%p1%d@"); + caps->set("ce"_short_string, "\033[K"); + caps->set("cl"_short_string, "\033[H\033[J"); + caps->set("cr"_short_string, "\015"); + caps->set("dc"_short_string, "\033[P"); + caps->set("ei"_short_string, ""); + caps->set("ic"_short_string, ""); + caps->set("im"_short_string, ""); + caps->set("kd"_short_string, "\033[B"); + caps->set("kl"_short_string, "\033[D"); + caps->set("kr"_short_string, "\033[C"); + caps->set("ku"_short_string, "\033[A"); + caps->set("ks"_short_string, ""); + caps->set("ke"_short_string, ""); + caps->set("le"_short_string, "\033[D"); + caps->set("mm"_short_string, ""); + caps->set("mo"_short_string, ""); + caps->set("pc"_short_string, ""); + caps->set("up"_short_string, "\033[A"); + caps->set("vb"_short_string, ""); + caps->set("am"_short_string, ""); + caps->set("@7"_short_string, ""); + caps->set("kH"_short_string, ""); + caps->set("kI"_short_string, "\033[L"); + caps->set("kh"_short_string, "\033[H"); + caps->set("vs"_short_string, ""); + caps->set("ve"_short_string, ""); + caps->set("E3"_short_string, ""); + caps->set("kD"_short_string, ""); + caps->set("nd"_short_string, "\033[C"); - caps->set("co", "80"); - caps->set("li", "25"); + caps->set("co"_short_string, "80"); + caps->set("li"_short_string, "25"); } // Unfortunately, tgetstr() doesn't accept a size argument for the buffer @@ -79,7 +79,7 @@ char* __attribute__((weak)) tgetstr(char const* id, char** area) { ensure_caps(); warnln_if(TERMCAP_DEBUG, "tgetstr: id='{}'", id); - auto it = caps->find(id); + auto it = caps->find(StringView { id, strlen(id) }); if (it != caps->end()) { char* ret = *area; char const* val = (*it).value; @@ -96,7 +96,7 @@ char* __attribute__((weak)) tgetstr(char const* id, char** area) int __attribute__((weak)) tgetflag([[maybe_unused]] char const* id) { warnln_if(TERMCAP_DEBUG, "tgetflag: '{}'", id); - auto it = caps->find(id); + auto it = caps->find(StringView { id, strlen(id) }); if (it != caps->end()) return 1; return 0; @@ -105,7 +105,7 @@ int __attribute__((weak)) tgetflag([[maybe_unused]] char const* id) int __attribute__((weak)) tgetnum(char const* id) { warnln_if(TERMCAP_DEBUG, "tgetnum: '{}'", id); - auto it = caps->find(id); + auto it = caps->find(StringView { id, strlen(id) }); if (it != caps->end()) return atoi((*it).value); return -1; @@ -114,7 +114,13 @@ int __attribute__((weak)) tgetnum(char const* id) static Vector s_tgoto_buffer; char* __attribute__((weak)) tgoto([[maybe_unused]] char const* cap, [[maybe_unused]] int col, [[maybe_unused]] int row) { - auto cap_str = StringView { cap, strlen(cap) }.replace("%p1%d"sv, DeprecatedString::number(col), ReplaceMode::FirstOnly).replace("%p2%d"sv, DeprecatedString::number(row), ReplaceMode::FirstOnly); + auto row_string = String::number(row); + auto column_string = String::number(col); + if (row_string.is_error() || column_string.is_error()) { + // According to Linux man pages (https://man7.org/linux/man-pages/man3/tgoto.3x.html) we apparently don't have to set errno. + return nullptr; + } + auto cap_str = StringView { cap, strlen(cap) }.replace("%p1%d"sv, column_string.release_value(), ReplaceMode::FirstOnly).replace("%p2%d"sv, row_string.release_value(), ReplaceMode::FirstOnly); s_tgoto_buffer.clear_with_capacity(); s_tgoto_buffer.ensure_capacity(cap_str.length());