diff --git a/Userland/Libraries/LibC/CMakeLists.txt b/Userland/Libraries/LibC/CMakeLists.txt index 6746a93b33..fc37efe40b 100644 --- a/Userland/Libraries/LibC/CMakeLists.txt +++ b/Userland/Libraries/LibC/CMakeLists.txt @@ -26,6 +26,7 @@ set(LIBC_SOURCES pty.cpp pwd.cpp qsort.cpp + regex.cpp scanf.cpp sched.cpp serenity.cpp diff --git a/Userland/Libraries/LibC/regex.cpp b/Userland/Libraries/LibC/regex.cpp new file mode 100644 index 0000000000..dca3624113 --- /dev/null +++ b/Userland/Libraries/LibC/regex.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +static void* s_libregex; +static pthread_mutex_t s_libregex_lock; + +static int (*s_regcomp)(regex_t*, const char*, int); +static int (*s_regexec)(const regex_t*, const char*, size_t, regmatch_t[], int); +static size_t (*s_regerror)(int, const regex_t*, char*, size_t); +static void (*s_regfree)(regex_t*); + +static void ensure_libregex() +{ + pthread_mutex_lock(&s_libregex_lock); + if (!s_libregex) { + s_libregex = __dlopen("libregex.so", RTLD_NOW).value(); + + s_regcomp = reinterpret_cast(__dlsym(s_libregex, "regcomp").value()); + s_regexec = reinterpret_cast(__dlsym(s_libregex, "regexec").value()); + s_regerror = reinterpret_cast(__dlsym(s_libregex, "regerror").value()); + s_regfree = reinterpret_cast(__dlsym(s_libregex, "regfree").value()); + } + pthread_mutex_unlock(&s_libregex_lock); +} + +extern "C" { + +int __attribute__((weak)) regcomp(regex_t* reg, const char* pattern, int cflags) +{ + ensure_libregex(); + return s_regcomp(reg, pattern, cflags); +} + +int __attribute__((weak)) regexec(const regex_t* reg, const char* string, size_t nmatch, regmatch_t pmatch[], int eflags) +{ + ensure_libregex(); + return s_regexec(reg, string, nmatch, pmatch, eflags); +} + +size_t __attribute__((weak)) regerror(int errcode, const regex_t* reg, char* errbuf, size_t errbuf_size) +{ + ensure_libregex(); + return s_regerror(errcode, reg, errbuf, errbuf_size); +} + +void __attribute__((weak)) regfree(regex_t* reg) +{ + ensure_libregex(); + return s_regfree(reg); +} +}