Commit e7fd8952 authored by A. Wilcox's avatar A. Wilcox

Merge branch 'patch-3' into 'master'

Add some more functions (notably __cxa_thread_atexit_impl and realpath) and run clang-format



See merge request !3
parents 938c8095 9bc7c737
......@@ -17,6 +17,17 @@ Build system
* Allow building against libucontext.
ctype
-----
* Add __ctype_b.
cxx_thread
----------
* Add __cxa_thread_atexit_impl.
math
----
......@@ -24,6 +35,14 @@ math
* Add most __*_finite functions, courtesy of Elizabeth Myers.
readlink/realpath
-----------------
* Intercept realpath as well as readlink.
* Report EIO on /proc read failure.
* Report ENOSYS on dlsym failure.
resolv
------
......@@ -36,6 +55,12 @@ socket
* Add __poll_chk
stdlib
------
* Add secure_getenv alias to __secure_getenv.
string
------
......@@ -43,6 +68,11 @@ string
* Add memfrob.
* Add strfry.
unistd
------
* Add __open_2/__open64_2.
malloc
------
......
LIBGCOMPAT_INCLUDE = \
libgcompat/alias.h
LIBGCOMPAT_SRC = \
libgcompat/ctype.c \
libgcompat/cxx_thread.c \
libgcompat/dlfcn.c \
libgcompat/error.c \
libgcompat/execinfo.c \
......@@ -14,6 +16,7 @@ LIBGCOMPAT_SRC = \
libgcompat/pthread.c \
libgcompat/pwd.c \
libgcompat/readlink.c \
libgcompat/realpath.c \
libgcompat/resolv.c \
libgcompat/resource.c \
libgcompat/setjmp.c \
......
const unsigned short int *__ctype_b;
#include <pthread.h> /* NULL, pthread_{key,once,{get,set}specific} */
#include <stdlib.h> /* malloc, free */
#include "internal.h"
struct dtor_node {
struct dtor_node *next;
void (*func)(void *);
void *obj;
};
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static void run_dtors(void *head)
{
struct dtor_node *next, *node = head;
while (node != NULL) {
next = node->next;
node->func(node->obj);
free(node);
node = next;
}
}
static void create_key(void)
{
int res = pthread_key_create(&key, run_dtors);
GCOMPAT__assert_with_reason(res, "No key for thread_atexit list");
}
/**
* Register a destructor to run at thread exit.
*
* See
* https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
*/
int __cxa_thread_atexit_impl(void (*func)(void *), void *obj, void *dso_symbol)
{
struct dtor_node *node;
pthread_once(&once, create_key);
node = malloc(sizeof(*node));
GCOMPAT__assert_with_reason(node, "No memory for thread_atexit node");
node->next = pthread_getspecific(key);
node->func = func;
node->obj = obj;
int res = pthread_setspecific(key, node);
GCOMPAT__assert_with_reason(!res, "Cannot update thread_atexit list");
return 0;
}
#include <sys/select.h>
#include "internal.h"
#define REASON_FD_SET_OVERFLOW \
"Fault: Overflow in fd_set detected.\n" \
"Description: This is caused by a programmer naively attempting to redefine FD_SETSIZE,\n" \
" which is not allowed on POSIX platforms. The program must be either rebuilt\n" \
" with the correct FD_SETSIZE definition, or preferably rewritten to avoid use\n" \
" of select(2) in general. See also: poll(2).\n" \
#define REASON_FD_SET_OVERFLOW \
"Fault: Overflow in fd_set detected.\n" \
"Description: This is caused by a programmer naively attempting to\n" \
" redefine FD_SETSIZE, which is not allowed on POSIX platforms.\n" \
" The program must either be rebuilt with the correct FD_SETSIZE\n" \
" definition, or else be rewritten to avoid use of select(2) in \n" \
" general. See also: poll(2).\n" \
" libgcompat believes FD_SETSIZE to be %zu.\n"
unsigned long __fdelt_chk(unsigned long size)
{
GCOMPAT__assert_with_reason(size < FD_SETSIZE, REASON_FD_SET_OVERFLOW, FD_SETSIZE);
GCOMPAT__assert_with_reason(size < FD_SETSIZE, REASON_FD_SET_OVERFLOW,
FD_SETSIZE);
return size / (sizeof(unsigned long) << 3);
}
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void GCOMPAT__panic(const char *fmt, ...)
{
va_list va;
......
#define _GNU_SOURCE /* Extra maths functions */
#include <math.h> /* Literally everything */
#define _GNU_SOURCE /* Extra maths functions */
#include <math.h> /* Literally everything */
#include "alias.h" /* weak_alias */
#include "internal.h" /* GCOMPAT__assert_with_reason */
#include "alias.h" /* weak_alias */
#include "internal.h" /* GCOMPAT__assert_with_reason */
/**
* Multiplies the first argument x by FLT_RADIX (probably 2) to the power of y.
......@@ -14,7 +14,7 @@ long double scalbl(long double x, long double y)
* 1) Good Enough(TM)
* 2) scalbl is deprecated anyway
* */
return scalblnl(x, (long int)y);
return scalblnl(x, (long int) y);
}
/*
......@@ -144,7 +144,6 @@ int __isnan(double arg)
}
weak_alias(__isnan, isnan);
/**
* Test for a NaN.
*
......@@ -290,7 +289,6 @@ long double __asinl_finite(long double x)
return res;
}
/**
* Returns the principal value of the arc tangent of x/y, expressed in radians.
*/
......@@ -363,7 +361,6 @@ long double __atanhl_finite(long double x)
return res;
}
/**
* Returns the hyperbolic cosine of x.
*/
......
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stddef.h>
......@@ -18,6 +19,7 @@ ssize_t readlink(const char *path, char *buf, size_t len)
if (real_readlink == NULL) {
real_readlink = dlsym(RTLD_NEXT, "readlink");
if (real_readlink == NULL) {
errno = ENOSYS;
return -1;
}
}
......@@ -78,6 +80,7 @@ ssize_t readlink(const char *path, char *buf, size_t len)
close(fd);
fail:
exe[0] = '\0';
errno = EIO;
return -1;
}
......
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef LINKER
#error LINKER must be defined
#endif
static char *(*real_realpath)(const char *restrict, char *restrict);
char *realpath(const char *restrict path, char *restrict resolved)
{
if (real_realpath == NULL) {
real_realpath = dlsym(RTLD_NEXT, "realpath");
if (real_realpath == NULL) {
errno = ENOSYS;
return NULL;
}
}
if (!strcmp(path, "/proc/self/exe")) {
char *fixed = resolved;
if (fixed == NULL) {
fixed = malloc(PATH_MAX);
if (fixed == NULL) {
errno = ENOMEM;
return NULL;
}
}
/* If passed in, the buffer is at least PATH_MAX per POSIX. */
ssize_t written = readlink(path, fixed, PATH_MAX - 1);
if (written == -1) {
/* Free the buffer iff we allocated it. */
if (fixed != resolved)
free(fixed);
return NULL;
}
fixed[written] = '\0';
return fixed;
}
return real_realpath(path, resolved);
}
......@@ -42,7 +42,7 @@ int __res_nclose(res_state statp)
weak_alias(__res_nclose, res_nclose);
int __res_search(const char *dname, int class, int type, unsigned char *answer,
int anslen)
int anslen)
{
return res_search(dname, class, type, answer, anslen);
}
#include <assert.h> /* assert */
#include <poll.h> /* poll, pollfd, nfds_t */
#include <stddef.h> /* NULL */
#include <poll.h> /* poll, pollfd, nfds_t */
#include <sys/socket.h> /* recv, recvfrom */
/**
......
......@@ -5,6 +5,8 @@
#include <stdlib.h> /* getenv, realpath, strto* */
#include <unistd.h> /* get*id */
#include "alias.h"
/**
* Resolve a pathname, with buffer overflow checking.
*
......@@ -30,6 +32,7 @@ char *__secure_getenv(const char *name)
return getenv(name);
}
weak_alias(__secure_getenv, secure_getenv);
/**
* Underlying function for strtod.
......
......@@ -2,10 +2,10 @@
#include <assert.h> /* assert */
#include <stddef.h> /* NULL, size_t */
#include <stdint.h> /* SIZE_MAX */
#include <string.h> /* memcpy, strcpy, strncat, strndup */
#include <stdlib.h> /* rand_r */
#include <unistd.h> /* getpid */
#include <string.h> /* memcpy, strcpy, strncat, strndup */
#include <time.h> /* time */
#include <unistd.h> /* getpid */
#include "alias.h" /* weak_alias */
......@@ -189,8 +189,7 @@ size_t __strcspn_c2(const char *str, int bad, int bad2)
{
size_t length = 0;
const char *s = str;
while(*s != bad && *s != bad2 && *s != '\0')
{
while (*s != bad && *s != bad2 && *s != '\0') {
length++;
s++;
}
......@@ -285,7 +284,7 @@ char *strfry(char *s)
if (!len)
return s;
seed += time(NULL) ^ getpid() ^ (uintptr_t)s;
seed += time(NULL) ^ getpid() ^ (uintptr_t) s;
for (i = 0; i < len - 1; ++i) {
j = rand_r(&seed) % (len - i) + i;
......
#include <assert.h> /* assert */
#include <fcntl.h> /* O_CREAT */
#include <limits.h> /* NGROUPS_MAX */
#include <stddef.h> /* NULL, size_t */
#include <unistd.h> /* confstr, getcwd, getgroups, ... */
......@@ -90,6 +91,14 @@ pid_t __getpgid(pid_t pid)
return getpgid(pid);
}
int __open_2(const char *path, int oflag)
{
assert(!(oflag & O_CREAT));
return open(path, oflag);
}
alias(__open_2, __open64_2);
/**
* Read from a file, with buffer overflow checking.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment