Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/Assertions.h>
8#include <dlfcn.h>
9#include <pthread.h>
10#include <regex.h>
11
12static void* s_libregex;
13static pthread_mutex_t s_libregex_lock;
14
15static int (*s_regcomp)(regex_t*, char const*, int);
16static int (*s_regexec)(regex_t const*, char const*, size_t, regmatch_t[], int);
17static size_t (*s_regerror)(int, regex_t const*, char*, size_t);
18static void (*s_regfree)(regex_t*);
19
20static void ensure_libregex()
21{
22 pthread_mutex_lock(&s_libregex_lock);
23 if (!s_libregex) {
24 s_libregex = dlopen("libregex.so", RTLD_NOW);
25 VERIFY(s_libregex);
26
27 s_regcomp = reinterpret_cast<int (*)(regex_t*, char const*, int)>(dlsym(s_libregex, "regcomp"));
28 VERIFY(s_regcomp);
29
30 s_regexec = reinterpret_cast<int (*)(regex_t const*, char const*, size_t, regmatch_t[], int)>(dlsym(s_libregex, "regexec"));
31 VERIFY(s_regexec);
32
33 s_regerror = reinterpret_cast<size_t (*)(int, regex_t const*, char*, size_t)>(dlsym(s_libregex, "regerror"));
34 VERIFY(s_regerror);
35
36 s_regfree = reinterpret_cast<void (*)(regex_t*)>(dlsym(s_libregex, "regfree"));
37 VERIFY(s_regerror);
38 }
39 pthread_mutex_unlock(&s_libregex_lock);
40}
41
42extern "C" {
43
44int __attribute__((weak)) regcomp(regex_t* reg, char const* pattern, int cflags)
45{
46 ensure_libregex();
47 return s_regcomp(reg, pattern, cflags);
48}
49
50int __attribute__((weak)) regexec(regex_t const* reg, char const* string, size_t nmatch, regmatch_t pmatch[], int eflags)
51{
52 ensure_libregex();
53 return s_regexec(reg, string, nmatch, pmatch, eflags);
54}
55
56size_t __attribute__((weak)) regerror(int errcode, regex_t const* reg, char* errbuf, size_t errbuf_size)
57{
58 ensure_libregex();
59 return s_regerror(errcode, reg, errbuf, errbuf_size);
60}
61
62void __attribute__((weak)) regfree(regex_t* reg)
63{
64 ensure_libregex();
65 return s_regfree(reg);
66}
67}