summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--libgcompat/dlfcn.c16
-rw-r--r--libgcompat/stdlib.c7
-rw-r--r--libgcompat/string.c2
-rw-r--r--libgcompat/uio.c32
-rw-r--r--libgcompat/wchar.c37
6 files changed, 88 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 426513f..641249b 100644
--- a/Makefile
+++ b/Makefile
@@ -34,6 +34,7 @@ LIBGCOMPAT_SRC = \
libgcompat/syslog.c \
libgcompat/time.c \
libgcompat/ucontext.c \
+ libgcompat/uio.c \
libgcompat/unistd.c \
libgcompat/utmp.c \
libgcompat/version.c \
diff --git a/libgcompat/dlfcn.c b/libgcompat/dlfcn.c
index f2eaa45..603336c 100644
--- a/libgcompat/dlfcn.c
+++ b/libgcompat/dlfcn.c
@@ -23,3 +23,19 @@ void *dlvsym(void *handle, char *symbol, char *version)
return dlsym(handle, symbol);
}
+
+int dladdr1(const void *addr, Dl_info *info, void **extra_info, int flags)
+{
+ if (getenv("GLIBC_FAKE_DEBUG") != NULL) {
+ fprintf(stderr, "request info of %p with flags %d", addr,
+ flags);
+ }
+
+ switch (flags) {
+ case 1 /* RTLD_DL_SYMEMT */:
+ case 2 /* RTLD_DL_LINKMAP */:
+ return 0;
+ default:
+ return dladdr(addr, info);
+ }
+}
diff --git a/libgcompat/stdlib.c b/libgcompat/stdlib.c
index 82f7602..2d3e5f7 100644
--- a/libgcompat/stdlib.c
+++ b/libgcompat/stdlib.c
@@ -22,6 +22,13 @@ char *__realpath_chk(const char *path, char *resolved_path, size_t resolved_len)
}
/**
+ * Return the canonicalized absolute pathname
+ */
+char *canonicalize_file_name(const char *path) {
+ return realpath(path, NULL);
+}
+
+/**
* Get an environment variable.
*/
char *__secure_getenv(const char *name)
diff --git a/libgcompat/string.c b/libgcompat/string.c
index a164ab2..162d94c 100644
--- a/libgcompat/string.c
+++ b/libgcompat/string.c
@@ -247,7 +247,7 @@ char *__strncat_chk(char *dest, const char *src, size_t n, size_t destlen)
assert(dest != NULL);
assert(src != NULL);
- total = strnlen(dest, destlen) + n + 1;
+ total = strnlen(dest, destlen) + strnlen(src, destlen) + 1;
assert(destlen >= total);
if (dest < src) {
assert(dest + total <= src);
diff --git a/libgcompat/uio.c b/libgcompat/uio.c
new file mode 100644
index 0000000..797cb3a
--- /dev/null
+++ b/libgcompat/uio.c
@@ -0,0 +1,32 @@
+#include <sys/syscall.h>
+#include <sys/uio.h> /* iovec, pwritev, preadv */
+#include <errno.h> /* errno */
+#include <unistd.h> /* syscall */
+
+ssize_t pwritev64v2(int fd, const struct iovec *iov, int count, off_t ofs, int flags)
+{
+ if (flags != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ofs == -1) {
+ return writev(fd, iov, count);
+ }
+
+ return syscall(__NR_pwritev2, fd, iov, count, ofs);
+}
+
+ssize_t preadv64v2(int fd, const struct iovec *iov, int count, off_t ofs, int flags)
+{
+ if (flags != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ofs == -1) {
+ return readv(fd, iov, count);
+ }
+
+ return syscall(__NR_preadv2, fd, iov, count, ofs);
+}
diff --git a/libgcompat/wchar.c b/libgcompat/wchar.c
index 78f7e02..4af686d 100644
--- a/libgcompat/wchar.c
+++ b/libgcompat/wchar.c
@@ -109,8 +109,8 @@ long int __wcstol_internal(const wchar_t *nptr, wchar_t **endptr, int base,
*
* Some day, when musl supports LC_NUMERIC, we can probably remove this.
*/
-unsigned long int wcstoul_l(const wchar_t *nptr, wchar_t **endptr,
- int base, locale_t loc)
+unsigned long int wcstoul_l(const wchar_t *nptr, wchar_t **endptr, int base,
+ locale_t loc)
{
return wcstoul(nptr, endptr, base);
}
@@ -120,8 +120,7 @@ unsigned long int wcstoul_l(const wchar_t *nptr, wchar_t **endptr,
*
* Some day, when musl supports LC_NUMERIC, we can probably remove this.
*/
-long int wcstol_l(const wchar_t *nptr, wchar_t **endptr, int base,
- locale_t loc)
+long int wcstol_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t loc)
{
return wcstol(nptr, endptr, base);
}
@@ -136,7 +135,33 @@ double wcstod_l(const wchar_t *nptr, wchar_t **endptr, locale_t loc)
return wcstod(nptr, endptr);
}
+size_t __mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
+{
+ return mbrlen(s, n, st);
+}
+
+wchar_t *__wcsncpy_chk(wchar_t *dest, const wchar_t *src, size_t n,
+ size_t destlen)
+{
+ assert(dest != NULL);
+ assert(src != NULL);
-size_t __mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st) {
- return mbrlen(s, n, st);
+ assert(destlen >= n);
+
+ return wcsncpy(dest, src, n);
+}
+
+wchar_t *__wcscat_chk(wchar_t *dest, const wchar_t *src, size_t n)
+{
+ wchar_t *a = dest;
+ size_t destlen = wcslen(dest);
+ assert(destlen + wcslen(src) + 1 <= n);
+
+ dest += destlen;
+ while (n && *src) {
+ n--;
+ *dest++ = *src++;
+ }
+ *dest++ = 0;
+ return a;
}