summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2015-03-29 04:50:56 -0500
committerWaldemar Brodkorb <wbx@openadk.org>2015-03-29 04:50:56 -0500
commitcd5f92704e1e17bbc0c15d197f3bc236c7dc9bf2 (patch)
tree1400302b543e4528aedea5d72731983559cfcf36 /libc
parentad2bffbf1926051ef333f9899344f6bddf2c03cf (diff)
parent24946289317ea23bb0d1814cca0a499a905f7d6f (diff)
merge uClibc git master
Diffstat (limited to 'libc')
-rw-r--r--libc/inet/resolv.c6
-rw-r--r--libc/misc/utmp/Makefile.in4
-rw-r--r--libc/misc/utmp/utent.c312
-rw-r--r--libc/misc/utmp/utxent.c109
-rw-r--r--libc/misc/utmp/wtent.c59
-rw-r--r--libc/stdio/_fpmaxtostr.h22
-rw-r--r--libc/stdio/_vfprintf.c15
-rw-r--r--libc/stdlib/Makefile.in4
-rw-r--r--libc/stdlib/malloc-standard/free.c6
-rw-r--r--libc/stdlib/malloc-standard/malloc.c5
-rw-r--r--libc/stdlib/malloc-standard/memalign.c2
-rw-r--r--libc/stdlib/malloc-standard/realloc.c2
-rw-r--r--libc/string/strverscmp.c69
-rw-r--r--libc/sysdeps/linux/arc/sigaction.c3
-rwxr-xr-xlibc/sysdeps/linux/arc/sys/procfs.h7
-rw-r--r--libc/sysdeps/linux/arm/Makefile.arch4
-rw-r--r--libc/sysdeps/linux/common/Makefile.in1
-rw-r--r--libc/sysdeps/linux/common/bits/kernel-features.h5
-rw-r--r--libc/sysdeps/linux/common/bits/mathcalls.h23
-rw-r--r--libc/sysdeps/linux/common/bits/utmp.h4
-rw-r--r--libc/sysdeps/linux/common/bits/utmpx.h2
-rw-r--r--libc/sysdeps/linux/common/getrandom.c14
-rw-r--r--libc/sysdeps/linux/common/getrusage.c1
-rw-r--r--libc/sysdeps/linux/common/makedev.c42
-rw-r--r--libc/sysdeps/linux/common/stubs.c4
-rw-r--r--libc/sysdeps/linux/common/sys/random.h33
-rw-r--r--libc/sysdeps/linux/mips/bits/mathdef.h7
-rw-r--r--libc/sysdeps/linux/mips/bits/wordsize.h3
-rw-r--r--libc/sysdeps/linux/powerpc/bits/wordsize.h2
-rw-r--r--libc/sysdeps/linux/sh/bits/atomic.h12
-rw-r--r--libc/sysdeps/linux/sh/bits/syscalls.h2
-rw-r--r--libc/sysdeps/linux/sparc/bits/wordsize.h1
-rw-r--r--libc/sysdeps/linux/x86_64/bits/wordsize.h9
33 files changed, 363 insertions, 431 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index cfc1eee9b..31e63810b 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1615,9 +1615,13 @@ int __read_etc_hosts_r(
#endif
;
int ret = HOST_NOT_FOUND;
+ /* make sure pointer is aligned */
+ int i = ALIGN_BUFFER_OFFSET(buf);
+ buf += i;
+ buflen -= i;
*h_errnop = NETDB_INTERNAL;
- if (buflen < aliaslen
+ if (/* (ssize_t)buflen < 0 || */ buflen < aliaslen
|| (buflen - aliaslen) < BUFSZ + 1)
return ERANGE;
if (parser == NULL)
diff --git a/libc/misc/utmp/Makefile.in b/libc/misc/utmp/Makefile.in
index 535efb150..6c54ade96 100644
--- a/libc/misc/utmp/Makefile.in
+++ b/libc/misc/utmp/Makefile.in
@@ -7,8 +7,8 @@
subdirs += libc/misc/utmp
-CSRC-y := utent.c wtent.c
-CSRC-$(UCLIBC_HAS_UTMPX) += utxent.c
+CSRC-y :=
+CSRC-$(if $(findstring y,$(UCLIBC_HAS_UTMP)$(UCLIBC_HAS_UTMPX)),y) += utent.c
MISC_UTMP_DIR := $(top_srcdir)libc/misc/utmp
MISC_UTMP_OUT := $(top_builddir)libc/misc/utmp
diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c
index a35bb2b84..3671bb05c 100644
--- a/libc/misc/utmp/utent.c
+++ b/libc/misc/utmp/utent.c
@@ -1,3 +1,4 @@
+/* vi: set sw=4 ts=4: */
/* utent.c <ndf@linux.mit.edu> */
/* Let it be known that this is very possibly the worst standard ever. HP-UX
does one thing, someone else does another, linux another... If anyone
@@ -18,230 +19,211 @@
#include <paths.h>
#include <errno.h>
#include <string.h>
-#include <utmp.h>
-#ifdef __UCLIBC_HAS_UTMPX__
-# include <utmpx.h>
-#endif
+#include "internal/utmp.h"
#include <not-cancel.h>
-
#include <bits/uClibc_mutex.h>
+
__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
/* Some global crap */
static int static_fd = -1;
-static struct utmp static_utmp;
-static const char default_file_name[] = _PATH_UTMP;
-static const char *static_ut_name = default_file_name;
+static struct UT static_utmp;
+static const char default_file[] = __DEFAULT_PATH_UTMP;
+static const char *current_file = default_file;
/* This function must be called with the LOCK held */
-static void __setutent_unlocked(void)
+static void __set_unlocked(void)
{
- if (static_fd < 0) {
- static_fd = open_not_cancel_2(static_ut_name, O_RDWR | O_CLOEXEC);
if (static_fd < 0) {
- static_fd = open_not_cancel_2(static_ut_name, O_RDONLY | O_CLOEXEC);
- if (static_fd < 0) {
- return; /* static_fd remains < 0 */
- }
- }
+ static_fd = open_not_cancel_2(current_file, O_RDWR | O_CLOEXEC);
+ if (static_fd < 0) {
+ static_fd = open_not_cancel_2(current_file, O_RDONLY | O_CLOEXEC);
+ if (static_fd < 0) {
+ return; /* static_fd remains < 0 */
+ }
+ }
#ifndef __ASSUME_O_CLOEXEC
- /* Make sure the file will be closed on exec() */
- fcntl_not_cancel(static_fd, F_SETFD, FD_CLOEXEC);
+ /* Make sure the file will be closed on exec() */
+ fcntl_not_cancel(static_fd, F_SETFD, FD_CLOEXEC);
#endif
- return;
- }
- lseek(static_fd, 0, SEEK_SET);
+ return;
+ }
+ lseek(static_fd, 0, SEEK_SET);
}
#if defined __UCLIBC_HAS_THREADS__
-static void __setutent(void)
+void set(void)
{
- __UCLIBC_MUTEX_LOCK(utmplock);
- __setutent_unlocked();
- __UCLIBC_MUTEX_UNLOCK(utmplock);
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ __set_unlocked();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
}
#else
-static void __setutent(void);
-strong_alias(__setutent_unlocked,__setutent)
-#endif
-strong_alias(__setutent,setutent)
-
-#ifdef __UCLIBC_HAS_UTMPX__
-strong_alias(__setutent,setutxent)
+strong_alias(__set_unlocked,set)
#endif
+/* not used in libc_hidden_def(set) */
+other(setutxent,setutent)
/* This function must be called with the LOCK held */
-static struct utmp *__getutent_unlocked(void)
+static struct UT *__get_unlocked(void)
{
- if (static_fd < 0) {
- __setutent();
if (static_fd < 0) {
- return NULL;
+ __set_unlocked();
+ if (static_fd < 0)
+ return NULL;
}
- }
- if (read_not_cancel(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) {
- return &static_utmp;
- }
+ if (read_not_cancel(static_fd, &static_utmp,
+ sizeof(static_utmp)) == sizeof(static_utmp)) {
+ return &static_utmp;
+ }
- return NULL;
+ return NULL;
}
#if defined __UCLIBC_HAS_THREADS__
-static struct utmp *__getutent(void)
+struct UT *get(void)
{
- struct utmp *ret;
+ struct UT *ret;
- __UCLIBC_MUTEX_LOCK(utmplock);
- ret = __getutent_unlocked();
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return ret;
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __get_unlocked();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
}
#else
-static struct utmp *__getutent(void);
-strong_alias(__getutent_unlocked,__getutent)
+strong_alias(__get_unlocked,get)
#endif
-strong_alias(__getutent,getutent)
+/* not used in libc_hidden_def(get) */
+other(getutxent,getutent)
-#ifdef __UCLIBC_HAS_UTMPX__
-struct utmpx *getutxent(void)
+void end(void)
{
- return (struct utmpx *) __getutent ();
-}
-#endif
-
-static void __endutent(void)
-{
- __UCLIBC_MUTEX_LOCK(utmplock);
- if (static_fd >= 0)
- close_not_cancel_no_status(static_fd);
- static_fd = -1;
- __UCLIBC_MUTEX_UNLOCK(utmplock);
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ if (static_fd >= 0)
+ close_not_cancel_no_status(static_fd);
+ static_fd = -1;
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
}
-strong_alias(__endutent,endutent)
-
-#ifdef __UCLIBC_HAS_UTMPX__
-strong_alias(__endutent,endutxent)
-#endif
+/* not used in libc_hidden_def(end) */
+other(endutxent,endutent)
/* This function must be called with the LOCK held */
-static struct utmp *__getutid_unlocked(const struct utmp *utmp_entry)
+static struct UT *__getid_unlocked(const struct UT *utmp_entry)
{
- struct utmp *lutmp;
- unsigned type;
-
- /* We use the fact that constants we are interested in are: */
- /* RUN_LVL=1, ... OLD_TIME=4; INIT_PROCESS=5, ... USER_PROCESS=8 */
- type = utmp_entry->ut_type - 1;
- type /= 4;
-
- while ((lutmp = __getutent_unlocked()) != NULL) {
- if (type == 0 && lutmp->ut_type == utmp_entry->ut_type) {
- /* one of RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME */
- return lutmp;
+ struct UT *lutmp;
+ unsigned type;
+
+ /* We use the fact that constants we are interested in are: */
+ /* RUN_LVL=1, ... OLD_TIME=4; INIT_PROCESS=5, ... USER_PROCESS=8 */
+ type = utmp_entry->ut_type - 1;
+ type /= 4;
+
+ while ((lutmp = __get_unlocked()) != NULL) {
+ if (type == 0 && lutmp->ut_type == utmp_entry->ut_type) {
+ /* one of RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME */
+ return lutmp;
+ }
+ if (type == 1
+ && strncmp(lutmp->ut_id, utmp_entry->ut_id,
+ sizeof(lutmp->ut_id)) == 0) {
+ /* INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS */
+ return lutmp;
+ }
}
- if (type == 1 && strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id)) == 0) {
- /* INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS */
- return lutmp;
- }
- }
- return NULL;
+ return NULL;
}
#if defined __UCLIBC_HAS_THREADS__
-static struct utmp *__getutid(const struct utmp *utmp_entry)
+struct UT *getid(const struct UT *utmp_entry)
{
- struct utmp *ret;
+ struct UT *ret;
- __UCLIBC_MUTEX_LOCK(utmplock);
- ret = __getutid_unlocked(utmp_entry);
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return ret;
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __getid_unlocked(utmp_entry);
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
}
#else
-static struct utmp *__getutid(const struct utmp *utmp_entry);
-strong_alias(__getutid_unlocked,__getutid)
-#endif
-strong_alias(__getutid,getutid)
-
-#ifdef __UCLIBC_HAS_UTMPX__
-struct utmpx *getutxid(const struct utmpx *utmp_entry)
-{
- return (struct utmpx *) __getutid ((const struct utmp *) utmp_entry);
-}
+strong_alias(__getid_unlocked,getid)
#endif
+/* not used in libc_hidden_def(getid) */
+other(getutxid,getutid)
-static struct utmp *__getutline(const struct utmp *utmp_entry)
+struct UT *getline(const struct UT *utmp_entry)
{
- struct utmp *lutmp;
-
- __UCLIBC_MUTEX_LOCK(utmplock);
- while ((lutmp = __getutent_unlocked()) != NULL) {
- if (lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) {
- if (strncmp(lutmp->ut_line, utmp_entry->ut_line, sizeof(lutmp->ut_line)) == 0) {
- break;
- }
+ struct UT *lutmp;
+
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ while ((lutmp = __get_unlocked()) != NULL) {
+ if (lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) {
+ if (strncmp(lutmp->ut_line, utmp_entry->ut_line,
+ sizeof(lutmp->ut_line)) == 0) {
+ break;
+ }
+ }
}
- }
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return lutmp;
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return lutmp;
}
-strong_alias(__getutline,getutline)
+/* libc_hidden_def(getline) */
+other(getutxline,getutline)
-#ifdef __UCLIBC_HAS_UTMPX__
-struct utmpx *getutxline(const struct utmpx *utmp_entry)
+struct UT *putline(const struct UT *utmp_entry)
{
- return (struct utmpx *) __getutline ((const struct utmp *) utmp_entry);
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ /* Ignore the return value. That way, if they've already positioned
+ the file pointer where they want it, everything will work out. */
+ lseek(static_fd, (off_t) - sizeof(struct UT), SEEK_CUR);
+
+ if (__getid_unlocked(utmp_entry) != NULL)
+ lseek(static_fd, (off_t) - sizeof(struct UT), SEEK_CUR);
+ else
+ lseek(static_fd, (off_t) 0, SEEK_END);
+ if (write(static_fd, utmp_entry, sizeof(struct UT))
+ != sizeof(struct UT))
+ utmp_entry = NULL;
+
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return (struct UT *)utmp_entry;
}
-#endif
+/* not used in libc_hidden_def(putline) */
+other(pututxline,pututline)
-static struct utmp *__pututline(const struct utmp *utmp_entry)
+int name(const char *new_file)
{
- __UCLIBC_MUTEX_LOCK(utmplock);
- /* Ignore the return value. That way, if they've already positioned
- the file pointer where they want it, everything will work out. */
- lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
-
- if (__getutid_unlocked(utmp_entry) != NULL)
- lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
- else
- lseek(static_fd, (off_t) 0, SEEK_END);
- if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
- utmp_entry = NULL;
-
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return (struct utmp *)utmp_entry;
-}
-strong_alias(__pututline,pututline)
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ if (new_file != NULL) {
+ if (current_file != default_file)
+ free((char *)current_file);
+ current_file = strdup(new_file);
+ if (current_file == NULL) {
+ /* We should probably whine about out-of-memory
+ * errors here... Instead just reset to the default */
+ current_file = default_file;
+ }
+ }
-#ifdef __UCLIBC_HAS_UTMPX__
-struct utmpx *pututxline (const struct utmpx *utmp_entry)
-{
- return (struct utmpx *) __pututline ((const struct utmp *) utmp_entry);
+ if (static_fd >= 0) {
+ close_not_cancel_no_status(static_fd);
+ static_fd = -1;
+ }
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return 0; /* or maybe return -(current_file != new_file)? */
}
-#endif
+/* not used in libc_hidden_def(name) */
+other(utmpxname,utmpname)
-static int __utmpname(const char *new_ut_name)
+void updw(const char *wtmp_file, const struct UT *lutmp)
{
- __UCLIBC_MUTEX_LOCK(utmplock);
- if (new_ut_name != NULL) {
- if (static_ut_name != default_file_name)
- free((char *)static_ut_name);
- static_ut_name = strdup(new_ut_name);
- if (static_ut_name == NULL) {
- /* We should probably whine about out-of-memory
- * errors here... Instead just reset to the default */
- static_ut_name = default_file_name;
+ int fd;
+
+ fd = open_not_cancel_2(wtmp_file, O_APPEND | O_WRONLY);
+ if (fd >= 0) {
+ if (lockf(fd, F_LOCK, 0) == 0) {
+ write_not_cancel(fd, lutmp, sizeof(struct UT));
+ lockf(fd, F_ULOCK, 0);
+ close_not_cancel_no_status(fd);
+ }
}
- }
-
- if (static_fd >= 0) {
- close_not_cancel_no_status(static_fd);
- static_fd = -1;
- }
- __UCLIBC_MUTEX_UNLOCK(utmplock);
- return 0; /* or maybe return -(static_ut_name != new_ut_name)? */
}
-strong_alias(__utmpname,utmpname)
-
-#ifdef __UCLIBC_HAS_UTMPX__
-strong_alias(__utmpname,utmpxname)
-#endif
+/* not used in libc_hidden_def(updw) */
+other(updwtmpx,updwtmp)
diff --git a/libc/misc/utmp/utxent.c b/libc/misc/utmp/utxent.c
deleted file mode 100644
index 71157ccd8..000000000
--- a/libc/misc/utmp/utxent.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * utexent.c : Support for accessing user accounting database.
- * Copyright (C) 2010 STMicroelectronics Ltd.
- *
- * Author: Salvatore Cro <salvatore.cro@st.com>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- *
- */
-
-#include <features.h>
-#include <string.h>
-#include <utmpx.h>
-#include <utmp.h>
-
-#if 0 /* moved to utent.c */
-void setutxent(void)
-{
- setutent ();
-}
-
-void endutxent(void)
-{
- endutent ();
-}
-
-struct utmpx *getutxent(void)
-{
- return (struct utmpx *) getutent ();
-}
-
-struct utmpx *getutxid(const struct utmpx *utmp_entry)
-{
- return (struct utmpx *) getutid ((const struct utmp *) utmp_entry);
-}
-
-struct utmpx *getutxline(const struct utmpx *utmp_entry)
-{
- return (struct utmpx *) getutline ((const struct utmp *) utmp_entry);
-}
-
-struct utmpx *pututxline (const struct utmpx *utmp_entry)
-{
- return (struct utmpx *) pututline ((const struct utmp *) utmp_entry);
-}
-
-int utmpxname (const char *new_ut_name)
-{
- return utmpname (new_ut_name);
-}
-
-/* moved to wtent.c */
-void updwtmpx (const char *wtmpx_file, const struct utmpx *utmpx)
-{
- updwtmp (wtmpx_file, (const struct utmp *) utmpx);
-}
-#endif
-
-/* Copy the information in UTMPX to UTMP. */
-void getutmp (const struct utmpx *utmpx, struct utmp *utmp)
-{
-#if _HAVE_UT_TYPE - 0
- utmp->ut_type = utmpx->ut_type;
-#endif
-#if _HAVE_UT_PID - 0
- utmp->ut_pid = utmpx->ut_pid;
-#endif
- memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line));
- memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user));
-#if _HAVE_UT_ID - 0
- memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id));
-#endif
-#if _HAVE_UT_HOST - 0
- memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host));
-#endif
-#if _HAVE_UT_TV - 0
- utmp->ut_tv.tv_sec = utmpx->ut_tv.tv_sec;
- utmp->ut_tv.tv_usec = utmpx->ut_tv.tv_usec;
-#else
- utmp->ut_time = utmpx->ut_time;
-#endif
-}
-
-/* Copy the information in UTMP to UTMPX. */
-void getutmpx (const struct utmp *utmp, struct utmpx *utmpx)
-{
- memset (utmpx, 0, sizeof (struct utmpx));
-
-#if _HAVE_UT_TYPE - 0
- utmpx->ut_type = utmp->ut_type;
-#endif
-#if _HAVE_UT_PID - 0
- utmpx->ut_pid = utmp->ut_pid;
-#endif
- memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line));
- memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user));
-#if _HAVE_UT_ID - 0
- memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id));
-#endif
-#if _HAVE_UT_HOST - 0
- memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host));
-#endif
-#if _HAVE_UT_TV - 0
- utmpx->ut_tv.tv_sec = utmp->ut_tv.tv_sec;
- utmpx->ut_tv.tv_usec = utmp->ut_tv.tv_usec;
-#else
- utmpx->ut_time = utmp->ut_time;
-#endif
-}
diff --git a/libc/misc/utmp/wtent.c b/libc/misc/utmp/wtent.c
deleted file mode 100644
index 9b3ad5084..000000000
--- a/libc/misc/utmp/wtent.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-/* wtmp support rubbish (i.e. complete crap) */
-
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include <utmp.h>
-#ifdef __UCLIBC_HAS_UTMPX__
-# include <utmpx.h>
-#endif
-#include <fcntl.h>
-#include <sys/file.h>
-#include <not-cancel.h>
-
-#if 0
-/* This is enabled in uClibc/libutil/logwtmp.c */
-void logwtmp (const char *line, const char *name, const char *host)
-{
- struct utmp lutmp;
- memset(&lutmp, 0, sizeof(lutmp));
-
- lutmp.ut_type = (name && *name) ? USER_PROCESS : DEAD_PROCESS;
- lutmp.ut_pid = getpid();
- strncpy(lutmp.ut_line, line, sizeof(lutmp.ut_line)-1);
- strncpy(lutmp.ut_name, name, sizeof(lutmp.ut_name)-1);
- strncpy(lutmp.ut_host, host, sizeof(lutmp.ut_host)-1);
- gettimeofday(&(lutmp.ut_tv), NULL);
-
- updwtmp(_PATH_WTMP, &lutmp);
-}
-#endif
-
-static void __updwtmp(const char *wtmp_file, const struct utmp *lutmp)
-{
- int fd;
-
- fd = open_not_cancel_2(wtmp_file, O_APPEND | O_WRONLY);
- if (fd >= 0) {
- if (lockf(fd, F_LOCK, 0) == 0) {
- write_not_cancel(fd, lutmp, sizeof(struct utmp));
- lockf(fd, F_ULOCK, 0);
- close_not_cancel_no_status(fd);
- }
- }
-}
-strong_alias(__updwtmp,updwtmp)
-
-#ifdef __UCLIBC_HAS_UTMPX__
-void updwtmpx (const char *wtmpx_file, const struct utmpx *utmpx)
-{
- __updwtmp (wtmpx_file, (const struct utmp *) utmpx);
-}
-#endif
diff --git a/libc/stdio/_fpmaxtostr.h b/libc/stdio/_fpmaxtostr.h
index b4e7321c2..7694629ec 100644
--- a/libc/stdio/_fpmaxtostr.h
+++ b/libc/stdio/_fpmaxtostr.h
@@ -11,39 +11,39 @@
#define _FPMAXTOSTR_H 1
#include <features.h>
-#ifdef __UCLIBC_HAS_FLOATS__
-
#define __need_size_t
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <printf.h>
#include <sys/types.h>
-#include <float.h>
-#include <bits/uClibc_fpmax.h>
+
+#ifdef __UCLIBC_HAS_FLOATS__
+# include <float.h>
+# include <bits/uClibc_fpmax.h>
/* WARNING: Adjust _fp_out_wide() in _vfprintf.c if this changes! */
/* With 32 bit ints, we can get 9 decimal digits per block. */
-#define DIGITS_PER_BLOCK 9
+# define DIGITS_PER_BLOCK 9
-#define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK)
+# define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK)
/* WARNING: Adjust _fp_out_wide() in _vfprintf.c if this changes! */
/* extra space for '-', '.', 'e+###', and nul */
-#define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK )
+# define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK )
/* psm: why do these internals differ? */
-#ifdef __USE_OLD_VFPRINTF__
+# ifdef __USE_OLD_VFPRINTF__
typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, intptr_t buf);
extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
__fp_outfunc_t fp_outfunc) attribute_hidden;
-#else
+# else
typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len, intptr_t buf);
extern ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
__fp_outfunc_t fp_outfunc) attribute_hidden;
-#endif
+# endif
-#endif /* __UCLIBC_HAS_FLOATS__ */
+# endif /* __UCLIBC_HAS_FLOATS__ */
#endif /* _FPMAXTOSTR_H */
diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c
index 01ee218e5..a795f4979 100644
--- a/libc/stdio/_vfprintf.c
+++ b/libc/stdio/_vfprintf.c
@@ -121,18 +121,6 @@
#error Apparently, LONG_LONG_MAX is defined but LLONG_MAX is not. You need to fix your toolchain headers to support the standard macros for (unsigned) long long.
#endif
-/**********************************************************************/
-/* These provide some control over printf's feature set */
-
-/* Now controlled by uClibc_config.h. */
-/* #define __UCLIBC_HAS_FLOATS__ 1 */
-
-/* Now controlled by uClibc_config.h. */
-/* #define __UCLIBC_HAS_PRINTF_M_SPEC__ */
-
-
-/**********************************************************************/
-
#include "_fpmaxtostr.h"
#undef __STDIO_HAS_VSNPRINTF
@@ -142,9 +130,6 @@
/**********************************************************************/
-/* Now controlled by uClibc_config.h. */
-/* #define __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */
-
#ifdef __UCLIBC_MJN3_ONLY__
# ifdef L_register_printf_function
/* emit only once */
diff --git a/libc/stdlib/Makefile.in b/libc/stdlib/Makefile.in
index 880de78d8..071f91119 100644
--- a/libc/stdlib/Makefile.in
+++ b/libc/stdlib/Makefile.in
@@ -61,7 +61,6 @@ CSRC-$(if $(findstring yyy,$(UCLIBC_HAS_FLOATS)$(UCLIBC_HAS_WCHAR)$(UCLIBC_HAS_X
# multi source _atexit.c
CSRC-y += __cxa_atexit.c __cxa_finalize.c __exit_handler.c exit.c on_exit.c
-CSRC-$(COMPAT_ATEXIT) += old_atexit.c
STDLIB_DIR := $(top_srcdir)libc/stdlib
STDLIB_OUT := $(top_builddir)libc/stdlib
@@ -71,11 +70,12 @@ STDLIB_OBJ := $(patsubst %.c,$(STDLIB_OUT)/%.o,$(CSRC-y))
libc-y += $(STDLIB_OBJ)
libc-static-y += $(STDLIB_OUT)/atexit.o $(STDLIB_OUT)/system.o
+libc-static-$(COMPAT_ATEXIT) += $(STDLIB_OUT)/old_atexit.o
libc-shared-y += $(STDLIB_OUT)/system.oS
# this should always be the PIC version, because it could be used in shared libs
libc-nonshared-y += $(STDLIB_OUT)/atexit.os
-
+libc-nonshared-$(COMPAT_ATEXIT) += $(STDLIB_OUT)/old_atexit.os
libc-nomulti-y += $(STDLIB_OUT)/labs.o $(STDLIB_OUT)/atol.o $(STDLIB_OUT)/_stdlib_strto_l.o $(STDLIB_OUT)/_stdlib_strto_ll.o
libc-nomulti-$(UCLIBC_HAS_XLOCALE) += $(STDLIB_OUT)/_stdlib_strto_l_l.o $(STDLIB_OUT)/_stdlib_strto_ll_l.o
diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c
index 39e54d635..8b7a81fca 100644
--- a/libc/stdlib/malloc-standard/free.c
+++ b/libc/stdlib/malloc-standard/free.c
@@ -104,9 +104,13 @@ static int __malloc_trim(size_t pad, mstate av)
*/
int malloc_trim(size_t pad)
{
+ int r;
+ __MALLOC_LOCK;
mstate av = get_malloc_state();
__malloc_consolidate(av);
- return __malloc_trim(pad, av);
+ r = __malloc_trim(pad, av);
+ __MALLOC_UNLOCK;
+ return r;
}
/*
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index 2abb5bbdd..fd33b50c7 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -832,8 +832,6 @@ void* malloc(size_t bytes)
}
#endif
- __MALLOC_LOCK;
- av = get_malloc_state();
/*
Convert request size to internal form by adding (sizeof(size_t)) bytes
overhead plus possibly more to obtain necessary alignment and/or
@@ -845,6 +843,9 @@ void* malloc(size_t bytes)
checked_request2size(bytes, nb);
+ __MALLOC_LOCK;
+ av = get_malloc_state();
+
/*
Bypass search if no frees yet
*/
diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c
index 6303c1dd9..e9ae5a7b9 100644
--- a/libc/stdlib/malloc-standard/memalign.c
+++ b/libc/stdlib/malloc-standard/memalign.c
@@ -52,8 +52,8 @@ void* memalign(size_t alignment, size_t bytes)
alignment = a;
}
- __MALLOC_LOCK;
checked_request2size(bytes, nb);
+ __MALLOC_LOCK;
/* Strategy: find a spot within that chunk that meets the alignment
* request, and then possibly free the leading and trailing space. */
diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c
index e060b70ea..e49d11125 100644
--- a/libc/stdlib/malloc-standard/realloc.c
+++ b/libc/stdlib/malloc-standard/realloc.c
@@ -54,9 +54,9 @@ void* realloc(void* oldmem, size_t bytes)
return NULL;
}
+ checked_request2size(bytes, nb);
__MALLOC_LOCK;
av = get_malloc_state();
- checked_request2size(bytes, nb);
oldp = mem2chunk(oldmem);
oldsize = chunksize(oldp);
diff --git a/libc/string/strverscmp.c b/libc/string/strverscmp.c
index 714f4ed67..7818a9186 100644
--- a/libc/string/strverscmp.c
+++ b/libc/string/strverscmp.c
@@ -1,13 +1,8 @@
-/* GNU's strverscmp() function, taken from glibc 2.3.2 sources
- */
-
/* Compare strings while treating digits characters numerically.
- Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
- Derived work for uClibc by Hai Zaar, Codefidence Ltd <haizaar@codefidence.com>
-
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@@ -22,63 +17,54 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <stdint.h>
#include <string.h>
#include <ctype.h>
-#include <stdint.h>
-
/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
- fractional parts, S_Z: idem but with leading Zeroes only */
+ fractionnal parts, S_Z: idem but with leading Zeroes only */
#define S_N 0x0
-#define S_I 0x4
-#define S_F 0x8
-#define S_Z 0xC
+#define S_I 0x3
+#define S_F 0x6
+#define S_Z 0x9
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
#define CMP 2
#define LEN 3
-/* using more efficient isdigit() */
-#undef isdigit
-#define isdigit(a) ((unsigned)((a) - '0') <= 9)
/* Compare S1 and S2 as strings holding indices/version numbers,
returning less than, equal to or greater than zero if S1 is less than,
equal to or greater than S2 (for more info, see the texinfo doc).
*/
+
int strverscmp (const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
- unsigned char c1, c2;
- int state;
- int diff;
- /* Symbol(s) 0 [1-9] others (padding)
- Transition (10) 0 (01) d (00) x (11) - */
+ /* Symbol(s) 0 [1-9] others
+ Transition (10) 0 (01) d (00) x */
static const uint8_t next_state[] =
{
- /* state x d 0 - */
- /* S_N */ S_N, S_I, S_Z, S_N,
- /* S_I */ S_N, S_I, S_I, S_I,
- /* S_F */ S_N, S_F, S_F, S_F,
- /* S_Z */ S_N, S_F, S_Z, S_Z
+ /* state x d 0 */
+ /* S_N */ S_N, S_I, S_Z,
+ /* S_I */ S_N, S_I, S_I,
+ /* S_F */ S_N, S_F, S_F,
+ /* S_Z */ S_N, S_F, S_Z
};
static const int8_t result_type[] =
{
- /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
- 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
-
- /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
- /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP,
- +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
- /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
- /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP,
- -1, CMP, CMP, CMP
+ /* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */
+
+ /* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
+ /* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
+ /* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+ /* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP
};
+ unsigned char c1, c2;
+ int state, diff;
if (p1 == p2)
return 0;
@@ -86,17 +72,20 @@ int strverscmp (const char *s1, const char *s2)
c1 = *p1++;
c2 = *p2++;
/* Hint: '0' is a digit too. */
- state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
+ state = S_N + ((c1 == '0') + (isdigit (c1) != 0));
- while ((diff = c1 - c2) == 0 && c1 != '\0')
+ while ((diff = c1 - c2) == 0)
{
+ if (c1 == '\0')
+ return diff;
+
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
- state |= (c1 == '0') + (isdigit (c1) != 0);
+ state += (c1 == '0') + (isdigit (c1) != 0);
}
- state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
+ state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
switch (state)
{
diff --git a/libc/sysdeps/linux/arc/sigaction.c b/libc/sysdeps/linux/arc/sigaction.c
index 4a4c9e2d0..67ca38aca 100644
--- a/libc/sysdeps/linux/arc/sigaction.c
+++ b/libc/sysdeps/linux/arc/sigaction.c
@@ -13,7 +13,8 @@
/*
* Default sigretrun stub if user doesn't specify SA_RESTORER
*/
-static void __default_rt_sa_restorer(void)
+static void attribute_optimize("Os") __attribute_noinline__
+__default_rt_sa_restorer(void)
{
INTERNAL_SYSCALL_NCS(__NR_rt_sigreturn, , 0);
}
diff --git a/libc/sysdeps/linux/arc/sys/procfs.h b/libc/sysdeps/linux/arc/sys/procfs.h
index a9e375b33..a47430340 100755
--- a/libc/sysdeps/linux/arc/sys/procfs.h
+++ b/libc/sysdeps/linux/arc/sys/procfs.h
@@ -20,17 +20,14 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/user.h>
+#include <asm/ptrace.h>
__BEGIN_DECLS
/* Type for a general-purpose register. */
typedef unsigned long elf_greg_t;
-/* And the whole bunch of them. We could have used `struct
- user_regs' directly in the typedef, but tradition says that
- the register set is an array, which does have some peculiar
- semantics, so leave it that way. */
-#define ELF_NGREG 40
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct { } elf_fpregset_t;
diff --git a/libc/sysdeps/linux/arm/Makefile.arch b/libc/sysdeps/linux/arm/Makefile.arch
index 3054273df..cda3db206 100644
--- a/libc/sysdeps/linux/arm/Makefile.arch
+++ b/libc/sysdeps/linux/arm/Makefile.arch
@@ -13,7 +13,9 @@ SSRC-y := \
vfork.S clone.S
SSRC-$(UCLIBC_HAS_LFS) += mmap64.S
-SSRC-$(UCLIBC_HAS_THREADS_NATIVE) += libc-aeabi_read_tp.S libc-thumb_atomics.S
+SSRC-$(UCLIBC_HAS_THREADS_NATIVE) += libc-thumb_atomics.S
+libc-nonshared-$(UCLIBC_HAS_THREADS_NATIVE) += $(ARCH_OUT)/libc-aeabi_read_tp.os
+libc-static-$(UCLIBC_HAS_THREADS_NATIVE) += $(ARCH_OUT)/libc-aeabi_read_tp.o
CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c
SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S swapcontext.S
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 8ee956b6b..82525984a 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -27,6 +27,7 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \
eventfd.c \
eventfd_read.c \
eventfd_write.c \
+ getrandom.c \
inotify.c \
ioperm.c \
iopl.c \
diff --git a/libc/sysdeps/linux/common/bits/kernel-features.h b/libc/sysdeps/linux/common/bits/kernel-features.h
index 6184c2b9d..708bb4906 100644
--- a/libc/sysdeps/linux/common/bits/kernel-features.h
+++ b/libc/sysdeps/linux/common/bits/kernel-features.h
@@ -507,3 +507,8 @@
#if defined __x86_64__ && __LINUX_KERNEL_VERSION >= 0x030100
# define __ASSUME_GETCPU_SYSCALL 1
#endif
+
+/* getrandom syscall (widely) appeared around 4.0.0 */
+#if __LINUX_KERNEL_VERSION >= 0x040000
+# define __ASSUME_GETRANDOM_SYSCALL 1
+#endif
diff --git a/libc/sysdeps/linux/common/bits/mathcalls.h b/libc/sysdeps/linux/common/bits/mathcalls.h
index 427027355..3d7e34fa2 100644
--- a/libc/sysdeps/linux/common/bits/mathcalls.h
+++ b/libc/sysdeps/linux/common/bits/mathcalls.h
@@ -74,8 +74,22 @@ __MATHCALLI (atan2,, (_Mdouble_ __y, _Mdouble_ __x))
/* Cosine of X. */
__MATHCALLI (cos,, (_Mdouble_ __x))
+# if defined _LIBC && defined _Mlong_double_
+libm_hidden_proto(cosl)
+# endif
+# if defined _LIBC && defined _Mfloat_
+libm_hidden_proto(cosf)
+# endif
+
/* Sine of X. */
__MATHCALLI (sin,, (_Mdouble_ __x))
+# if defined _LIBC && defined _Mlong_double_
+libm_hidden_proto(sinl)
+# endif
+# if defined _LIBC && defined _Mfloat_
+libm_hidden_proto(sinf)
+# endif
+
/* Tangent of X. */
__MATHCALLI (tan,, (_Mdouble_ __x))
@@ -111,6 +125,9 @@ __END_NAMESPACE_C99
_Mdouble_BEGIN_NAMESPACE
/* Exponential function of X. */
__MATHCALLI (exp,, (_Mdouble_ __x))
+# if defined _LIBC && defined _Mlong_double_
+libm_hidden_proto(expl)
+# endif
/* Break VALUE into a normalized fraction and an integral power of 2. */
__MATHCALLI (frexp,, (_Mdouble_ __x, int *__exponent))
@@ -173,6 +190,9 @@ _Mdouble_END_NAMESPACE
__BEGIN_NAMESPACE_C99
/* Return `sqrt(X*X + Y*Y)'. */
__MATHCALLI (hypot,, (_Mdouble_ __x, _Mdouble_ __y))
+# if defined _LIBC && defined _Mlong_double_
+libm_hidden_proto(hypotl)
+# endif
__END_NAMESPACE_C99
#endif
@@ -300,6 +320,9 @@ __MATHCALLI (rint,, (_Mdouble_ __x))
/* Return X + epsilon if X < Y, X - epsilon if X > Y. */
__MATHCALLX (nextafter,, (_Mdouble_ __x, _Mdouble_ __y), (__const__))
+# if defined _LIBC && defined _Mlong_double_
+libm_hidden_proto(nextafterl)
+# endif
# if defined __USE_ISOC99 && !defined __LDBL_COMPAT
# ifndef _Mdouble_is_float_
__MATHCALLX (nexttoward,, (_Mdouble_ __x, long double __y), (__const__))
diff --git a/libc/sysdeps/linux/common/bits/utmp.h b/libc/sysdeps/linux/common/bits/utmp.h
index c13380ab8..6ece31e34 100644
--- a/libc/sysdeps/linux/common/bits/utmp.h
+++ b/libc/sysdeps/linux/common/bits/utmp.h
@@ -36,7 +36,7 @@
previous logins. */
struct lastlog
{
-#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+#ifdef __WORDSIZE_TIME64_COMPAT32
int32_t ll_time;
#else
__time_t ll_time;
@@ -69,7 +69,7 @@ struct utmp
/* The ut_session and ut_tv fields must be the same size when compiled
32- and 64-bit. This allows data files and shared memory to be
shared between 32- and 64-bit applications. */
-#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+#ifdef __WORDSIZE_TIME64_COMPAT32
int32_t ut_session; /* Session ID, used for windowing. */
struct
{
diff --git a/libc/sysdeps/linux/common/bits/utmpx.h b/libc/sysdeps/linux/common/bits/utmpx.h
index 87626f085..815fc90b8 100644
--- a/libc/sysdeps/linux/common/bits/utmpx.h
+++ b/libc/sysdeps/linux/common/bits/utmpx.h
@@ -66,7 +66,7 @@ struct utmpx
/* The fields ut_session and ut_tv must be the same size when compiled
32- and 64-bit. This allows files and shared memory to be shared
between 32- and 64-bit applications. */
-#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+#ifdef __WORDSIZE_TIME64_COMPAT32
__int32_t ut_session; /* Session ID, used for windowing. */
struct
{
diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c
new file mode 100644
index 000000000..d33d5224a
--- /dev/null
+++ b/libc/sysdeps/linux/common/getrandom.c
@@ -0,0 +1,14 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * getrandom() for uClibc
+ *
+ * Copyright (C) 2015 Bernhard Reutner-Fischer
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <sys/random.h>
+#ifdef __NR_getrandom
+_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
+#endif
diff --git a/libc/sysdeps/linux/common/getrusage.c b/libc/sysdeps/linux/common/getrusage.c
index 3e719f294..fb7614be8 100644
--- a/libc/sysdeps/linux/common/getrusage.c
+++ b/libc/sysdeps/linux/common/getrusage.c
@@ -10,4 +10,5 @@
#include <sys/syscall.h>
#include <unistd.h>
#include <wait.h>
+#include <sys/resource.h>
_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage)
diff --git a/libc/sysdeps/linux/common/makedev.c b/libc/sysdeps/linux/common/makedev.c
new file mode 100644
index 000000000..d7761671b
--- /dev/null
+++ b/libc/sysdeps/linux/common/makedev.c
@@ -0,0 +1,42 @@
+/* Definitions of functions to access `dev_t' values.
+ Copyright (C) 2003-2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <endian.h>
+#include <sys/sysmacros.h>
+
+unsigned int
+gnu_dev_major (unsigned long long int dev)
+{
+ return ((dev >> 8) & 0xfff) | ((unsigned int) (dev >> 32) & ~0xfff);
+}
+libc_hidden_def(gnu_dev_major)
+
+unsigned int
+gnu_dev_minor (unsigned long long int dev)
+{
+ return (dev & 0xff) | ((unsigned int) (dev >> 12) & ~0xff);
+}
+libc_hidden_def(gnu_dev_minor)
+
+unsigned long long int
+gnu_dev_makedev (unsigned int major, unsigned int minor)
+{
+ return ((minor & 0xff) | ((major & 0xfff) << 8)
+ | (((unsigned long long int) (minor & ~0xff)) << 12)
+ | (((unsigned long long int) (major & ~0xfff)) << 32));
+}
diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c
index 2c50307aa..19a33714a 100644
--- a/libc/sysdeps/linux/common/stubs.c
+++ b/libc/sysdeps/linux/common/stubs.c
@@ -157,6 +157,10 @@ make_stub(getpeername)
make_stub(getpgrp)
#endif
+#if !defined __NR_getrandom && defined __UCLIBC_LINUX_SPECIFIC__
+make_stub(getrandom)
+#endif
+
#if !defined __NR_getsockname && !defined __NR_socketcall && defined __UCLIBC_HAS_SOCKET__
make_stub(getsockname)
#endif
diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h
new file mode 100644
index 000000000..42f802576
--- /dev/null
+++ b/libc/sysdeps/linux/common/sys/random.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2015 Bernhard Reutner-Fischer
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+*/
+
+#ifndef _SYS_RANDOM_H
+#define _SYS_RANDOM_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+#if defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
+# if 0 /*def __ASSUME_GETRANDOM_SYSCALL */
+# include <linux/random.h>
+# else
+# undef GRND_NONBLOCK
+# undef GRND_RANDOM
+/*
+ * Flags for getrandom(2)
+ *
+ * GRND_NONBLOCK Don't block and return EAGAIN instead
+ * GRND_RANDOM Use the /dev/random pool instead of /dev/urandom
+ */
+# define GRND_NONBLOCK 0x0001
+# define GRND_RANDOM 0x0002
+# endif
+/* FIXME: aren't there a couple of __restrict and const missing ? */
+extern int getrandom(void *__buf, size_t count, unsigned int flags)
+ __nonnull ((1)) __wur;
+#endif
+
+__END_DECLS
+
+#endif /* sys/random.h */
diff --git a/libc/sysdeps/linux/mips/bits/mathdef.h b/libc/sysdeps/linux/mips/bits/mathdef.h
index 1c636a199..6afe20d8a 100644
--- a/libc/sysdeps/linux/mips/bits/mathdef.h
+++ b/libc/sysdeps/linux/mips/bits/mathdef.h
@@ -25,10 +25,9 @@
#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
# define _MATH_H_MATHDEF 1
-/* Normally, there is no long double type and the `float' and `double'
- expressions are evaluated as `double'. */
-typedef double float_t; /* `float' expressions are evaluated as
- `double'. */
+/* MIPS has both `float' and `double' arithmetic. */
+typedef float float_t; /* `float' expressions are evaluated as
+ `float'. */
typedef double double_t; /* `double' expressions are evaluated as
`double'. */
diff --git a/libc/sysdeps/linux/mips/bits/wordsize.h b/libc/sysdeps/linux/mips/bits/wordsize.h
index 39e15062c..fe130806c 100644
--- a/libc/sysdeps/linux/mips/bits/wordsize.h
+++ b/libc/sysdeps/linux/mips/bits/wordsize.h
@@ -16,3 +16,6 @@
<http://www.gnu.org/licenses/>. */
#define __WORDSIZE _MIPS_SZPTR
+#if _MIPS_SIM == _ABI64
+# define __WORDSIZE_TIME64_COMPAT32 1
+#endif
diff --git a/libc/sysdeps/linux/powerpc/bits/wordsize.h b/libc/sysdeps/linux/powerpc/bits/wordsize.h
index cf934234f..3e8a1e0a1 100644
--- a/libc/sysdeps/linux/powerpc/bits/wordsize.h
+++ b/libc/sysdeps/linux/powerpc/bits/wordsize.h
@@ -2,7 +2,7 @@
#if defined __powerpc64__
# define __WORDSIZE 64
-# define __WORDSIZE_COMPAT32 1
+# define __WORDSIZE_TIME64_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
diff --git a/libc/sysdeps/linux/sh/bits/atomic.h b/libc/sysdeps/linux/sh/bits/atomic.h
index 745c85c1d..18ae9ea77 100644
--- a/libc/sysdeps/linux/sh/bits/atomic.h
+++ b/libc/sysdeps/linux/sh/bits/atomic.h
@@ -68,6 +68,12 @@ typedef uintmax_t uatomic_max_t;
r1: saved stack pointer
*/
+#if __GNUC_PREREQ (4, 7)
+# define rNOSP "u"
+#else
+# define rNOSP "r"
+#endif
+
/* Avoid having lots of different versions of compare and exchange,
by having this one complicated version. Parameters:
bwl: b, w or l for 8, 16 and 32 bit versions.
@@ -94,7 +100,7 @@ typedef uintmax_t uatomic_max_t;
movt %0\n\
.endif\n" \
: "=&r" (__arch_result) \
- : "r" (mem), "r" (newval), "r" (oldval) \
+ : rNOSP (mem), rNOSP (newval), rNOSP (oldval) \
: "r0", "r1", "t", "memory"); \
__arch_result; })
@@ -150,7 +156,7 @@ typedef uintmax_t uatomic_max_t;
mov." #bwl " %1,@%2\n\
1: mov r1,r15" \
: "=&r" (old), "=&r"(new) \
- : "r" (mem), "r" (value) \
+ : rNOSP (mem), rNOSP (value) \
: "r0", "r1", "memory"); \
})
@@ -194,7 +200,7 @@ typedef uintmax_t uatomic_max_t;
mov." #bwl " %0,@%1\n\
1: mov r1,r15" \
: "=&r" (__new) \
- : "r" (mem), "r" (__value) \
+ : rNOSP (mem), rNOSP (__value) \
: "r0", "r1", "memory"); \
__new; \
})
diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h
index b308276c5..efd423ed3 100644
--- a/libc/sysdeps/linux/sh/bits/syscalls.h
+++ b/libc/sysdeps/linux/sh/bits/syscalls.h
@@ -122,7 +122,7 @@
__asm__ __volatile__ (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \
: "=z" (resultvar) \
: "r" (r3) ASMFMT_##nr \
- : "memory" \
+ : "memory", "t" \
); \
(int) resultvar; \
}) \
diff --git a/libc/sysdeps/linux/sparc/bits/wordsize.h b/libc/sysdeps/linux/sparc/bits/wordsize.h
index c0e600ed5..aa15dbc7a 100644
--- a/libc/sysdeps/linux/sparc/bits/wordsize.h
+++ b/libc/sysdeps/linux/sparc/bits/wordsize.h
@@ -2,6 +2,7 @@
#if defined __arch64__ || defined __sparcv9
# define __WORDSIZE 64
+# define __WORDSIZE_TIME64_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
diff --git a/libc/sysdeps/linux/x86_64/bits/wordsize.h b/libc/sysdeps/linux/x86_64/bits/wordsize.h
index e55524100..9db982c90 100644
--- a/libc/sysdeps/linux/x86_64/bits/wordsize.h
+++ b/libc/sysdeps/linux/x86_64/bits/wordsize.h
@@ -1,9 +1,12 @@
/* Determine the wordsize from the preprocessor defines. */
-#if defined __x86_64__
+#if defined __x86_64__ && !defined __ILP32__
# define __WORDSIZE 64
-/* This makes /var/run/utmp compatible with 32-bit environment: */
-# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
+
+#ifdef __x86_64__
+/* This makes /var/run/utmp compatible with 32-bit environment: */
+# define __WORDSIZE_TIME64_COMPAT32 1
+#endif