فهرست منبع

LibC: Add stub forwarders to LibRegex C API

The POSIX C regex functions are expected to live in the C standard
library, but Serenity split off its regex library into LibRegex. Make a
compromise by implementing stub forwarders for the C regex library that
load libregex.so and call the real implementation.

This is needed for ports that expect these C functions to be available
inside the standard C library without introducing a strong coupling
between LibC and LibDl or LibRegex. The non-standard Serenity C++ regex
API still lives inside LibRegex as before.
Jean-Baptiste Boric 4 سال پیش
والد
کامیت
62cd3af5a0
2فایلهای تغییر یافته به همراه61 افزوده شده و 0 حذف شده
  1. 1 0
      Userland/Libraries/LibC/CMakeLists.txt
  2. 60 0
      Userland/Libraries/LibC/regex.cpp

+ 1 - 0
Userland/Libraries/LibC/CMakeLists.txt

@@ -26,6 +26,7 @@ set(LIBC_SOURCES
     pty.cpp
     pty.cpp
     pwd.cpp
     pwd.cpp
     qsort.cpp
     qsort.cpp
+    regex.cpp
     scanf.cpp
     scanf.cpp
     sched.cpp
     sched.cpp
     serenity.cpp
     serenity.cpp

+ 60 - 0
Userland/Libraries/LibC/regex.cpp

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Assertions.h>
+#include <LibDl/dlfcn.h>
+#include <LibDl/dlfcn_integration.h>
+#include <pthread.h>
+#include <regex.h>
+
+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<int (*)(regex_t*, const char*, int)>(__dlsym(s_libregex, "regcomp").value());
+        s_regexec = reinterpret_cast<int (*)(const regex_t*, const char*, size_t, regmatch_t[], int)>(__dlsym(s_libregex, "regexec").value());
+        s_regerror = reinterpret_cast<size_t (*)(int, const regex_t*, char*, size_t)>(__dlsym(s_libregex, "regerror").value());
+        s_regfree = reinterpret_cast<void (*)(regex_t*)>(__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);
+}
+}