mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 07:24:58 +00:00
LibC: Convert semaphore and termcap to String
This commit is contained in:
parent
bd13cc0732
commit
a3f6236bec
2 changed files with 57 additions and 46 deletions
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/Atomic.h>
|
#include <AK/Atomic.h>
|
||||||
#include <AK/DeprecatedString.h>
|
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <bits/pthread_cancel.h>
|
#include <bits/pthread_cancel.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -31,7 +31,9 @@ static constexpr u32 POST_WAKES = 1 << 31;
|
||||||
|
|
||||||
static constexpr auto sem_path_prefix = "/tmp/semaphore/"sv;
|
static constexpr auto sem_path_prefix = "/tmp/semaphore/"sv;
|
||||||
static constexpr auto SEM_NAME_MAX = PATH_MAX - sem_path_prefix.length();
|
static constexpr auto SEM_NAME_MAX = PATH_MAX - sem_path_prefix.length();
|
||||||
static ErrorOr<DeprecatedString> 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<String> sem_name_to_path(char const* name)
|
||||||
{
|
{
|
||||||
if (name[0] != '/')
|
if (name[0] != '/')
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -48,7 +50,9 @@ static ErrorOr<DeprecatedString> sem_name_to_path(char const* name)
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
TRY(builder.try_append(sem_path_prefix));
|
TRY(builder.try_append(sem_path_prefix));
|
||||||
TRY(builder.try_append(name_view));
|
TRY(builder.try_append(name_view));
|
||||||
return builder.to_deprecated_string();
|
|
||||||
|
TRY(builder.try_append_code_point(0));
|
||||||
|
return builder.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NamedSemaphore {
|
struct NamedSemaphore {
|
||||||
|
@ -58,7 +62,7 @@ struct NamedSemaphore {
|
||||||
sem_t* sem { nullptr };
|
sem_t* sem { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
static HashMap<DeprecatedString, NamedSemaphore> s_named_semaphores;
|
static HashMap<String, NamedSemaphore> s_named_semaphores;
|
||||||
static pthread_mutex_t s_sem_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t s_sem_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_once_t s_sem_once = PTHREAD_ONCE_INIT;
|
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);
|
pthread_mutex_lock(&s_sem_mutex);
|
||||||
ScopeGuard unlock_guard = [] { pthread_mutex_unlock(&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)
|
if (fd == -1)
|
||||||
return SEM_FAILED;
|
return SEM_FAILED;
|
||||||
|
|
||||||
|
@ -200,7 +205,7 @@ int sem_unlink(char const* name)
|
||||||
}
|
}
|
||||||
auto path = path_or_error.release_value();
|
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
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/DeprecatedString.h>
|
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -27,47 +27,47 @@ int __attribute__((weak)) tgetent([[maybe_unused]] char* bp, [[maybe_unused]] ch
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HashMap<DeprecatedString, char const*>* caps = nullptr;
|
static HashMap<String, char const*>* caps = nullptr;
|
||||||
|
|
||||||
static void ensure_caps()
|
static void ensure_caps()
|
||||||
{
|
{
|
||||||
if (caps)
|
if (caps)
|
||||||
return;
|
return;
|
||||||
caps = new HashMap<DeprecatedString, char const*>;
|
caps = new HashMap<String, char const*>;
|
||||||
caps->set("DC", "\033[%p1%dP");
|
caps->set("DC"_short_string, "\033[%p1%dP");
|
||||||
caps->set("IC", "\033[%p1%d@");
|
caps->set("IC"_short_string, "\033[%p1%d@");
|
||||||
caps->set("ce", "\033[K");
|
caps->set("ce"_short_string, "\033[K");
|
||||||
caps->set("cl", "\033[H\033[J");
|
caps->set("cl"_short_string, "\033[H\033[J");
|
||||||
caps->set("cr", "\015");
|
caps->set("cr"_short_string, "\015");
|
||||||
caps->set("dc", "\033[P");
|
caps->set("dc"_short_string, "\033[P");
|
||||||
caps->set("ei", "");
|
caps->set("ei"_short_string, "");
|
||||||
caps->set("ic", "");
|
caps->set("ic"_short_string, "");
|
||||||
caps->set("im", "");
|
caps->set("im"_short_string, "");
|
||||||
caps->set("kd", "\033[B");
|
caps->set("kd"_short_string, "\033[B");
|
||||||
caps->set("kl", "\033[D");
|
caps->set("kl"_short_string, "\033[D");
|
||||||
caps->set("kr", "\033[C");
|
caps->set("kr"_short_string, "\033[C");
|
||||||
caps->set("ku", "\033[A");
|
caps->set("ku"_short_string, "\033[A");
|
||||||
caps->set("ks", "");
|
caps->set("ks"_short_string, "");
|
||||||
caps->set("ke", "");
|
caps->set("ke"_short_string, "");
|
||||||
caps->set("le", "\033[D");
|
caps->set("le"_short_string, "\033[D");
|
||||||
caps->set("mm", "");
|
caps->set("mm"_short_string, "");
|
||||||
caps->set("mo", "");
|
caps->set("mo"_short_string, "");
|
||||||
caps->set("pc", "");
|
caps->set("pc"_short_string, "");
|
||||||
caps->set("up", "\033[A");
|
caps->set("up"_short_string, "\033[A");
|
||||||
caps->set("vb", "");
|
caps->set("vb"_short_string, "");
|
||||||
caps->set("am", "");
|
caps->set("am"_short_string, "");
|
||||||
caps->set("@7", "");
|
caps->set("@7"_short_string, "");
|
||||||
caps->set("kH", "");
|
caps->set("kH"_short_string, "");
|
||||||
caps->set("kI", "\033[L");
|
caps->set("kI"_short_string, "\033[L");
|
||||||
caps->set("kh", "\033[H");
|
caps->set("kh"_short_string, "\033[H");
|
||||||
caps->set("vs", "");
|
caps->set("vs"_short_string, "");
|
||||||
caps->set("ve", "");
|
caps->set("ve"_short_string, "");
|
||||||
caps->set("E3", "");
|
caps->set("E3"_short_string, "");
|
||||||
caps->set("kD", "");
|
caps->set("kD"_short_string, "");
|
||||||
caps->set("nd", "\033[C");
|
caps->set("nd"_short_string, "\033[C");
|
||||||
|
|
||||||
caps->set("co", "80");
|
caps->set("co"_short_string, "80");
|
||||||
caps->set("li", "25");
|
caps->set("li"_short_string, "25");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfortunately, tgetstr() doesn't accept a size argument for the buffer
|
// 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();
|
ensure_caps();
|
||||||
warnln_if(TERMCAP_DEBUG, "tgetstr: id='{}'", id);
|
warnln_if(TERMCAP_DEBUG, "tgetstr: id='{}'", id);
|
||||||
auto it = caps->find(id);
|
auto it = caps->find(StringView { id, strlen(id) });
|
||||||
if (it != caps->end()) {
|
if (it != caps->end()) {
|
||||||
char* ret = *area;
|
char* ret = *area;
|
||||||
char const* val = (*it).value;
|
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)
|
int __attribute__((weak)) tgetflag([[maybe_unused]] char const* id)
|
||||||
{
|
{
|
||||||
warnln_if(TERMCAP_DEBUG, "tgetflag: '{}'", id);
|
warnln_if(TERMCAP_DEBUG, "tgetflag: '{}'", id);
|
||||||
auto it = caps->find(id);
|
auto it = caps->find(StringView { id, strlen(id) });
|
||||||
if (it != caps->end())
|
if (it != caps->end())
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -105,7 +105,7 @@ int __attribute__((weak)) tgetflag([[maybe_unused]] char const* id)
|
||||||
int __attribute__((weak)) tgetnum(char const* id)
|
int __attribute__((weak)) tgetnum(char const* id)
|
||||||
{
|
{
|
||||||
warnln_if(TERMCAP_DEBUG, "tgetnum: '{}'", id);
|
warnln_if(TERMCAP_DEBUG, "tgetnum: '{}'", id);
|
||||||
auto it = caps->find(id);
|
auto it = caps->find(StringView { id, strlen(id) });
|
||||||
if (it != caps->end())
|
if (it != caps->end())
|
||||||
return atoi((*it).value);
|
return atoi((*it).value);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -114,7 +114,13 @@ int __attribute__((weak)) tgetnum(char const* id)
|
||||||
static Vector<char> s_tgoto_buffer;
|
static Vector<char> s_tgoto_buffer;
|
||||||
char* __attribute__((weak)) tgoto([[maybe_unused]] char const* cap, [[maybe_unused]] int col, [[maybe_unused]] int row)
|
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.clear_with_capacity();
|
||||||
s_tgoto_buffer.ensure_capacity(cap_str.length());
|
s_tgoto_buffer.ensure_capacity(cap_str.length());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue