This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The branch, 1.0 has been updated
via 73490b63e659336596420a263c3a7133ccfd914b (commit)
via 7ccac5e8a4a0fd123eb8c035225ee12d30c0bb00 (commit)
via ce64875415e7d50da86379b48f04f96d633b4e9d (commit)
via 5178df3e156a436c4888a1a95996aea55525e7b6 (commit)
via 3aabb58d126445092dca953223c1730d975491dc (commit)
via 8340ffd2997feaca9074e0272e3c4663793baf77 (commit)
via cc04ab27ba6341f46bbe094478c9af3e3706f411 (commit)
via eaedbdaa0877ec6d0501b8c19ad5175c80764c67 (commit)
via 64917add7f4aeec8720d2fba5e96ea39aac35623 (commit)
via 8a992d6715c8149f7efc0553eeaf31f3e27de60c (commit)
via e83b4786d78b97f1657e96c0dfd13f0e9298e55f (commit)
via a574f01947321cfc4dc746db90c2291f3e9f10c2 (commit)
via 8a783f5440817b8db8d27b6a3fb14c301ffa9ad7 (commit)
via f72e003a5f168a32a77ee9248b2169b1e11d5198 (commit)
via 78443c6a541b807f912f33ef01857acd079559c4 (commit)
via 219b69d72e878094f3ce03a9e70719709a9b4c43 (commit)
via 2e116b2eeea5f47ca26458b1962783baced2784c (commit)
from d1b81113b43a6d26dec4e0e58a380895d121006e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 73490b63e659336596420a263c3a7133ccfd914b
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Thu Dec 17 20:21:18 2015 +0100
reduce stack cache size to save memory space
Idea from different projects as OpenWrt and others.
https://lists.openwrt.org/pipermail/openwrt-devel/2013-November/022299.html
https://github.com/wl500g/toolchain/blob/master/toolchain/uClibc/patches/0.…
commit 7ccac5e8a4a0fd123eb8c035225ee12d30c0bb00
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Thu Dec 17 07:59:05 2015 +0100
testsuite subdir fix
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit ce64875415e7d50da86379b48f04f96d633b4e9d
Author: Khem Raj <raj.khem(a)gmail.com>
Date: Sat Oct 31 18:32:54 2015 +0000
Add implementation for copysignl for ppc
Signed-off-by: Khem Raj <raj.khem(a)gmail.com>
commit 5178df3e156a436c4888a1a95996aea55525e7b6
Author: Wojciech Nizinski <w.nizinski at grinn-global.com>
Date: Tue Oct 20 14:08:09 2015 +0200
libc/stdlib: canonicalize_file_name() memory leak
Uclibc's canonicalize_file_name() is allocating temprary buffer of 4kB
(PATH_MAX), and passing it to realpath() as second argument. Function is
not checking if realpath() fails and memory is lost.
commit 3aabb58d126445092dca953223c1730d975491dc
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:52:24 2015 +0100
utlis/ldd: Fix host ldd in case of target wordsize differs from host one
improved solution from
http://freetz.org/ticket/842
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit 8340ffd2997feaca9074e0272e3c4663793baf77
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:51:12 2015 +0100
test/tls: tls-macros*.h fixes from glibc
glibc commits
4822a2a520 Add x32 support to TLS_LE/TLS_IE/TLS_GD
63fb881a04 tls-macros-mips.h: Load $gp as required.
Merge 32-bit and 64-bit versions.
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit cc04ab27ba6341f46bbe094478c9af3e3706f411
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:49:06 2015 +0100
dlclose fix
Patch is from Timo Teras
Refs.:
http://lists.uclibc.org/pipermail/uclibc/2012-October/047059.html
http://git.alpinelinux.org/cgit/aports/tree/main/libc0.9.32/uclibc-dlclose-…
commit eaedbdaa0877ec6d0501b8c19ad5175c80764c67
Author: Vladislav Grishenko <themiron(a)mail.ru>
Date: Wed Sep 12 18:04:48 2012 +0600
Fix syslog messages lost if syslogd is temporary busy
Commit 4139fe5aec935ba3f462dcaf6aafb6e5eadf1ab9 fixes SIGSTOPed syslogd issue.
but introduced new one - messages will be lost when socket buffer gets full,
not only if syslogd is stalled, but even if it accepts message slower than
someone sends and possibly leads to security hole, when important messages get
lost as result of attacker flooding.
Patch adds 1 second waiting for socket buffer can accept the message, helps
when syslogd is working hard. If it's stalled/SIGSTOPed, message will be sent
to errout as before. After that, further non-blocking /dev/log connect attempts
will fail immediately with EAGAIN error until syslogd reads some from it.
function old new delta
openlog_intern 259 355 +96
static.tv - 8 +8
.rodata 151 159 +8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 112/0) Total: 112 bytes
Signed-off-by: Vladislav Grishenko <themiron(a)mail.ru>
commit 64917add7f4aeec8720d2fba5e96ea39aac35623
Author: Vladislav Grishenko <themiron(a)mail.ru>
Date: Wed Sep 12 17:13:55 2012 +0600
Fix syslog messages lost after syslogd restarts
If syslogd is stopped and restarted while a process has the log open, the next
message that process produces will be logged to the console and not to the new
instance of syslogd. Further messages will be routed correctly, but not the
first one.
Based on original patch
Bug 3889 - syslog loses messages when syslogd restarted
https://bugs.busybox.net/show_bug.cgi?id=3889
function old new delta
openlog 33 68 +35
__vsyslog 851 848 -3
openlog_intern 318 259 -59
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 35/-62) Total: -27 bytes
Signed-off-by: Vladislav Grishenko <themiron(a)mail.ru>
commit 8a992d6715c8149f7efc0553eeaf31f3e27de60c
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:44:54 2015 +0100
resolv: NI_IDN unimplemented
Some programs trying to use NI_IDN flag in case of it defined in netdb.h,
so hide it to suppress bad values for ai_flags.
Inspired by OpenWRT issue #12323
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit e83b4786d78b97f1657e96c0dfd13f0e9298e55f
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:42:34 2015 +0100
resolv: __dns_lookup - immediately switch to next server in case of poll() set error
events
https://bugs.busybox.net/show_bug.cgi?id=3211
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit a574f01947321cfc4dc746db90c2291f3e9f10c2
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:40:36 2015 +0100
dynamically allocate ahostbuf buffer
Free 1k of static data (.bss)
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit 8a783f5440817b8db8d27b6a3fb14c301ffa9ad7
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:38:30 2015 +0100
svc.c: svc_getreqset() buffer overflow
http://bugs.busybox.net/show_bug.cgi?id=5588
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit f72e003a5f168a32a77ee9248b2169b1e11d5198
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Sun Dec 13 23:36:46 2015 +0100
only strip test binaries when DOSTRIP is enabled
commit 78443c6a541b807f912f33ef01857acd079559c4
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Thu Dec 10 11:14:41 2015 +0100
test needs -fPIC for m68k
commit 219b69d72e878094f3ce03a9e70719709a9b4c43
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Wed Dec 9 08:05:10 2015 +0100
libc/stdio: Rework custom streams interface similar to glibc.
Save 20 bytes per FILE structure, avoid indirect call for
read/write/seek/close operations for normal streams.
Additionally, custom streams has fileno = -2 now, like in glibc.
bloat-o-meter report (UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y):
function old new delta
fopencookie 69 131 +62
ftello64 233 260 +27
fseeko64 298 319 +21
fclose 423 442 +19
.rodata 16696 16708 +12
fileno_unlocked 53 45 -8
__ns_name_pack 859 851 -8
vswscanf 184 144 -40
vdprintf 231 187 -44
vsscanf 210 151 -59
vswprintf 269 201 -68
vsnprintf 249 181 -68
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/7 up/down: 141/-295) Total: -154 bytes
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit 2e116b2eeea5f47ca26458b1962783baced2784c
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Wed Dec 9 08:07:09 2015 +0100
fix readdir_r returns success code while it in fact failed
Taken from
Freetz.org.
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
-----------------------------------------------------------------------
Summary of changes:
include/netdb.h | 3 +-
ldso/libdl/libdl.c | 4 +-
libc/inet/resolv.c | 4 +
libc/inet/rpc/rexec.c | 9 ++-
libc/inet/rpc/svc.c | 2 +
libc/misc/dirent/readdir_r.c | 2 +-
libc/misc/syslog/syslog.c | 46 +++++++----
libc/stdio/_READ.c | 2 +-
libc/stdio/_WRITE.c | 2 +-
libc/stdio/_cs_funcs.c | 42 ----------
libc/stdio/_fopen.c | 2 -
libc/stdio/_rfill.c | 2 +-
libc/stdio/_scanf.c | 27 -------
libc/stdio/_stdio.c | 23 +-----
libc/stdio/_stdio.h | 102 ++++++++++++++-----------
libc/stdio/fclose.c | 2 -
libc/stdio/fopencookie.c | 29 +++++--
libc/stdio/fread.c | 2 +-
libc/stdio/vdprintf.c | 9 ---
libc/stdio/vsnprintf.c | 46 ++++-------
libc/stdio/vswprintf.c | 9 ---
libc/stdlib/canonicalize.c | 21 +----
libc/sysdeps/linux/common/bits/uClibc_stdio.h | 4 -
libc/sysdeps/linux/powerpc/Makefile.arch | 2 +-
libc/sysdeps/linux/powerpc/copysignl.c | 89 +++++++++++++++++++++
libpthread/nptl/allocatestack.c | 8 +-
test/Rules.mak | 4 +-
test/Test.mak | 4 +
test/stdio/Makefile.in | 6 ++
test/stdio/tst-fmemopen.c | 53 +++++++++++++
test/tls/tls-macros-mips.h | 94 +++++++++--------------
test/tls/tls-macros.h | 16 ++--
utils/Makefile.in | 1 +
utils/ldd.c | 13 +++-
utils/porting.h | 10 +++
35 files changed, 375 insertions(+), 319 deletions(-)
create mode 100644 libc/sysdeps/linux/powerpc/copysignl.c
create mode 100644 test/stdio/tst-fmemopen.c
diff --git a/include/netdb.h b/include/netdb.h
index 7ce01c2..a636b5f 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -671,7 +671,8 @@ struct addrinfo
# define NI_NOFQDN 4 /* Only return nodename portion. */
# define NI_NAMEREQD 8 /* Don't return numeric addresses. */
# define NI_DGRAM 16 /* Look up UDP service rather than TCP. */
-# ifdef __USE_GNU
+#if 0 /* uClibc: not implemented */
+/* # ifdef __USE_GNU */
# define NI_IDN 32 /* Convert name from IDN format. */
# define NI_IDN_ALLOW_UNASSIGNED 64 /* Don't reject unassigned Unicode
code points. */
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 388e3c7..2c4b064 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -964,8 +964,8 @@ static int do_dlclose(void *vhandle, int need_fini)
dtv_t *dtv = THREAD_DTV ();
- _dl_assert(!(dtv[tls_lmap->l_tls_modid].pointer.is_static));
- if (dtv[tls_lmap->l_tls_modid].pointer.val != TLS_DTV_UNALLOCATED) {
+ if (!(dtv[tls_lmap->l_tls_modid].pointer.is_static) &&
+ dtv[tls_lmap->l_tls_modid].pointer.val != TLS_DTV_UNALLOCATED) {
/* Note that free is called for NULL is well. We
deallocate even if it is this dtv entry we are
supposed to load. The reason is that we call
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index fffe428..8e5a97d 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1410,6 +1410,10 @@ int __dns_lookup(const char *name,
* to next nameserver */
goto try_next_server;
}
+ if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+ DPRINTF("Bad event\n");
+ goto try_next_server;
+ }
/*TODO: better timeout accounting?*/
reply_timeout -= 1000;
#endif /* USE_SELECT */
diff --git a/libc/inet/rpc/rexec.c b/libc/inet/rpc/rexec.c
index 9f7cc80..e17be50 100644
--- a/libc/inet/rpc/rexec.c
+++ b/libc/inet/rpc/rexec.c
@@ -39,12 +39,13 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <malloc.h>
#define SA_LEN(_x) __libc_sa_len((_x)->sa_family)
extern int __libc_sa_len(sa_family_t __af) __THROW attribute_hidden;
/* int rexecoptions; - google does not know it */
-static char ahostbuf[NI_MAXHOST];
+static char *ahostbuf = NULL;
int
rexec_af(char **ahost, int rport, const char *name, const char *pass, const char *cmd,
int *fd2p, sa_family_t af)
@@ -77,8 +78,10 @@ rexec_af(char **ahost, int rport, const char *name, const char *pass,
const char
}
if (res0->ai_canonname) {
- strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf));
- ahostbuf[sizeof(ahostbuf)-1] = '\0';
+ if (!ahostbuf)
+ ahostbuf = __uc_malloc(NI_MAXHOST);
+ strncpy(ahostbuf, res0->ai_canonname, NI_MAXHOST);
+ ahostbuf[NI_MAXHOST-1] = '\0';
*ahost = ahostbuf;
}
else {
diff --git a/libc/inet/rpc/svc.c b/libc/inet/rpc/svc.c
index 6d7253a..c3d5518 100644
--- a/libc/inet/rpc/svc.c
+++ b/libc/inet/rpc/svc.c
@@ -448,6 +448,8 @@ svc_getreqset (fd_set *readfds)
register int bit;
setsize = _rpc_dtablesize ();
+ if (setsize > FD_SETSIZE)
+ setsize = FD_SETSIZE;
maskp = (u_int32_t *) readfds->fds_bits;
for (sock = 0; sock < setsize; sock += 32)
for (mask = *maskp++; (bit = ffs (mask)); mask ^= (1 << (bit - 1)))
diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c
index 7cdc0ab..5beebfe 100644
--- a/libc/misc/dirent/readdir_r.c
+++ b/libc/misc/dirent/readdir_r.c
@@ -27,7 +27,6 @@ int __READDIR_R(DIR *dir, __DIRENT_TYPE *entry, __DIRENT_TYPE **result)
__set_errno(EBADF);
return(EBADF);
}
- de = NULL;
__UCLIBC_MUTEX_LOCK(dir->dd_lock);
@@ -36,6 +35,7 @@ int __READDIR_R(DIR *dir, __DIRENT_TYPE *entry, __DIRENT_TYPE **result)
/* read dir->dd_max bytes of directory entries. */
bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max);
if (bytes <= 0) {
+ de = NULL;
*result = NULL;
ret = (bytes==0)? 0 : errno;
goto all_done;
diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c
index 1ab4707..1df0d1a 100644
--- a/libc/misc/syslog/syslog.c
+++ b/libc/misc/syslog/syslog.c
@@ -122,23 +122,16 @@ closelog_intern(int sig)
}
static void
-openlog_intern(const char *ident, int logstat, int logfac)
+openlog_intern(void)
{
int fd;
int logType = SOCK_DGRAM;
-
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
- /* (we were checking also for logfac != 0, but it breaks
- * openlog(xx, LOG_KERN) since LOG_KERN == 0) */
- if ((logfac & ~LOG_FACMASK) == 0) /* if we don't have invalid bits */
- LogFacility = (unsigned)logfac >> 3;
+ static const struct timeval tv = { 1, 0 };
fd = LogFile;
if (fd == -1) {
retry:
- if (logstat & LOG_NDELAY) {
+ if (1) { /* if statement left in to make .diff cleaner */
LogFile = fd = socket(AF_UNIX, logType, 0);
if (fd == -1) {
return;
@@ -151,6 +144,9 @@ openlog_intern(const char *ident, int logstat, int logfac)
if (fd != -1 && !connected) {
if (connect(fd, &SyslogAddr, sizeof(SyslogAddr)) != -1) {
+ /* We want to block send if e.g. syslogd is SIGSTOPed */
+ fcntl(fd, F_SETFL, ~O_NONBLOCK & fcntl(fd, F_GETFL));
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
connected = 1;
} else {
if (fd != -1) {
@@ -172,7 +168,18 @@ void
openlog(const char *ident, int logstat, int logfac)
{
__UCLIBC_MUTEX_LOCK(mylock);
- openlog_intern(ident, logstat, logfac);
+
+ if (ident != NULL)
+ LogTag = ident;
+ LogStat = logstat;
+ /* (we were checking also for logfac != 0, but it breaks
+ * openlog(xx, LOG_KERN) since LOG_KERN == 0) */
+ if ((logfac & ~LOG_FACMASK) == 0) /* if we don't have invalid bits */
+ LogFacility = (unsigned)logfac >> 3;
+
+ if (logstat & LOG_NDELAY)
+ openlog_intern();
+
__UCLIBC_MUTEX_UNLOCK(mylock);
}
@@ -206,7 +213,7 @@ __vsyslog(int pri, const char *fmt, va_list ap)
if ((LogMask & LOG_MASK(LOG_PRI(pri))) == 0)
goto getout;
if (LogFile < 0 || !connected)
- openlog_intern(NULL, LogStat | LOG_NDELAY, (int)LogFacility << 3);
+ openlog_intern();
/* Set default facility if none specified. */
if ((pri & LOG_FACMASK) == 0)
@@ -266,14 +273,23 @@ __vsyslog(int pri, const char *fmt, va_list ap)
/* Output the message to the local logger using NUL as a message delimiter. */
p = tbuf;
*last_chr = '\0';
+ retry:
if (LogFile >= 0) {
do {
/* can't just use write, it can result in SIGPIPE */
rc = send(LogFile, p, last_chr + 1 - p, MSG_NOSIGNAL);
if (rc < 0) {
- /* I don't think looping forever on EAGAIN is a good idea.
- * Imagine that syslogd is SIGSTOPed... */
- if (/* (errno != EAGAIN) && */ (errno != EINTR)) {
+ switch (errno) {
+ case EINTR:
+ break;
+ case ECONNRESET:
+ /* syslogd restarted, reopen log */
+ closelog_intern(1);
+ openlog_intern();
+ goto retry;
+ case EAGAIN:
+ /* syslogd stalled, noting we can do */
+ default:
closelog_intern(1); /* 1: do not reset LogXXX globals to default */
goto write_err;
}
diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c
index 02601c0..a548dbb 100644
--- a/libc/stdio/_READ.c
+++ b/libc/stdio/_READ.c
@@ -27,7 +27,7 @@ size_t attribute_hidden __stdio_READ(register FILE *stream,
ssize_t rv = 0;
__STDIO_STREAM_VALIDATE(stream);
- assert(stream->__filedes >= -1);
+ assert(stream->__filedes >= -2);
assert(__STDIO_STREAM_IS_READING(stream));
assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */
assert(!(stream->__modeflags & __FLAG_UNGOT));
diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c
index 6af5da8..712236f 100644
--- a/libc/stdio/_WRITE.c
+++ b/libc/stdio/_WRITE.c
@@ -36,7 +36,7 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream,
ssize_t rv, stodo;
__STDIO_STREAM_VALIDATE(stream);
- assert(stream->__filedes >= -1);
+ assert(stream->__filedes >= -2);
assert(__STDIO_STREAM_IS_WRITING(stream));
assert(!__STDIO_STREAM_BUFFER_WUSED(stream)); /* Buffer must be empty. */
diff --git a/libc/stdio/_cs_funcs.c b/libc/stdio/_cs_funcs.c
index 9df93f2..be416a4 100644
--- a/libc/stdio/_cs_funcs.c
+++ b/libc/stdio/_cs_funcs.c
@@ -8,46 +8,6 @@
#include "_stdio.h"
/**********************************************************************/
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
-/**********************************************************************/
-
-ssize_t attribute_hidden _cs_read(void *cookie, char *buf, size_t bufsize)
-{
- return read(*((int *) cookie), buf, bufsize);
-}
-
-/**********************************************************************/
-
-ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize)
-{
- return write(*((int *) cookie), (char *) buf, bufsize);
-}
-
-/**********************************************************************/
-
-int attribute_hidden _cs_seek(void *cookie, register __offmax_t *pos, int whence)
-{
- __offmax_t res;
-
-#ifdef __UCLIBC_HAS_LFS__
- res = lseek64(*((int *) cookie), *pos, whence);
-#else
- res = lseek(*((int *) cookie), *pos, whence);
-#endif
-
- return (res >= 0) ? ((*pos = res), 0) : ((int) res);
-}
-
-/**********************************************************************/
-
-int attribute_hidden _cs_close(void *cookie)
-{
- return close(*((int *) cookie));
-}
-
-/**********************************************************************/
-#else
-/**********************************************************************/
int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int whence)
{
@@ -63,5 +23,3 @@ int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t
*pos, int wh
}
/**********************************************************************/
-#endif
-/**********************************************************************/
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index 5bc61cf..be05c48 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -192,8 +192,6 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
__STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
#endif
- __STDIO_STREAM_RESET_GCS(stream);
-
#ifdef __UCLIBC_HAS_WCHAR__
stream->__ungot_width[0] = 0;
#endif
diff --git a/libc/stdio/_rfill.c b/libc/stdio/_rfill.c
index d61b1a9..e9d2fa6 100644
--- a/libc/stdio/_rfill.c
+++ b/libc/stdio/_rfill.c
@@ -24,7 +24,7 @@ size_t attribute_hidden __stdio_rfill(register FILE *__restrict stream)
size_t rv;
__STDIO_STREAM_VALIDATE(stream);
- assert(stream->__filedes >= -1);
+ assert(stream->__filedes >= -2);
assert(__STDIO_STREAM_IS_READING(stream));
assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */
assert(__STDIO_STREAM_BUFFER_SIZE(stream)); /* Must have a buffer. */
diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c
index f2a9670..80e4956 100644
--- a/libc/stdio/_scanf.c
+++ b/libc/stdio/_scanf.c
@@ -202,15 +202,6 @@ int vsscanf(const char *sp, const char *fmt, va_list ap)
{
FILE f;
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES;
f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING);
@@ -249,15 +240,6 @@ int vsscanf(const char *sp, const char *fmt, va_list ap)
f.bufpos = (unsigned char *) ((void *) sp);
f.bufread = f.bufpos + strlen(sp);
-/* __STDIO_STREAM_RESET_GCS(&f.f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.f.__cookie = &(f.f.__filedes);
- f.f.__gcs.read = NULL;
- f.f.__gcs.write = NULL;
- f.f.__gcs.seek = NULL;
- f.f.__gcs.close = NULL;
-#endif
-
f.f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB;
f.f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING);
@@ -383,15 +365,6 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t *
__restrict format,
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_DISABLE_PUTC(&f);
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
f.__filedes = __STDIO_STREAM_FAKE_VSWSCANF_FILEDES;
f.__modeflags = (__FLAG_WIDE|__FLAG_READONLY|__FLAG_READING);
diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
index ee247a5..2a10546 100644
--- a/libc/stdio/_stdio.c
+++ b/libc/stdio/_stdio.c
@@ -51,13 +51,6 @@
#define __STDIO_FILE_INIT_BUFFERS(buf,bufsize)
#endif
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
-#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream) \
- &((stream).__filedes), { _cs_read, _cs_write, _cs_seek, _cs_close },
-#else
-#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream)
-#endif
-
#ifdef __STDIO_MBSTATE
#define __STDIO_FILE_INIT_MBSTATE \
{ 0, 0 },
@@ -92,7 +85,6 @@
__STDIO_FILE_INIT_BUFGETC((buf)) \
__STDIO_FILE_INIT_BUFPUTC((buf)) \
__STDIO_FILE_INIT_NEXT(next) \
- __STDIO_FILE_INIT_CUSTOM_STREAM(stream) \
__STDIO_FILE_INIT_WUNGOT \
__STDIO_FILE_INIT_MBSTATE \
__STDIO_FILE_INIT_UNUSED \
@@ -240,7 +232,7 @@ void _stdio_term(void)
#endif
#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
/* Actually close all custom streams to perform any special cleanup. */
- if (ptr->__cookie != &ptr->__filedes) {
+ if (__STDIO_STREAM_IS_CUSTOM(ptr)) {
__CLOSE(ptr);
}
#endif
@@ -284,14 +276,9 @@ void attribute_hidden _stdio_validate_FILE(const FILE *stream)
#endif
#warning Define a constant for minimum possible valid __filedes?
- assert(stream->__filedes >= -3);
+ assert(stream->__filedes >= -4);
if (stream->__filedes < 0) {
-/* assert((stream->__filedes != -1) */
-/* #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
-/* || (stream->__cookie == &stream->__filedes) /\* custom *\/ */
-/* #endif */
-/* ); */
/* assert((stream->__filedes == -1) || __STDIO_STREAM_IS_FBF(stream)); */
assert(!__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)
@@ -308,12 +295,6 @@ void attribute_hidden _stdio_validate_FILE(const FILE *stream)
#endif
}
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- if (stream->__cookie != &stream->__filedes) { /* custom */
- assert(stream->__filedes == -1);
- }
-#endif
-
/* Can not be both narrow and wide oriented at the same time. */
assert(!(__STDIO_STREAM_IS_NARROW(stream)
&& __STDIO_STREAM_IS_WIDE(stream)));
diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
index 94557c2..310510d 100644
--- a/libc/stdio/_stdio.h
+++ b/libc/stdio/_stdio.h
@@ -4,6 +4,8 @@
*
* Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
*/
+#ifndef __STDIO_H_I
+#define __STDIO_H_I 1
#include <features.h>
#include <assert.h>
@@ -96,48 +98,61 @@ do { \
/**********************************************************************/
#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
-extern __ssize_t _cs_read(void *cookie, char *buf, size_t bufsize) attribute_hidden;
-extern __ssize_t _cs_write(void *cookie, const char *buf, size_t bufsize)
attribute_hidden;
-extern int _cs_seek(void *cookie, __offmax_t *pos, int whence) attribute_hidden;
-extern int _cs_close(void *cookie) attribute_hidden;
-
-#define __STDIO_STREAM_RESET_GCS(S) \
- (S)->__cookie = &((S)->__filedes); \
- (S)->__gcs.read = _cs_read; \
- (S)->__gcs.write = _cs_write; \
- (S)->__gcs.seek = _cs_seek; \
- (S)->__gcs.close = _cs_close
-
-
-#define __READ(STREAMPTR,BUF,SIZE) \
- ((((STREAMPTR)->__gcs.read) == NULL) ? -1 : \
- (((STREAMPTR)->__gcs.read)((STREAMPTR)->__cookie,(BUF),(SIZE))))
-#define __WRITE(STREAMPTR,BUF,SIZE) \
- ((((STREAMPTR)->__gcs.write) == NULL) ? -1 : \
- (((STREAMPTR)->__gcs.write)((STREAMPTR)->__cookie,(BUF),(SIZE))))
-#define __SEEK(STREAMPTR,PPOS,WHENCE) \
- ((((STREAMPTR)->__gcs.seek) == NULL) ? -1 : \
- (((STREAMPTR)->__gcs.seek)((STREAMPTR)->__cookie,(PPOS),(WHENCE))))
-#define __CLOSE(STREAMPTR) \
- ((((STREAMPTR)->__gcs.close) == NULL) ? 0 : \
- (((STREAMPTR)->__gcs.close)((STREAMPTR)->__cookie)))
+#define __STDIO_STREAM_GLIBC_CUSTOM_FILEDES (-2)
+
+#define __STDIO_STREAM_IS_CUSTOM(S) \
+ ((S)->__filedes == __STDIO_STREAM_GLIBC_CUSTOM_FILEDES)
+
+#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...) \
+ if (__STDIO_STREAM_IS_CUSTOM((S))) { \
+ _IO_cookie_file_t *cfile = (_IO_cookie_file_t *) (S); \
+ return (cfile->__gcs.NAME == NULL) ? (RC) : \
+ cfile->__gcs.NAME(cfile->__cookie, ##ARGS); \
+ }
+
+typedef struct {
+ struct __STDIO_FILE_STRUCT __fp;
+ void *__cookie;
+ _IO_cookie_io_functions_t __gcs;
+} _IO_cookie_file_t;
#else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
+#undef __STDIO_STREAM_GLIBC_CUSTOM_FILEDES
+#define __STDIO_STREAM_IS_CUSTOM(S) (0)
+#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...)
+
+#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
+
extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence)
attribute_hidden;
-#define __STDIO_STREAM_RESET_GCS(S) ((void)0)
+static inline ssize_t __READ(FILE *stream, char *buf, size_t bufsize)
+{
+ __STDIO_STREAM_CUSTOM_IO_FUNC(stream, read, -1, buf, bufsize);
-#define __READ(STREAMPTR,BUF,SIZE) \
- (read((STREAMPTR)->__filedes,(BUF),(SIZE)))
-#define __WRITE(STREAMPTR,BUF,SIZE) \
- (write((STREAMPTR)->__filedes,(BUF),(SIZE)))
-#define __SEEK(STREAMPTR,PPOS,WHENCE) \
- (__stdio_seek((STREAMPTR),(PPOS),(WHENCE)))
-#define __CLOSE(STREAMPTR) \
- (close((STREAMPTR)->__filedes))
+ return read(stream->__filedes, buf, bufsize);
+}
-#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
+static inline ssize_t __WRITE(FILE *stream, const char *buf, size_t bufsize)
+{
+ __STDIO_STREAM_CUSTOM_IO_FUNC(stream, write, -1, buf, bufsize);
+
+ return write(stream->__filedes, buf, bufsize);
+}
+
+static inline int __SEEK(FILE *stream, register __offmax_t *pos, int whence)
+{
+ __STDIO_STREAM_CUSTOM_IO_FUNC(stream, seek, -1, pos, whence);
+
+ return __stdio_seek(stream, pos, whence);
+}
+
+static inline int __CLOSE(FILE *stream)
+{
+ __STDIO_STREAM_CUSTOM_IO_FUNC(stream, close, 0);
+
+ return close(stream->__filedes);
+}
/**********************************************************************/
#ifdef __UCLIBC_HAS_WCHAR__
@@ -254,12 +269,6 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int
whence) attr
# define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S) (0)
#endif
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
-#define __STDIO_STREAM_IS_CUSTOM(S) ((S)->__cookie != &((S)->__filedes))
-#else
-#define __STDIO_STREAM_IS_CUSTOM(S) (0)
-#endif
-
/**********************************************************************/
#ifdef __STDIO_BUFFERS
@@ -346,10 +355,10 @@ extern void _store_inttype(void *dest, int desttype, uintmax_t val)
attribute_hi
(S)->__bufread = (S)->__bufpos = (S)->__bufstart
-#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-2)
-#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-2)
-#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-3)
-#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-3)
+#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-3)
+#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-3)
+#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-4)
+#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-4)
#define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) \
((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES)
@@ -386,6 +395,7 @@ extern void _store_inttype(void *dest, int desttype, uintmax_t val)
attribute_hi
#define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) (0)
#define __STDIO_STREAM_IS_FAKE_VSSCANF(S) (0)
#undef __STDIO_STREAM_IS_FAKE_VSWPRINTF
+#undef __STDIO_STREAM_IS_FAKE_VSWSCANF
# ifdef __USE_OLD_VFPRINTF__
# define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB (-2)
@@ -461,3 +471,5 @@ extern int _vfwprintf_internal (FILE * __restrict stream,
#if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) ||
defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)
#define __STDIO_HAS_VSNPRINTF 1
#endif
+
+#endif /* __STDIO_H_I */
diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
index 3417b26..7e7bc3b 100644
--- a/libc/stdio/fclose.c
+++ b/libc/stdio/fclose.c
@@ -69,8 +69,6 @@ int fclose(register FILE *stream)
stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);
#ifndef NDEBUG
- __STDIO_STREAM_RESET_GCS(stream);
-
/* Reinitialize everything (including putc since fflush could fail). */
__STDIO_STREAM_DISABLE_GETC(stream);
__STDIO_STREAM_DISABLE_PUTC(stream);
diff --git a/libc/stdio/fopencookie.c b/libc/stdio/fopencookie.c
index c4927e0..216dac3 100644
--- a/libc/stdio/fopencookie.c
+++ b/libc/stdio/fopencookie.c
@@ -39,21 +39,34 @@ FILE *_fopencookie(void * __restrict cookie, const char * __restrict
mode,
#endif
{
FILE *stream;
+ _IO_cookie_file_t *new_f;
+ new_f = malloc(sizeof(_IO_cookie_file_t));
+ if (new_f == NULL) {
+ return NULL;
+ }
+ new_f->__fp.__modeflags = __FLAG_FREEFILE;
+#ifdef __STDIO_BUFFERS
+ new_f->__fp.__bufstart = NULL; /* We allocate a buffer below. */
+#endif
+#ifdef __UCLIBC_HAS_THREADS__
+ /* We only initialize the mutex in the non-freopen case. */
+ STDIO_INIT_MUTEX(new_f->__fp.__lock);
+#endif
/* Fake an fdopen guaranteed to pass the _stdio_fopen basic agreement
* check without an fcntl call. */
- stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, NULL, INT_MAX);
+ stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, &new_f->__fp, INT_MAX);
if (stream) {
- stream->__filedes = -1;
+ stream->__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES;
#ifndef __BCC__
- stream->__gcs = io_functions;
+ new_f->__gcs = io_functions;
#else
- stream->__gcs.read = io_functions->read;
- stream->__gcs.write = io_functions->write;
- stream->__gcs.seek = io_functions->seek;
- stream->__gcs.close = io_functions->close;
+ new_f->__gcs.read = io_functions->read;
+ new_f->__gcs.write = io_functions->write;
+ new_f->__gcs.seek = io_functions->seek;
+ new_f->__gcs.close = io_functions->close;
#endif
- stream->__cookie = cookie;
+ new_f->__cookie = cookie;
__STDIO_STREAM_VALIDATE(stream);
}
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
index d2fcc70..5df33b4 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -15,7 +15,7 @@ size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,
FILE * __restrict stream)
{
__STDIO_STREAM_VALIDATE(stream);
- assert(stream->__filedes >= -1);
+ assert(stream->__filedes >= -2);
/* Note: If nmbem * size > SIZE_MAX then there is an application
* bug since no array can be larger than SIZE_MAX in size. */
diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
index 457018b..46b8dfe 100644
--- a/libc/stdio/vdprintf.c
+++ b/libc/stdio/vdprintf.c
@@ -26,15 +26,6 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
__STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);
#endif
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = _cs_write;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
f.__filedes = filedes;
f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index 31adc52..3a4c607 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -22,15 +22,6 @@ int vsnprintf(char *__restrict buf, size_t size,
FILE f;
int rv;
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES;
f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
@@ -96,15 +87,6 @@ int vsnprintf(char *__restrict buf, size_t size,
}
f.bufend = buf + size;
-/* __STDIO_STREAM_RESET_GCS(&f.f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.f.__cookie = &(f.f.__filedes);
- f.f.__gcs.read = NULL;
- f.f.__gcs.write = NULL;
- f.f.__gcs.seek = NULL;
- f.f.__gcs.close = NULL;
-#endif
-
f.f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB;
f.f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
@@ -137,7 +119,7 @@ libc_hidden_def(vsnprintf)
typedef struct {
size_t pos;
size_t len;
- unsigned char *buf;
+ char *buf;
FILE *fp;
} __snpf_cookie;
@@ -175,34 +157,34 @@ static ssize_t snpf_write(register void *cookie, const char *buf,
int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
{
- FILE f;
+ _IO_cookie_file_t cf;
__snpf_cookie cookie;
int rv;
cookie.buf = buf;
cookie.len = size;
cookie.pos = 0;
- cookie.fp = &f;
+ cookie.fp = &cf.__fp;
- f.__cookie = &cookie;
- f.__gcs.write = snpf_write;
- f.__gcs.read = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
+ cf.__cookie = &cookie;
+ cf.__gcs.write = snpf_write;
+ cf.__gcs.read = NULL;
+ cf.__gcs.seek = NULL;
+ cf.__gcs.close = NULL;
- f.__filedes = -1; /* For debugging. */
- f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
+ cf.__fp.__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES;
+ cf.__fp.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
#ifdef __UCLIBC_HAS_WCHAR__
- f.__ungot_width[0] = 0;
+ cf.__fp.__ungot_width[0] = 0;
#endif /* __UCLIBC_HAS_WCHAR__ */
#ifdef __STDIO_MBSTATE
- __INIT_MBSTATE(&(f.__state));
+ __INIT_MBSTATE(&(cf.__fp.__state));
#endif /* __STDIO_MBSTATE */
- f.__nextopen = NULL;
+ cf.__fp.__nextopen = NULL;
- rv = _vfprintf_internal(&f, format, arg);
+ rv = _vfprintf_internal(&cf.__fp, format, arg);
return rv;
}
diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c
index 2195248..58a06a7 100644
--- a/libc/stdio/vswprintf.c
+++ b/libc/stdio/vswprintf.c
@@ -22,15 +22,6 @@ int vswprintf(wchar_t *__restrict buf, size_t size,
FILE f;
int rv;
-/* __STDIO_STREAM_RESET_GCS(&f); */
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- f.__cookie = &(f.__filedes);
- f.__gcs.read = NULL;
- f.__gcs.write = NULL;
- f.__gcs.seek = NULL;
- f.__gcs.close = NULL;
-#endif
-
f.__filedes = __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES;
f.__modeflags = (__FLAG_WIDE|__FLAG_WRITEONLY|__FLAG_WRITING);
diff --git a/libc/stdlib/canonicalize.c b/libc/stdlib/canonicalize.c
index 06e710a..da09d58 100644
--- a/libc/stdlib/canonicalize.c
+++ b/libc/stdlib/canonicalize.c
@@ -9,30 +9,11 @@
*/
#include <stdlib.h>
-#include <limits.h>
#ifdef __USE_GNU
-#ifndef PATH_MAX
-# ifdef _POSIX_VERSION
-# define PATH_MAX _POSIX_PATH_MAX
-# else
-# ifdef MAXPATHLEN
-# define PATH_MAX MAXPATHLEN
-# else
-# define PATH_MAX 1024
-# endif
-# endif
-#endif
-
char * canonicalize_file_name (const char *name)
{
- char *buf = (char *) malloc(PATH_MAX);
-
- if(unlikely(buf == NULL))
- return NULL;
-
- *buf='\0';
- return realpath (name, buf);
+ return realpath (name, NULL);
}
#endif
diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
index 5b3a1b3..efd8a6c 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
@@ -245,10 +245,6 @@ struct __STDIO_FILE_STRUCT {
#ifdef __STDIO_HAS_OPENLIST
struct __STDIO_FILE_STRUCT *__nextopen;
#endif
-#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
- void *__cookie;
- _IO_cookie_io_functions_t __gcs;
-#endif
#ifdef __UCLIBC_HAS_WCHAR__
wchar_t __ungot[2];
#endif
diff --git a/libc/sysdeps/linux/powerpc/Makefile.arch
b/libc/sysdeps/linux/powerpc/Makefile.arch
index 4fbcb11..7c09c87 100644
--- a/libc/sysdeps/linux/powerpc/Makefile.arch
+++ b/libc/sysdeps/linux/powerpc/Makefile.arch
@@ -5,7 +5,7 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC-y := __syscall_error.c ioctl.c
+CSRC-y := __syscall_error.c ioctl.c copysignl.c
SSRC-y := \
__longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S \
diff --git a/libc/sysdeps/linux/powerpc/copysignl.c
b/libc/sysdeps/linux/powerpc/copysignl.c
new file mode 100644
index 0000000..000f653
--- /dev/null
+++ b/libc/sysdeps/linux/powerpc/copysignl.c
@@ -0,0 +1,89 @@
+/* s_copysignl.c -- long double version of s_copysign.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper(a)cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * copysignl(long double x, long double y)
+ * copysignl(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include <endian.h>
+#include <stdint.h>
+
+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ int sign_exponent:16;
+ unsigned int empty:16;
+ uint32_t msw;
+ uint32_t lsw;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ uint32_t lsw;
+ uint32_t msw;
+ int sign_exponent:16;
+ unsigned int empty:16;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+/* Get int from the exponent of a long double. */
+
+#define GET_LDOUBLE_EXP(exp,d) \
+do { \
+ ieee_long_double_shape_type ge_u; \
+ ge_u.value = (d); \
+ (exp) = ge_u.parts.sign_exponent; \
+} while (0)
+
+/* Set exponent of a long double from an int. */
+
+#define SET_LDOUBLE_EXP(d,exp) \
+do { \
+ ieee_long_double_shape_type se_u; \
+ se_u.value = (d); \
+ se_u.parts.sign_exponent = (exp); \
+ (d) = se_u.value; \
+} while (0)
+
+long double copysignl(long double x, long double y);
+libc_hidden_proto(copysignl);
+
+long double copysignl(long double x, long double y)
+{
+ uint32_t es1,es2;
+ GET_LDOUBLE_EXP(es1,x);
+ GET_LDOUBLE_EXP(es2,y);
+ SET_LDOUBLE_EXP(x,(es1&0x7fff)|(es2&0x8000));
+ return x;
+}
+
+libc_hidden_def(copysignl);
diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c
index 118820a..bf99252 100644
--- a/libpthread/nptl/allocatestack.c
+++ b/libpthread/nptl/allocatestack.c
@@ -98,8 +98,12 @@
/* Cache handling for not-yet free stacks. */
-/* Maximum size in kB of cache. */
-static size_t stack_cache_maxsize = 40 * 1024 * 1024; /* 40MiBi by default. */
+/*
+ Maximum size in kB of cache. GNU libc default is 40MiB
+ embedded systems don't have enough ram for big dirty stack caches,
+ reduce it to 16MiB. 4 does not work, f.e. tst-kill4 segfaults.
+*/
+static size_t stack_cache_maxsize = 16 * 1024 * 1024;
static size_t stack_cache_actsize;
/* Mutex protecting this variable. */
diff --git a/test/Rules.mak b/test/Rules.mak
index c5d1d63..86ea855 100644
--- a/test/Rules.mak
+++ b/test/Rules.mak
@@ -91,7 +91,9 @@ ifeq ($(DODEBUG),y)
HOST_CFLAGS += -g
LDFLAGS += -Wl,-g
HOST_LDFLAGS += -Wl,-g
-else
+endif
+
+ifeq ($(DOSTRIP),y)
LDFLAGS += -Wl,-s
HOST_LDFLAGS += -Wl,-s
endif
diff --git a/test/Test.mak b/test/Test.mak
index 52992a7..a82505f 100644
--- a/test/Test.mak
+++ b/test/Test.mak
@@ -45,6 +45,9 @@ U_TARGETS += $(TESTS_DISABLED)
G_TARGETS += $(addsuffix _glibc,$(TESTS_DISABLED)) $(GLIBC_TESTS_DISABLED)
TARGETS += $(SHELL_TESTS)
CFLAGS += $(CFLAGS_$(notdir $(CURDIR)))
+ifeq (1,$(UCLIBCNG_GENERATE_TESTRUNNER))
+UCLIBCNG_TEST_SUBDIR ?= $(patsubst $(realpath $(TESTDIR))/%,%,$(CURDIR))
+endif
define binary_name
$(patsubst %.exe,%,$@)
@@ -92,6 +95,7 @@ $(addsuffix .exe,$(U_TARGETS)): SIMULATOR:=$(SIMULATOR_uclibc)
$(addsuffix .exe,$(G_TARGETS)): SIMULATOR:=$(SIMULATOR_glibc)
$(RUN_TARGETS):
ifeq (1,$(UCLIBCNG_GENERATE_TESTRUNNER))
+ $(Q)\
expected_ret="$(RET_$(tst_src_name))"; echo \
"$${expected_ret:-0}" \
$(call shellescape,$(tst_src_name)) \
diff --git a/test/stdio/Makefile.in b/test/stdio/Makefile.in
index 0bfbd13..3e60b40 100644
--- a/test/stdio/Makefile.in
+++ b/test/stdio/Makefile.in
@@ -2,3 +2,9 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
DODIFF_64bit := 1
+
+ifeq ($(UCLIBC_HAS_GLIBC_CUSTOM_STREAMS),)
+TESTS_DISABLED += tst-fmemopen
+endif
+
+CFLAGS_tst-fmemopen = -fPIC
diff --git a/test/stdio/tst-fmemopen.c b/test/stdio/tst-fmemopen.c
new file mode 100644
index 0000000..384faa1
--- /dev/null
+++ b/test/stdio/tst-fmemopen.c
@@ -0,0 +1,53 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static char *text_input = "1 23 43";
+
+static const char *good_answer = "1 529 1849 ";
+
+
+static int
+do_test (void)
+{
+ FILE *out, *in;
+ int v, s;
+ size_t size;
+ char *ptr;
+
+ in = fmemopen(text_input, strlen(text_input), "r");
+ if (in == NULL) {
+ perror("fmemopen");
+ return 1;
+ }
+
+ out = open_memstream(&ptr, &size);
+ if (out == NULL) {
+ perror("open_memstream");
+ return 1;
+ }
+
+ for (;;) {
+ s = fscanf(in, "%d", &v);
+ if (s <= 0)
+ break;
+
+ s = fprintf(out, "%d ", v * v);
+ if (s == -1) {
+ puts("fprintf failed");
+ exit(1);
+ }
+ }
+ fclose(in);
+ fclose(out);
+
+ if (size != strlen(good_answer) || strcmp(good_answer, ptr) != 0) {
+ printf("failed: size=%zu; ptr=%s\n", size, ptr);
+ exit(1);
+ }
+ free(ptr);
+ exit(0);
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/test/tls/tls-macros-mips.h b/test/tls/tls-macros-mips.h
index 0db3830..eed0938 100644
--- a/test/tls/tls-macros-mips.h
+++ b/test/tls/tls-macros-mips.h
@@ -1,44 +1,56 @@
/* Macros to support TLS testing in times of missing compiler support. */
-#if _MIPS_SIM != _ABI64
+#include <sys/cdefs.h>
+#include <sys/asm.h>
-/* These versions are for o32 and n32. */
+#define __STRING2(X) __STRING(X)
+#define ADDU __STRING2(PTR_ADDU)
+#define ADDIU __STRING2(PTR_ADDIU)
+#define LW __STRING2(PTR_L)
-# define TLS_GD(x) \
- ({ void *__result; \
- extern void *__tls_get_addr (void *); \
- __asm__ ("addiu %0, $28, %%tlsgd(" #x ")" \
- : "=r" (__result)); \
- (int *)__tls_get_addr (__result); })
+/* Load the GOT pointer, which may not be in $28 in a non-PIC
+ (abicalls pic0) function. */
+#ifndef __PIC__
+# if _MIPS_SIM != _ABI64
+# define LOAD_GP "move %[tmp], $28\n\tla $28, __gnu_local_gp\n\t"
+# else
+# define LOAD_GP "move %[tmp], $28\n\tdla $28, __gnu_local_gp\n\t"
+# endif
+# define UNLOAD_GP "\n\tmove $28, %[tmp]"
#else
+# define LOAD_GP
+# define UNLOAD_GP
+#endif
+
# define TLS_GD(x) \
- ({ void *__result; \
+ ({ void *__result, *__tmp; \
extern void *__tls_get_addr (void *); \
- __asm__ ("daddiu %0, $28, %%tlsgd(" #x ")" \
- : "=r" (__result)); \
+ __asm__ (LOAD_GP ADDIU " %0, $28, %%tlsgd(" #x ")" \
+ UNLOAD_GP \
+ : "=r" (__result), [tmp] "=&r" (__tmp)); \
(int *)__tls_get_addr (__result); })
-#endif
-
-#if _MIPS_SIM != _ABI64
# define TLS_LD(x) \
- ({ void *__result; \
+ ({ void *__result, *__tmp; \
extern void *__tls_get_addr (void *); \
- __asm__ ("addiu %0, $28, %%tlsldm(" #x ")" \
- : "=r" (__result)); \
+ __asm__ (LOAD_GP ADDIU " %0, $28, %%tlsldm(" #x ")" \
+ UNLOAD_GP \
+ : "=r" (__result), [tmp] "=&r" (__tmp)); \
__result = __tls_get_addr (__result); \
__asm__ ("lui $3,%%dtprel_hi(" #x ")\n\t" \
"addiu $3,$3,%%dtprel_lo(" #x ")\n\t" \
- "addu %0,%0,$3" \
+ ADDU " %0,%0,$3" \
: "+r" (__result) : : "$3"); \
__result; })
# define TLS_IE(x) \
- ({ void *__result; \
+ ({ void *__result, *__tmp; \
__asm__ (".set push\n\t.set mips32r2\n\t" \
"rdhwr\t%0,$29\n\t.set pop" \
: "=v" (__result)); \
- __asm__ ("lw $3,%%gottprel(" #x ")($28)\n\t" \
- "addu %0,%0,$3" \
- : "+r" (__result) : : "$3"); \
+ __asm__ (LOAD_GP LW " $3,%%gottprel(" #x ")($28)\n\t" \
+ ADDU " %0,%0,$3" \
+ UNLOAD_GP \
+ : "+r" (__result), [tmp] "=&r" (__tmp) \
+ : : "$3"); \
__result; })
# define TLS_LE(x) \
({ void *__result; \
@@ -47,42 +59,6 @@
: "=v" (__result)); \
__asm__ ("lui $3,%%tprel_hi(" #x ")\n\t" \
"addiu $3,$3,%%tprel_lo(" #x ")\n\t" \
- "addu %0,%0,$3" \
+ ADDU " %0,%0,$3" \
: "+r" (__result) : : "$3"); \
__result; })
-
-#else
-
-/* These versions are for n64. */
-
-# define TLS_LD(x) \
- ({ void *__result; \
- extern void *__tls_get_addr (void *); \
- __asm__ ("daddiu %0, $28, %%tlsldm(" #x ")" \
- : "=r" (__result)); \
- __result = __tls_get_addr (__result); \
- __asm__ ("lui $3,%%dtprel_hi(" #x ")\n\t" \
- "daddiu $3,$3,%%dtprel_lo(" #x ")\n\t" \
- "daddu %0,%0,$3" \
- : "+r" (__result) : : "$3"); \
- __result; })
-# define TLS_IE(x) \
- ({ void *__result; \
- __asm__ (".set push\n\t.set mips32r2\n\t" \
- "rdhwr\t%0,$29\n\t.set pop" \
- : "=v" (__result)); \
- __asm__ ("ld $3,%%gottprel(" #x ")($28)\n\t" \
- "daddu %0,%0,$3" \
- : "+r" (__result) : : "$3"); \
- __result; })
-# define TLS_LE(x) \
- ({ void *__result; \
- __asm__ (".set push\n\t.set mips32r2\n\t" \
- "rdhwr\t%0,$29\n\t.set pop" \
- : "=v" (__result)); \
- __asm__ ("lui $3,%%tprel_hi(" #x ")\n\t" \
- "daddiu $3,$3,%%tprel_lo(" #x ")\n\t" \
- "daddu %0,%0,$3" \
- : "+r" (__result) : : "$3"); \
- __result; })
-#endif
diff --git a/test/tls/tls-macros.h b/test/tls/tls-macros.h
index d243743..e4d87f2 100644
--- a/test/tls/tls-macros.h
+++ b/test/tls/tls-macros.h
@@ -111,15 +111,15 @@
# define TLS_LE(x) \
({ int *__l; \
- __asm__ ("movq %%fs:0,%0\n\t" \
- "leaq " #x "@tpoff(%0), %0" \
+ __asm__ ("mov %%fs:0,%0\n\t" \
+ "lea " #x "@tpoff(%0), %0" \
: "=r" (__l)); \
__l; })
# define TLS_IE(x) \
({ int *__l; \
- __asm__ ("movq %%fs:0,%0\n\t" \
- "addq " #x "@gottpoff(%%rip),%0" \
+ __asm__ ("mov %%fs:0,%0\n\t" \
+ "add " #x "@gottpoff(%%rip),%0" \
: "=r" (__l)); \
__l; })
@@ -132,9 +132,15 @@
: : "rdi", "rsi", "r8", "r9", "r10",
"r11"); \
__l; })
+# ifdef __ILP32__
+# define TLS_GD_PREFIX
+# else
+# define TLS_GD_PREFIX ".byte 0x66\n\t"
+# endif
+
# define TLS_GD(x) \
({ int *__l, __c, __d; \
- __asm__ (".byte 0x66\n\t" \
+ __asm__ (TLS_GD_PREFIX \
"leaq " #x "@tlsgd(%%rip),%%rdi\n\t" \
".word 0x6666\n\t" \
"rex64\n\t" \
diff --git a/utils/Makefile.in b/utils/Makefile.in
index d725282..a601721 100644
--- a/utils/Makefile.in
+++ b/utils/Makefile.in
@@ -14,6 +14,7 @@ CFLAGS-utils := \
-I$(top_srcdir)ldso/include \
-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" \
+ -DARCH_NATIVE_BIT=$(ARCH_NATIVE_BIT) \
-I$(top_srcdir)/$(KERNEL_HEADERS) \
-DNOT_IN_libc \
-B$(top_builddir)lib \
diff --git a/utils/ldd.c b/utils/ldd.c
index a12acd2..7e1c314 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -174,10 +174,10 @@ static __inline__ uint64_t byteswap64_to_host(uint64_t value)
}
}
-#if ELFCLASSM == ELFCLASS32
-# define byteswap_to_host(x) byteswap32_to_host(x)
-#else
+#if __WORDSIZE == 64
# define byteswap_to_host(x) byteswap64_to_host(x)
+#else
+# define byteswap_to_host(x) byteswap32_to_host(x)
#endif
static ElfW(Shdr) *elf_find_section_type(uint32_t key, ElfW(Ehdr) *ehdr)
@@ -239,7 +239,8 @@ static char *elf_find_rpath(ElfW(Ehdr) *ehdr, ElfW(Dyn) *dynamic)
static int check_elf_header(ElfW(Ehdr) *const ehdr)
{
if (!ehdr || *(uint32_t*)ehdr != ELFMAG_U32
- || ehdr->e_ident[EI_CLASS] != ELFCLASSM
+ /* Use __WORDSIZE, not ELFCLASSM which depends on the host */
+ || ehdr->e_ident[EI_CLASS] != (__WORDSIZE >> 5)
|| ehdr->e_ident[EI_VERSION] != EV_CURRENT
) {
return 1;
@@ -506,6 +507,8 @@ static int add_library(ElfW(Ehdr) *ehdr, ElfW(Dyn) *dynamic, int
is_setuid, char
for (cur = lib_list; cur; cur = cur->next) {
/* Check if this library is already in the list */
tmp1 = tmp2 = cur->name;
+ if (!cur->name)
+ continue;
while (*tmp1) {
if (*tmp1 == '/')
tmp2 = tmp1 + 1;
@@ -583,6 +586,8 @@ static struct library *find_elf_interpreter(ElfW(Ehdr) *ehdr)
}
for (cur = lib_list; cur; cur = cur->next) {
/* Check if this library is already in the list */
+ if (!tmp1 || !cur->name)
+ return NULL;
if (strcmp(cur->name, tmp1) == 0) {
/*printf("find_elf_interpreter is replacing '%s' (already in
list)\n", cur->name); */
newlib = cur;
diff --git a/utils/porting.h b/utils/porting.h
index f1fdc70..f830741 100644
--- a/utils/porting.h
+++ b/utils/porting.h
@@ -41,6 +41,16 @@
#include "dl-defs.h"
#endif
+/* __WORDSIZE ist used for __ELF_NATIVE_CLASS, which is used for ElfW().
+ We want to provide the wordsize of the target, not of the host, when
+ compiling readelf.host
+ */
+#include <link.h>
+#ifdef ARCH_NATIVE_BIT
+#undef __WORDSIZE
+#define __WORDSIZE ARCH_NATIVE_BIT
+#endif
+
#ifdef DMALLOC
#include <dmalloc.h>
#endif
hooks/post-receive
--
uClibc-ng - small C library for embedded systems